Linux Bluez 5.48-如何强制蓝牙传输状态从活动变为空闲-嵌入式接收器端

Linux Bluez 5.48-如何强制蓝牙传输状态从活动变为空闲-嵌入式接收器端,linux,bluetooth,embedded,dbus,bluez,Linux,Bluetooth,Embedded,Dbus,Bluez,通常情况下,iOS应用程序不通过AVRCP DBus信令向接收器提供暂停和播放信号。安卓很好。许多iOS应用上暂停流的唯一迹象(如果仍然最大化)是传输状态将在一段时间后变为空闲状态。如果用户在暂停和播放之间切换,则除了实际音频之外,无法知道该接收器端(即嵌入式扬声器)。Android将发出暂停信号,并在我测试过的应用程序上通过AVRCP播放。在iOS上,一旦传输空闲,“播放”将立即将传输恢复到活动状态。所以有没有一种方法,Bash、Python、C或其他任何东西,可以从嵌入式接收器端强制连接设备

通常情况下,iOS应用程序不通过AVRCP DBus信令向接收器提供暂停和播放信号。安卓很好。许多iOS应用上暂停流的唯一迹象(如果仍然最大化)是传输状态将在一段时间后变为空闲状态。如果用户在暂停和播放之间切换,则除了实际音频之外,无法知道该接收器端(即嵌入式扬声器)。Android将发出暂停信号,并在我测试过的应用程序上通过AVRCP播放。在iOS上,一旦传输空闲,“播放”将立即将传输恢复到活动状态。所以有没有一种方法,Bash、Python、C或其他任何东西,可以从嵌入式接收器端强制连接设备(如iPad)的传输?如果可能的话,我会知道何时按下“播放”按钮,使传输再次激活。
谢谢

简而言之,您需要在
org.bluez.MediaTransport1
界面上收听
PropertiesChanged
信号,并解析状态更改的信号

您可以在初始化期间注册到Bluez DBUS接口,如下所示

g_dbus_connection_signal_subscribe(conn, "org.bluez", "org.freedesktop.DBus.Properties",
                "PropertiesChanged", NULL, "org.bluez.MediaTransport1", G_DBUS_SIGNAL_FLAGS_NONE,
                bluez_signal_transport_changed, NULL, NULL);
下面的示例是解析状态变化信号的功能

static void bluez_signal_transport_changed(GDBusConnection *conn, const gchar *sender,
        const gchar *path, const gchar *interface, const gchar *signal, GVariant *params,
        void *userdata) {
    (void)conn;
    (void)sender;
    (void)interface;
    (void)userdata;

    const gchar *signature = g_variant_get_type_string(params);
    GVariantIter *properties = NULL;
    GVariantIter *unknown = NULL;
    GVariant *value = NULL;
    struct ba_transport *t;
    const char *iface;
    const char *key;

    if (strcmp(signature, "(sa{sv}as)") != 0) {
        error("Invalid signature for %s: %s != %s", signal, signature, "(sa{sv}as)");
        goto fail;
    }    

    g_variant_get(params, "(&sa{sv}as)", &iface, &properties, &unknown);
    debug("Signal: %s: %s", signal, iface);

    while (g_variant_iter_next(properties, "{&sv}", &key, &value)) {

        if (strcmp(key, "State") == 0) {

            if (!g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
                error("Invalid argument type for %s: %s != %s", key,
                        g_variant_get_type_string(value), "s");
                goto fail;
            }

             printf("state is %s\n", g_variant_get_string(value, NULL));  
        }

        g_variant_unref(value);
        value = NULL;
    }

fail:
    if (properties != NULL)
        g_variant_iter_free(properties);
    if (value != NULL)
        g_variant_unref(value);
}

其中
g\u variant\u get\u string(value,NULL))
将为您提供当前状态,您将根据当前状态决定接收器操作。

谢谢,我已经可以轻松监控MediaTransport状态。我想强制传输状态为空闲,仅此而已@edtrx850 AFAIK您不能手动强制执行。在这里,
state
是只读属性。唯一的方法是通过暂停源端的音频来通知bluez接收器端。底层堆栈会自动更改状态。这是没有办法强迫的!我猜到了!一些iOS应用程序没有发出AVRCP播放/暂停信号真的很痛苦,我无法知道它是否在冒烟。我需要知道的原因是为了方便起见,切换到挤压水槽;然而,我也需要知道蓝牙什么时候想要它回来!因此需要检测播放。系统也不能为水槽使用混合器,需要尽可能的未加工。不知道我是否可以在某个地方破解Bluez,迫使传输闲置?@edtrx850:我不喜欢为此而调整Bluez。简言之,状态更改由远程设备
org.bluez.MediaTransport1
接口报告。所以受控端的bluez只是监听器。如果你仍然想调整它,你需要检查
org.bluez.MediaTransport1
中的回调,在这里的GET实现中定义,我当然也不喜欢调整它!但值得一试,事实上,我正在仔细阅读你昨晚发送的链接,所以这在某种程度上让人放心。如果iOS YouTube编码人员只是实现了完整的AVRCP套件,那么就容易多了。无论如何,谢谢你的意见-谢谢!