Hoe RADR apparaatinstanties ontdekt en maakt op basis van BLE-service-UUID's
Het apparaatregister is het kernsysteem dat de UUID's van Bluetooth Low Energy (BLE)-services koppelt aan apparaatfabrieken. Wanneer RADR naar apparaten scant, gebruikt het service-UUID's om te bepalen welke fabriek de apparaatinstantie moet maken.
Architectuuroverzicht
RADR maakt gebruik van een registersysteem met twee niveaus:
| Laag | Beschrijving | Voorbeeld |
|---|---|---|
| Hardgecodeerd | Apparaten die rechtstreeks in code zijn geregistreerd met aangepaste fabrieken | OSSM |
| Dynamisch | Apparaten geladen vanuit registry.json met behulp van de ButtplugIO-fabriek | Lovense, Satisfyer, Kiiroo |
┌─────────────────────────────────────────────────────────────┐
│ Device Registry │
│ │
│ ┌─────────────────────┐ ┌─────────────────────────────┐│
│ │ Hardcoded Devices │ │ Dynamic Devices ││
│ │ (Custom Factory) │ │ (ButtplugIOFactory) ││
│ │ │ │ ││
│ │ Service UUID → │ │ registry.json → ││
│ │ Lambda → Device │ │ Service UUID → ││
│ │ │ │ Spec files → Device ││
│ └─────────────────────┘ └─────────────────────────────┘│
└─────────────────────────────────────────────────────────────┘Het register wordt één keer gevuld bij het opstarten van het apparaat via initRegistry().
Registerstructuur
Het register is een globale map die service-UUID's koppelt aan fabrieksfuncties:
std::unordered_map<std::string, DeviceFactory> registry;Hierbij is DeviceFactory als volgt gedefinieerd:
typedef Device *(*DeviceFactory)(const NimBLEAdvertisedDevice *advertisedDevice);Kernfuncties
| Functie | Doel |
|---|---|
initRegistry() | Vult het register met hardgecodeerde en dynamische apparaten |
getDeviceFactory() | Zoekt een fabriek op via de service-UUID |
Hardgecodeerde apparaten
Hardgecodeerde apparaten worden rechtstreeks in initRegistry() geregistreerd met een lambda-fabriek. Deze aanpak wordt gebruikt voor apparaten met aangepaste protocollen die gespecialiseerde verwerking vereisen.
OSSM-voorbeeld
registry.emplace(
OSSM_SERVICE_ID, // "522B443A-4F53-534D-0001-420BADBABE69"
[](const NimBLEAdvertisedDevice *advertisedDevice) -> Device * {
return new OSSM(advertisedDevice);
});OSSM maakt gebruik van een aangepast BLE-protocol met meerdere kenmerken voor snelheid, diepte, sensatie en slagregeling. Daarom is een speciale apparaatklasse nodig in plaats van de generieke ButtplugIO-implementatie.
Wanneer moet u hardgecodeerde registratie gebruiken?
Gebruik hardgecodeerde registratie wanneer:
- het apparaat een aangepast protocol gebruikt dat niet door Buttplug.io wordt ondersteund
- u een gespecialiseerde gebruikersinterface of besturingslogica nodig hebt
- het apparaat een speciale verwerking van kenmerken vereist
Dynamische apparaten (ButtplugIO)
Dynamische apparaten worden geladen vanuit het bestand data/registry.json op het bestandssysteem. Hierdoor kan ondersteuning voor nieuwe apparaten worden toegevoegd zonder de code te wijzigen.
registry.json-structuur
Het register koppelt service-UUID's aan arrays met protocolspecificatiebestanden:
{
"0000fff0-0000-1000-8000-00805f9b34fb": ["/protocols/lovense.json"],
"88f80580-0000-01e6-aace-0002a5d5c51b": ["/protocols/kiiroo-v2.json"],
"51361500-c5e7-47c7-8a6e-47ebc99d80e8": ["/protocols/satisfyer.json"]
}Elke invoer koppelt een BLE-service-UUID (sleutel) aan een of meer protocolspecificatiebestanden (waardenarray).
Fabrieksverloop
Wanneer een apparaat met een geregistreerde service-UUID wordt ontdekt:
ButtplugIODeviceFactoryleestregistry.jsonvan LittleFS- Haalt de lijst met spec-bestanden op voor de service-UUID
- Voor elk specificatiebestand:
- Laadt en parseert de JSON-configuratie
- Vergelijkt de geadverteerde apparaatnaam met de patronen in
communication[0].btle.names - Extraheert de TX/RX-kenmerken voor de service-UUID
- Creëert een
LovenseDevice-instantie met de overeenkomende configuratie
Bestandsindeling van protocolspecificaties
Specificatiebestanden volgen het Buttplug.io v4-formaat:
{
"defaults": {
"name": "Lovense Device",
"features": [...]
},
"configurations": [
{
"identifier": ["B"],
"name": "Max",
"features": [...]
}
],
"communication": [{
"btle": {
"names": ["LVS-*", "LOVE-*"],
"services": {
"0000fff0-0000-1000-8000-00805f9b34fb": {
"tx": "0000fff2-0000-1000-8000-00805f9b34fb",
"rx": "0000fff1-0000-1000-8000-00805f9b34fb"
}
}
}
}]
}| Veld | Doel |
|---|---|
defaults | Standaardapparaatnaam en functieset |
configurations | Apparaatspecifieke varianten en identificatiegegevens |
communication[].btle.names | Apparaatnaamspatronen (ondersteunt het jokerteken *) |
communication[].btle.services | UUID's van TX/RX-kenmerken per service |
Apparaatdetectieverloop
┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ BLE Scan │────▶│ Get Service │────▶│ Lookup in │────▶│ Factory │
│ Discovers │ │ UUID │ │ Registry │ │ Creates │
│ Device │ │ │ │ │ │ Device │
└──────────────┘ └──────────────┘ └──────────────┘ └──────────────┘- Scan: RADR zoekt naar BLE-apparaten
- UUID extraheren: Haalt de geadverteerde service-UUID op
- Register opzoeken:
getDeviceFactory(serviceUUID)vindt de fabriek - Apparaat maken: De fabriek maakt een instantie van de juiste apparaatklasse
Ondersteuning voor nieuwe apparaten toevoegen
Optie A: Dynamisch (Buttplug.io-register)
Voor apparaten die compatibel zijn met het Buttplug.io-protocol:
Verkrijg of maak het specificatiebestand
Haal de Buttplug.io v4-protocolspecificatie voor het apparaat op. Deze is beschikbaar in de Buttplug-configuratierepository voor apparaten.
Voeg een spec-bestand toe aan protocollen
Plaats het JSON-specificatiebestand in data/protocols/:
data/protocols/your-device.jsonWerk `registry.json` bij
Voeg de service-UUID-toewijzing toe aan data/registry.json:
{
"your-service-uuid": ["/protocols/your-device.json"]
}Bestandssysteem uploaden
Gebruik PlatformIO om het bestandssysteem naar het apparaat te uploaden.
Optie B: Hardgecodeerd (aangepast protocol)
Voor apparaten die aangepaste protocolverwerking vereisen:
Apparaatklasse maken
Maak een nieuwe apparaatklasse in src/devices/ die de basisklasse Device uitbreidt.
Implementeer de vereiste methoden
Implementeer getServiceUUID(), getName() en alle apparaatspecifieke besturingslogica.
Registreren in initRegistry
Voeg registratiecode toe aan initRegistry():
registry.emplace(
YOUR_SERVICE_UUID,
[](const NimBLEAdvertisedDevice *adv) -> Device * {
return new YourDevice(adv);
});Firmware opnieuw bouwen
Bouw de bijgewerkte firmware en flash deze.
Ontwikkelingsworkflow
Het register bijwerken (ontwikkeling)
Wanneer u lokaal ontwikkelt, gebruikt u de functie "Upload Filesystem" van PlatformIO om de map data/ naar LittleFS te flashen:
- Wijzig
data/registry.jsonof voeg spec-bestanden toe aandata/protocols/ - Klik in VS Code met PlatformIO op Upload Filesystem (of voer
pio run --target uploadfsuit) - Het apparaat gebruikt het bijgewerkte register wanneer het de volgende keer opstart
"Upload Filesystem" wist de bestaande LittleFS-partitie vóór het schrijven. Eventuele runtime-wijzigingen gaan verloren.
Het register bijwerken (productie)
OTA-registerupdates zijn een geplande functie die nog niet beschikbaar is. Momenteel vereisen registerupdates een firmware-flash.
De geplande workflow voor productieapparaten:
- Navigeer naar Settings > Look for updates op het apparaat
- RADR controleert op registerupdates van de server
- Bijgewerkte
registry.jsonen protocolbestanden worden OTA gedownload - Ondersteuning voor nieuwe apparaten is beschikbaar zonder een volledige firmware-update
Belangrijke bronbestanden
| Bestand | Doel |
|---|---|
src/devices/registry.h | Registerinterface en typedefinities |
src/devices/registry.cpp | Registerimplementatie en -initialisatie |
src/devices/buttplugio/buttplugIOFactory.cpp | Dynamische apparaatfabriek |
src/devices/device.h | Basisapparaatklasse |
data/registry.json | Service-UUID-koppelingen met specificatiebestanden |
data/protocols/*.json | Buttplug.io v4 apparaatspecificaties |