我在内核3.4.79+的嵌入式Linux项目中使用BlueZ 4.101。正常的蓝牙操作非常好,我可以在设备上使用许多耳机来传输音频。现在我正在努力实现蓝牙合规性,因此我正在使用Bluetooth SIG的USB PTS Dongle。我正在通过每个测试,除了部分来电测试,我需要在接受PTS加密狗的呼叫后打开SCO连接。
SCO连接尝试适用于耳机,但不适用于PTS加密狗。该错误来自bluetoothd:
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;
}
我在Kernel Config中缺少什么才能让PTS加密狗进入具有开放SCO连接的播放状态?
这是我的.config for Linux(我使用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
答案 0 :(得分:0)
问题不在于内核的配置,而是我正在使用的驱动程序集。我编译了蓝牙驱动程序的linux backports(http://drvbp1.linux-foundation.org/~mcgrof/rel-html/backports/)版本,因为我需要后向移植的wifi驱动程序,这给了我不支持协议(93)错误。我切换回使用内核3.4.79+发布的驱动程序,它运行良好。