Ricerca…


In C, con Bluez

int get_l2cap_connection () {

Prima di tutto, tutte le variabili di cui abbiamo bisogno, la spiegazione per seguirà nel punto appropriato.

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

Per prima cosa, dobbiamo creare un socket, da cui possiamo accettare una connessione. La famiglia di socket è PF_BLUETOOTH , il tipo di socket è SOCK_SEQPACKET (vogliamo avere un socket simile a TCP, non raw) e il protocollo è il protocollo Bluetooth L2CAP ( BTPROTO_L2CAP ).

    ssock = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);

Vogliamo assicurarci che sia stato un successo:

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

Ora dobbiamo riempire la struttura dell'indirizzo sorgente con un indirizzo jolly, in modo che qualsiasi dispositivo Bluetooth con qualsiasi indirizzo possa connetterci. L'indirizzo jolly è definito come BDADDR_ANY in bluetooth.h . Per copiarlo nella struttura dell'indirizzo, possiamo usare la funzione bacpy . Dobbiamo anche impostare la famiglia di indirizzi, il tipo di indirizzo e l'ID del canale.

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

L'impostazione dell'opzione SO_REUSEADDR ci consentirà di richiamare rapidamente il bind, se necessario (questo può essere escluso):

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

Quindi dobbiamo legare il socket con la struttura dell'indirizzo sorgente che abbiamo appena definito. Ancora una volta, controlliamo il valore di ritorno per assicurarci che funzioni.

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

Il prossimo è impostare il livello di sicurezza. Si noti che questo passaggio è facoltativo, ma l'impostazione del livello di sicurezza su MEDIUM consentirà l'accoppiamento automatico con il dispositivo (il kernel gestisce l'accoppiamento effettivo).

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

Ora possiamo dire al kernel che il nostro ssock è un socket passivo, che accetterà una connessione. Il secondo parametro è il backlog. Se vuoi saperne di più, la manpage di listen contiene tutte le informazioni di cui hai bisogno.

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

Ora possiamo aspettare una connessione in arrivo. La struttura peer_addr conterrà l'indirizzo del dispositivo connesso, una volta accettata la restituzione. csock sarà il descrittore di file del socket da cui possiamo leggere / scrivere, per comunicare con il dispositivo connesso.

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

Possiamo stampare l'indirizzo del dispositivo connesso (facoltativo, ovviamente). Possiamo usare la funzione batostr per convertire l'indirizzo Bluetooth in una stringa.

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

Se non vogliamo connettere altri dispositivi, dovremmo chiudere il socket del server. Fai la stessa cosa con csock, una volta terminata la comunicazione con il dispositivo.

    close(ssock);
    return csock;
}


Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow