working:
authorRadoslaw Pajak <r.pajak@samsung.com>
Wed, 26 Jun 2013 13:53:12 +0000 (15:53 +0200)
committerRadoslaw Pajak <r.pajak@samsung.com>
Wed, 26 Jun 2013 13:53:12 +0000 (15:53 +0200)
   - request name (without some flags not supperted by kdbus now)
   - upload policy for kdbus (probably to use in different place)

new useful function - dbus_transport_is_kdbus - tells whether transfor is kdbus

dbus/dbus-bus.c
dbus/dbus-connection.c
dbus/dbus-transport-kdbus.c
dbus/dbus-transport-kdbus.h

index 6622595..019298d 100644 (file)
@@ -642,7 +642,7 @@ dbus_bool_t dbus_bus_register_kdbus(DBusAddressEntry *entry, DBusConnection *con
 
                if (bd->unique_name != NULL)
                {
-                 _dbus_verbose ("Ignoring attempt to register the same DBusConnection %s with the message bus a second time.\n",
+                 _dbus_verbose ("Ignoring attempt to register the same DBusConnection %s with the kdbus message bus a second time.\n",
                                                 bd->unique_name);
                  /* Success! */
                  retval = TRUE;
@@ -652,6 +652,9 @@ dbus_bool_t dbus_bus_register_kdbus(DBusAddressEntry *entry, DBusConnection *con
                if(!bus_register_kdbus(&bd->unique_name, connection, error))
                        goto out;
 
+//             if(!bus_register_kdbus_policy(bd->unique_name, connection, error))   //todo should it be here?
+//                     goto out;
+
                retval = TRUE;
 
                out:
@@ -1184,65 +1187,77 @@ dbus_bus_request_name (DBusConnection *connection,
                        unsigned int    flags,
                        DBusError      *error)
 {
-  DBusMessage *message, *reply;
-  dbus_uint32_t result;
+       dbus_uint32_t result;
+
+       _dbus_return_val_if_fail (connection != NULL, 0);
+       _dbus_return_val_if_fail (name != NULL, 0);
+       _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), 0);
+       _dbus_return_val_if_error_is_set (error, 0);
+
+       if(!dbus_transport_is_kdbus(connection))
+       {
+               DBusMessage *message, *reply;
+
+               message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
+                                                                                         DBUS_PATH_DBUS,
+                                                                                         DBUS_INTERFACE_DBUS,
+                                                                                         "RequestName");
+               if (message == NULL)
+               {
+                 _DBUS_SET_OOM (error);
+                 return -1;
+               }
 
-  _dbus_return_val_if_fail (connection != NULL, 0);
-  _dbus_return_val_if_fail (name != NULL, 0);
-  _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), 0);
-  _dbus_return_val_if_error_is_set (error, 0);
-  
-  message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
-                                          DBUS_PATH_DBUS,
-                                          DBUS_INTERFACE_DBUS,
-                                          "RequestName");
+               if (!dbus_message_append_args (message,
+                                        DBUS_TYPE_STRING, &name,
+                                        DBUS_TYPE_UINT32, &flags,
+                                        DBUS_TYPE_INVALID))
+               {
+                 dbus_message_unref (message);
+                 _DBUS_SET_OOM (error);
+                 return -1;
+               }
 
-  if (message == NULL)
-    {
-      _DBUS_SET_OOM (error);
-      return -1;
-    }
-  if (!dbus_message_append_args (message,
-                                DBUS_TYPE_STRING, &name,
-                                DBUS_TYPE_UINT32, &flags,
-                                DBUS_TYPE_INVALID))
-    {
-      dbus_message_unref (message);
-      _DBUS_SET_OOM (error);
-      return -1;
-    }
-  
-  reply = dbus_connection_send_with_reply_and_block (connection, message, -1,
-                                                     error);
-  
-  dbus_message_unref (message);
-  
-  if (reply == NULL)
-    {
-      _DBUS_ASSERT_ERROR_IS_SET (error);
-      return -1;
-    }  
+               reply = dbus_connection_send_with_reply_and_block (connection, message, -1,
+                                                                                                                error);
 
-  if (dbus_set_error_from_message (error, reply))
-    {
-      _DBUS_ASSERT_ERROR_IS_SET (error);
-      dbus_message_unref (reply);
-      return -1;
-    }
-  
-  if (!dbus_message_get_args (reply, error,
-                              DBUS_TYPE_UINT32, &result,
-                              DBUS_TYPE_INVALID))
-    {
-      _DBUS_ASSERT_ERROR_IS_SET (error);
-      dbus_message_unref (reply);
-      return -1;
-    }
+               dbus_message_unref (message);
 
-  dbus_message_unref (reply);
+               if (reply == NULL)
+               {
+                 _DBUS_ASSERT_ERROR_IS_SET (error);
+                 return -1;
+               }
+
+               if (dbus_set_error_from_message (error, reply))
+               {
+                 _DBUS_ASSERT_ERROR_IS_SET (error);
+                 dbus_message_unref (reply);
+                 return -1;
+               }
+
+               if (!dbus_message_get_args (reply, error,
+                                                                 DBUS_TYPE_UINT32, &result,
+                                                                 DBUS_TYPE_INVALID))
+               {
+                 _DBUS_ASSERT_ERROR_IS_SET (error);
+                 dbus_message_unref (reply);
+                 return -1;
+               }
+
+               dbus_message_unref (reply);
+       }
+       else
+       {
+               if(!bus_register_kdbus_policy(name, connection, error))  //todo should it be here?
+                       return -1;
+
+               result = bus_request_name_kdbus(connection, name, flags, error);
+               if(dbus_error_is_set(error))
+                       return -1;
+       }
   
-  return result;
+       return result;
 }
 
 
index bb51996..b3fa9cf 100644 (file)
@@ -6299,7 +6299,7 @@ dbus_connection_get_outgoing_unix_fds (DBusConnection *connection)
   return res;
 }
 
-#ifdef DBUS_BUILD_TESTS
+//#ifdef DBUS_BUILD_TESTS
 /**
  * Returns the address of the transport object of this connection
  *
@@ -6311,6 +6311,6 @@ _dbus_connection_get_address (DBusConnection *connection)
 {
   return _dbus_transport_get_address (connection->transport);
 }
-#endif
+//#endif
 
 /** @} */
index 105206c..204a50e 100644 (file)
 #include <fcntl.h>
 #include <sys/ioctl.h>
 #include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+
+#define KDBUS_ALIGN8(l) (((l) + 7) & ~7)
+
 
 /*struct and type below copied from dbus_transport_socket.c
  * needed for _dbus_transport_new_for_socket_kdbus and kdbus_vtable(?)
@@ -58,10 +65,15 @@ struct DBusTransportSocket
                                          */
 };
 
+
+
 //prototypes of local functions, needed for compiler
 int _dbus_connect_kdbus (const char *path, DBusError *error);
 DBusTransport* _dbus_transport_new_for_kdbus (const char *path, DBusError *error);
 DBusTransport* _dbus_transport_new_for_socket_kdbus (int fd, const DBusString *server_guid, const DBusString *address);
+struct kdbus_policy *make_policy_name(const char *name);
+struct kdbus_policy *make_policy_access(__u64 type, __u64 bits, __u64 id);
+void append_policy(struct kdbus_cmd_policy *cmd_policy, struct kdbus_policy *policy, __u64 max_size);
 
 /* Functions from dbus_transport_socket - to be modified or reused
  *
@@ -1431,9 +1443,97 @@ DBusTransportOpenResult _dbus_transport_open_kdbus(DBusAddressEntry  *entry,
     }
 }
 
+struct kdbus_policy *make_policy_name(const char *name)
+{
+       struct kdbus_policy *p;
+       __u64 size;
+
+       size = offsetof(struct kdbus_policy, name) + strlen(name) + 1;
+       p = malloc(size);
+       if (!p)
+               return NULL;
+       memset(p, 0, size);
+       p->size = size;
+       p->type = KDBUS_POLICY_NAME;
+       strcpy(p->name, name);
+
+       return p;
+}
+
+struct kdbus_policy *make_policy_access(__u64 type, __u64 bits, __u64 id)
+{
+       struct kdbus_policy *p;
+       __u64 size = sizeof(*p);
+
+       p = malloc(size);
+       if (!p)
+               return NULL;
+
+       memset(p, 0, size);
+       p->size = size;
+       p->type = KDBUS_POLICY_ACCESS;
+       p->access.type = type;
+       p->access.bits = bits;
+       p->access.id = id;
+
+       return p;
+}
+
+void append_policy(struct kdbus_cmd_policy *cmd_policy, struct kdbus_policy *policy, __u64 max_size)
+{
+       struct kdbus_policy *dst = (struct kdbus_policy *) ((char *) cmd_policy + cmd_policy->size);
+
+       if (cmd_policy->size + policy->size > max_size)
+               return;
+
+       memcpy(dst, policy, policy->size);
+       cmd_policy->size += KDBUS_ALIGN8(policy->size);
+       free(policy);
+}
+
+dbus_bool_t bus_register_kdbus_policy(const char* name, DBusConnection *connection, DBusError *error)
+{
+       struct kdbus_cmd_policy *cmd_policy;
+       struct kdbus_policy *policy;
+       int size = 0xffff;
+       int fd;
+
+       if(!dbus_connection_get_socket(connection, &fd))
+       {
+               dbus_set_error (error, "Failed to get fd for registering policy", NULL);
+               return FALSE;
+       }
+
+       cmd_policy = (struct kdbus_cmd_policy *) alloca(size);
+       memset(cmd_policy, 0, size);
+
+       policy = (struct kdbus_policy *) cmd_policy->policies;
+       cmd_policy->size = offsetof(struct kdbus_cmd_policy, policies);
+
+       policy = make_policy_name(name);                //todo to be verified or changed when meaning will be known
+       append_policy(cmd_policy, policy, size);
+
+       policy = make_policy_access(KDBUS_POLICY_ACCESS_USER, KDBUS_POLICY_OWN, getuid());
+       append_policy(cmd_policy, policy, size);
+
+       policy = make_policy_access(KDBUS_POLICY_ACCESS_WORLD, KDBUS_POLICY_RECV, 0);
+       append_policy(cmd_policy, policy, size);
+
+       policy = make_policy_access(KDBUS_POLICY_ACCESS_WORLD, KDBUS_POLICY_SEND, 0);
+       append_policy(cmd_policy, policy, size);
+
+       if (ioctl(fd, KDBUS_CMD_EP_POLICY_SET, cmd_policy) < 0)
+       {
+               dbus_set_error(error,_dbus_error_from_errno (errno), "Error setting EP policy: %s", _dbus_strerror (errno));
+               return FALSE;
+       }
+
+       _dbus_verbose("Policy %s set correctly\n", name);
+       return TRUE;
+}
+
 dbus_bool_t bus_register_kdbus(char** unique_name, DBusConnection *connection, DBusError *error)
 {
-       dbus_bool_t retval = TRUE;
        char name[18];
        struct kdbus_cmd_hello hello;
        int fd;
@@ -1452,23 +1552,84 @@ dbus_bool_t bus_register_kdbus(char** unique_name, DBusConnection *connection, D
 
        if(!dbus_connection_get_socket(connection, &fd))
        {
-               dbus_set_error (error, "failed to get fd for connection", NULL);
+               dbus_set_error (error, "failed to get fd for bus registration", NULL);
                return FALSE;
        }
        if (ioctl(fd, KDBUS_CMD_HELLO, &hello))
        {
-               dbus_set_error(error,_dbus_error_from_errno (errno), "Failed to send  hello: %s", _dbus_strerror (errno));
+               dbus_set_error(error,_dbus_error_from_errno (errno), "Failed to send hello: %s", _dbus_strerror (errno));
                return FALSE;
        }
 
-       _dbus_verbose("-- Our peer ID is: %llu\n", (unsigned long long)hello.id);  //todo [RP] can be removed after development
-       *unique_name = _dbus_strdup(name);
+       _dbus_verbose("-- Our peer ID is: %llu\n", (unsigned long long)hello.id);
        sprintf(name, "%llx", (unsigned long long)hello.id);
+       *unique_name = _dbus_strdup(name);
        if (*unique_name == NULL)
        {
          _DBUS_SET_OOM (error);
          return FALSE;
        }
 
-       return retval;
+       return TRUE;
+}
+
+uint64_t bus_request_name_kdbus(DBusConnection *connection, const char *name, const uint64_t flags, DBusError *error)
+{
+       struct kdbus_cmd_name *cmd_name;
+       int fd;
+       uint64_t size = sizeof(*cmd_name) + strlen(name) + 1;
+       uint64_t flags_kdbus = 0;
+
+       cmd_name = alloca(size);
+
+       memset(cmd_name, 0, size);
+       strcpy(cmd_name->name, name);
+       cmd_name->size = size;
+
+       if(flags & DBUS_NAME_FLAG_ALLOW_REPLACEMENT)
+               flags_kdbus |= KDBUS_NAME_ALLOW_REPLACEMENT;
+       if(!(flags & DBUS_NAME_FLAG_DO_NOT_QUEUE))
+               flags_kdbus |= KDBUS_NAME_QUEUE;
+       if(flags & DBUS_NAME_FLAG_REPLACE_EXISTING)
+               flags_kdbus |= KDBUS_NAME_REPLACE_EXISTING;
+
+       cmd_name->conn_flags = flags_kdbus;
+
+       if(!dbus_connection_get_socket(connection, &fd))
+       {
+               dbus_set_error (error, "failed to get fd for name request", NULL);
+               return FALSE;
+       }
+
+       _dbus_verbose("Request name - flags sent: 0x%llx       !!!!!!!!!\n", cmd_name->conn_flags);
+
+       if (ioctl(fd, KDBUS_CMD_NAME_ACQUIRE, cmd_name))
+       {
+               dbus_set_error(error,_dbus_error_from_errno (errno), "error acquiring name: %s", _dbus_strerror (errno));
+               return FALSE;
+       }
+
+       _dbus_verbose("Request name - received flag: 0x%llx       !!!!!!!!!\n", cmd_name->conn_flags);
+
+       if(cmd_name->conn_flags & KDBUS_NAME_IN_QUEUE)
+               return DBUS_REQUEST_NAME_REPLY_IN_QUEUE;
+       else
+               return DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER;
+       //todo now 2 codes are never returned - DBUS_REQUEST_NAME_REPLY_EXISTS and DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER
+}
+
+/**
+ * Checks if the connection's transport is kdbus on the basis of its address
+ *
+ * @param pointer to the connection
+ * @returns TRUE if kdbus transport, otherwise FALSE
+ */
+dbus_bool_t dbus_transport_is_kdbus(DBusConnection *connection)
+{
+       const char* address = _dbus_connection_get_address(connection);
+
+       if(address == strstr(address, "kdbus:path="))
+               return TRUE;
+       else
+               return FALSE;
 }
index 1b1d98c..40ee6f5 100644 (file)
@@ -3,6 +3,10 @@
 #include "dbus-transport-protected.h"
 #include "dbus-address.h"
 #include "dbus-errors.h"
+#include "dbus-types.h"
 
+dbus_bool_t dbus_transport_is_kdbus(DBusConnection *connection);
 DBusTransportOpenResult _dbus_transport_open_kdbus(DBusAddressEntry *entry, DBusTransport **transport_p, DBusError *error);
 dbus_bool_t bus_register_kdbus(char** uniqe_name, DBusConnection *connection, DBusError *error);
+dbus_bool_t bus_register_kdbus_policy(const char* name, DBusConnection *connection, DBusError *error);
+uint64_t bus_request_name_kdbus(DBusConnection *connection, const char *name, const uint64_t flags, DBusError *error);