bluetooth
Abra el conector L2CAP para la comunicación de baja energía.
Buscar..
En C, con Bluez.
int get_l2cap_connection () {
En primer lugar, todas las variables que necesitamos, la explicación seguirá en el lugar apropiado.
int ssock = 0;
int csock = 0;
int reuse_addr = 1;
struct sockaddr_l2 src_addr;
struct bt_security bt_sec;
int result = 0;
Primero, necesitamos crear un socket, desde el cual podemos aceptar una conexión. La familia de sockets es PF_BLUETOOTH , el tipo de socket es SOCK_SEQPACKET (queremos tener un socket similar a TCP, no en bruto), y el protocolo es el protocolo Bluetooth L2CAP ( BTPROTO_L2CAP ).
ssock = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
Queremos asegurarnos de que haya sido exitoso:
if (ssock < 0) {
perror("Opening L2CAP socket failed");
return -1;
}
Ahora tenemos que completar la estructura de la dirección de origen con una dirección de comodín, para que cualquier dispositivo Bluetooth con cualquier dirección pueda conectarse a nosotros. La dirección de comodín se define como BDADDR_ANY en bluetooth.h . Para copiarlo en la estructura de direcciones, podemos usar la función bacpy . También tenemos que configurar la familia de direcciones, el tipo de dirección y la identificación del canal.
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);
La configuración de la opción SO_REUSEADDR nos permitirá llamar al enlace de nuevo rápidamente si es necesario (esto se puede omitir):
setsockopt(ssock, SOL_SOCKET, SO_REUSEADDR, &reuse_addr, sizeof(reuse_addr));
A continuación, debemos vincular el socket con la estructura de dirección de origen que acabamos de definir. Una vez más, verificamos el valor de retorno para asegurarnos de que funcionó.
result = bind(ssock, (struct sockaddr*) &src_addr, sizeof(src_addr));
if (result < 0) {
perror("Binding L2CAP socket failed");
return -1;
}
Lo siguiente es establecer el nivel de seguridad. Tenga en cuenta que este paso es opcional, pero establecer el nivel de seguridad en MEDIO permitirá el emparejamiento automático con el dispositivo (el kernel se encarga del emparejamiento real).
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;
}
Ahora podemos decirle al kernel que nuestro ssock es un socket pasivo, que aceptará una conexión. El segundo parámetro es el backlog. Si desea saber más, la página de manual de listen contiene toda la información que necesita.
result = listen(ssock, 10);
if (result < 0) {
perror("Listening on L2CAP socket failed");
return -1;
}
Ahora podemos esperar una conexión entrante. La estructura peer_addr contendrá la dirección del dispositivo conectado, una vez que acepte devoluciones. csock será el descriptor de archivo del socket que podemos leer y escribir para comunicarnos con el dispositivo conectado.
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;
}
Podemos imprimir la dirección del dispositivo conectado (opcional, por supuesto). Podemos usar la función batostr para convertir la dirección Bluetooth en una cadena.
printf("Accepted connection from %s", batostr(&peer_addr->l2_bdaddr));
Si no queremos que se conecten otros dispositivos, debemos cerrar el socket del servidor. Haga lo mismo con csock, una vez finalizada la comunicación con el dispositivo.
close(ssock);
return csock;
}