bluetooth
Offene L2CAP-Buchse für Low Energy-Kommunikation
Suche…
In C mit Bluez
int get_l2cap_connection () {
Zunächst werden alle Variablen, für die wir eine Erklärung benötigen, an der entsprechenden Stelle angezeigt.
int ssock = 0;
int csock = 0;
int reuse_addr = 1;
struct sockaddr_l2 src_addr;
struct bt_security bt_sec;
int result = 0;
Zuerst müssen wir einen Socket erstellen, von dem aus wir eine Verbindung annehmen können. Die Socket-Familie ist PF_BLUETOOTH , der Socket-Typ ist SOCK_SEQPACKET (wir möchten einen TCP-artigen Socket haben, nicht roh), und das Protokoll ist das Bluetooth-Protokoll L2CAP ( BTPROTO_L2CAP ).
ssock = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
Wir möchten sicherstellen, dass es erfolgreich war:
if (ssock < 0) {
perror("Opening L2CAP socket failed");
return -1;
}
Wir müssen nun die Quelladressstruktur mit einer Platzhalteradresse füllen, damit sich jedes Bluetooth-Gerät mit einer beliebigen Adresse mit uns verbinden kann. Die Platzhalteradresse ist in bluetooth.h als BDADDR_ANY definiert. Um es in die bacpy zu kopieren, können wir die Funktion bacpy verwenden. Wir müssen auch die Adressfamilie, den Adresstyp und die Kanal-ID einstellen.
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);
Wenn Sie die Option SO_REUSEADDR festlegen, können Sie bei Bedarf schnell erneut bind aufrufen (dies kann weggelassen werden):
setsockopt(ssock, SOL_SOCKET, SO_REUSEADDR, &reuse_addr, sizeof(reuse_addr));
Als Nächstes müssen wir den Socket mit der soeben definierten Quelladressstruktur binden. Wir überprüfen erneut den Rückgabewert, um sicherzustellen, dass er funktioniert.
result = bind(ssock, (struct sockaddr*) &src_addr, sizeof(src_addr));
if (result < 0) {
perror("Binding L2CAP socket failed");
return -1;
}
Als nächstes legen Sie die Sicherheitsstufe fest. Beachten Sie, dass dieser Schritt optional ist. Wenn Sie jedoch die Sicherheitsstufe auf MEDIUM setzen, wird das automatische Pairing mit dem Gerät ermöglicht (der Kernel übernimmt das eigentliche Pairing).
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;
}
Jetzt können wir dem Kernel sagen, dass unser Ssock ein passiver Socket ist, der eine Verbindung akzeptiert. Der zweite Parameter ist der Rückstand. Wenn Sie mehr wissen möchten, enthält die Manpage von Listen alle Informationen, die Sie benötigen.
result = listen(ssock, 10);
if (result < 0) {
perror("Listening on L2CAP socket failed");
return -1;
}
Jetzt können wir auf eine eingehende Verbindung warten. Die peer_addr-Struktur enthält die Adresse des verbundenen Geräts, sobald die Rückgabe akzeptiert wird. csock ist der Dateideskriptor des Sockets, von dem wir lesen / schreiben können, um mit dem angeschlossenen Gerät zu kommunizieren.
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;
}
Wir können die Adresse des angeschlossenen Geräts ausdrucken (natürlich optional). Wir können die batostr-Funktion verwenden, um die Bluetooth-Adresse in eine Zeichenfolge umzuwandeln.
printf("Accepted connection from %s", batostr(&peer_addr->l2_bdaddr));
Wenn wir nicht möchten, dass andere Geräte eine Verbindung herstellen, sollten wir den Server-Socket schließen. Machen Sie dasselbe mit csock, nachdem die Kommunikation mit dem Gerät abgeschlossen ist.
close(ssock);
return csock;
}