diff options
-rw-r--r-- | tdecore/tdehw/hwlibdaemons/dbus/org.trinitydesktop.hardwarecontrol.conf | 15 | ||||
-rw-r--r-- | tdecore/tdehw/hwlibdaemons/dbus/tde_dbus_hardwarecontrol.cpp | 287 |
2 files changed, 287 insertions, 15 deletions
diff --git a/tdecore/tdehw/hwlibdaemons/dbus/org.trinitydesktop.hardwarecontrol.conf b/tdecore/tdehw/hwlibdaemons/dbus/org.trinitydesktop.hardwarecontrol.conf index 47fbee050..5ef5e52f0 100644 --- a/tdecore/tdehw/hwlibdaemons/dbus/org.trinitydesktop.hardwarecontrol.conf +++ b/tdecore/tdehw/hwlibdaemons/dbus/org.trinitydesktop.hardwarecontrol.conf @@ -13,17 +13,10 @@ <policy context="default"> <allow send_destination="org.trinitydesktop.hardwarecontrol" send_interface="org.freedesktop.DBus.Introspectable"/> - - <allow send_destination="org.trinitydesktop.hardwarecontrol" - send_interface="org.freedesktop.DBus.Properties"/> - <allow send_destination="org.trinitydesktop.hardwarecontrol.Brightness" - send_interface="org.freedesktop.DBus.Properties"/> - <allow send_destination="org.trinitydesktop.hardwarecontrol.CPUGovernor" - send_interface="org.freedesktop.DBus.Properties"/> - <allow send_destination="org.trinitydesktop.hardwarecontrol.InputEvents" - send_interface="org.freedesktop.DBus.Properties"/> - <allow send_destination="org.trinitydesktop.hardwarecontrol.Power" - send_interface="org.freedesktop.DBus.Properties"/> + <allow send_destination="org.trinitydesktop.hardwarecontrol" + send_interface="org.freedesktop.DBus.Peer"/> + <allow send_destination="org.trinitydesktop.hardwarecontrol" + send_interface="org.freedesktop.DBus.Properties"/> <allow send_destination="org.trinitydesktop.hardwarecontrol" send_interface="org.trinitydesktop.hardwarecontrol"/> diff --git a/tdecore/tdehw/hwlibdaemons/dbus/tde_dbus_hardwarecontrol.cpp b/tdecore/tdehw/hwlibdaemons/dbus/tde_dbus_hardwarecontrol.cpp index 3ef9196ee..ce6343601 100644 --- a/tdecore/tdehw/hwlibdaemons/dbus/tde_dbus_hardwarecontrol.cpp +++ b/tdecore/tdehw/hwlibdaemons/dbus/tde_dbus_hardwarecontrol.cpp @@ -90,6 +90,33 @@ void replyBool(DBusMessage* msg, DBusConnection* conn, int value) { dbus_message_unref(reply); } +void replyString(DBusMessage* msg, DBusConnection* conn, const char *str) { + DBusMessage* reply; + DBusMessageIter args; + const char* member = dbus_message_get_member(msg); + dbus_uint32_t serial = 0; + + // create a reply from the message + reply = dbus_message_new_method_return(msg); + + // add the arguments to the reply + dbus_message_iter_init_append(reply, &args); + if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &str)) { + fprintf(stderr, "[tde_dbus_hardwarecontrol] %s: dbus_message_iter_append_basic failed\n", member); + return; + } + + // send the reply && flush the connection + if (!dbus_connection_send(conn, reply, &serial)) { + fprintf(stderr, "[tde_dbus_hardwarecontrol] %s: dbus_connection_send failed\n", member); + return; + } + dbus_connection_flush(conn); + + // free the reply + dbus_message_unref(reply); +} + bool setGivenPath(const char *path, const char *contents) { int writable = (access(path, W_OK) == 0); bool result = false; @@ -504,6 +531,40 @@ void reply_Introspect(DBusMessage* msg, DBusConnection* conn) { } else if(strcmp("/org/trinitydesktop/hardwarecontrol", path) == 0) { strncat(data, + " <interface name=\"org.freedesktop.DBus.Introspectable\">\n" + " <method name=\"Introspect\">\n" + " <arg name=\"xml_data\" direction=\"out\" type=\"s\" />\n" + " </method>\n" + " </interface>\n" + " <interface name=\"org.freedesktop.DBus.Peer\">\n" + " <method name=\"Ping\"/>\n" + " <method name=\"GetMachineId\">\n" + " <arg name=\"machineUuid\" direction=\"out\" type=\"s\"/>\n" + " </method>\n" + " </interface>\n" + " <interface name=\"org.freedesktop.DBus.Properties\">\n" + " <method name=\"Get\">\n" + " <arg name=\"interfaceName\" direction=\"in\" type=\"s\"/>\n" + " <arg name=\"propertyName\" direction=\"in\" type=\"s\"/>\n" + " <arg name=\"value\" direction=\"out\" type=\"v\"/>\n" + " </method>\n" + " <method name=\"GetAll\">\n" + " <arg name=\"interfaceName\" direction=\"in\" type=\"s\"/>\n" + " <arg name=\"propertyValues\" direction=\"out\" type=\"a{sv}\"/>\n" + " </method>\n" + " <method name=\"Set\">\n" + " <arg name=\"interfaceName\" direction=\"in\" type=\"s\"/>\n" + " <arg name=\"propertyName\" direction=\"in\" type=\"s\"/>\n" + " <arg name=\"value\" direction=\"in\" type=\"v\"/>\n" + " </method>\n" + " <signal name=\"PropertiesChanged\">\n" + " <arg name=\"interfaceName\" type=\"s\"/>\n" + " <arg name=\"changedProperties\" type=\"a{sv}\"/>\n" + " <arg name=\"invalidatedProperties\" type=\"as\"/>\n" + " </signal>\n" + " </interface>\n", + size-strlen(data)); + strncat(data, " <interface name=\"org.trinitydesktop.hardwarecontrol.Brightness\">\n" " <method name=\"CanSetBrightness\">\n" " <arg name=\"device\" direction=\"in\" type=\"s\" />\n" @@ -607,16 +668,131 @@ void reply_Introspect(DBusMessage* msg, DBusConnection* conn) { delete[] data; } -void reply_PropertiesGetAll(DBusMessage* msg, DBusConnection* conn) { - DBusMessage* reply; - DBusMessageIter args, arrayIter; +void reply_PeerPing(DBusMessage* msg, DBusConnection* conn) { + // create and send a reply from the message + DBusMessage *reply = dbus_message_new_method_return(msg); const char* member = dbus_message_get_member(msg); dbus_uint32_t serial = 0; + if (!dbus_connection_send(conn, reply, &serial)) { + fprintf(stderr, "[tde_dbus_hardwarecontrol] %s: dbus_connection_send failed\n", member); + return; + } + + // flush the connection + dbus_connection_flush(conn); + + // free the reply + dbus_message_unref(reply); +} + +void reply_PeerGetMachineId(DBusMessage* msg, DBusConnection* conn) { + // get machine id from polkit service + TQT_DBusConnection dbusConn = TQT_DBusConnection::addConnection(TQT_DBusConnection::SystemBus); + if (dbusConn.isConnected()) { + TQT_DBusProxy polkitProxy("org.freedesktop.PolicyKit1", "/org/freedesktop/DBus", + "org.freedesktop.DBus.Peer", dbusConn); + if (polkitProxy.canSend()) { + TQValueList<TQT_DBusData> params; + TQT_DBusMessage reply = polkitProxy.sendWithReply("GetMachineId", params); + if (reply.type() == TQT_DBusMessage::ReplyMessage && reply.count() == 1) { + TQCString machineId = reply[0].toString().utf8(); + replyString(msg, conn, (const char*)machineId); + return; + } + } + } + + // Return an error in case of failure + DBusMessage* reply = dbus_message_new_error(msg, "org.freedesktop.DBus.Error.Failed", "Failed to get machine id."); + dbus_uint32_t serial = 0; + if (!dbus_connection_send(conn, reply, &serial)) { + fprintf(stderr, "[tde_dbus_hardwarecontrol] Failed to get machine id.\n"); + return; + } + // flush the connection + dbus_connection_flush(conn); + + // free the reply + dbus_message_unref(reply); + +} + +void reply_PropertiesGet(DBusMessage* msg, DBusConnection* conn) { // create a reply from the message - reply = dbus_message_new_method_return(msg); + DBusMessage* reply = dbus_message_new_method_return(msg); + const char* member = dbus_message_get_member(msg); + + // read the arguments + char *interfaceName, *propertyName; + + bool argsOk = true; + DBusMessageIter args; + if (!dbus_message_iter_init(msg, &args)) { + fprintf(stderr, "[tde_dbus_hardwarecontrol] %s: no arguments supplied\n", member); + argsOk = false; + } + else if (DBUS_TYPE_STRING != dbus_message_iter_get_arg_type(&args)) { + fprintf(stderr, "[tde_dbus_hardwarecontrol] %s: first argument not string\n", member); + argsOk = false; + } + else { + dbus_message_iter_get_basic(&args, &interfaceName); + } + + if (argsOk) { + if (!dbus_message_iter_next(&args)) { + fprintf(stderr, "[tde_dbus_hardwarecontrol] %s: second argument not supplied\n", member); + argsOk = false; + } + else if (DBUS_TYPE_STRING != dbus_message_iter_get_arg_type(&args)) { + fprintf(stderr, "[tde_dbus_hardwarecontrol] %s: second argument not string\n", member); + argsOk = false; + } + else { + dbus_message_iter_get_basic(&args, &propertyName); + } + } + + // send the reply + if (!argsOk) { + DBusMessage* reply = dbus_message_new_error(msg, + "org.freedesktop.DBus.Error.InvalidArgs", "Number or type of arguments do not match the expected signature."); + + dbus_uint32_t serial = 0; + if (!dbus_connection_send(conn, reply, &serial)) { + fprintf(stderr, "[tde_dbus_hardwarecontrol] Number or type of arguments do not match the expected signature.\n"); + return; + } + } + else { + // Currently there are no properties at all, so return an error in all cases. + DBusMessage* reply = dbus_message_new_error_printf(msg, + "org.freedesktop.DBus.Error.InvalidArgs", "Property '%s' not found in interface '%s'.", + propertyName, interfaceName); + + dbus_uint32_t serial = 0; + if (!dbus_connection_send(conn, reply, &serial)) { + fprintf(stderr, "[tde_dbus_hardwarecontrol] Property '%s' not found in interface '%s'.\n", + propertyName, interfaceName); + return; + } + } + + // flush the connection + dbus_connection_flush(conn); + + // free the reply + dbus_message_unref(reply); +} + +void reply_PropertiesGetAll(DBusMessage* msg, DBusConnection* conn) { + // create a reply from the message + DBusMessage* reply = dbus_message_new_method_return(msg); + const char* member = dbus_message_get_member(msg); // add the arguments to the reply + DBusMessageIter args, arrayIter; dbus_message_iter_init_append(reply, &args); if (!dbus_message_iter_open_container(&args, DBUS_TYPE_ARRAY, "sv", &arrayIter)) { fprintf(stderr, "[tde_dbus_hardwarecontrol] %s: dbus_message_iter_open_container failed\n", member); @@ -628,6 +804,7 @@ void reply_PropertiesGetAll(DBusMessage* msg, DBusConnection* conn) { } // send the reply && flush the connection + dbus_uint32_t serial = 0; if (!dbus_connection_send(conn, reply, &serial)) { fprintf(stderr, "[tde_dbus_hardwarecontrol] %s: dbus_connection_send failed\n", member); return; @@ -638,6 +815,93 @@ void reply_PropertiesGetAll(DBusMessage* msg, DBusConnection* conn) { dbus_message_unref(reply); } +void reply_PropertiesSet(DBusMessage* msg, DBusConnection* conn) { + // create a reply from the message + DBusMessage* reply = dbus_message_new_method_return(msg); + const char* member = dbus_message_get_member(msg); + + // read the arguments + char *interfaceName, *propertyName; + + bool argsOk = true; + DBusMessageIter args; + if (!dbus_message_iter_init(msg, &args)) { + fprintf(stderr, "[tde_dbus_hardwarecontrol] %s: no arguments supplied\n", member); + argsOk = false; + } + else if (DBUS_TYPE_STRING != dbus_message_iter_get_arg_type(&args)) { + fprintf(stderr, "[tde_dbus_hardwarecontrol] %s: first argument not string\n", member); + argsOk = false; + } + else { + dbus_message_iter_get_basic(&args, &interfaceName); + } + + if (argsOk) { + if (!dbus_message_iter_next(&args)) { + fprintf(stderr, "[tde_dbus_hardwarecontrol] %s: second argument not supplied\n", member); + argsOk = false; + } + else if (DBUS_TYPE_STRING != dbus_message_iter_get_arg_type(&args)) { + fprintf(stderr, "[tde_dbus_hardwarecontrol] %s: second argument not string\n", member); + argsOk = false; + } + else { + dbus_message_iter_get_basic(&args, &propertyName); + } + } + + if (argsOk) { + if (!dbus_message_iter_next(&args)) { + fprintf(stderr, "[tde_dbus_hardwarecontrol] %s: third argument not supplied\n", member); + argsOk = false; + } + else if (DBUS_TYPE_VARIANT != dbus_message_iter_get_arg_type(&args)) { + fprintf(stderr, "[tde_dbus_hardwarecontrol] %s: third argument not variant\n", member); + argsOk = false; + } + else { + // TODO when real properties are passed: check variant type is consistent with required property + } + } + + // send the reply + if (!argsOk) { + DBusMessage* reply = dbus_message_new_error(msg, + "org.freedesktop.DBus.Error.InvalidArgs", "Number or type of arguments do not match the expected signature."); + + dbus_uint32_t serial = 0; + if (!dbus_connection_send(conn, reply, &serial)) { + fprintf(stderr, "[tde_dbus_hardwarecontrol] Number or type of arguments do not match the expected signature.\n"); + return; + } + } + else { + // Currently there are no properties at all, so nothing to set + DBusMessage* reply = dbus_message_new_error_printf(msg, + "org.freedesktop.DBus.Error.InvalidArgs", "Property '%s' not found in interface '%s'.", + propertyName, interfaceName); + + dbus_uint32_t serial = 0; + if (!dbus_connection_send(conn, reply, &serial)) { + fprintf(stderr, "[tde_dbus_hardwarecontrol] Property '%s' not found in interface '%s'.\n", + propertyName, interfaceName); + return; + } + } + + // flush the connection + dbus_connection_flush(conn); + + // free the reply + dbus_message_unref(reply); +} + +void signal_PropertiesChanged(DBusMessage* msg) { + // Currently there are no properties at all, so nothing to do + fprintf(stderr, "[tde_dbus_hardwarecontrol] PropertiesChanged signal was received\n"); +} + void error_UnknownMessage(DBusMessage* msg, DBusConnection* conn) { const char* member = dbus_message_get_member(msg); const char* interface = dbus_message_get_interface(msg); @@ -912,9 +1176,24 @@ void listen() { else if (dbus_message_is_method_call(msg, "org.freedesktop.DBus.Introspectable", "Introspect")) { reply_Introspect(msg, conn); } + else if (dbus_message_is_method_call(msg, "org.freedesktop.DBus.Peer", "Ping")) { + reply_PeerPing(msg, conn); + } + else if (dbus_message_is_method_call(msg, "org.freedesktop.DBus.Peer", "GetMachineId")) { + reply_PeerGetMachineId(msg, conn); + } + else if (dbus_message_is_method_call(msg, "org.freedesktop.DBus.Properties", "Get")) { + reply_PropertiesGet(msg, conn); + } else if (dbus_message_is_method_call(msg, "org.freedesktop.DBus.Properties", "GetAll")) { reply_PropertiesGetAll(msg, conn); } + else if (dbus_message_is_method_call(msg, "org.freedesktop.DBus.Properties", "Set")) { + reply_PropertiesSet(msg, conn); + } + else if (dbus_message_is_signal(msg, "org.freedesktop.DBus", "PropertiesChanged")) { + signal_PropertiesChanged(msg); + } else { error_UnknownMessage(msg, conn); } |