【问题标题】:Can anybody explain this command谁能解释这个命令
【发布时间】:2012-02-12 02:28:09
【问题描述】:

这里我想简要了解一下dbus-send命令

我想知道我们如何使用它以及这个命令如何自动调用其他 c 文件的函数。

这里我举一个例子,它用于蓝牙配对和取消配对。请解释一下

dbus-send --system --print-reply --dest=org.bluez  $BT_ADAPTER org.bluez.Adapter.RemoveDevice objpath:$BT_ADAPTER/dev_$BD_ADDR_XX

这里的 BT_ADAPTER 是蓝色适配器,例如:/org/bluez/1536/hci0 BD_ADDR_XX 为蓝牙地址:XX_XX_XX_XX_XX_XX

在这里我知道 --system --print-reply 选项和所有其他选项,但我不知道它如何处理源文件。

所以请任何人解释一下这个命令如何调用和使用 C 源文件中的函数。

【问题讨论】:

    标签: c bluetooth embedded dbus


    【解决方案1】:

    你需要查看 dbus 文档,还有很长的路要走。

    http://www.freedesktop.org/wiki/IntroductionToDBus

    你到底想要什么?编写 dbus 服务还是客户端?

    您必须用 C 编写,因为 python 会是一个更好的选择。 http://dbus.freedesktop.org/doc/dbus-python/doc/tutorial.html

    =============================

    首先,一个 dbus 服务连接到 dbus-daemon 并请求一个服务地址(在你的例子中是 org.bluez)。 然后在不同的对象路径注册不同的接口,每个接口都包含一些方法调用/信号供用户使用。

    在你的情况下:

    • Dbus 守护进程(dbus-daemon --system) 已启动。

    • Bluez 守护进程已启动并向 dbus-daemon 询问“org.bluez”服务地址

    • Bluez 守护进程在 /org/bluez/{process pid}/{bluetooth controller name} 注册一些接口(检查 bluez 源代码,在 doc 目录中)

    • 调用dbus-send命令时,命令行工具会连接dbus-daemon,发送服务地址(-dest),对象路径(/org/bluez/1536/hci0),接口名称,你调用的方法( org.bluez.Adapter.RemoveDevice) 和参数。

    • Dbus-daemon 将其重新发送到 bluez

    =============================

    Dbus 守护进程没有获得服务地址或方法调用。 告诉它服务地址和方法调用名称的是您或客户端进程。

    DBus 守护进程随后会向目标服务进程发送一个数据包,其中包含 obj-path、接口/方法名称和以自己的格式(通过 unix 本地套接字文件)的参数。

    然后目标服务进程解包,获取对象路径,接口等,决定它应该做什么。这不是自动完成的,您需要编写自己的代码来处理它(方法分派等),或者使用像 dbus-glib/gdbus 这样的库。

    =============================

    我检查了 Bluez-4.98 的源代码。它使用 gdbus 进行方法调度。

    以“CreateDevice”为例。

    在src/adapter.c中有这样一个结构

    static GDBusMethodTable adapter_methods[] = {
    { "GetProperties",  "", "a{sv}",get_properties      },
    { "SetProperty",    "sv",   "", set_property,
                        G_DBUS_METHOD_FLAG_ASYNC},
    { "RequestSession", "", "", request_session,
                        G_DBUS_METHOD_FLAG_ASYNC},
    { "ReleaseSession", "", "", release_session     },
    { "StartDiscovery", "", "", adapter_start_discovery },
    { "StopDiscovery",  "", "", adapter_stop_discovery,
                        G_DBUS_METHOD_FLAG_ASYNC},
    { "ListDevices",    "", "ao",   list_devices,
                        G_DBUS_METHOD_FLAG_DEPRECATED},
    { "CreateDevice",   "s",    "o",    create_device,
                        G_DBUS_METHOD_FLAG_ASYNC},
    { "CreatePairedDevice", "sos",  "o",    create_paired_device,
                        G_DBUS_METHOD_FLAG_ASYNC},
    { "CancelDeviceCreation","s",   "", cancel_device_creation,
                        G_DBUS_METHOD_FLAG_ASYNC},
    { "RemoveDevice",   "o",    "", remove_device,
                        G_DBUS_METHOD_FLAG_ASYNC},
    { "FindDevice",     "s",    "o",    find_device     },
    { "RegisterAgent",  "os",   "", register_agent      },
    { "UnregisterAgent",    "o",    "", unregister_agent    },
    { }
    };
    

    这意味着 CreateDevice 方法调用最终会调用 create_device 函数。

    在第 2418 行

        if (!g_dbus_register_interface(conn, path, ADAPTER_INTERFACE,
                    adapter_methods, adapter_signals, NULL,
                    adapter, adapter_free)) {
        error("Adapter interface init failed on path %s", path);
        adapter_free(adapter);
        return NULL;
    }
    

    您使用其所有方法和信号注册接口 ADAPTER_INTERFACE("org.bluez.Adapter")。

    然后所有底层的dbus事件监视器和方法调度将由gdbus处理(在src/main.c中初始化dbus连接和事件处理之后)。当某些客户端调用 org.bluez.Adapter.CreateDevice 时,它​​最终会进入 src/adapter.c 第 1468 行的函数 create_device。

    static DBusMessage *create_device(DBusConnection *conn,
                    DBusMessage *msg, void *data)
    {
    struct btd_adapter *adapter = data;
    struct btd_device *device;
    const gchar *address;
    DBusMessage *reply;
    int err;
    
    if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &address,
                        DBUS_TYPE_INVALID) == FALSE)
        return btd_error_invalid_args(msg);
    
    if (check_address(address) < 0)
        return btd_error_invalid_args(msg);
    
    if (!adapter->up)
        return btd_error_not_ready(msg);
    
    if (adapter_find_device(adapter, address))
        return btd_error_already_exists(msg);
    
    DBG("%s", address);
    ......
    

    我对gdbus不熟悉,如果你想深入了解,建议你查看官网:http://developer.gnome.org/gio/stable/gdbus-convenience.html

    =============================

    哈哈

    然后你只需要查看bluez源代码的'test'目录。

    有 python 和 C 的例子。

    另外,bluez dbus 接口从 3.XX 到 4.XX 变化很大,所以请查看正确的版本。

    【讨论】:

    • 我想知道它是如何调用对象路径和目标选项的。意思是我想在上面的例子中知道 org.bluez.Adapter.RemoveDevice 是如何调用的?
    • 首先,一个 dbus 服务连接到 dbus-daemon 并请求一个地址(在你的例子中是 org.bluez)。
    • 非常感谢您的解释。但有一件事是混乱。 Dbus 守护进程如何获取源代码中的服务地址和方法调用。这如何自动调用那里。?是否有任何与 dbus 相关的源文件启动此方法(org.Bluez.Adapter.RemoveDevice)?
    • ========================对不起,太长了
    • 非常感谢。但我问的不是这件事。我问这个方法是如何通过 dbus 调用的。因为我看到了 bluez 的源代码,所以有方法名称 Remove Device、CreatePairedDevice 和 CreateDevice。我想知道这些方法是如何通过 dbus-deamon 调用的。
    猜你喜欢
    • 2017-03-11
    • 2019-02-07
    • 2021-01-08
    • 1970-01-01
    • 2016-04-10
    • 2010-10-19
    • 2013-04-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多