Szukaj…


W C z Bluez

int get_l2cap_connection () {

Po pierwsze, wszystkie zmienne, których potrzebujemy, wyjaśnienie nastąpi w odpowiednim miejscu.

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

Najpierw musimy utworzyć gniazdo, z którego możemy zaakceptować połączenie. Rodzina gniazd to PF_BLUETOOTH , typ gniazda to SOCK_SEQPACKET (chcemy mieć gniazdo podobne do TCP, a nie surowe), a protokołem jest protokół Bluetooth L2CAP ( BTPROTO_L2CAP ).

    ssock = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);

Chcemy mieć pewność, że się udało:

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

Teraz musimy wypełnić strukturę adresu źródłowego adresem zastępczym, aby każde urządzenie Bluetooth o dowolnym adresie mogło się z nami połączyć. Adres wieloznaczny jest zdefiniowany jako BDADDR_ANY w bluetooth.h . Aby skopiować go do struktury adresu, możemy użyć funkcji bacpy . Musimy również ustawić rodzinę adresów, typ adresu i identyfikator kanału.

    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);

Ustawienie opcji SO_REUSEADDR pozwoli nam szybko wywołać bind, jeśli to konieczne (można to pominąć):

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

Następnie musimy powiązać gniazdo ze zdefiniowaną właśnie strukturą adresu źródłowego. Ponownie sprawdzamy wartość zwracaną, aby upewnić się, że zadziałała.

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

Następnie ustawia poziom bezpieczeństwa. Pamiętaj, że ten krok jest opcjonalny, ale ustawienie poziomu bezpieczeństwa na ŚREDNI pozwoli na automatyczne parowanie z urządzeniem (jądro obsługuje faktyczne parowanie).

    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;
    }

Teraz możemy powiedzieć kernelowi, że nasze ssock jest pasywnym gniazdem, które zaakceptuje połączenie. Drugi parametr to zaległości. Jeśli chcesz dowiedzieć się więcej, strona odsłuchu zawiera wszystkie potrzebne informacje.

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

Teraz możemy poczekać na połączenie przychodzące. Struktura peer_addr będzie zawierać adres podłączonego urządzenia, po zaakceptowaniu zwrotów. csock będzie deskryptorem pliku gniazda, z którego możemy czytać / zapisywać, aby komunikować się z podłączonym urządzeniem.

    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;
    }

Możemy wydrukować adres podłączonego urządzenia (oczywiście opcjonalnie). Możemy użyć funkcji batostr do konwersji adresu Bluetooth na ciąg znaków.

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

Jeśli nie chcemy, aby inne urządzenia się łączyły, powinniśmy zamknąć gniazdo serwera. Zrób to samo z csock, po zakończeniu komunikacji z urządzeniem.

    close(ssock);
    return csock;
}


Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow