Bluez上的Linux下方的C 蓝牙耳机

C++ Bluetooth headphones under Linux over BlueZ

本文关键字:蓝牙耳机 上的 Linux Bluez      更新时间:2023-10-16

我正在尝试在linux下(bluez stack(编写蓝牙耳机的音频应用程序。它是嵌入式版本,所以我只想使用C 和Bluez,而无需任何DBU或Python。目前,我可以成功询问设备并与它们配对。但是几秒钟后,连接丢失了。

据我所知,配对后应该建立一些链接,以防止断开连接。但是我不知道我在做什么错。

这是我的代码示例:

int main(int argc, char** argv) {
    int max_rsp, num_rsp;
    int dev_id, sock, len, flags;
    inquiry_info*   ii      = NULL;
    char        addr[19]    = {0};
    char        name[248]   = {0};
    uint8_t     cod[3]      = {0};
    const char localName[8] = "TestKIT";
    dev_id  = hci_get_route(NULL);
    sock    = hci_open_dev(dev_id);
    if (dev_id < 0 || sock < 0) {
        std::cerr << "HCI open device:tt" << strerror(errno) << std::endl;
        return -1;
    }
    hci_write_local_name(sock, localName, 8);
    std::cout << std::endl;
    std::cout << "Device name set to:t"" << localName << """ << std::endl;
    len = 8;
    max_rsp = 255;
    flags   = IREQ_CACHE_FLUSH;
    ii  = new inquiry_info[max_rsp * sizeof(inquiry_info)];
    num_rsp = hci_inquiry(dev_id, len, max_rsp, NULL, &ii, flags);
    if (num_rsp < 0) {
        std::cerr << "HCI inquiry: " << strerror(errno) << std::endl;
    }
    std::cout << std::endl;
    std::cout << "=========================================================================" << std::endl;
    std::cout << " #t" << "BTAttt" << "Nametttt" << "COD" << std::endl;
    std::cout << "-------------------------------------------------------------------------" << std::endl;
        for (int i = 0; i < num_rsp; ++i) {
        ba2str(&ii[i].bdaddr, addr);
        memset(name, 0, sizeof(name));
        if (hci_read_remote_name(sock, &ii[i].bdaddr, sizeof(name), name, 0) < 0) {
            strcpy(name, "[unknown]");
        }
        hci_read_class_of_dev(sock, cod, 0);
        std::cout << std::setw(2) << std::setfill(' ') << i + 1 << '.' << "t";
        std::cout << addr << "t";
        std::cout << std::setw(30) << std::left << name << "t" << std::right;
        std::cout << "0x";
        std::cout << std::setw(2) << std::setfill('0') << std::hex << static_cast<unsigned int>(cod[2]);
        std::cout << std::setw(2) << std::setfill('0') << std::hex << static_cast<unsigned int>(cod[1]);
        std::cout << std::setw(2) << std::setfill('0') << std::hex << static_cast<unsigned int>(cod[0]);
        std::cout << std::endl;
    }
    std::cout << "=========================================================================" << std::endl;
    unsigned int userChoise = 0;
    std::cout << std::endl;
    std::cout << "Device to connect: ";
    std::cin >> userChoise;
    uint16_t    handle;
    unsigned int    ptype   = HCI_DM1 | HCI_DM3 | HCI_DM5 | HCI_DH1 | HCI_DH3 | HCI_DH5;
    if (userChoise > 0 && userChoise <= num_rsp) {
        std::cout << "Connecting to device #" << userChoise << " ..." << std::endl;
        std::cout << std::endl;
        if (hci_create_connection(sock, &ii[userChoise - 1].bdaddr, htobs(ptype), 0, 0, &handle, 0) < 0) {
            std::cerr << "HCI create connection:t" << strerror(errno) << std::endl;
        } else {
            std::cout << "Connection:ttOK" << std::endl;
        }
        if (hci_authenticate_link(sock, handle, 0) < 0) {
            std::cerr << "HCI authenticate connection:t" << strerror(errno) << std::endl;
        } else {
            std::cout << "Authentication:ttOK" << std::endl;
        }
        if (hci_encrypt_link(sock, handle, 1, 0) < 0) {
            std::cerr << "HCI encrypt connection:t" << strerror(errno) << std::endl;
        } else {
            std::cout << "Encryption:ttOK" << std::endl;
        }
    } else {
        std::cout << "Wrong device number: " <<  userChoise << " (should be ";
        if (num_rsp > 1) {
            std::cout << "in range [1 .. " << num_rsp << "]";
        } else {
            std::cout << "1";
        }
        std::cout << ")" << std::endl;
    }
    hci_close_dev(sock);
    close(sock);
    // Connection to prevent disconnect
    struct sockaddr_l2 rAddr;
    int sk = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
    if (sk < 0) {
        std::cerr << "Socket:t" << strerror(errno) << std::endl;
    }
    memset(&rAddr, 0, sizeof(rAddr));
    rAddr.l2_family = AF_BLUETOOTH;
    rAddr.l2_psm = 0x1001;
    rAddr.l2_bdaddr = ii[userChoise - 1].bdaddr;
    if (connect(sk, (struct sockaddr *) &rAddr, sizeof(rAddr)) < 0 ) {
        std::cerr << "Connect:t" << strerror(errno) << std::endl;
    } 
    std::cout << "Socket "sk": " << sk << std::endl;
    delete [] ii;
    ii = NULL;
    return 0;
}

好吧,找到解决方案 - 是在连接之前启动所有SDP例程以获取所需协议所需的频道。目前,RFCOMM连接成功建立了。

这是现在的工作方式:C 示例形成我的github。

P.S。注意 - 这个项目现在没有维护,因为我没有足够的时间。但是它可能会在将来改变