Поиск…


В C, с Bluez

int get_l2cap_connection () {

Прежде всего, все переменные, которые нам нужны, объяснение будет следовать в соответствующем месте.

    int ssock = 0;
    int csock = 0;
    int reuse_addr = 1;
    struct sockaddr_l2 src_addr;
    struct bt_security bt_sec;
    int result = 0;

Во-первых, нам нужно создать сокет, из которого мы можем принять соединение. Семейство сокетов - PF_BLUETOOTH , тип сокета - SOCK_SEQPACKET (мы хотим иметь TCP-подобный сокет, а не raw), а протокол - протокол Bluetooth L2CAP ( BTPROTO_L2CAP ).

    ssock = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);

Мы хотим убедиться, что это было успешным:

    if (ssock < 0) {
        perror("Opening L2CAP socket failed");
        return -1;
    }

Теперь нам нужно заполнить структуру адреса источника с помощью подстановочного адреса, поэтому любое устройство Bluetooth с любым адресом может подключиться к нам. Подстановочный адрес определяется как BDADDR_ANY в bluetooth.h . Чтобы скопировать его в структуру адреса, мы можем использовать функцию bacpy . Мы также должны установить семейство адресов, тип адреса и идентификатор канала.

    memset(&src_addr, 0, sizeof(src_addr));
    bacpy(&src_addr.l2_bdaddr, BDADDR_ANY);
    src_addr.l2_family = AF_BLUETOOTH;
    src_addr.l2_bdaddr_type = BDADDR_LE_PUBLIC;
    src_addr.l2_cid = htobs(CID_ATT);

Установка опции SO_REUSEADDR позволит нам быстро вызвать привязку снова, если это необходимо (это может быть опущено):

    setsockopt(ssock, SOL_SOCKET, SO_REUSEADDR, &reuse_addr, sizeof(reuse_addr));

Затем мы должны связать сокет с исходной структурой адреса, которую мы только что определили. Опять же, мы проверяем возвращаемое значение, чтобы убедиться, что оно сработало.

    result = bind(ssock, (struct sockaddr*) &src_addr, sizeof(src_addr));
    if (result < 0) {
        perror("Binding L2CAP socket failed");
        return -1;
    }

Затем настройка уровня безопасности. Обратите внимание, что этот шаг является необязательным, но установка уровня безопасности в MEDIUM позволит автоматически спариваться с устройством (ядро обрабатывает фактическое сопряжение).

    memset(&bt_sec, 0, sizeof(bt_sec));
    bt_sec.level = BT_SECURITY_MEDIUM;
    result = setsockopt(ssock, SOL_BLUETOOTH, BT_SECURITY, &bt_sec, sizeof(bt_sec));
    if (result != 0) {
        perrorno("Setting L2CAP security level failed");
        return -1;
    }

Теперь мы можем сказать ядру, что наш ssock является пассивным сокетом, который будет принимать соединение. Второй параметр - это отставание. Если вы хотите узнать больше, справочная страница прослушивания содержит всю необходимую информацию.

    result = listen(ssock, 10);
    if (result < 0) {
        perror("Listening on L2CAP socket failed");
        return -1;
    }

Теперь мы можем дождаться входящего соединения. Структура peer_addr будет содержать адрес подключенного устройства, после принятия возврата. csock будет файловым дескриптором сокета, который мы можем читать / записывать, для связи с подключенным устройством.

    memset(peer_addr, 0, sizeof(*peer_addr));
    socklen_t addrlen = sizeof(*peer_addr);
    csock = accept(ssock, (struct sockaddr*)peer_addr, &addrlen);
    if (csock < 0) {
        perror("Accepting connection on L2CAP socket failed");
        return -1;
    }

Мы можем распечатать адрес подключенного устройства (необязательно, конечно). Мы можем использовать функцию batostr для преобразования адреса Bluetooth в строку.

    printf("Accepted connection from %s", batostr(&peer_addr->l2_bdaddr));

Если мы не хотим, чтобы какие-либо другие устройства подключались, мы должны закрыть серверный сокет. Сделайте то же самое с csock после того, как ваше сообщение с устройством будет завершено.

    close(ssock);
    return csock;
}


Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow