2003-01-21 Anders Carlsson <andersca@codefactory.se>
authorAnders Carlsson <andersca@codefactory.se>
Tue, 21 Jan 2003 12:42:33 +0000 (12:42 +0000)
committerAnders Carlsson <andersca@codefactory.se>
Tue, 21 Jan 2003 12:42:33 +0000 (12:42 +0000)
* bus/Makefile.am:
Add driver.[ch]

* bus/connection.c: (connection_disconnect_handler):
Remove the connection from the bus driver's list.

(connection_watch_callback): Dispatch messages.

(free_connection_data): Free connection name.

(bus_connection_setup): Add connection to the bus driver's list.
(bus_connection_remove_owned_service):
(bus_connection_set_name), (bus_connection_get_name):
Add functions for setting and getting the connection's name.

* bus/connection.h:
Add function headers.

* bus/driver.c: (create_unique_client_name),
(bus_driver_handle_hello_message),
(bus_driver_send_welcome_message), (bus_driver_message_handler),
(bus_driver_add_connection), (bus_driver_remove_connection):
* bus/driver.h:
* bus/main.c:
* bus/services.c: (bus_service_free):
* bus/services.h:
New file that handles communication and registreation with the bus
itself.

ChangeLog
bus/Makefile.am
bus/connection.c
bus/connection.h
bus/driver.c [new file with mode: 0644]
bus/driver.h [new file with mode: 0644]
bus/main.c
bus/services.c
bus/services.h

index 8ab9ba6..2049004 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,36 @@
 2003-01-21  Anders Carlsson  <andersca@codefactory.se>
 
+       * bus/Makefile.am:
+       Add driver.[ch]
+       
+       * bus/connection.c: (connection_disconnect_handler):
+       Remove the connection from the bus driver's list.
+       
+       (connection_watch_callback): Dispatch messages.
+
+       (free_connection_data): Free connection name.
+       
+       (bus_connection_setup): Add connection to the bus driver's list.
+       (bus_connection_remove_owned_service): 
+       (bus_connection_set_name), (bus_connection_get_name):
+       Add functions for setting and getting the connection's name.
+       
+       * bus/connection.h:
+       Add function headers.
+       
+       * bus/driver.c: (create_unique_client_name),
+       (bus_driver_handle_hello_message),
+       (bus_driver_send_welcome_message), (bus_driver_message_handler),
+       (bus_driver_add_connection), (bus_driver_remove_connection):
+       * bus/driver.h:
+       * bus/main.c:
+       * bus/services.c: (bus_service_free):
+       * bus/services.h:
+       New file that handles communication and registreation with the bus
+       itself. 
+       
+2003-01-21  Anders Carlsson  <andersca@codefactory.se>
+
        * dbus/dbus-connection.c: (dbus_connection_send_message):
        Add a new client_serial parameter.
        
index b7f4504..af25867 100644 (file)
@@ -9,6 +9,8 @@ bin_PROGRAMS=dbus-daemon-1
 dbus_daemon_1_SOURCES=                         \
        connection.c                            \
        connection.h                            \
+       driver.c                                \
+       driver.h                                \
        loop.c                                  \
        loop.h                                  \
        main.c                                  \
index a80e46d..4a80573 100644 (file)
@@ -21,6 +21,7 @@
  *
  */
 #include "connection.h"
+#include "driver.h"
 #include "loop.h"
 #include "services.h"
 #include <dbus/dbus-list.h>
@@ -32,6 +33,7 @@ typedef struct
 {
   DBusList *services_owned;
 
+  char *name;
 } BusConnectionData;
 
 #define BUS_CONNECTION_DATA(connection) (dbus_connection_get_data ((connection), connection_data_slot))
@@ -52,6 +54,9 @@ connection_disconnect_handler (DBusConnection *connection,
   while ((service = _dbus_list_get_last (&d->services_owned)))
     bus_service_remove_owner (service, connection);
 
+  /* Tell bus driver that we want to get off */
+  bus_driver_remove_connection (connection);
+  
   /* no more watching */
   dbus_connection_set_watch_functions (connection,
                                        NULL, NULL,
@@ -74,6 +79,8 @@ connection_watch_callback (DBusWatch     *watch,
   DBusConnection *connection = data;
 
   dbus_connection_handle_watch (connection, watch, condition);
+
+  while (dbus_connection_dispatch_message (connection));
 }
 
 static void
@@ -98,6 +105,8 @@ free_connection_data (void *data)
 
   /* services_owned should be NULL since we should be disconnected */
   _dbus_assert (d->services_owned == NULL);
+
+  dbus_free (d->name);
   
   dbus_free (d);
 }
@@ -150,6 +159,9 @@ bus_connection_setup (DBusConnection *connection)
                                            connection_disconnect_handler,
                                            NULL, NULL);
 
+  if (!bus_driver_add_connection (connection))
+    return FALSE;
+  
   return TRUE;
 }
 
@@ -180,3 +192,35 @@ bus_connection_remove_owned_service (DBusConnection *connection,
 
   _dbus_list_remove_last (&d->services_owned, service);
 }
+
+dbus_bool_t
+bus_connection_set_name (DBusConnection   *connection,
+                        const DBusString *name)
+{
+  const char *c_name;
+  BusConnectionData *d;
+  
+  d = BUS_CONNECTION_DATA (connection);
+  _dbus_assert (d != NULL);
+  _dbus_assert (d->name == NULL);
+
+  _dbus_string_get_const_data (name, &c_name);
+
+  d->name = _dbus_strdup (c_name);
+
+  if (d->name == NULL)
+    return FALSE;
+
+  return TRUE;
+}
+
+const char *
+bus_connection_get_name (DBusConnection *connection)
+{
+  BusConnectionData *d;
+  
+  d = BUS_CONNECTION_DATA (connection);
+  _dbus_assert (d != NULL);
+  
+  return d->name;
+}
index e6f9d10..1a23867 100644 (file)
@@ -31,11 +31,16 @@ dbus_bool_t bus_connection_init (void);
 
 dbus_bool_t bus_connection_setup (DBusConnection *connection);
 
-
 /* called by services.c */
 dbus_bool_t bus_connection_add_owned_service    (DBusConnection *connection,
                                                  BusService     *service);
 void        bus_connection_remove_owned_service (DBusConnection *connection,
                                                  BusService     *service);
 
+/* called by driver.c */
+dbus_bool_t bus_connection_set_name (DBusConnection   *connection,
+                                    const DBusString *name);
+const char *bus_connection_get_name (DBusConnection   *connection);
+
+
 #endif /* BUS_CONNECTION_H */
diff --git a/bus/driver.c b/bus/driver.c
new file mode 100644 (file)
index 0000000..d24cb77
--- /dev/null
@@ -0,0 +1,217 @@
+/* -*- mode: C; c-file-style: "gnu" -*- */
+/* bus.c  Bus client (driver)
+ *
+ * Copyright (C) 2003  CodeFactory AB
+ *
+ * Licensed under the Academic Free License version 1.2
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#include "connection.h"
+#include "driver.h"
+#include "services.h"
+#include <dbus/dbus-internals.h>
+#include <dbus/dbus-string.h>
+#include <string.h>
+
+#define BUS_DRIVER_SERVICE_NAME "org.freedesktop.DBus"
+#define BUS_DRIVER_HELLO_NAME "org.freedesktop.DBus.Hello"
+#define BUS_DRIVER_WELCOME_NAME "org.freedesktop.DBus.Welcome"
+
+static dbus_bool_t  bus_driver_send_welcome_message (DBusConnection *connection,
+                                                    DBusMessage    *hello_message);
+
+static dbus_bool_t
+create_unique_client_name (const char *name, DBusString *str)
+{
+  int i, len;
+
+  if (!_dbus_string_init (str, _DBUS_INT_MAX))
+    return FALSE;
+
+  if (!_dbus_string_append (str, name))
+    return FALSE;
+  
+  len = _dbus_string_get_length (str);
+  
+  i = 0;  
+  while (1)
+    {
+      if (!_dbus_string_append_int (str, i))
+       {
+         _dbus_string_free (str);
+         return FALSE;
+       }
+      
+      /* Check if a client with the name exists */
+      if (bus_service_lookup (str, FALSE) == NULL)
+       break;
+
+      _dbus_string_set_length (str, len);
+      
+      i++;
+    }
+
+  return TRUE;
+}
+
+static dbus_bool_t
+bus_driver_handle_hello_message (DBusConnection *connection,
+                                DBusMessage    *message)
+{
+  DBusResultCode result;
+  char *name;
+  DBusString unique_name;
+  BusService *service;
+  dbus_bool_t retval;
+  
+  result = dbus_message_get_fields (message,
+                                   DBUS_TYPE_STRING, &name,
+                                   0);
+
+  /* FIXME: Handle this in a better way */
+  if (result != DBUS_RESULT_SUCCESS)
+    return FALSE;
+
+  if (!create_unique_client_name (name, &unique_name))
+    return FALSE;
+
+  /* Create the service */
+  service = bus_service_lookup (&unique_name, TRUE);
+  if (!service)
+    {
+      _dbus_string_free (&unique_name);
+      return FALSE;
+    }
+
+  /* FIXME: Error checks from this point */
+  
+  /* Add the connection as the owner */
+  bus_service_add_owner (service, connection);
+  bus_connection_set_name (connection, &unique_name);
+
+  /* We need to assign the sender to the message here */
+  _dbus_message_set_sender (message,
+                           bus_connection_get_name (connection));
+  
+  _dbus_string_free (&unique_name);
+
+  retval = bus_driver_send_welcome_message (connection, message);
+
+  return retval;
+}
+
+static dbus_bool_t
+bus_driver_send_welcome_message (DBusConnection *connection,
+                                DBusMessage    *hello_message)
+{
+  DBusMessage *welcome;
+  const char *name;
+  dbus_bool_t retval;
+  
+  
+  name = bus_connection_get_name (connection);
+  _dbus_assert (name != NULL);
+  
+  welcome = dbus_message_new_reply (BUS_DRIVER_WELCOME_NAME,
+                                   hello_message);
+  if (welcome == NULL)
+    return FALSE;
+
+  /* FIXME: Return value */
+  _dbus_message_set_sender (welcome, BUS_DRIVER_SERVICE_NAME);
+  
+  if (!dbus_message_append_fields (welcome,
+                                  DBUS_TYPE_STRING, name,
+                                  NULL))
+    {
+      dbus_message_unref (welcome);
+      return FALSE;
+    }
+
+  retval = dbus_connection_send_message (connection, welcome, NULL, NULL);
+  dbus_message_unref (welcome);
+
+  return retval;
+}
+
+/* This is where all the magic occurs */
+static DBusHandlerResult
+bus_driver_message_handler (DBusMessageHandler *handler,
+                           DBusConnection     *connection,
+                           DBusMessage        *message,
+                           void               *user_data)
+{
+  const char *service, *name;
+
+  service = dbus_message_get_service (message);
+  name = dbus_message_get_name (message);
+
+  _dbus_message_set_sender (message,
+                           bus_connection_get_name (connection));
+  
+  if (strcmp (service, BUS_DRIVER_SERVICE_NAME) == 0)
+    {
+      if (strcmp (name, BUS_DRIVER_HELLO_NAME) == 0)
+       bus_driver_handle_hello_message (connection, message);
+    }
+  else
+    {
+      /* FIXME: Dispatch the message :-) */
+    }
+
+  return DBUS_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
+}
+
+dbus_bool_t
+bus_driver_add_connection (DBusConnection *connection)
+{
+  DBusMessageHandler *handler;
+
+  handler = dbus_message_handler_new (bus_driver_message_handler, NULL, NULL);
+
+  if (!dbus_connection_add_filter (connection, handler))
+    {
+      dbus_message_handler_unref (handler);
+
+      return FALSE;
+    }
+
+  _dbus_verbose ("D-Bus driver on board...\n");
+  
+  return TRUE;
+}
+
+void
+bus_driver_remove_connection (DBusConnection *connection)
+{
+  BusService *service;
+  DBusString service_name;
+  const char *name;
+
+  name = bus_connection_get_name (connection);
+
+  if (name == NULL)
+    return;
+  
+  _dbus_string_init_const (&service_name, name);
+  
+  service = bus_service_lookup (&service_name, FALSE);
+
+  if (service)
+    bus_service_free (service);
+}
diff --git a/bus/driver.h b/bus/driver.h
new file mode 100644 (file)
index 0000000..3667aac
--- /dev/null
@@ -0,0 +1,32 @@
+/* -*- mode: C; c-file-style: "gnu" -*- */
+/* bus.h  Bus client (driver)
+ *
+ * Copyright (C) 2003  CodeFactory AB
+ *
+ * Licensed under the Academic Free License version 1.2
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#ifndef BUS_DRIVER_H
+#define BUS_DRIVER_H
+
+#include <dbus/dbus.h>
+
+dbus_bool_t bus_driver_add_connection    (DBusConnection *connection);
+void        bus_driver_remove_connection (DBusConnection *connection);
+
+#endif /* BUS_DRIVER_H */
index 27720fb..fb5e039 100644 (file)
@@ -22,6 +22,7 @@
  */
 #include "loop.h"
 #include "connection.h"
+#include "driver.h"
 #include <dbus/dbus-list.h>
 
 static void
index f8124b0..c07b20f 100644 (file)
@@ -98,6 +98,17 @@ bus_service_lookup (const DBusString *service_name,
   return service;
 }
 
+void
+bus_service_free (BusService *service)
+{
+  _dbus_assert (service->owners == NULL);
+
+  _dbus_hash_table_remove_string (service_hash, service->name);
+  
+  dbus_free (service->name);
+  _dbus_mem_pool_dealloc (service_pool, service);
+}
+
 dbus_bool_t
 bus_service_add_owner (BusService     *service,
                        DBusConnection *owner)
index 56ed3d1..8c2344a 100644 (file)
@@ -39,15 +39,15 @@ typedef void (* BusServiceForeachFunction) (BusService       *service,
                                             void             *data);
 
 BusService*     bus_service_lookup            (const DBusString          *service_name,
-                                               dbus_bool_t                create_if_not_found);
+                                              dbus_bool_t                create_if_not_found);
+void            bus_service_free              (BusService                *service);
 dbus_bool_t     bus_service_add_owner         (BusService                *service,
-                                               DBusConnection            *owner);
+                                              DBusConnection            *owner);
 void            bus_service_remove_owner      (BusService                *service,
-                                               DBusConnection            *owner);
+                                              DBusConnection            *owner);
 DBusConnection* bus_service_get_primary_owner (BusService                *service);
 const char*     bus_service_get_name          (BusService                *service);
-
 void            bus_service_foreach           (BusServiceForeachFunction  function,
-                                               void                      *data);
+                                              void                      *data);
 
 #endif /* BUS_SERVICES_H */