BLE al microscopio (ATTы GATTы…)

BLE al microscopio (ATTы GATTы...)

BLE al microscopio (ATTы GATTы…)

Parte 1, panoramica

È già passato molto tempo da quando è stata rilasciata la prima specifica per Bluetooth 4.0. Anche se l'argomento BLE è molto interessante, a causa della sua complessità scoraggia ancora molti sviluppatori. Nei miei articoli precedenti, ho esaminato principalmente il livello più basso, Link Layer e Physical Layer. Ciò ci ha permesso di evitare di dover ricorrere a concetti complessi e confusi come il Protocollo degli Attributi (ATT) e il Profilo Generale degli Attributi (GATT). Tuttavia, non c'è nessun posto dove andare, senza comprenderli è impossibile sviluppare dispositivi compatibili. Oggi vorrei condividere con voi questa conoscenza. Nel mio articolo farò affidamento su manuale per principianti dal sito web nordico. Quindi iniziamo.

Perché è tutto così difficile?

Secondo me è stato subito chiaro che la gestione dei dispositivi tramite smartphone è un argomento molto promettente e di lunga durata. Pertanto hanno deciso di strutturarlo subito e al massimo. In modo che i produttori di vari gadget non presentino i propri protocolli, che saranno quindi incompatibili. Da qui la difficoltà. Già nella prima fase hanno cercato di inserire tutto il possibile nel protocollo BLE. E non importa se tornerà utile in seguito oppure no. Inoltre, hanno previsto la possibilità di ampliare l'elenco dei dispositivi per il futuro.

Diamo un'occhiata all'immagine in cui è disegnato il diagramma del protocollo BLE. Si compone di diversi strati. Lo strato fisico più basso (PHY) è responsabile del canale radio del dispositivo. Link Layer(LL) contiene l'intera sequenza di byte nel messaggio trasmesso. Negli articoli precedenti abbiamo studiato proprio questo. Host Controller Interface (HCI) è un protocollo di scambio tra livelli o chip BLE se il controller e l'host sono implementati su chip diversi. Il Logical Link Control and Adaptation Protocol (L2CAP) è responsabile della formazione, del framing, del controllo degli errori e dell'assemblaggio dei pacchetti. Security Manager Protocol (SMP) è responsabile della crittografia dei pacchetti. Il General Access Profile (GAP) è responsabile dello scambio iniziale di dati tra i dispositivi per determinare “Who is who”. Include anche la scansione e la pubblicità. In questo articolo mi concentrerò sulle due parti rimanenti del protocollo: GATT e ATT. Il GATT è una sovrastruttura dell’ATT, quindi sono strettamente intrecciati.

BLE al microscopio (ATTы GATTы...)

Per semplificare la storia, vorrei ricorrere a un’analogia. L'ho sentito da qualche parte e vorrei sostenerlo. Pensa a un dispositivo BLE come a una libreria con diversi ripiani. Ogni scaffale è un tema separato. Ad esempio, abbiamo scaffali con fantascienza, matematica ed enciclopedie. Su ogni scaffale ci sono libri con un argomento specifico. E alcuni libri hanno anche segnalibri di carta con note. Inoltre, disponiamo di un piccolo catalogo cartaceo di tutti i libri. Se ricordi, le biblioteche scolastiche sono una scatola stretta con carte di carta. Con questa analogia, il mobile è il profilo del nostro dispositivo. Gli scaffali sono servizi, i libri sono caratteristiche e il catalogo è una tabella di attributi. I segnalibri nei libri sono descrittori, di cui parlerò anche più avanti in modo più dettagliato.

Chiunque abbia sviluppato dispositivi sa che molti progetti hanno pezzi di codice simili. Il fatto è che molti dispositivi hanno funzionalità simili. Ad esempio, se i dispositivi sono alimentati da batterie, il problema della ricarica e del monitoraggio del loro livello sarà lo stesso. Lo stesso vale per i sensori. In realtà, un approccio alla programmazione orientato agli oggetti “fornisce la possibilità di creare oggetti che combinano proprietà e comportamenti in un’unione autonoma che può poi essere riutilizzata”. A mio parere, BLE ha tentato un approccio simile. I profili sono stati sviluppati dal Bluetooth Special Interest Group (SIG). I dispositivi di diversi produttori che hanno gli stessi profili dovrebbero funzionare tra loro senza difficoltà. I profili, a loro volta, sono costituiti da servizi e servizi di caratteristiche, integrati da descrittori. In generale potrebbe assomigliare a questo:

BLE al microscopio (ATTы GATTы...)

Consideriamo ad esempio il diagramma del profilo di un cardiofrequenzimetro (braccialetto fitness). Si compone di due servizi e diverse caratteristiche. Da ciò diventa immediatamente chiara la gerarchia del profilo. La caratteristica checkpoint ripristina il conteggio del dispendio calorico totale a zero.

1. Il servizio di frequenza cardiaca comprende tre caratteristiche (0x180D):
    a) Caratteristica obbligatoria della frequenza cardiaca (0x2A37)
    b) Caratteristica opzionale della posizione del sensore del corpo (0x2A38)
    c) Caratteristiche condizionali del punto di controllo della frequenza cardiaca (0x2A39)
2. Servizio di manutenzione della batteria (0x180F):
    a) Caratteristica obbligatoria del livello di carica della batteria (0x2A19)

UUID

Per poter accedere in modo univoco agli elementi del profilo (servizi, caratteristiche e descrittori), dobbiamo numerarli tutti in qualche modo. A questo scopo viene introdotto un concetto come Universally Unique ID (UUID) o Universally Unique Identifier. L'UUID è indicato tra parentesi di ogni riga. E qui c'è una particolarità. Per l'UUID abbiamo deciso di utilizzare un codice di 16 e 128 bit di lunghezza. Perchè lo chiedi? Nel protocollo BLE tutto ruota intorno al risparmio energetico. Pertanto la dimensione di 16 bit è abbastanza ragionevole. Difficilmente ne verranno creati più di 65mila nel prossimo futuro. servizi e caratteristiche uniche. Al momento, tutto ciò che avrebbero potuto già essere contato (ricorda da dove viene - "ha contato anche te" :-)) Elementi numerati profili, servizi, характеристик и descrittori puoi guardare i link.

Tuttavia, penso che tutti ricordino la storia dei 4 byte di indirizzi IP su Internet. All’inizio pensavamo che fosse sufficiente, ma ora non possiamo ancora passare a un indirizzo a 6 byte. Per non ripetere questo errore e dare libero sfogo alle giocose mani degli DIYer, SIG ha deciso subito di introdurre gli UUID a 128 bit. Questo personalmente mi ricorda la banda 433 MHz senza licenza, che è stata data a tutti i tipi di Kulibin dal canale radio. Nel nostro caso è stato appaltato un identificatore di servizi e caratteristiche a 128 bit. Ciò significa che noi, per i nostri servizi e dispositivi, possiamo utilizzare quasi tutti i valori a 128 bit. Tuttavia, la probabilità di ottenere lo stesso UUID tende a zero.

In effetti, gli UUID brevi a 16 bit hanno la loro estensione fino a un valore di 128 bit. Nelle specifiche questa estensione si chiama Bluetooth Base UUID e ha il valore 00000000-0000-1000-8000-00805F9B34FB. Se, ad esempio, l'UUID dell'attributo a 16 bit ha il valore 0x1234, l'UUID a 128 bit equivalente avrà il valore 00001234-0000-1000-8000-00805F9B34FB. E viene fornita anche la formula corrispondente:

                                valore_128_bit = valore_16_bit * 2^96 + Bluetooth_Base_UUID

Non so da dove venga questo numero magico. Se qualcuno dei lettori lo sa, lascialo scrivere nei commenti (un utente con il soprannome Sinopteek lo ha già fatto. Vedi i commenti). Per quanto riguarda l'ideazione di UUID a 128 bit, in linea di principio è possibile utilizzare uno speciale generatorechi lo farà per te.

ATTy GATTy...

In realtà, allora inizia il divertimento. Lascia che ti ricordi che ATT si basa su una relazione client-server. Ora stiamo esaminando il dispositivo server. Contiene informazioni come valori dei sensori, stato dell'interruttore della luce, dati sulla posizione, ecc. Ora che tutti i “partecipanti alla nostra sfilata” sono contati, dobbiamo in qualche modo inserirli nella memoria del dispositivo. Per fare ciò, li inseriamo in una tabella chiamata tabella degli attributi. Ricordatelo bene. Questo è il vero cuore di BLE. Questo è ciò che considereremo ulteriormente. Ora chiameremo ogni riga un attributo. Questa tabella si trova in profondità nello stack e, di norma, non abbiamo accesso diretto ad essa. Lo inizializziamo e vi accediamo, ma ciò che accade all'interno ci è nascosto dietro sette sigilli.

Diamo un'occhiata all'immagine dalle specifiche, ma prima vorrei attirare immediatamente l'attenzione sulla frequente confusione nei termini, in particolare nei descrittori. Il ruolo del descrittore è quello di integrare la descrizione della caratteristica. Quando è necessario espandere le sue capacità, vengono utilizzati i descrittori. Anche loro sono attributi e, proprio come i servizi e le caratteristiche, si trovano nella tabella degli attributi. Li esamineremo in dettaglio nella seconda parte dell’articolo. Tuttavia, a volte i descrittori si riferiscono al numero di riga nella tabella degli attributi. Questo deve essere tenuto presente. Per evitare confusione, utilizzeremo il termine “puntatore di attributo” per questi scopi.
BLE al microscopio (ATTы GATTы...)

Quindi un attributo è un valore discreto a cui sono associate le seguenti proprietà:
1. L'handle dell'attributo è l'indice della tabella corrispondente all'attributo
2. Il tipo di attributo è un UUID che ne descrive il tipo
3. Il valore dell'attributo è i dati indicizzati dal puntatore dell'attributo
4. I permessi degli attributi sono la parte di un attributo, i permessi, che non può essere letto o scritto utilizzando il protocollo degli attributi

Come capire tutto questo? Il puntatore dell'attributo è, relativamente parlando, il suo numero nella nostra tabella.
Consente a un client di fare riferimento a un attributo nelle richieste di lettura o scrittura. Possiamo numerare le nostre linee (attributi) da 0x0001 a 0xFFFF. Nella nostra associazione con la libreria, questo è il numero della scheda nel catalogo cartaceo. Analogamente, come nel catalogo della biblioteca, le schede sono disposte in ordine crescente di numero. Il numero di ciascuna riga successiva deve essere maggiore di quella precedente. Proprio come nella biblioteca, a volte alcune carte si perdono, quindi da noi potrebbero esserci delle lacune nella numerazione delle righe. Questo è permesso. La cosa principale è che vanno progressivamente.

Il tipo di attributo determina cosa rappresenta l'attributo. Per analogia con il linguaggio C,
dove ci sono variabili booleane, numeriche e stringhe, quindi è qui. Per tipo di attributo riconosciamo
con cosa abbiamo a che fare e come possiamo continuare a lavorare con questo attributo. Di seguito esamineremo alcuni tipi specifici di attributi. Ad esempio, "dichiarazione di servizio" (0x2800), "dichiarazione di caratteristiche" (0x2803), "dichiarazione di descrittore" (0x2902).

Il valore di un attributo è il suo vero significato, perdonate la tautologia. Se il tipo di attributo è una stringa, il valore dell'attributo può essere, ad esempio, lo slogan “Hello World !!!”. Se il tipo di attributo è una “dichiarazione di servizio”, allora il suo valore è il servizio stesso. E a volte si tratta di informazioni su dove trovare altri attributi e le loro proprietà.

Le autorizzazioni degli attributi consentono al server di comprendere se è consentito l'accesso in lettura o scrittura.
Tieni presente che queste autorizzazioni si applicano solo al valore dell'attributo e non al puntatore, al tipo o al campo di autorizzazione stesso. Quelli. se la registrazione degli attributi è consentita, possiamo modificare, ad esempio, la riga "Hello World !!!" alla riga "Buongiorno". Ma non possiamo vietare di scrivere una nuova riga o modificare il tipo di attributo e designare la riga come “dichiarazione di servizio”. Quando un client contatta un server, il client richiede i suoi attributi. Ciò consente al client di sapere cosa può fornire il server. Sebbene non sia necessario leggere e scrivere i valori.

Che aspetto ha

Il concetto del GATT è quello di raggruppare insieme gli attributi in una tabella degli attributi in un ordine molto specifico e logico. Diamo uno sguardo più da vicino al profilo della frequenza cardiaca di seguito. La colonna più a sinistra di questa tabella è facoltativa. Ci descrive semplicemente cos'è questa linea (attributo). Tutte le altre colonne ci sono già familiari.

BLE al microscopio (ATTы GATTы...)

Nella parte superiore di ogni gruppo abbiamo sempre un attributo di dichiarazione di servizio. Il suo tipo è sempre 0x2800 e il puntatore dipende da quanti attributi sono già presenti nella tabella. I suoi permessi sono sempre di sola lettura, senza alcuna autenticazione o autorizzazione. Parleremo di questi concetti un po 'più tardi. Il valore è un altro UUID che identifica qual è il servizio. Nella tabella il valore è 0x180D, che viene definito da Bluetooth SIG come servizio di frequenza cardiaca.

Dopo l'annuncio del servizio arriva l'annuncio delle caratteristiche. È simile nella forma a una dichiarazione di servizio. Il suo UUID è sempre 0x2803 e le sue autorizzazioni sono sempre di sola lettura senza alcuna autenticazione o autorizzazione. Diamo un'occhiata al campo Valore attributo, che include alcuni dati. Contiene sempre un puntatore, un UUID e un insieme di proprietà. Questi tre elementi descrivono la successiva dichiarazione del valore caratteristico. Il puntatore indica naturalmente la posizione della dichiarazione del valore caratteristico nella tabella degli attributi. L'UUID descrive il tipo di informazioni o valore che possiamo aspettarci. Ad esempio, il valore della temperatura, lo stato dell'interruttore della luce o qualche altro valore arbitrario. E infine le proprietà, che descrivono come è possibile interagire con il valore caratteristico.

Un'altra trappola ci aspetta qui. È associato ai permessi degli attributi e alle proprietà caratteristiche. Diamo un'occhiata all'immagine delle proprietà del campo bit dalla specifica.

BLE al microscopio (ATTы GATTы...)

Come puoi vedere, qui ci sono anche campi che forniscono funzionalità di lettura e scrittura. Forse ti starai chiedendo perché disponiamo di permessi di lettura/scrittura per attributi e proprietà
leggere/scrivere il valore caratteristico? Non dovrebbero essere sempre uguali? Il fatto è che le proprietà del valore caratteristico sono in realtà solo raccomandazioni per il cliente utilizzate nel GATT e nei livelli applicativi. Questi sono semplicemente suggerimenti su ciò che il cliente potrebbe aspettarsi dall'attributo di dichiarazione caratteristica. Diamo un'occhiata a questo in modo più dettagliato. Quali tipi di autorizzazioni ha un attributo?

1. Permessi di accesso:
     - lettura
     - documentazione
     - leggere e scrivere
2. Autorizzazione di autenticazione:
     - autenticazione richiesta
     - nessuna autenticazione richiesta
3. Autorizzazione:
     - Autorizzazione Richiesta
     - non è richiesta alcuna autorizzazione

La differenza principale tra la risoluzione degli attributi e le proprietà caratteristiche è che le prime si applicano ai server e le seconde ai client. Al server può essere consentito leggere il valore caratteristico, ma potrebbe richiedere autenticazione o autorizzazione. Pertanto, quando il cliente richiederà le proprietà della caratteristica, riceveremo che la lettura è consentita. Ma quando proviamo a leggere, otteniamo un errore. Pertanto, possiamo tranquillamente parlare della priorità delle autorizzazioni rispetto alle proprietà. Dal lato client, non possiamo conoscere i permessi di un attributo.

Descrittore

Torniamo alla nostra tavola. Dopo aver dichiarato il valore di una caratteristica, sono possibili le seguenti dichiarazioni di attributi:
1. Nuova dichiarazione delle caratteristiche (un servizio può avere molte caratteristiche)
2. Nuova dichiarazione di servizio (potrebbero essercene molte nella tabella)
3. Dichiarazione di un handle

Nel caso della caratteristica di misurazione della frequenza cardiaca, nella nostra tabella, la dichiarazione del valore caratteristico è accompagnata dalla dichiarazione del descrittore. Un descrittore è un attributo con informazioni aggiuntive su una caratteristica. Esistono diversi tipi di descrittori. Ne parleremo in dettaglio nella seconda parte di questo articolo. Per ora, toccheremo solo il descrittore di configurazione delle caratteristiche del client (CCCD). Ha un UUID pari a 0x2902. Utilizzando questo descrittore, il client ha la possibilità di abilitare l'indicazione o la notifica sul server. La differenza tra loro è piccola, ma ancora lì. La notifica non richiede conferma di ricezione da parte del cliente. L'indicazione lo richiede, anche se avviene a livello del GATT, non raggiungendo il livello applicativo. Perché così, chiedi? Ahimè, questo non lo so. Lasciatemi solo dire che gli esperti nordici consigliano di utilizzare le notifiche. Inoltre, in entrambi i casi viene effettuata la verifica dell'integrità del pacchetto (utilizzando CRC).

conclusione

Alla fine dell’articolo vorrei dire questo. L'ultima tabella è un po' confusa. Comunque l'ho scelto perché è ceduto Articolo, su cui faccio affidamento. Nella seconda parte del mio articolo intendo approfondire le specifiche BlueTooth 4.0. Lì ci aspettano diagrammi e disegni più corretti. Nella terza parte, vorrei analizzare il log ottenuto utilizzando il programma Wireshark da uno dei gadget e vedere “dal vivo” tutta la teoria che stiamo studiando.

Dipendente del Gruppo di Società "Satellite Cesare"
Pecherskich Vladimir

Fonte: habr.com

Aggiungi un commento