DBUS的 hello 消息

六月ゝ 毕业季﹏ 提交于 2019-11-26 05:00:43

DBUS connection 在建立之前,需要给 dbus daemon 发一个 hello消息, 以便获得 connection 的 unique name.

下面是 DBUS specification 里的一段话:

Each connection has at least one name, assigned at connection time and returned in response to theorg.freedesktop.DBus.Hello method call. This automatically-assigned name is called the connection'sunique name. Unique names are never reused for two different connections to the same bus.

org.freedesktop.DBus.Hello

As a method:

            STRING Hello ()
          

Reply arguments:

Argument Type Description
0 STRING Unique name assigned to the connection

Before an application is able to send messages to other applications it must send theorg.freedesktop.DBus.Hello message to the message bus to obtain a unique name. If an application without a unique name tries to send a message to another application, or a message to the message bus itself that isn't theorg.freedesktop.DBus.Hello message, it will be disconnected from the bus.

hello 消息和相应的处理函数定义在 dbus/driver.c 里:

static const MessageHandler dbus_message_handlers[] = {
  { "Hello",
    "",
    DBUS_TYPE_STRING_AS_STRING,
    bus_driver_handle_hello },
typedef struct
{
  const char *name;
  const char *in_args;
  const char *out_args;
  dbus_bool_t (* handler) (DBusConnection *connection,
                           BusTransaction *transaction,
                           DBusMessage    *message,
                           DBusError      *error);
} MessageHandler;
static dbus_bool_t
bus_driver_handle_hello (DBusConnection *connection,
                         BusTransaction *transaction,
                         DBusMessage    *message,
                         DBusError      *error)
{

调用 bus_driver_handle_hello的 stack 如下:

(gdb) where
#0  bus_driver_handle_hello (connection=0x813dbc0, transaction=0x81462e8, message=0x813de30, error=0xbfffeaa0)
    at /home/charles/code/dbus/bus/driver.c:300
#1  0x080797b1 in bus_driver_handle_message (connection=0x813dbc0, transaction=0x81462e8, message=0x813de30, 
    error=0xbfffeaa0) at /home/charles/code/dbus/bus/driver.c:2038
#2  0x0806df77 in bus_dispatch (connection=0x813dbc0, message=0x813de30) at /home/charles/code/dbus/bus/dispatch.c:284
#3  0x0806e302 in bus_dispatch_message_filter (connection=0x813dbc0, message=0x813de30, user_data=0x0)
    at /home/charles/code/dbus/bus/dispatch.c:407
#4  0x08092672 in dbus_connection_dispatch (connection=0x813dbc0) at /home/charles/code/dbus/dbus/dbus-connection.c:4677
#5  0x080de738 in _dbus_loop_dispatch (loop=0x8137320) at /home/charles/code/dbus/dbus/dbus-mainloop.c:533
#6  0x080deef4 in _dbus_loop_iterate (loop=0x8137320, block=1) at /home/charles/code/dbus/dbus/dbus-mainloop.c:859
#7  0x080defb9 in _dbus_loop_run (loop=0x8137320) at /home/charles/code/dbus/dbus/dbus-mainloop.c:885
#8  0x080872b8 in main (argc=3, argv=0xbffff004) at /home/charles/code/dbus/bus/main.c:647

和dbus daemon 连接的stack如下:

(gdb) where
#0  dbus_bus_register (connection=0x804e8d0, error=0xbfffefa0) at /home/charles/code/dbus/dbus/dbus-bus.c:684
#1  0xb7f48ed4 in internal_bus_get (type=DBUS_BUS_SESSION, private=0, error=0xbfffefa0)
    at /home/charles/code/dbus/dbus/dbus-bus.c:483
#2  0xb7f49041 in dbus_bus_get (type=DBUS_BUS_SESSION, error=0xbfffefa0) at /home/charles/code/dbus/dbus/dbus-bus.c:561
#3  0x08049946 in main (argc=1, argv=0xbffff054) at /home/charles/code/dbus/tools/dbus-monitor.c:341

dbus_bus_register()里会发送 hello 消息:

  message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
                                          DBUS_PATH_DBUS,
                                          DBUS_INTERFACE_DBUS,
                                          "Hello");

在  peer-to-peer通信里面, hello 消息是不需要发送的。GDBUS里面, g_bus_get()会发送 hello消息,但是g_dbus_connection_new()只有在G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION被设置的时候踩会发送 hello 消息。

在 libdbus里面,dbus_connection_open()不会发送 hello 消息,dbus_bus_get()会发送。所以,我们在 dbus monitor的代码里能看到下面的代码:

  if (address != NULL)
    {   
      connection = dbus_connection_open (address, &error);
      if (connection)
        {
          if (!dbus_bus_register (connection, &error))
            {
              fprintf (stderr, "Failed to register connection to bus at %s: %s\n",
                       address, error.message);
              dbus_error_free (&error);
              exit (1);
            }
        }
    }   
  else
    connection = dbus_bus_get (type, &error);

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!