static void signalCallback( GDBusConnection *connection, const gchar *sender_name, const gchar *object_path, const gchar *interface_name, const gchar *signal_name, GVariant *parameters, gpointer user_data) { AutomotiveManager* manager = static_cast<AutomotiveManager*>(user_data); if(!manager) { DebugOut(DebugOut::Error)<<"Bad user_data"<<endl; return; } gchar* name=nullptr; gchar* newOwner=nullptr; gchar* oldOwner = nullptr; g_variant_get(parameters,"(sss)",&name, &oldOwner, &newOwner); std::list<AbstractDBusInterface*> toRemove; if(std::string(newOwner) == "") { for(auto &i : manager->subscribedProcesses) { AbstractDBusInterface* iface = i.first; for(auto itr = i.second.begin(); itr != i.second.end(); itr++) { std::string n = *itr; if(n == name) { DebugOut()<<"unreferencing "<<n<<" from the subscription of "<<iface->objectPath()<<endl; itr = manager->subscribedProcesses[iface].erase(itr); DebugOut()<<"new ref count: "<<manager->subscribedProcesses[iface].size()<<endl; } } if(manager->subscribedProcesses[iface].empty()) { DebugOut()<<"No more subscribers. Unregistering: "<<iface->objectPath()<<endl; ///Defer removal to not screw up the list toRemove.push_back(iface); iface->unregisterObject(); } } for(auto & i : toRemove) { manager->subscribedProcesses.erase(i); } } g_free(name); g_free(newOwner); g_free(oldOwner); }
static void signalCallback( GDBusConnection *connection, const gchar *sender_name, const gchar *object_path, const gchar *interface_name, const gchar *signal_name, GVariant *parameters, gpointer user_data) { AutomotiveManager* manager = static_cast<AutomotiveManager*>(user_data); gchar* name=nullptr; gchar* newOwner=nullptr; gchar* oldOwner = nullptr; g_variant_get(parameters,"(sss)",&name, &oldOwner, &newOwner); if(std::string(newOwner) == "") { for(auto i : manager->subscribedProcesses) { AbstractDBusInterface* iface = i.first; for(auto n : i.second) { if(n == name) { DebugOut()<<"unreferencing "<<n<<" from the subscription of "<<iface->objectPath()<<endl; manager->subscribedProcesses[iface].remove(n); } } if(manager->subscribedProcesses[iface].empty()) { DebugOut()<<"No more subscribers. Unregistering."<<endl; iface->unregisterObject(); } } } g_free(name); g_free(newOwner); g_free(oldOwner); }
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."); }
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."); } }