node.js - 从 Node 插件回复 Dbus 调用时出现 Bluez MediaEndpoint1 超时问题

标签 node.js dbus bluez

Bluez 版本:5.43

让我开门见山:

我的 Bluez 日志文件中有以下错误:

Calling SetConfiguration: name = :1.3 path = /MediaEndpoint/A2DPSink
...
Endpoint replied with an error: org.freedesktop.DBus.Error.NoReply

如果我改变这行代码

#define REQUEST_TIMEOUT (3 * 1000)/* 3 秒 */

~/bluez-5.43/profiles/audio/media.c文件中,

设置一个更大的值,比如 5 左右...错误就会消失。

那么这个错误是什么?

基本上,我有执行以下操作的nodejs插件代码:

初始化端点

void endpoint_init(DBusConnection *connection, const char *endpoint) {
    DBusObjectPathVTable vtable_endpoint;
    vtable_endpoint.message_function = endpoint_handler;
    dbus_connection_register_object_path(connection, endpoint, &vtable_endpoint, NULL);
}

在 Bluez 日志中,您将看到bluetoothd[25176]:端点已注册:sender=:1.130 path=/MediaEndpoint/A2DPSink

endpoint_handler 函数将收到调用 set_configuration 或 select_configuration 函数的通知...

接到电话后,会像这样回复...

sender = dbus_message_get_sender(m);
r = dbus_message_new_method_return(m);

printf("!! ----- endpoint_set_configuration, time_right_before_reply_sent: ");
print_time();

assert( dbus_connection_send(conn, r, NULL) );
dbus_connection_flush(conn);

    printf("!! ----- endpoint_set_configuration, time_right_after_reply_sent: ");
    print_time();

如您所见,我正在记录一些时间信息。

现在,我还在 Bluez 中记录了时间信息并重新编译了它。

这是 Bluez 的日志:

bluetoothd[789]: profiles/audio/media.c:media_endpoint_async_call() Calling SetConfiguration: name = :1.3 path = /MediaEndpoint/A2DPSink
bluetoothd[789]: profiles/audio/media.c:endpoint_reply() [GOT HERE -- endpoint_reply -- original_msg --] SetConfiguration: name = :1.3 path = /MediaEndpoint/A2DPSink
bluetoothd[789]: profiles/audio/media.c:print_time() TIME BEFORE -- dbus_pending_call_steal_reply --: 2017-01-25 04:54:01
bluetoothd[789]: profiles/audio/media.c:print_time() TIME AFTER -- dbus_pending_call_steal_reply --: 2017-01-25 04:54:01
bluetoothd[789]: profiles/audio/media.c:endpoint_reply() [GOT HERE -- endpoint_reply -- reply_msg] (null): name = (null) path = (null)
bluetoothd[789]: Endpoint replied with an error: org.freedesktop.DBus.Error.NoReply

这是我的 Node 插件的日志:

 endpoint_handler: path=/MediaEndpoint/A2DPSink, interface=org.bluez.MediaEndpoint1, member=SetConfiguration 
!! ----- endpoint_set_configuration, endpoint_path: /MediaEndpoint/A2DPSink 
!! ----- endpoint_set_configuration, time_right_before_reply_sent: 
 2017-01-25 04:54:03 
!! ----- endpoint_set_configuration, time_right_after_reply_sent: 
 2017-01-25 04:54:03 

您可以清楚地看到 Bluez 默认的 3 秒超时太短了...回复仍在路上...

但是pulseaudio的实现没有这个问题...为什么呢?

是不是因为有两个不同的事件循环,即node插件使用lib-uv事件循环而Bluez和pulse使用glib事件循环...

这是怎么回事,谁能解释一下。

我更愿意将其识别为 Bluez bug 或了解如何在我的 Node 插件端修复它...

谢谢 Stackoverflowers :)

附注

Bluez ~/bluez-5.43/profiles/audio/media.c 有代码建议将 REQUEST_TIMEOUT 保持在 3,这让我担心...

/* Timeout should be less than avdtp request timeout (4 seconds) */
if (g_dbus_send_message_with_reply(btd_get_dbus_connection(),
                    msg, &request->call,
                    REQUEST_TIMEOUT) == FALSE) {
    error("D-Bus send failed");
    g_free(request);
    return FALSE;
}

最佳答案

我发现glib和libuv在同一个进程下运行有一些冲突..

我使用的node-dbus插件是一个c级绑定(bind),它实例化了一个glib事件循环...

nodejs 有一个 libuv 事件循环

他们不能很好地合作......

这就是我可以假设的问题所在..

我的解决方案是从 bluez media enpoint 中删除 c 代码,然后我创建了自己的 Nodejs NAN 绑定(bind)到它......而不使用任何 glib 事件循环。

这是我正在使用的node-dbus库:

https://github.com/Shouqun/node-dbus

关于node.js - 从 Node 插件回复 Dbus 调用时出现 Bluez MediaEndpoint1 超时问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41843793/

相关文章:

javascript - mongodb中客户端和服务器之间的搜索API

python - Dbus & Bluez 编程语言

qt - 我们可以生成抽象的 Qt D-Bus 适配器类吗?

linux - Bluez:广告服务/gatt 服务器示例?

android - 蓝牙 Bluez : Unable to create crypto contex

qt - QDBusAbstractAdaptor 对象不导出已实现的 dbus 接口(interface)

javascript - 如何使用可以启动/停止的递归函数编写应用程序

javascript - Bluebird 的绑定(bind)方法在调用之间保存上下文(this)

javascript - request.auth.session.set(user_info) 不工作 HapiJS

linux - 如何从命令行发出 dbus 信号