static void handleMethodCall(GDBusConnection *connection, const gchar *sender, const gchar *object_path, const gchar *interface_name, const gchar *method_name, GVariant *parameters, GDBusMethodInvocation *invocation, gpointer user_data) { AutomotiveManager* manager = static_cast<AutomotiveManager*>(user_data); std::string method = method_name; uint pid = getPid(sender); if(DebugOut::getDebugThreshhold() >= 6) { DebugOut(6)<<"DBus method call from: "<<sender<< " pid: " <<pid<< " interface: "<<interface_name<<" method: "<<method<<endl; DebugOut(6)<<"DBus method call path: "<<object_path<<endl; } if(method == "FindObject") { gchar* arg; g_variant_get(parameters,"(s)",&arg); std::string objectToFind = arg; if(objectToFind == "") { g_dbus_method_invocation_return_error(invocation,G_DBUS_ERROR,G_DBUS_ERROR_INVALID_ARGS, "Invalid argument."); return; } std::list<AbstractDBusInterface*> interfaces = AbstractDBusInterface::getObjectsForProperty(objectToFind); if(!interfaces.size()) { g_dbus_method_invocation_return_dbus_error(invocation,"org.automotive.Manager.ObjectNotFound", "Object not found"); return; } GVariantBuilder params; g_variant_builder_init(¶ms, G_VARIANT_TYPE_ARRAY); bool hasItems = false; for(auto itr = interfaces.begin(); itr != interfaces.end(); itr++) { AbstractDBusInterface* t = *itr; if(!t->isSupported()) continue; hasItems = true; if(!t->isRegistered()) t->registerObject(); std::list<std::string> processes = manager->subscribedProcesses[t]; if(!contains(processes,sender)) { DebugOut()<<"Referencing "<<t->objectPath()<<" with sender: "<<sender<<endl; manager->subscribedProcesses[t].push_back(sender); } GVariant *newvar = g_variant_new("o",t->objectPath().c_str()); g_variant_builder_add_value(¶ms, newvar); } if(hasItems) g_dbus_method_invocation_return_value(invocation, g_variant_new("(ao)",¶ms)); else g_dbus_method_invocation_return_dbus_error(invocation,"org.automotive.Manager.ObjectNotFound", "Property not found"); } else if(method == "FindObjectForZone") { gchar* arg; int zone; g_variant_get(parameters,"(si)", &arg, &zone); std::string propertyToFind = arg; if(propertyToFind == "") { g_dbus_method_invocation_return_error(invocation,G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, "Invalid argument."); return; } std::list<AbstractDBusInterface*> interfaces = AbstractDBusInterface::getObjectsForProperty(propertyToFind); if(!interfaces.size()) { g_dbus_method_invocation_return_dbus_error(invocation, "org.automotive.Manager.ObjectNotFound", "Property not found"); return; } for(auto itr = interfaces.begin(); itr != interfaces.end(); itr++) { AbstractDBusInterface* t = *itr; if(t->zone() == (Zone::Type)zone) { if(!t->isRegistered()) t->registerObject(); std::list<std::string> processes = manager->subscribedProcesses[t]; if(!contains(processes,sender)) { DebugOut()<<"Referencing "<<t->objectPath()<<" with sender: "<<sender<<endl; manager->subscribedProcesses[t].push_back(sender); } g_dbus_method_invocation_return_value(invocation,g_variant_new("(o)", t->objectPath().c_str())); return; } } g_dbus_method_invocation_return_dbus_error(invocation,"org.automotive.Manager.InvalidZone", "zone not found"); } else if (method == "ZonesForObjectName") { gchar* arg; g_variant_get(parameters,"(s)",&arg); std::string propertyToFind = arg; if(propertyToFind == "") { g_dbus_method_invocation_return_error(invocation, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, "Invalid argument."); return; } std::list<AbstractDBusInterface*> interfaces = AbstractDBusInterface::getObjectsForProperty(propertyToFind); if(!interfaces.size()) { g_dbus_method_invocation_return_dbus_error(invocation,"org.automotive.Manager.ObjectNotFound", "Property not found"); return; } GVariantBuilder params; g_variant_builder_init(¶ms, G_VARIANT_TYPE_ARRAY); for(auto itr = interfaces.begin(); itr != interfaces.end(); itr++) { AbstractDBusInterface* t = *itr; GVariant *newvar = g_variant_new("i",t->zone()); g_variant_builder_add_value(¶ms, newvar); } g_dbus_method_invocation_return_value(invocation,g_variant_new("(ai)",¶ms)); } else if(method == "List") { std::list<AbstractDBusInterface*> list = AbstractDBusInterface::interfaces(); if(!list.size()) { g_dbus_method_invocation_return_dbus_error(invocation,"org.automotive.Manager.Error", "No supported objects"); return; } GVariantBuilder builder; g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY); for(auto itr = list.begin(); itr != list.end(); itr++) { if(!(*itr)->isSupported()) continue; std::string objectName = (*itr)->objectName(); g_variant_builder_add(&builder, "s", objectName.c_str()); } g_dbus_method_invocation_return_value(invocation,g_variant_new("(as)",&builder)); } else if(method == "SourcesForObjectName") { gchar* arg; g_variant_get(parameters,"(s)",&arg); std::string propertyToFind = arg; if(propertyToFind == "") { g_dbus_method_invocation_return_error(invocation, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, "Invalid argument."); return; } std::list<AbstractDBusInterface*> interfaces = AbstractDBusInterface::getObjectsForProperty(propertyToFind); if(!interfaces.size()) { g_dbus_method_invocation_return_dbus_error(invocation,"org.automotive.Manager.ObjectNotFound", "Property not found"); return; } GVariantBuilder params; g_variant_builder_init(¶ms, G_VARIANT_TYPE_ARRAY); for(auto itr = interfaces.begin(); itr != interfaces.end(); itr++) { AbstractDBusInterface* t = *itr; string source = t->source(); boost::algorithm::erase_all(source, "-"); GVariant *newvar = g_variant_new("s", source.c_str()); g_variant_builder_add_value(¶ms, newvar); } g_dbus_method_invocation_return_value(invocation,g_variant_new("(as)",¶ms)); } else if(method == "FindObjectForSourceZone") { gchar* arg; gchar* arg2; int zone; g_variant_get(parameters,"(ssi)", &arg, &arg2, &zone); std::string propertyToFind = arg; std::string source = arg2; if(propertyToFind == "" || source == "") { g_dbus_method_invocation_return_error(invocation,G_DBUS_ERROR,G_DBUS_ERROR_INVALID_ARGS, "Invalid argument."); return; } std::list<AbstractDBusInterface*> interfaces = AbstractDBusInterface::getObjectsForProperty(propertyToFind); if(!interfaces.size()) { g_dbus_method_invocation_return_dbus_error(invocation,"org.automotive.Manager.ObjectNotFound", "Property not found"); return; } for(auto itr = interfaces.begin(); itr != interfaces.end(); itr++) { AbstractDBusInterface* t = *itr; string targetSource = t->source(); boost::algorithm::erase_all(targetSource, "-"); if(t->zone() == (Zone::Type)zone && source == targetSource) { if(!t->isRegistered()) t->registerObject(); std::list<std::string> processes = manager->subscribedProcesses[t]; if(!contains(processes,sender)) { DebugOut()<<"Referencing "<<t->objectPath()<<" with sender: "<<sender<<endl; manager->subscribedProcesses[t].push_back(sender); } g_dbus_method_invocation_return_value(invocation,g_variant_new("(o)", t->objectPath().c_str())); return; } } g_dbus_method_invocation_return_dbus_error(invocation,"org.automotive.Manager.ObjectNotFound", "Property not found"); } else if(method == "SupportsProperty") { gchar* objectName; gchar* propertyToFindStr; g_variant_get(parameters,"(ss)",&objectName, &propertyToFindStr); auto objectNamePtr = amb::make_super(objectName); auto propertyToFindStrPtr = amb::make_super(propertyToFindStr); DebugOut(6) << "Checking " << objectNamePtr.get() << " for member: " << propertyToFindStrPtr.get() << endl; std::list<AbstractDBusInterface*> interfaces = AbstractDBusInterface::getObjectsForProperty(objectNamePtr.get()); for(auto i : interfaces) { if(i->hasPropertyDBus(propertyToFindStrPtr.get())) { DebugOut(6) << "member " << propertyToFindStrPtr.get() << " of " << objectNamePtr.get() << " was found!!" << endl; g_dbus_method_invocation_return_value(invocation, g_variant_new("(b)", true)); return; } } DebugOut(6) << "member " << propertyToFindStrPtr.get() << " of " << objectNamePtr.get() << " was not found." << endl; g_dbus_method_invocation_return_value(invocation,g_variant_new("(b)", false)); } else { g_dbus_method_invocation_return_error(invocation,G_DBUS_ERROR,G_DBUS_ERROR_UNKNOWN_METHOD, "Unknown method."); } }
static void handleMethodCall(GDBusConnection *connection, const gchar *sender, const gchar *object_path, const gchar *interface_name, const gchar *method_name, GVariant *parameters, GDBusMethodInvocation *invocation, gpointer user_data) { AutomotiveManager* manager = static_cast<AutomotiveManager*>(user_data); std::string method = method_name; if(method == "findProperty") { DebugOut(DebugOut::Warning)<<"org.automotive.Manager.findProperty() is deprecated. Use org.automotive.Manager.FindObject() instead."<<endl; gchar* arg; g_variant_get(parameters,"(s)",&arg); std::string objectToFind = arg; if(objectToFind == "") { g_dbus_method_invocation_return_error(invocation,G_DBUS_ERROR,G_DBUS_ERROR_INVALID_ARGS, "Invalid argument."); return; } std::list<AbstractDBusInterface*> interfaces = AbstractDBusInterface::getObjectsForProperty(objectToFind); if(!interfaces.size()) { g_dbus_method_invocation_return_dbus_error(invocation,"org.automotive.Manager.PropertyNotFound", "Object not found"); return; } auto itr = interfaces.begin(); g_dbus_method_invocation_return_value(invocation, g_variant_new("(o)",(*itr)->objectPath().c_str())); ///TODO: we might need to clean up stuff there (like var) } else if(method == "FindObject") { gchar* arg; g_variant_get(parameters,"(s)",&arg); std::string objectToFind = arg; if(objectToFind == "") { g_dbus_method_invocation_return_error(invocation,G_DBUS_ERROR,G_DBUS_ERROR_INVALID_ARGS, "Invalid argument."); return; } std::list<AbstractDBusInterface*> interfaces = AbstractDBusInterface::getObjectsForProperty(objectToFind); if(!interfaces.size()) { g_dbus_method_invocation_return_dbus_error(invocation,"org.automotive.Manager.ObjectNotFound", "Object not found"); return; } GVariantBuilder params; g_variant_builder_init(¶ms, G_VARIANT_TYPE_ARRAY); for(auto itr = interfaces.begin(); itr != interfaces.end(); itr++) { AbstractDBusInterface* t = *itr; if(!t->isSupported()) continue; GVariant *newvar = g_variant_new("o",t->objectPath().c_str()); g_variant_builder_add_value(¶ms, newvar); } //GVariant* var = g_variant_builder_end(¶ms); g_dbus_method_invocation_return_value(invocation, g_variant_new("(ao)",¶ms)); ///TODO: we might need to clean up stuff there (like var) } else if(method == "FindObjectForZone") { gchar* arg; int zone; g_variant_get(parameters,"(si)", &arg, &zone); std::string propertyToFind = arg; if(propertyToFind == "") { g_dbus_method_invocation_return_error(invocation,G_DBUS_ERROR,G_DBUS_ERROR_INVALID_ARGS, "Invalid argument."); return; } std::list<AbstractDBusInterface*> interfaces = AbstractDBusInterface::getObjectsForProperty(propertyToFind); if(!interfaces.size()) { g_dbus_method_invocation_return_dbus_error(invocation,"org.automotive.Manager.ObjectNotFound", "Property not found"); return; } for(auto itr = interfaces.begin(); itr != interfaces.end(); itr++) { AbstractDBusInterface* t = *itr; if(t->zone() == (Zone::Type)zone) { g_dbus_method_invocation_return_value(invocation,g_variant_new("(o)", t->objectPath().c_str())); return; } } g_dbus_method_invocation_return_dbus_error(invocation,"org.automotive.Manager.ObjectNotFound", "Property not found"); } else if (method == "ZonesForObjectName") { gchar* arg; g_variant_get(parameters,"(s)",&arg); std::string propertyToFind = arg; if(propertyToFind == "") { g_dbus_method_invocation_return_error(invocation, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, "Invalid argument."); return; } std::list<AbstractDBusInterface*> interfaces = AbstractDBusInterface::getObjectsForProperty(propertyToFind); if(!interfaces.size()) { g_dbus_method_invocation_return_dbus_error(invocation,"org.automotive.Manager.ObjectNotFound", "Property not found"); return; } GVariantBuilder params; g_variant_builder_init(¶ms, G_VARIANT_TYPE_ARRAY); for(auto itr = interfaces.begin(); itr != interfaces.end(); itr++) { AbstractDBusInterface* t = *itr; GVariant *newvar = g_variant_new("i",t->zone()); g_variant_builder_add_value(¶ms, newvar); } g_dbus_method_invocation_return_value(invocation,g_variant_new("(ai)",¶ms)); } else if(method == "List") { std::list<AbstractDBusInterface*> list = AbstractDBusInterface::interfaces(); if(!list.size()) { g_dbus_method_invocation_return_dbus_error(invocation,"org.automotive.Manager.Error", "No supported objects"); return; } GVariantBuilder builder; g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY); for(auto itr = list.begin(); itr != list.end(); itr++) { if(!(*itr)->isSupported()) continue; std::string objectName = (*itr)->objectName(); g_variant_builder_add(&builder, "s", objectName.c_str()); } g_dbus_method_invocation_return_value(invocation,g_variant_new("(as)",&builder)); } g_dbus_method_invocation_return_error(invocation,G_DBUS_ERROR,G_DBUS_ERROR_UNKNOWN_METHOD, "Unknown method."); }
void AbstractDBusInterface::handleMyMethodCall(GDBusConnection *connection, const gchar *sender, const gchar *object_path, const gchar *interface_name, const gchar *method_name, GVariant *parameters, GDBusMethodInvocation *invocation, gpointer user_data) { std::string method = method_name; AbstractDBusInterface* iface = static_cast<AbstractDBusInterface*>(user_data); if(DebugOut::getDebugThreshhold() >= 6) { DebugOut(6)<<"DBus method call from: "<<sender<< " pid: " <<getPid(sender)<< " interface: "<<interface_name<<" method: "<<method<<endl; DebugOut(6)<<"DBus method call path: "<<object_path<<endl; } g_assert(iface); if(std::string(interface_name) == "org.freedesktop.DBus.Properties") { if(method == "Get") { gchar* propertyName = nullptr; gchar* ifaceName = nullptr; g_variant_get(parameters, "(ss)", &ifaceName, &propertyName); DebugOut(6) << "Parameter signature: " << g_variant_get_type_string(parameters) << endl; // DebugOut(6) << "Get property " << propertyName << " for interface " << ifaceName << endl; GError* error = nullptr; auto value = AbstractDBusInterface::getProperty(connection, sender, object_path, ifaceName, propertyName, &error, iface); amb::make_super(error); if(!value) { g_dbus_method_invocation_return_dbus_error(invocation, std::string(std::string(ifaceName)+".PropertyNotFound").c_str(), "Property not found in interface"); } g_dbus_method_invocation_return_value(invocation, g_variant_new("(v)", value)); return; } else if(method == "GetAll") { gchar* ifaceName = nullptr; g_variant_get(parameters, "(s)", &ifaceName); GVariantBuilder builder; g_variant_builder_init(&builder, G_VARIANT_TYPE("a{sv}")); auto propertyMap = iface->getProperties(); for(auto itr : propertyMap) { auto prop = itr.second; GError* error = nullptr; auto value = AbstractDBusInterface::getProperty(connection, sender, object_path, ifaceName, prop->name().c_str(), &error, iface); amb::make_super(error); g_variant_builder_add(&builder, "{sv}", prop->name().c_str(), g_variant_new("v", value)); //sequence auto sequence = AbstractDBusInterface::getProperty(connection, sender, object_path, ifaceName, std::string(prop->name()+"Sequence").c_str(), &error, iface); g_variant_builder_add(&builder, "{sv}", std::string(prop->name()+"Sequence").c_str(), g_variant_new("v", sequence)); auto quality = AbstractDBusInterface::getProperty(connection, sender, object_path, ifaceName, std::string(prop->name()+"ValueQuality").c_str(), &error, iface); g_variant_builder_add(&builder, "{sv}", std::string(prop->name()+"ValueQuality").c_str(), g_variant_new("v", quality)); auto freq = AbstractDBusInterface::getProperty(connection, sender, object_path, ifaceName, std::string(prop->name()+"UpdateFrequency").c_str(), &error, iface); g_variant_builder_add(&builder, "{sv}", std::string(prop->name()+"UpdateFrequency").c_str(), g_variant_new("v", freq)); } auto time = AbstractDBusInterface::getProperty(connection, sender, object_path, ifaceName, "Time", nullptr, iface); auto zone = AbstractDBusInterface::getProperty(connection, sender, object_path, ifaceName, "Zone", nullptr, iface); g_variant_builder_add(&builder, "{sv}", "Time", g_variant_new("v", time)); g_variant_builder_add(&builder, "{sv}", "Zone", g_variant_new("v", zone)); g_dbus_method_invocation_return_value(invocation, g_variant_new("(a{sv})", &builder)); return; } else if(method == "Set") { gchar* ifaceName = nullptr; gchar* propName = nullptr; GVariant* value; g_variant_get(parameters, "(ssv)", &ifaceName, &propName, &value); AbstractDBusInterface::setProperty(connection, sender, object_path, ifaceName, propName, value, nullptr, iface, [&invocation, &ifaceName](bool success, AsyncPropertyReply::Error error) { if(success) { g_dbus_method_invocation_return_value(invocation, nullptr); } else { g_dbus_method_invocation_return_dbus_error(invocation, ifaceName, AsyncPropertyReply::errorToStr(error).c_str()); } }); return; } } else if(method == "GetHistory") { double beginTime = 0; double endTime = 0; g_variant_get(parameters, "(dd)", &beginTime, &endTime); auto propertyMap = iface->getProperties(); PropertyList propertyList; for(auto itr = propertyMap.begin(); itr != propertyMap.end(); itr++) { VariantType* prop = (*itr).second; if(!contains(propertyList, prop->ambPropertyName())) propertyList.push_back(prop->ambPropertyName()); } std::string ifaceName = iface->interfaceName(); AsyncRangePropertyRequest request; request.properties = propertyList; request.timeBegin = beginTime; request.timeEnd = endTime; request.zone = iface->zone(); //request.sourceUuid = iface->source(); request.completed = [&invocation,&ifaceName](AsyncRangePropertyReply* r) { auto reply = amb::make_unique(r); if(!reply->success) { stringstream str; str<<"Error during request: "<<AsyncPropertyReply::errorToStr(reply->error); ifaceName += ".Error"; g_dbus_method_invocation_return_dbus_error(invocation, ifaceName.c_str(), str.str().c_str()); return; } if(!reply->values.size()) { ifaceName += ".Error"; g_dbus_method_invocation_return_dbus_error(invocation, ifaceName.c_str(), "No results"); return; } GVariantBuilder builder; g_variant_builder_init(&builder, G_VARIANT_TYPE("a{svd}")); for(auto itr = reply->values.begin(); itr != reply->values.end(); itr++) { AbstractPropertyType* value = *itr; g_variant_builder_add(&builder, "{svd}", value->name.c_str(), g_variant_ref(value->toVariant()),value->timestamp); } g_dbus_method_invocation_return_value(invocation,g_variant_new("(a{svd})",&builder)); }; iface->re->getRangePropertyAsync(request); return; } g_dbus_method_invocation_return_error(invocation,G_DBUS_ERROR,G_DBUS_ERROR_UNKNOWN_METHOD, "Unknown method."); }