linux - BlueZ scotest应用程序并带有Linux Config无法连接到SCO套接字

我在带有Kernel 3.4.79+的嵌入式Linux项目上使用BlueZ 4.101。正常的蓝牙操作效果很好,我可以在设备上使用许多耳机来传输音频。现在,我正在努力实现蓝牙合规性,因此我正在使用蓝牙SIG的USB PTS加密狗。我正在通过所有测试,但来电测试的一部分除外,在接受PTS加密狗的 call 后,我需要打开SCO连接。

SCO连接尝试适用于耳机,但不适用于PTS加密狗。错误从蓝牙给出为:

bluetoothd[6306]: audio/headset.c:headset_set_state() State changed /org/bluez/6306/hci0/dev_00_1B_DC_07_30_40: HEADSET_STATE_PLAY_IN_PROGRESS -> HEADSET_STATE_CONNECTED
bluetoothd[6306]: audio/headset.c:headset_set_state() State changed /org/bluez/6306/hci0/dev_00_1B_DC_07_30_40: HEADSET_STATE_CONNECTED -> HEADSET_STATE_PLAY_IN_PROGRESS
bluetoothd[6306]: Protocol not supported (93)

因此,我从BlueZ的测试目录中编译了scotest,并在与加密狗连接后运行了该测试,并得到了相同的结果:
# ./scotest -s -b HELLO 00:1B:DC:07:30:40
scotest[1687]: Can't connect: Protocol not supported (93)
scotest[1687]: Can't connect to the server: Protocol not supported (93)

这是scotest.c中失败的do_connect函数:
static int do_connect(char *svr)
{
    struct sockaddr_sco addr;
    struct sco_conninfo conn;
    socklen_t optlen;
    int sk;

    /* Create socket */
    sk = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO);
    if (sk < 0) {
        syslog(LOG_ERR, "Can't create socket: %s (%d)",
                            strerror(errno), errno);
        return -1;
    }

    /* Bind to local address */
    memset(&addr, 0, sizeof(addr));
    addr.sco_family = AF_BLUETOOTH;
    bacpy(&addr.sco_bdaddr, &bdaddr);

    if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
        syslog(LOG_ERR, "Can't bind socket: %s (%d)",
                            strerror(errno), errno);
        goto error;
    }

    /* Connect to remote device */
    memset(&addr, 0, sizeof(addr));
    addr.sco_family = AF_BLUETOOTH;
    str2ba(svr, &addr.sco_bdaddr);

    if (connect(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
        syslog(LOG_ERR, "Can't connect: %s (%d)",
                            strerror(errno), errno);
        goto error;
    }

    /* Get connection information */
    memset(&conn, 0, sizeof(conn));
    optlen = sizeof(conn);

    if (getsockopt(sk, SOL_SCO, SCO_CONNINFO, &conn, &optlen) < 0) {
        syslog(LOG_ERR, "Can't get SCO connection information: %s (%d)",
                            strerror(errno), errno);
        goto error;
    }

    syslog(LOG_INFO, "Connected [handle %d, class 0x%02x%02x%02x]",
        conn.hci_handle,
        conn.dev_class[2], conn.dev_class[1], conn.dev_class[0]);

    return sk;

error:
    close(sk);
    return -1;
}

我在内核配置中缺少什么以允许通过开放的SCO连接将PTS加密狗置于“播放”状态?

这是我的Linux版.config(我正在使用backports-3.13.2-1支持TI WL1271 BT/WiFi模块):
CPTCFG_IPV6_SUBTREES=y
CPTCFG_NFT_RBTREE=m
CPTCFG_BRIDGE_NF_EBTABLES=m
CPTCFG_BRIDGE_EBT_BROUTE=m
CPTCFG_BRIDGE_EBT_T_FILTER=m
CPTCFG_BRIDGE_EBT_T_NAT=m
CPTCFG_BRIDGE_EBT_802_3=m
CPTCFG_BRIDGE_EBT_AMONG=m
CPTCFG_BRIDGE_EBT_ARP=m
CPTCFG_BRIDGE_EBT_IP=m
CPTCFG_BRIDGE_EBT_IP6=m
CPTCFG_BRIDGE_EBT_LIMIT=m
CPTCFG_BRIDGE_EBT_MARK=m
CPTCFG_BRIDGE_EBT_PKTTYPE=m
CPTCFG_BRIDGE_EBT_STP=m
CPTCFG_BRIDGE_EBT_VLAN=m
CPTCFG_BRIDGE_EBT_ARPREPLY=m
CPTCFG_BRIDGE_EBT_DNAT=m
CPTCFG_BRIDGE_EBT_MARK_T=m
CPTCFG_BRIDGE_EBT_REDIRECT=m
CPTCFG_BRIDGE_EBT_SNAT=m
CPTCFG_BRIDGE_EBT_LOG=m
CPTCFG_BRIDGE_EBT_NFLOG=m
CPTCFG_MAC_EMUMOUSEBTN=m
CPTCFG_RTLBTCOEXIST=m
CPTCFG_TABLET_USB_KBTAB=m
CPTCFG_INPUT_ATLAS_BTNS=m
CPTCFG_SND_BT87X=m
CPTCFG_LIRC_BT829=m
CPTCFG_USB_BTMTK=m
CPTCFG_TOSHIBA_BT_RFKILL=m
CPTCFG_BTRFS_FS=m
CPTCFG_BTRFS_FS_POSIX_ACL=y
CPTCFG_RBTREE_TEST=m
CPTCFG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=y
CPTCFG_BTREE=y
CPTCFG_BACKPORT_OPTION_BT_SOCK_CREATE_NEEDS_KERN=y
CPTCFG_BT=m
CPTCFG_BT_RFCOMM=m
# CPTCFG_BT_RFCOMM_TTY is not set
CPTCFG_BT_BNEP=m
CPTCFG_BT_BNEP_MC_FILTER=y
CPTCFG_BT_BNEP_PROTO_FILTER=y
# CPTCFG_BT_CMTP is not set
CPTCFG_BT_HIDP=m
CPTCFG_BT_HCIBTUSB=m
CPTCFG_BT_HCIBTSDIO=m
CPTCFG_BT_HCIUART=m
CPTCFG_BT_HCIUART_H4=y
CPTCFG_BT_HCIUART_BCSP=y
# CPTCFG_BT_HCIUART_ATH3K is not set
CPTCFG_BT_HCIUART_LL=y
CPTCFG_BT_HCIUART_3WIRE=y
# CPTCFG_BT_HCIBCM203X is not set
# CPTCFG_BT_HCIBPA10X is not set
# CPTCFG_BT_HCIBFUSB is not set
# CPTCFG_BT_HCIDTL1 is not set
# CPTCFG_BT_HCIBT3C is not set
# CPTCFG_BT_HCIBLUECARD is not set
CPTCFG_BT_HCIBTUART=m
CPTCFG_BT_HCIVHCI=m
# CPTCFG_BT_MRVL is not set
# CPTCFG_BT_ATH3K is not set
CPTCFG_BT_WILINK=m

我使用printks在内核中检测了sco.c文件。

成功打开SCO连接后,使用普通头戴式耳机成功显示如下:
*** sco_sock_create
*** sco_sock_alloc
*** sco_sock_init
*** sco_sock_bind
*** sco_sock_connect
*** sco_connect
*** sco_conn_add
*** sco_chan_add
*** __sco_chan_add
*** sco_sock_set_timer
*** sco_connect_cfm
*** sco_conn_add
*** sco_conn_ready
*** sco_sock_clear_timer
*** sco_sock_getsockopt
*** sco_sock_setsockopt_old
*** sco_sock_getsockopt
*** sco_sock_setsockopt_old
*** sco_sock_sendmsg
*** sco_send_frame
*** sco_sock_sendmsg
*** sco_send_frame
*** sco_sock_sendmsg
*** sco_send_frame

失败时看起来像这样:
*** sco_sock_create
*** sco_sock_alloc
*** sco_sock_init
*** sco_sock_bind
*** sco_sock_connect
*** sco_connect
*** sco_conn_add
*** sco_chan_add
*** __sco_chan_add
*** sco_sock_set_timer
*** sco_connect_cfm
*** sco_conn_del
*** sco_chan_get
*** sco_sock_clear_timer
*** sco_chan_del
*** sco_sock_release
*** sco_sock_close
*** sco_sock_kill
*** sco_sock_clear_timer
*** __sco_sock_connect
*** sco_sock_kill
*** sco_sock_kill
*** sco_sock_destruct

进一步的检测显示此sco.c函数中正在发生故障:
void sco_connect_cfm(struct hci_conn *hcon, __u8 status)
{

    printk("*** sco_connect_cfm start\n");

    BT_DBG("hcon %p bdaddr %pMR status %d", hcon, &hcon->dst, status);
    printk("*** sco_connect_cfm_stat hcon %p bdaddr %pMR status %d\n", hcon, &hcon->dst, status);
    if (!status) {
        struct sco_conn *conn;

        conn = sco_conn_add(hcon);
        printk("*** sco_connect_cfm sco_conn_add: %d\n",conn);
        if (conn)
            printk("*** sco_connect_cfm ready\n");
            sco_conn_ready(conn);
    } else
        printk("*** sco_connect_delete: %d\n",status);
        sco_conn_del(hcon, bt_to_errno(status));
}

该输出看起来像这样:
*** sco_sock_create
*** sco_sock_alloc
*** sco_sock_init
*** sco_sock_bind
*** sco_sock_connect
*** sco_connect
*** sco_conn_add
*** sco_chan_add
*** __sco_chan_add
*** sco_sock_set_timer
*** sco_connect_cfm start
*** sco_connect_cfm_stat hcon d9ec2400 bdaddr 40:30:07:dc:1b:00 status 26
*** sco_connect_delete: 26
*** sco_conn_del
*** sco_chan_get
*** sco_sock_clear_timer
*** sco_chan_del
*** sco_sock_release
*** sco_sock_close
*** sco_sock_clear_timer
*** sco_sock_kill
*** __sco_sock_connect
*** sco_sock_kill
*** sco_sock_kill
*** sco_sock_destruct

最佳答案

问题不在于内核的配置,而是我正在使用的驱动程序集。我已经编译了蓝牙驱动程序的linux backports(http://drvbp1.linux-foundation.org/~mcgrof/rel-html/backports/)版本,因为我需要backported wifi驱动程序,这给了我Protocol Not Supported(93)错误。我切换回了随Kernel 3.4.79+一起分发的驱动程序,它可以正常工作。