11.14. Yhteenveto

Olet käynyt läpi Bluetooth Low Energyn radiosta aina Python-rajapintaan asti, jolla sitä ohjataan:

  • Motivaatio – BLE on vastaus, kun kamera haluaa kommunikoida läheisen laitteen kanssa ilman mitään infrastruktuuria niiden välissä. Puhelin samassa huoneessa, puettava laite ranteessa, majakka seinällä. Lyhyt kantama, ei verkkoa johon liittyä, lähes ei virtaa.

  • Radio – 2,4 GHz, 40 kanavaa: kolme mainostukseen, 37 yhteysdataan, hypäten pseudosatunnaista sekvenssiä noudattaen ja välttäen mukautuvasti meluisia kanavia. Lyhyitä paketteja, enimmäkseen nukkuvia radioita.

  • Linkkikerros – pakettien kehystys, osoitteistus, yhteyden ajoitus, uudelleenlähetys ja linkkikerroksen salaus. Mitään siitä ei konfiguroida Pythonista; kaikki näkyy yhteysparametreissa ja MTU:ssa.

  • Generic Access Profile (GAP) – löytäminen ja yhteyden hallinta. Neljä roolia: oheislaite ja lähettäjä (mainostavat), keskuslaite ja tarkkailija (skannaavat). Mainostuksen hyötykuormat kuljettavat paikallisen nimen, palvelu-UUID:t, ulkoasun ja valmistajakohtaisen datan – 31 tavua plus valinnainen 31 tavun skannausvastaus. Yhteysväli, oheislaitteen viive ja valvonnan aikakatkaisu määräävät, miltä avoin yhteys tuntuu.

  • Generic Attribute Profile (GATT) – palveluiden puu, joista jokainen sisältää ominaisuuksia, joista jokainen sisältää valinnaisesti kuvaajia, tunnistettuina UUID:illä (16-bittiset Bluetooth-SIG-standardeille, 128-bittiset mukautetuille). Viisi operaatiota: read ja write (vetävät, asiakkaan aloittamat), notify ja indicate (työntävät, palvelimen aloittamat, tilattu Client Characteristic Configuration Descriptorin kautta). Hyötykuorman koko on rajattu neuvotellulla MTU:lla.

  • Python-rajapintaaioble muuttaa jokaisen BLE-mallin asyncio-korutiiniksi. Oheislaite on aioble.advertise() joka silmukoi yhteyksiä, Service- / Characteristic-objekteilla, jotka rakennetaan kerran ja vahvistetaan funktiolla aioble.register_services(). Keskuslaite on aioble.scan() vertaislaitteen löytämiseen, connect() yhteyden avaamiseen, service() ja characteristic() etä-GATT-puun läpikäyntiin, sitten read() / write() / subscribe() / notified() varsinaiselle datalle. Yhteyden katkeamiset tulevat esiin poikkeuksena aioble.DeviceDisconnectedError siinä korutiinissa, joka oli odottamassa.

  • L2CAP-kanavat – pakoluukku massadatan tavuvirroille, jotka eivät sovi GATT:n avain/arvo-malliin. aioble.DeviceConnection.l2cap_accept() / l2cap_connect() avaavat sovelluskohtaisen kanavan GAP-yhteyden päälle, luotto-vuonohjatulla lähetyksellä / vastaanotolla ja suuremmalla MTU:lla kuin GATT pystyy kuljettamaan.

  • Pariutuminen ja salaus – BLE-yhteydet ovat oletuksena julkisia. aioble.DeviceConnection.pair() aloittaa avaintenvaihdon, joka tuottaa salatun yhteyden; bond=True (oletus) säilyttää avaimet, jotta myöhemmät yhteydet ohittavat kättelyn. Ilman mitm=True-asetusta ja käyttökelpoista IO-ominaisuutta salaus suojaa passiivisilta salakuuntelijoilta, mutta ei aktiiviselta uudelleenohjaukselta alkuperäisen pariutumisen aikana.

Tämä riittää kameran sovellusten kirjoittamiseen, jotka julkaisevat tilan oheislaitteena, lukevat sensoridataa keskuslaitteena, työntävät reaaliaikaisia arvoja puhelimeen BLE:n yli, turvaavat yhteyden pariudu-ja-sido-vaiheella, ja – harvinaisessa massasiirtotapauksessa – siirtyvät pois GATT:sta L2CAP-kanavaan.

11.14.1. Vianmääritys

BLE-virheet ovat enimmäkseen yhteensopimattomuuksia sen välillä, mitä kaksi osapuolta odottavat, ja puhelimen puolen tarkastelutyökalu on nopein tapa nähdä, kenen odotukset ovat pielessä. Vakiotyökalu on nRF Connect for Mobile (Nordic Semiconductor, ilmainen Androidille ja iOS:lle): se skannaa, yhdistää, käy läpi GATT-tietokannan, lukee ja kirjoittaa ominaisuuksia ja tilaa ilmoituksia – joten kameran puolen toimintaa voidaan testata eristyksissä, kirjoittamatta lainkaan kumppanisovellusta.

Yleiset vikatilat:

  • ”Laitteeni näkyy skannerissa mutta ei yhdisty.” Useimmiten mainostuspaketissa on connectable=False (lähettäjätila), tai aiempi yhteys on yhä auki ja kamera on jo ohittanut aioble.advertise()-kutsun. Lisää print-lauseita mainostuskutsun ympärille varmistaaksesi.

  • ”exchange_mtu(512) suoritettiin mutta ilmoitukseni ovat yhä rajoitettu 20 tavuun.” Neuvoteltu MTU on min(local, peer) – puhelin tai keskuslaitekirjasto ei välttämättä ole pyytänyt suurempaa MTU:ta omalla puolellaan, jolloin yhteys pysyy arvossa 23. Tarkasta mtu sen jälkeen kun exchange_mtu() palaa. Huomaa myös, että exchange_mtu() toimii vain kerran yhteyttä kohden; kutsu sitä ennen ensimmäistä suurta operaatiota.

  • ”Pariutuminen epäonnistuu yleisellä virheellä.” Kaksi tavallista syyllistä: IO-ominaisuuksien yhteensopimattomuus (pyydetään mitm=True kameralle, joka ilmoittaa io=3 / ei syöttöä ei tulostusta – numeerista koodia ei ole mitään tapaa vahvistaa, joten pariutumismoottori luovuttaa), ja villisti väärä seinäkellon aika kamerassa, kun vertaislaite sitä edellyttää. Aseta kello funktiolla ntptime.settime() ennen ensimmäistä pariutumisyritystä.

  • ”Ilmoitukset eivät koskaan saavu asiakkaalle.” Kaksi tarkistettavaa asiaa, järjestyksessä: (a) onko ominaisuus määritelty asetuksella notify=True? – ominaisuusbitti täytyy asettaa palvelimen puolella; (b) kutsuiko asiakas subscribe()? – ilman Client Characteristic Configuration Descriptorin (CCCD) kirjoittamista palvelimelle kerrotaan, ettei yksikään asiakas halua ilmoituksia, ja se pudottaa ne hiljaisesti.

  • ”Mainostettu nimi on katkaistu tai puuttuu.” Mainostuksen hyötykuorma on 31 tavua, ja liput + palvelu-UUID + ulkoasu -kentät vievät kukin tavuja yläosasta. Pitkä name= plus useita palvelu-UUID:itä ylittää rajan. Joko lyhennä nimeä tai käytä aktiivista skannausta, jotta skannausvastaus (toiset 31 tavua) kuljettaa ylivuodon. nRF Connect näyttää molemmat puoliskot erikseen, mikä tekee jaon ilmeiseksi.

  • ”L2CAP-yhteys nostaa poikkeuksen välittömästi.” Yleensä PSM-yhteensopimattomuus – molempien osapuolten on sovittava samasta PSM-numerosta out-of-band. L2CAPConnectionError kuljettaa Bluetooth-tilakoodin ensimmäisenä argumenttinaan; tila 2 (”PSM not supported”) on paljastava.

  • ”Sidotut yhteydet laukaisevat yhä täyden pariutumiskättelyn jokaisella uudelleenyhdistyksellä.” aioble.security.load_secrets() -funktiota ei kutsuttu käynnistyksessä. Ilman sitä tallennetut avaimet ovat flash-muistissa mutta niitä ei koskaan ladata muistiin, joten vertaislaitteen identiteetti on tuntematon ja pariutuminen suoritetaan alusta joka kerta.

Kun kaikki muu epäonnistuu, matalamman tason bluetooth-moduuli paljastaa IRQ-takaisinkutsun, joka laukeaa jokaisesta taustalla olevasta tapahtumasta; siihen hetkellisesti tilautuminen ja tapahtumien tulostaminen vastaa Wireshark-jäljitystä kameran puolella.

11.14.2. Tämän viitemateriaalin käyttäminen myöhemmin

Käsittele Bluetooth-lukuja viitemateriaalina; palaaminen takaisin oheislaitteen mainostushyötykuorman tarkkaa rakennetta tai keskuslaitteen skannaa-ja-tilaa-kulkua varten on tarkoitettu käyttötapa. aioble — Asynkroninen BLE- ja bluetooth — matalan tason Bluetooth-viitesivut luettelevat jokaisen metodin, lipun ja vakion yhdessä paikassa, kun kysymys on vain ”mikä on tämän kutsun tarkka nimi”.