Nel precedente articolo abbiamo visto come è possibile inviare pacchetti di advertising con il chip esp32.
Per definire il contenuto del pacchetto, abbiamo utilizzato una struct, di tipo esp_ble_adv_data_t:
La definizione di tale struct è nel file esp_gap_ble_api.h:
Sebbene i campi disponibili siano molti, a volte è necessario poter definire il contenuto del pacchetto di advertising in modo arbitrario. Per questa ragione il framework esp-idf ci mette a disposizione la modalità raw.
Invece che definire una struct, creiamo un array di byte e memorizziamo al suo interno l’intero contenuto del payload del pacchetto:
static uint8_t adv_raw_data[10] = {0x09,0x09,0x4c,0x75,0x6b,0x45,0x53,0x50,0x33,0x32}; |
quindi utilizziamo la funzione esp_ble_gap_config_scan_rsp_data_raw() per passare tale array al driver Bluetooth. Dobbiamo specificare come parametri sia l’array che la sua dimensione:
esp_ble_gap_config_scan_rsp_data_raw(scan_rsp_raw_data, 8); |
Utilizzando questa nuova funzione, cambia anche l’evento che il driver passa alla nostra funzione di callback una volta terminata la configurazione. Il nuovo evento è ESP_GAP_BLE_ADV_DATA_RAW_SET_COMPLETE_EVT. Come nell’esempio precedente, quando tale evento si presenta è possibile avviare il processo di advertising:
case ESP_GAP_BLE_ADV_DATA_RAW_SET_COMPLETE_EVT: esp_ble_gap_start_advertising(&ble_adv_params); break; |
Raw data
Perché il processo di advertising funzioni, i dati contenuti nell’array devono corrispondere ad un payload valido.
Nell’articolo relativo agli iBeacons vi ho già mostrato la sua struttura. Rivediamola brevemente:
Il payload contiene una o più strutture AD (advertising data). Ogni struttura è formata da 3 campi:
- un byte iniziale che rappresenta la lunghezza (in byte) della struttura, escluso sè stesso
- un byte che rappresenta il tipo di dato contenuto nella struttura
- un numero variabile di byte che sono il dato effettivo
I codici utilizzabili per definire il tipo di dato si trovano nelle specifiche Bluetooth. In base al tipo di dato, è poi necessario applicare un particolare fomato ai dati che lo seguono. Nel documento Core Specification Supplement (disponibile sempre sul sito Bluetooth.com) si trovano le informazioni necessarie.
Vediamo un semplice esempio: l’AD type 0x09 rappresenta il complete local name, ovvero il nome del dispositivo. Tale nome deve essere specificato nel campo AD data semplicemente come sequenza dei codici ASCII che corrispondono alle diverse lettere.
Possiamo utilizzare un sito web per effettuare la conversione:
Il payload per trasmettere tale nome sarà quindi:
adv_raw_data[7] = {0x06,0x09,0x4d,0x79,0x42,0x4c,0x45}; |
Il primo byte ha il valore 0x06 ovvero la somma della lunghezza del nome (5 byte) + 1 byte per il tipo di dato (0x09).
Demo
Nel video seguente (sottotitoli in italiano disponibili) mostro come utilizzare le funzionalità di raw advertising per simulare il pacchetto di advertising trasmesso dal mio iBeacon e quindi attivare il relay come mostrato nell’esempio precedente.
Il codice sorgente del programma è disponibile nel mio repository Github.