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."); }