11.14. Összegzés¶
Végigjártad a Bluetooth Low Energy-t a rádiótól egészen a vezérléséhez használt Python API-ig:
A motiváció – a BLE a válasz, amikor a kamera valamivel a közelében szeretne beszélni, anélkül hogy bármilyen infrastruktúra lenne közöttük. Egy telefon ugyanabban a helyiségben, egy viselhető eszköz a csuklón, egy jelfény a falon. Rövid hatótáv, nincs csatlakozandó hálózat, szinte semmi energia.
A rádió – 2,4 GHz, 40 csatorna: három hirdetésre, 37 kapcsolati adatokra, amelyeket egy pszeudovéletlen sorozat szerint ugratnak, a zajos csatornák adaptív elkerülésével. Rövid csomagok, többnyire alvó rádiók.
A kapcsolati réteg – csomagkeretezés, címzés, kapcsolatütemezés, újraküldés és kapcsolati rétegű titkosítás. Ezek közül semmit sem konfigurálnak Pythonból; mindegyik a kapcsolati paramétereken és az MTU-n keresztül mutatkozik meg.
Generic Access Profile (GAP) – felderítés és kapcsolatkezelés. Négy szerep: peripheral és broadcaster (hirdet), central és observer (szkennel). A hirdetési hasznos teher a helyi nevet, a szolgáltatás-UUID-kat, a megjelenést és a gyártóspecifikus adatokat hordozza – 31 bájt plusz egy opcionális 31 bájtos szkennelési válasz. A kapcsolati intervallum, a periféria-késleltetés és a felügyeleti időtúllépés szabályozza, hogy milyen érzés egy nyitott kapcsolat.
Generic Attribute Profile (GATT) – szolgáltatások fája, mindegyik karakterisztikákat tartalmaz, mindegyik opcionálisan leírókat tartalmaz, amelyeket UUID-k azonosítanak (16 bites a Bluetooth-SIG szabványokhoz, 128 bites az egyedi szabványokhoz). Öt művelet: read és write (lehúzás, kliens által kezdeményezett), notify és indicate (feltolás, szerver által kezdeményezett, a Client Characteristic Configuration Descriptoron keresztül feliratkozva). A hasznos teher méretét a megtárgyalt MTU korlátozza.
A Python API – az
aiobleminden BLE-mintát asyncio korutinná alakít. Egy periféria azaioble.advertise(), amely kapcsolatokon ciklusol, az egyszer felépített és azaioble.register_services()által véglegesítettService/Characteristicobjektumokkal. Egy central azaioble.scan()egy társ megtalálásához, aconnect()a kapcsolat megnyitásához, aservice()és acharacteristic()a távoli GATT-fa bejárásához, majd aread()/write()/subscribe()/notified()a tényleges adatokhoz. A szétkapcsolódásokaioble.DeviceDisconnectedErrorformájában jelennek meg abban a korutinban, amely várakozott.L2CAP csatornák – a menekülőút a tömeges bájtfolyamokhoz, amelyek nem férnek bele a GATT kulcs/érték modelljébe. Az
aioble.DeviceConnection.l2cap_accept()/l2cap_connect()egy alkalmazásonkénti csatornát nyit a GAP-kapcsolat tetején, kreditáramlás-vezérelt küldéssel / fogadással és nagyobb MTU-val, mint amit a GATT hordozni tud.Párosítás és titkosítás – a BLE-kapcsolatok alapértelmezetten nyilvánosak. Az
aioble.DeviceConnection.pair()egy kulcscserét kezdeményez, amely titkosított kapcsolatot hoz létre; abond=True(az alapértelmezés) megőrzi a kulcsokat, így a későbbi kapcsolatok kihagyják a kézfogást.mitm=Trueés egy használható IO-képesség nélkül a titkosítás véd a passzív lehallgatók ellen, de nem véd az eredeti párosítás alatti aktív átirányítás ellen.
Ez elegendő ahhoz, hogy olyan kameraalkalmazásokat írj, amelyek perifériaként közzéteszik az állapotot, centralként érzékelőadatokat olvasnak, élő értékeket tolnak fel egy telefonra BLE-n keresztül, biztosítják a kapcsolatot egy párosítás-és-kötés lépéssel, és – a ritka tömeges átviteli esethez – lelépnek a GATT-ról egy L2CAP csatornára.
11.14.1. Hibaelhárítás¶
A BLE-hibák többnyire eltérések aközött, amit a két oldal elvár, és egy telefonoldali vizsgáló a leggyorsabb módja annak, hogy lássuk, kinek az elvárásai hibásak. A szabványos eszköz az nRF Connect for Mobile (Nordic Semiconductor, ingyenes Androidon és iOS-en): szkennel, csatlakozik, bejárja a GATT-adatbázist, olvas és ír karakterisztikákat, és feliratkozik értesítésekre – így a kameraoldali viselkedés elszigetelten tesztelhető, anélkül hogy egyáltalán társalkalmazást kellene írni.
A gyakori hibamódok:
„Az eszközöm megjelenik a szkennerben, de nem csatlakozik.” Leggyakrabban a hirdetési csomagban
connectable=Falsevan (broadcaster mód), vagy egy korábbi kapcsolat még nyitva van, és a kamera már túljutott azaioble.advertise()híváson. Adj print utasításokat az advertise hívás köré a megerősítéshez.„Az exchange_mtu(512) lefutott, de az értesítéseim még mindig 20 bájtra vannak korlátozva.” A megtárgyalt MTU
min(local, peer)– lehet, hogy a telefon vagy a central könyvtár nem kért nagyobb MTU-t a saját oldalán, ebben az esetben a kapcsolat 23-on marad. Vizsgáld meg amtuértéket, miután aexchange_mtu()visszatér. Vedd figyelembe azt is, hogy aexchange_mtu()kapcsolatonként csak egyszer működik; hívd meg az első nagy művelet előtt.„A párosítás egy általános hibával bukik el.” Két szokásos bűnös: az IO-képesség eltérése (
mitm=Truekérése egyio=3/ se bemenet se kimenet kamerán – nincs mód a numerikus kód megerősítésére, így a párosítómotor feladja), és egy vadul rossz faliórai idő a kamerán, amikor a társ megköveteli azt. Állítsd be az órát azntptime.settime()függvénnyel az első párosítási kísérlet előtt.„Az értesítések soha nem érkeznek meg a klienshez.” Két dolgot kell ellenőrizni, ebben a sorrendben: (a) a karakterisztikát
notify=Trueértékkel deklarálták? – a tulajdonságbitet be kell állítani a szerveroldalon; (b) a kliens meghívta asubscribe()metódust? – a Client Characteristic Configuration Descriptor (CCCD) megírása nélkül a szervernek azt mondják, hogy egyetlen kliens sem kér értesítéseket, és csendben eldobja őket.„A hirdetett név csonkolódik vagy hiányzik.” A hirdetési hasznos teher 31 bájt, és a flags + service-UUID + appearance mezők mindegyike bájtokat vesz el a tetejéből. Egy hosszú
name=plusz több szolgáltatás-UUID túlcsordul. Vagy rövidítsd le a nevet, vagy használj aktív szkennelést, hogy a szkennelési válasz (újabb 31 bájt) hordozza a túlcsordulást. Az nRF Connect mindkét felet külön mutatja, ami nyilvánvalóvá teszi a felosztást.„Az L2CAP connect azonnal kivételt dob.” Általában PSM-eltérés – mindkét oldalnak meg kell egyeznie ugyanabban a PSM-számban sávon kívül. Egy
L2CAPConnectionErrora Bluetooth-státuszkódot hordozza az első argumentumaként; a2státusz („PSM not supported”) árulkodó jel.„A kötött kapcsolatok még mindig teljes párosítási kézfogást váltanak ki minden újracsatlakozáskor.” Az
aioble.security.load_secrets()nem lett meghívva az indításkor. Enélkül a mentett kulcsok a flash memórián vannak, de soha nem töltődnek be a memóriába, így a társ identitása ismeretlen, és a párosítás minden alkalommal a nulláról fut.
Amikor minden más kudarcot vall, az alacsonyabb szintű bluetooth modul egy IRQ visszahívást tesz elérhetővé, amely minden mögöttes eseménynél kivált; ha rövid időre feliratkozol rá és kiírod az eseményeket, az a kamera oldalon a Wireshark-nyomkövetés megfelelője.
11.14.2. Ennek a referenciának a későbbi használata¶
Kezeld a Bluetooth fejezeteket referenciaanyagként; a periféria hirdetési hasznos teherének pontos elrendezéséért vagy a central szkennelés-és-feliratkozás folyamatáért való visszatérés a szándékolt használat. Az aioble — Aszinkron BLE és az bluetooth — alacsony szintű Bluetooth referenciaoldalak egy helyen sorolják fel az összes metódust, jelzőt és konstanst, amikor a kérdés csak az, hogy „mi ennek a hívásnak a pontos neve”.