From b2dc16ffc8097438510b61e9bd07b4a7bebab112 Mon Sep 17 00:00:00 2001 From: Michele Calgaro Date: Wed, 6 Feb 2019 23:45:57 +0900 Subject: TDE hw lib daemon: added standard DBus interfaces: Introspect, Peer, Properties. This relates to issue #9 and #12. Signed-off-by: Michele Calgaro --- .../dbus/org.trinitydesktop.hardwarecontrol.conf | 15 +- .../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 @@ - - - - - - + + 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; @@ -503,6 +530,40 @@ void reply_Introspect(DBusMessage* msg, DBusConnection* conn) { strncat(data, " \n", size-strlen(data)); } else if(strcmp("/org/trinitydesktop/hardwarecontrol", path) == 0) { + strncat(data, + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n", + size-strlen(data)); strncat(data, " \n" " \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 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); } -- cgit v1.2.3