1 d-bus的内部工作方式

 

典型的 D-BUS 设置将由几个总线构成。将有一个持久的 系统总线(system bus),它在 引导时就会启动。这个总线由操作系统和后台进程使用,安全性非常好,以使得任意的应用程序 不能欺骗系统事件。还将有很多 会话总线(session buses),这些总线当用户登录后启动,属于 那个用户私有。它是用户的应用程序用来通信的一个会话总线。当然,如果一个应用程序需要接收 来自系统总线的消息,它不如直接连接到系统总线 —— 不过,它可以发送的消息将是受限的。一旦应用程序连接到了一个总线,它们就必须通过添加 匹配器(matchers) 来声明它们希望 收到哪种消息。匹配器为可以基于接口、对象路径和方法进行接收的消息指定一组规则(见后)。 这样就使得应用程序可以集中精力去处理它们想处理的内容,以实现消息的高效路由,并保持总线 上消息的预期数量,以使得不会因为这些消息导致所有应用程序的性能下降并变得很慢。

 

2 bluez使用d-bus
是在android的基础上学习,首先在init.rc通过service启动d-bus的守护进程
service dbus /system/bin/dbus-daemon --system --nofork
    socket dbus stream 660 bluetooth bluetooth
    user bluetooth
    group bluetooth net_bt_admin
 
android里bluetooth上层通过JNI调用到android_server_Bluetooth.cpp文件里的initializeNativeDataNative()函数,这里bluetooth用户获取系统总线:
DBusError err;
    dbus_error_init(&err);
    dbus_threads_init_default();
    nat->conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
    if (dbus_error_is_set(&err)) {
        LOGE("Could not get onto the system bus: %s", err.message);
        dbus_error_free(&err);
        return false;
    }
    dbus_connection_set_exit_on_disconnect(nat->conn, FALSE);
 
这个总线就是以后和bluez进行通信的渠道。譬如说discovery行为,在函数startDiscoveryNative里
 msg = dbus_message_new_method_call(BLUEZ_DBUS_BASE_IFC,
                                       get_adapter_path(env, object),
                                       DBUS_ADAPTER_IFACE, "StartDiscovery");
 
    if (msg == NULL) {
        if (dbus_error_is_set(&err)) {
            LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
        }
        goto done;
    }
 
    /* Send the command. */
    reply = dbus_connection_send_with_reply_and_block(nat->conn, msg, -1, &err);

 

通过该方式调用到bluez里的adapter.c文件里的adapter_start_discovery函数。

 

3 在bluez里也有很多地方使用了d-bus进行进程间通信。这部分还想再学习中。。。。


最近在学习bluez的源码,里面用的比较多的一个进程间通信是D-bus,因此通过源码和网上的一些资料,写了下个人心得:

 

1 d-bus的内部工作方式

 

典型的 D-BUS 设置将由几个总线构成。将有一个持久的 系统总线(system bus),它在 引导时就会启动。这个总线由操作系统和后台进程使用,安全性非常好,以使得任意的应用程序 不能欺骗系统事件。还将有很多 会话总线(session buses),这些总线当用户登录后启动,属于 那个用户私有。它是用户的应用程序用来通信的一个会话总线。当然,如果一个应用程序需要接收 来自系统总线的消息,它不如直接连接到系统总线 —— 不过,它可以发送的消息将是受限的。一旦应用程序连接到了一个总线,它们就必须通过添加 匹配器(matchers) 来声明它们希望 收到哪种消息。匹配器为可以基于接口、对象路径和方法进行接收的消息指定一组规则(见后)。 这样就使得应用程序可以集中精力去处理它们想处理的内容,以实现消息的高效路由,并保持总线 上消息的预期数量,以使得不会因为这些消息导致所有应用程序的性能下降并变得很慢。

 

2 bluez使用d-bus
是在android的基础上学习,首先在init.rc通过service启动d-bus的守护进程
service dbus /system/bin/dbus-daemon --system --nofork
    socket dbus stream 660 bluetooth bluetooth
    user bluetooth
    group bluetooth net_bt_admin
 
android里bluetooth上层通过JNI调用到android_server_Bluetooth.cpp文件里的initializeNativeDataNative()函数,这里bluetooth用户获取系统总线:
DBusError err;
    dbus_error_init(&err);
    dbus_threads_init_default();
    nat->conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
    if (dbus_error_is_set(&err)) {
        LOGE("Could not get onto the system bus: %s", err.message);
        dbus_error_free(&err);
        return false;
    }
    dbus_connection_set_exit_on_disconnect(nat->conn, FALSE);
 
这个总线就是以后和bluez进行通信的渠道。譬如说discovery行为,在函数startDiscoveryNative里
 msg = dbus_message_new_method_call(BLUEZ_DBUS_BASE_IFC,
                                       get_adapter_path(env, object),
                                       DBUS_ADAPTER_IFACE, "StartDiscovery");
 
    if (msg == NULL) {
        if (dbus_error_is_set(&err)) {
            LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
        }
        goto done;
    }
 
    /* Send the command. */
    reply = dbus_connection_send_with_reply_and_block(nat->conn, msg, -1, &err);

 

通过该方式调用到bluez里的adapter.c文件里的adapter_start_discovery函数。

 

3 在bluez里也有很多地方使用了d-bus进行进程间通信。这部分还想再学习中。。。。