简体   繁体   中英

C++ Bluetooth headphones under Linux over BlueZ

I'm trying to write audio application for Bluetooth headphones under Linux (over BlueZ stack). It's embedded version so I want to use only C++ and BlueZ without any DBus or Python. For now I could successfully inquire devices and pair with them. But after few seconds connection gets lost.

As far as I understand - there's should be some link established after pairing to prevent disconnection. But I can't figure out what am I doing wrong..

Here is my code sample:

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:\t\t" << 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" << "BTA\t\t\t" << "Name\t\t\t\t" << "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:\t\tOK" << std::endl;

        }

        if (hci_authenticate_link(sock, handle, 0) < 0) {

            std::cerr << "HCI authenticate connection:\t" << strerror(errno) << std::endl;

        } else {

            std::cout << "Authentication:\t\tOK" << 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:\t\tOK" << 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;

}

Okay, thanks to all who helped me (yes, you Google and you Github). The sollution was to init all SDP routine to get required channel for required protocol befor connecting. For now RFCOMM connection establishing successfully

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM