微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

无法使用 BlueZ 堆栈创建 BLE L2CAP 连接

如何解决无法使用 BlueZ 堆栈创建 BLE L2CAP 连接

我正在尝试在 nRF52840DK 和 RPI 的原生蓝牙之间创建 L2CAP 连接。 nRF52840 运行 RIOT OS 和灵活堆栈,RPI 使用 BlueZ 5.50 蓝牙堆栈。

目前,RPI 可以发现 nRF52840 并使用 hci_le_create_conn 成功创建 GAP 连接。在连接建立阶段,节点接收到两个GAP事件,分别是BLE_GAP_EVENT_CONNECT (code 0)BLE_GAP_EVENT_MTU (code 15)。 MTU 事件将 ATT 的 MTU 从 0 更改为 256。

但是,当我使用 connect() 创建 L2CAP 套接字连接时,发生超时并返回错误 Host is down。 nRF52840 收到 BLE_GAP_EVENT_disCONNECT (code 1)。可能我的代码有一些错误,因为网上相关的代码很少。我怎样才能做到正确?

nRF52840DK 正在运行 nimble_l2cap_server example输出为:

user@ubuntu:/mnt/hgfs/DATA_SHARE/RIOT/tests/nimble_l2cap_server$ rv -s 1 -vt
rtt viewer appiation
Connectiong to sn: 1
SN =  1  log file writing enabled
SN =  1  Connecting...
SN =  1  Connected
Auto init xtimer.
Auto init NimBLE.
main(): This is RIOT! (Version: 2021.04-devel-903-g89939)
NimBLE L2CAP test server
# Now advertising
# GAP event 0
current att mtu = 0
# GAP event 15
my handle = 1,conn handle = 1 cid = 4,mtu value = 256
current att mtu = 256
# GAP event 1

我的 BlueZ 代码是:

#include "blescan.h"
#include <sys/socket.h>
#include <bluetooth/l2cap.h>

int main(int argc,char *argv[]){
    int id_type;
    char *id;
    bdaddr_t src_addr;
    uint16_t le_conn_handle = 0;
    char dest_addr_str[18];
    // to check wether the device is advertisiing
    if (argc < 3){
        perror("Too few arguments");
        exit(0);
    }
    id = argv[2];
    if (strcmp(argv[1],"-m") == 0){
        id_type = ID_TYPE_MAC;
    }
    else if (strcmp(argv[1],"-n") == 0){
        id_type = ID_TYPE_NAME;
    }
    else{
        perror("UnkNow argument");
        exit(0);
    }
    memset(dest_addr_str,sizeof(dest_addr_str));
    int res = blescan(id_type,id,100,dest_addr_str);
    if (res == 0){  // Cannot find the corresponding BLE device
        perror("Can not find the target device");
        exit(0);
    }
    printf("find the target\n");
    // open a hci socket
    int device_id = hci_get_route(NULL);
    int hci_socket = hci_open_dev(device_id);
    hci_devba(device_id,&src_addr);

    // Create a le connection
    bdaddr_t dest_bdaddr;
    memset(&dest_bdaddr,sizeof(dest_bdaddr));
    str2ba(dest_addr_str,&dest_bdaddr);
    res = hci_le_create_conn(hci_socket,htobs(0x04),LE_RANDOM_ADDRESS,dest_bdaddr,LE_PUBLIC_ADDRESS,htobs(0x0018),htobs(0x0028),htobs(0),htobs(0x0100),htobs(0x0000),&le_conn_handle,25000);
    if (res != 0){
        perror("Connection error");
        goto hciclose;
    }

    // Create a L2CAP socket
    struct sockaddr_l2 dest_sockaddr;
    memset(&dest_sockaddr,sizeof(dest_sockaddr));
    memset(&src_sockaddr,sizeof(src_sockaddr));
    dest_sockaddr.l2_family = AF_BLUetoOTH;
    dest_sockaddr.l2_psm = htobs(0x0235);
    str2ba(dest_addr_str,&dest_sockaddr.l2_bdaddr);
    int l2cap_client_socket = socket(AF_BLUetoOTH,SOCK_SEQPACKET,BTPROTO_L2CAP);
    if (l2cap_client_socket < 0){
        perror("Can not open l2cap socket");
        goto hciclose;
    }
    // Connect to nrf52840 Failed with a timeout
    res = connect(l2cap_client_socket,(struct sockaddr *)&dest_sockaddr,sizeof(dest_sockaddr));
    if (res == 0){
        res = write(l2cap_client_socket,"hello from linux",17);
    }

> Blockquote

    else if(res < 0){
        printf("error code = %d\n",res);
        perror("l2cap socket connction Failed");
        hci_disconnect(hci_socket,le_conn_handle,HCI_OE_USER_ENDED_CONNECTION,1000);
        goto hciclose;
    }

hciclose:
    if (le_conn_handle != 0){
        hci_disconnect(hci_socket,1000);
    }
    hci_close_dev(device_id);
    exit(0);
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。