Hallo, Ich habe hier ein BLE Server (Lichtring mit Gyro) und möchte via ESP32 (und PlatformIO mit Arduino Plugin) damit Daten austauschen. Das connecten und Daten lesen über eine bestimmte Service/Characteristic funktioniert auch soweit mit dieser Arduino LIB. https://github.com/nkolban/ESP32_BLE_Arduino/tree/master/examples Die Connection wird aber nach ca. 5 Sec immer wieder abgebrochen. Wenn ich mich testweise mit der nrfConnect App auf den Server verbinde, bricht die Verbindung dann auch wieder ab mit dem Fehlercode 19. Recherchiert und M.m.n. müsste ich nun von ESP32 aus erstmal die Connection Parameter an den Server senden, damit die Connection dauerhaft erhalten bleibt. Wie mache ich das? Es gibt ja auch verschiedene Layer; ATT, GATT, L2Layer, LL, LE LL, Connection Parameter usw. Was muss ich wie senden oder gibt es da einen Kniff? Das in einem Service die Characteristics sind und dazu Descriptor gehören, auch das Thema UUIDs (kurz oder lang) ist mir bekannt. Zu dem Server gehört original eigentlich eine APP und ich habe diesen Datenaustausch mit Wireshark mal mitgesnifft. Hier wird dann erstmal ein LL_Connection_Update an den Server gesendet, dann passiert jede Mende ATT und GATT hin und her und zum Schluss nochmal Connection Parameter. Dieses möchte ich quasi mit dem ESP nachbilden, das ich mit dem Server und dem ESP32 ohne App dann Daten austauschen kann. Hat die o.g. LIB jemand im Einsatz und kann mir mehr über dieses Thema erklären? Ich stecke da fest. ... Und bitte nicht "nutz Google" usw. bisher habe ich da was nicht verstanden, denke ich. Nützliche Code Snippets gerne willkommen. Viele Grüße Carsten
:
Verschoben durch Moderator
C. L. schrieb: > Recherchiert und M.m.n. müsste ich nun von ESP32 aus erstmal die > Connection Parameter an den Server senden, damit die Connection > dauerhaft erhalten bleibt. Wie mache ich das? > > Es gibt ja auch verschiedene Layer; > ATT, GATT, L2Layer, LL, LE LL, Connection Parameter usw. > Was muss ich wie senden oder gibt es da einen Kniff? Keine Ahnung, ob Dir das irgendwie hilft, aber hier mal meine 2 Cents: Ich habe auch schon mehrere BLE-Geräte gesehen, mit denen man sich zwar verbinden kann, die dann aber nach wenigen Sekunden von sich aus die Verbindung trennen. Bei diesen Geräten war es dann immer so, dass man unmittelbar nach dem Verbinden quasi zur Initialisierung irgendwelche Daten an irgendwelche Characteristics senden musste. Wenn das nicht binnen weniger Sekunden geschah, beendeten sie die Verbindung. Mit irgendwelchen standardisierten "Connection Parametern" habe ich das bislang nie in Verbindung gebracht - wenn es sowas bei BLE gibt, hatte ich bislang nicht wissentlich damit zu tun, das hat die BLE-Library dann vermutlich für mich transparent von selbst erledigt. Die "Lösung" war für mich in solchen Fällen ziemlich genau das, was Du bereits angefangen hast: - die "Original-App" verwenden - die Kommunikation zwischen App und BLE-Gadget mitschneiden, zumindest die ersten Sekunden - und zwar am besten mehrfach, damit man weiss, ob sich irgendwelche Teile ändern - In der eigenen Software dann die Kommunikation beim Verbindungsaufbau imitieren - Wenn's erst einmal klappt und das BLE-Gerät die Verbindung nicht mehr kappt: Nach und nach einzelne Schritte der Kommunikation entfernen, schauen, ob es dann immer noch klappt ohne dass die Verbindung getrennt wird, auf diese Weise den herausfinden, welche Schritte wirklich erforderlich sind und welche nicht. Meiner Erfahrung nach ist es meistens nur ein einziger Schritt, der erforderlich ist, damit die Verbindung nicht mehr getrennt wird
Joachim S. schrieb: > Meiner Erfahrung nach ist es > meistens nur ein einziger Schritt, der erforderlich ist, damit die > Verbindung nicht mehr getrennt wird ... da habe ich noch gar nicht drüber nach gedacht, das es möglicherweise nur ein einziger Schritt ist das die Verbindung dann gehalten wird. Es scheint auch so zu sein, das irgendwas erst "getriggert" werden muss, bevor der Lichtring von Peripheral sich steuern lässt. Aber genau das ist das nächste Problem. Ich kann via Wireshark bei der Original App gar nicht erkennen, was genau bzw. welcher Inhalt wie gesendet wird, damit irgendwas weitergeht, deswegen war ich bei den Connection Parametern. Da werden Sent Requests geschickt, das kann ich nicht interpretieren. Muss ichmich weiter informieren. Ich werde mal weitersuchen und mit Wireshark weiter filtern. Der ganze Datenverkehr ist ja voll mit Empty PDU´s Carsten
Hallo Carsten, C. L. schrieb: > Die Connection wird aber nach ca. 5 Sec immer wieder abgebrochen. > Wenn ich mich testweise mit der nrfConnect App auf den Server verbinde, > bricht die Verbindung dann auch wieder ab mit dem Fehlercode 19. Error code 19 entspricht: REMOTE USER TERMINATED CONNECTION Wenn Du einen GATT Client hat, der auf eine fehlerfreie GATT Implementierung zurück greift (iOS zum Beispiel), dann kannst Du da eigentlich nichts falsch machen, das dazu führt, dass die Verbindung abgebrochen wird. Du kannst mit Wireshark aber auch noch mal sicher stellen, dass die LL_TERMINATE_IND vom Server kommt. Die Verbindung mit niedrigem Connection Interval zu starten und dann irgend wann, nach der Discovery auf ein höheres Interval zu gehen, um Energie zu sparen, ist nicht unüblich. Meine Vermutung ist, dass das nichts mit Deinem Problem zu tun hat. Für mich sieht es so aus, als würde der GATT Server einfach einen Timer aufsetzen und nach 5 Sekunden Inaktivität (wahrscheinlich auf GATT-Ebene), die Verbindung einfach schließen. Jetzt müsstest Du einfach damit leben und bei Bedarf die Verbindung einfach wieder aufbauen, oder mal die original App angucken, ob die ggf. irgend etwas periodisch macht, dass dieses Timeout aushebelt. Ggf. wird dieses Timeout aber auch ausgesetzt, wenn sich ein Client auf Notifications oder Indications einer Characteristic subscribed. Meine Empfehlung: Frag doch einfach mal den Hersteller. Der verdient sein Geld damit, dass er Hardware verkauft. Jedes Projekt, dass seine Hardware nutzbarer macht, kann die Verkaufszahlen eigentlich nur verbessern. Schöne Grüße Torsten
Hey Torsten, gestern noch auf YT ein Video von Dir gesehen zu dem Thema... Torsten R. schrieb: > Du kannst mit Wireshark aber auch noch mal sicher > stellen, dass die LL_TERMINATE_IND vom Server kommt. Habe ich gemacht, kommt vom Server. Ich habe mich mit der nrf Connect app verbunden, auf Abbruch gewartet und das mitgesnifft. Torsten R. schrieb: > Für mich sieht es so aus, als würde der GATT Server einfach einen Timer > aufsetzen und nach 5 Sekunden Inaktivität (wahrscheinlich auf > GATT-Ebene), die Verbindung einfach schließen. Heisst das, ich muss auf GATT Ebene irgend was tun? Momentan kenne ich nur die Thematik Service/Characteristic und damit dann Werte lesen und schreiben. Hilf da noch mal bitte. Vlt ist die o.g. LIB dafür gar nicht geeignet? Torsten R. schrieb: > Ggf. wird dieses Timeout aber auch > ausgesetzt, wenn sich ein Client auf Notifications oder Indications > einer Characteristic subscribed. Wie genau abonniere ich denn? ist das sowas hier? UUID usw. ist klar...
1 | if(l_BLERemoteChar->canNotify()) |
2 | l_BLERemoteChar->registerForNotify(notifyCallback); |
Und in der Notify Routine kann ich dann auch schon den Gyro lesen. Ist das dann abonnieren? Jetzt noch rausfinden, was benötigt wird um die Connection zu halten und den Lichtring zu steuern. Die Datenwerte um den Lichtring zu steuern liegen mir vor und sehe ich in der Original App via Wireshark auch. Kann es vlt. sein das ich den Batterielevel erst abonnieren muss? Den um diese "Nebensächlichen Dinge", wie auch FW Strings und Seriennummer und co habe ich mich noch nicht gekümmert. VG Carsten
C. L. schrieb: > Wie genau abonniere ich denn? ist das sowas hier? UUID usw. ist klar... >
1 | > if(l_BLERemoteChar->canNotify()) |
2 | > l_BLERemoteChar->registerForNotify(notifyCallback); |
3 | >
|
ja, das sieht korrekt aus. Bei Notifications / Indications sendet Dir der GATT-Server direkt den Wert der Characteristic (üblicherweise, wenn sich der Wert geändert hat). Das ist aber alles nur eine Vermutung. Ich vermute, dass die 5s Timeout auf der Server-Seite implementiert sind. Von daher kommt es darauf an, woran die Kollegen dieses Timeout fest machen. Wenn Du Dir die Characteristics in nRfConnect anguckst, kannst Du erkennen, welche Characteristics Notifications / Indications unterstützen. > Und in der Notify Routine kann ich dann auch schon den Gyro lesen. Im Callback, solltest Du bereits den neuen / geänderten Wert der Characteristic haben, > Ist das dann abonnieren? Jep. > Jetzt noch rausfinden, was benötigt wird um die Connection zu halten und > den Lichtring zu steuern. Vielleicht doch einfach den Hersteller fragen? ;-) > Kann es vlt. sein das ich den Batterielevel erst abonnieren muss? Kann sein. Du kannst so lange rum probieren, bis Du es heraus bekommen hast, oder Du fragst halt ;-)
Torsten R. schrieb: > GATT-Server direkt den Wert der Characteristic (üblicherweise, wenn > sich der Wert geändert hat). ok, das wäre bei dem Gyro dann der Fall, denn da habe ich die Callbackroutine und die gibt mir die Gyro Werte raus, sobald ich das Teil bewege, dann passt das also. Torsten R. schrieb: > Wenn Du Dir die Characteristics in nRfConnect anguckst, kannst Du > erkennen, welche Characteristics Notifications / Indications > unterstützen. Ich habe was gefunden: Service 0x1801 Char 0x2A05 INDICATE => das soll dann Service changed sein, wozu das gut ist weiss ich noch nicht. Service 0x180F Char 0x2A19 NOTIFY, READ => Batterie Level Service unique 128Bit ID Char unique 128Bit ID NOTIFY, WRITE => Experimental Buttonless DFU, ist das fürs Firmware Update der Server aus der Original APP wahrscheinlich? Service unique 128Bit ID Char unique 128Bit ID NOTIFY Char unique 128Bit ID WRITE, WRITE NO RESP => Nordic UART, der obere ist TX und der untere RX. Wie kann man denn an RX schreiben? - ist warscheinlich das übliche mit den Sichtweisen und den Verwechslungen. Hier habe ich in Wireschark gesehen, das vom Master zum Slave UART TX immer am Anfang 7 Bytes gesschickt werden. Habe ich mal angehangen. Das kann doch dann nur der Char mit WRITE, WRITE NO RESP sein. Sollte man das mal probieren? Wozu braucht man den RX/TX wenn die Firmware Update Geschichte einen eigenen Dienst hat. Dann habe ich noch einen gefunden, einmal ist das der Lichtring und das andere ist der Gyro, das weis ich genau. Dann haben wir noch den Service mit 0x180A und da werden dann über die Char die Values gelesen wie Device, SN, Hard-/ und Software Revision, alles READ. Und noch 0x180 und da ist über die Char dann Name, Appearance und Peripheral preferred connection parameters. Auch alles READ. Dann wäre doch der nächste Ansatz jetzt mal die 7 Bytes zu senden, oder sollte man die Serv/Char jetzt mal alle sauber abbonieren und lesen? So richtig schön mit Service suchen, dann Char suchen, die Callbacks anlegen registrieren wie es sein soll. Was meinst Du? Übrigens hier erstmal vielen Dank an alle die mir da helfen/geholfen haben. Carsten Achsooooo... Mit Anfragen beim Hersteller habe ich wenig gute Erfahrungen. Bis man da erstmal in der Entwickler-Ebene ist, hat man schon selbst alles geproggt, finde ich irgendwie. Aber anfragen kostet nichts, vlt. mache ich das dann doch mal.
:
Bearbeitet durch User
C. L. schrieb: > Ich habe was gefunden: > > Service 0x1801 > Char 0x2A05 INDICATE > => das soll dann Service changed sein, wozu das gut ist weiss ich noch > nicht. Ist von Bluetooth definiert. Wenn Du die beim Discovery festgestellten Paarungen von UUID zu Handle persistent speichern möchtest, um bei der nächsten Verbindung auf das Discovern verzichten zu können, dann kannst Du Dich auf diese Characteristic subscriben. Wenn sich dann auf dem Server die Zuordnung von UUID zu Handle ändert (z.B. durch einen Firmware-Update), dann bekommst Du hier eine Indication gesendet. > Service unique 128Bit ID > Char unique 128Bit ID NOTIFY > Char unique 128Bit ID WRITE, WRITE NO RESP > => Nordic UART, der obere ist TX und der untere RX. > Wie kann man denn an RX schreiben? - ist warscheinlich das übliche mit > den Sichtweisen und den Verwechslungen. > Hier habe ich in Wireschark gesehen, das vom Master zum Slave UART TX > immer am Anfang 7 Bytes gesschickt werden. Habe ich mal angehangen. > Das kann doch dann nur der Char mit WRITE, WRITE NO RESP sein. > Sollte man das mal probieren? Ja, probiere es mal aus. > Wozu braucht man den RX/TX wenn die Firmware Update Geschichte einen > eigenen Dienst hat. Damit man zwischen Firmware-Update und Command / Response im normalen Betrieb unterscheiden kann. Ich denke, die Kollegen haben sich einfach einige Komponenten aus dem Nordic SDK genommen um Ihre Software fertig zu stellen. > Dann haben wir noch den Service mit 0x180A und da werden dann über die > Char die Values gelesen wie Device, SN, Hard-/ und Software Revision, > alles READ. Ja, das ist der Device Information Service (DIS). Die Details zu den services und characteristics mit 16 bit UUIDs kannst Du alle auf der Webseite von der Bluetooth SIG nachlesen: https://www.bluetooth.com > Dann wäre doch der nächste Ansatz jetzt mal die 7 Bytes zu senden, oder > sollte man die Serv/Char jetzt mal alle sauber abbonieren und lesen? > So richtig schön mit Service suchen, dann Char suchen, die Callbacks > anlegen registrieren wie es sein soll. Erst abonnieren, dann schreiben. Es könnte auch sein, dass die Software prüft, ob sie überhaupt antworten kann.
Sooo.... Ich bin noch nicht wirklich weiter, die Verbindung bricht immer noch ab. Ich kann nun den Batterielevel via READ lesen und sehen. Auch ein Notify habe ich darauf angelegt. Hier direkt die erste Frage: Kann der Server mitbekommen, das auf der Gegenseite ein Notify darauf lauscht, um daran z.B. zu entscheiden? Es hiess ja, das wäre dann abonniert. Also könnte der Server auch sagen, wenn nicht abboniert, dann mach ich auch nix. Dann habe ich den Service/Char vom Nordic so bedient, wie es die Original App auch tut. Allerdings sind die hinten 4 Bytes im Original immer anders. Was da noch für ein Algorythmus hintersteckt weiß ich noch nicht. Im Wireshark sieht es aber genaus so aus wie bei einem Mitschnitt. Bisher alles der Reihe nach, so wie es auch im Original Mitschnitt erkennbar ist. Dann muss mir nochmal jemand erklären, wie das mit den Handles usw. ist. Denn da kann ich noch Unterschiede sehen, die mir aber noch nicht klar sind. Ich habe hier im Mitschnitt ein Send Write Request, Sent Read Request, Send Write Command... Wo bzw. was ist da der Unterschied und wie stehen die Handles dazu in Verbindung. Komisch kommt mir vor, das ich Sent Write Request sehe, obwohl ich gar nichts sende aus dem ESP32. Den von mir gesendeten Commands (die 7 Bytes über Nordic Char) sehe ich in Wireshark. Was bzw. wer sendet denn da noch? Kann es sein, das ein registerNotify(); was zum Server sendet und darauf geantwortet wird? Ist das dann noch Teil der Pairing Kommunikation? Z.B. das Bild im Anhang... Die Anforderung habe ich im ESP garnicht gemacht - Kommt das dann aus der o.g. Bluetooth SIG und ist das dann gar nicht weiter zu beachten? Kernfrage: kann der Server penibel genau checken was der Client so liest bzw. möchte? Hatte immer gedacht, der Server legt das in die Characteristic und kümmert sich nicht mehr drum und auf der anderen Seite wird das abgeholt wenn es gebraucht wird. Wenn das nicht so ist, dann muss ich das möglicherweise extakt nach emulieren, dafür fehlt mir aber noch das Verständnis. VG Carsten @ Moderation Die Bilder können bis auf eines gelöscht werden, ist bei der Vorschau weg gegangen und ich habe die immer neu angehangen - sry
:
Bearbeitet durch User
C. L. schrieb: > Hier direkt die erste Frage: Kann der Server mitbekommen, das auf der > Gegenseite ein Notify darauf lauscht, um daran z.B. zu entscheiden? > Es hiess ja, das wäre dann abonniert. > Also könnte der Server auch sagen, wenn nicht abboniert, dann mach ich > auch nix. Ja, der Server kann das schon mitbekommen. Und ich halte es zumindest für denkbar, dass das Gerät deshalb die Verbindung beenden könnte, weil Du eine Characteristic nicht subscribed hast, die die Original-App üblicherweise subscriben würde. Neben der "Nordic UART RX"-Characteristic, an die Du die sieben Bytes sendest, gibt es ja z.B. auch noch die "Nordic UART TX"-Characteristic (UUID: 6E400003-B5A3-F393-E0A9-E50E24DCCA9E) für die Gegenrichtung, zum Empfangen. Auch die würde ich daher einfach mal subscriben, einfach um das als potentielle Fehlerquelle auszuschliessen. Ausserdem könnte dort ja als Reaktion auf die sieben gesendeten Bytes irgendwas zurückgeschickt werden. > Ich habe hier im Mitschnitt ein Send Write Request, Sent Read Request, > Send Write Command... Wo bzw. was ist da der Unterschied und wie stehen > die Handles dazu in Verbindung. Der Unterschied zwischen einem "Write Request" und einem "Write Command" ist damit vergleichbar, ob Du ein Paket via TCP oder UDP verschickst: Das "Write Command" ist mit UDP vergleichbar - der Empfänger bestätigt den Empfang des Schreib-Befehls nicht, daher kann man nicht 100% sicher sein, dass der Befehl korrekt übermittelt wurde. Der "Write Request" hingegen macht im Grunde exakt das gleiche, nur dass hier das BLE-Gerät den Empfang bestätigt - falls der Schreib-Befehl also nicht erfolgreich übermittelt wurde, dann bekommt die Seite, die den "Write Request" gesendet hat, das mit. In der Gegenrichtung gibt es das auch, als Unterschied zwischen "notify" und "indicate": Es ist quasi das Gleiche, nur dass bei "notify" der Empfang nicht quittiert wird. Edit: Ich bin eben zufällig noch auf einen GitHub-Issue gestossen, der mit der ESP32-BLE-Library und genau diesem Unterschied zwischen "Write Request" und "Write Command" zu tun hat: https://github.com/nkolban/esp32-snippets/issues/382 Wenn ich das richtig verstehe, hat oder hatte die ESP32-BLE-Library da einen Bug, dass Write Requests (Opcode 0x12) fälschlicherweise als Write Commands (Opcode 0x52) gesendet werden. Ich konnte beim kurzen Überfliegen allerdings nicht erkennen, ob das mittlerweile behoben ist. > Komisch kommt mir vor, das ich Sent Write Request sehe, obwohl ich gar > nichts sende aus dem ESP32. Den von mir gesendeten Commands (die 7 Bytes > über Nordic Char) sehe ich in Wireshark. Was bzw. wer sendet denn da > noch? > Kann es sein, das ein registerNotify(); was zum Server sendet und darauf > geantwortet wird? Ist das dann noch Teil der Pairing Kommunikation? > > Z.B. das Bild im Anhang... > Die Anforderung habe ich im ESP garnicht gemacht - Kommt das dann aus > der o.g. Bluetooth SIG und ist das dann gar nicht weiter zu beachten? Bei diesem Abschnitt bin ich mir nicht sicher, ob ich Dich richtig verstehe. z.B. der Screenshot: Soll das ein mitgesniffter Teil der Kommunikation zwischen dem ESP32 und dem BLE-Gerät ESP32 sein? Und man sieht da, dass die Firmware-Version und der Batterie-Stand abgefragt wird, obwohl Du das in Deinem ESP32-Code gar nicht tust? Falls ja, fände ich das in der Tat höchst merkwürdig. Dass die ESP32-BLE-Library völlig ungefragt einfach mal die Firmware-Revision und den Batteriestand abfragt, kann ich mir irgendwie nicht vorstellen. > Kernfrage: kann der Server penibel genau checken was der Client so liest > bzw. möchte? Hatte immer gedacht, der Server legt das in die > Characteristic und kümmert sich nicht mehr drum und auf der anderen > Seite wird das abgeholt wenn es gebraucht wird. > Wenn das nicht so ist, dann muss ich das möglicherweise extakt nach > emulieren, dafür fehlt mir aber noch das Verständnis. In "High-Level"-BLE-Libraries wie eben der von Nick Kolban für den ESP32 kümmert man sich um sowas normalerweise nicht, aber grundsätzlich könnte ein BLE-Gerät natürlich schon genau mitkriegen, was ein Client so liest, schreibt, abonniert etc. Die Frage ist, ob das hier wirklich das Problem ist.
:
Bearbeitet durch User
C. L. schrieb: > Hier direkt die erste Frage: Kann der Server mitbekommen, das auf der > Gegenseite ein Notify darauf lauscht, um daran z.B. zu entscheiden? Ja. Wenn Du auf Server-Seite zwischen dem Bluetooth-Stack und der Applikation unterscheidest, dann muss der Stack das sogar wissen, der er sendet aktiv Notifications und Indications, wenn die Applikation geänderte Daten meldet und sich ein verbundener Client auf diese Daten (Characteristic) abonniert hat. Auf der Applikations-Ebene ist diese Information (ob ein Client abonniert ist) in der Regel auch verfügbar. > Komisch kommt mir vor, das ich Sent Write Request sehe, obwohl ich gar > nichts sende aus dem ESP32. Den von mir gesendeten Commands (die 7 Bytes > über Nordic Char) sehe ich in Wireshark. Was bzw. wer sendet denn da > noch? > Kann es sein, das ein registerNotify(); was zum Server sendet und darauf > geantwortet wird? Ja, technisch besteht eine Characteristic auf die man sich abonnieren kann aus mindestens 3 Attributen: Characteristic Description, Characteristic Value und Characteristic Client Configuration Descriptor (CCCD). Auf den letzten schreibt ein Client, damit der Server weis, dass der Client abonniert ist. > Ist das dann noch Teil der Pairing Kommunikation? Nein, Pairing ist im wesentlichen der Austausch von Schlüsseln für die Verschlüsselte Kommunikation. > Kernfrage: kann der Server penibel genau checken was der Client so liest > bzw. möchte? Ja, der Bluetooth Stack kann der Applikation sicher einiges abnehmen, in der Regel hat aber jeder Stack die Möglichkeit, dass die Applikation diese Informationen bekommt. > Hatte immer gedacht, der Server legt das in die > Characteristic und kümmert sich nicht mehr drum und auf der anderen > Seite wird das abgeholt wenn es gebraucht wird. Abholen bedeute, der Client schickt einen Read Request und der Server antwortet mit einem Read Response. Du kannst Dir die Details auch direkt in den entsprechenden Spezifikationen angucken. Für ATT/GATT wäre das dann Core Spec. Vol 3; Part F und Part G. Die Spezifikation ist sehr leserlich geschrieben.
Joachim S. schrieb: > Neben der "Nordic UART RX"-Characteristic, an die Du die sieben Bytes > sendest, gibt es ja z.B. auch noch die "Nordic UART TX"-Characteristic > (UUID: 6E400003-B5A3-F393-E0A9-E50E24DCCA9E) für die Gegenrichtung, zum > Empfangen. Auch die würde ich daher einfach mal subscriben, einfach um > das als potentielle Fehlerquelle auszuschliessen. Ausserdem könnte dort > ja als Reaktion auf die sieben gesendeten Bytes irgendwas > zurückgeschickt werden. Habe ich gemacht, kommt keine Reaktion auf die von mir gesendeten Daten. Dabei stellt sich mir direkt die Frage nochmal mit dem subscriben. Wenn ich sowas hier mache:
1 | pRemoteChar_NORDICUART_TX->registerForNotify(notifyCallbackTX); |
dann erschließt sich mir, das da was abonniert wird. Aber wie ist es denn z.B. beim READ? Abonniere ich automatisch, wenn ich einmal gelesen habe? Denn in der LIB habe ich kein "register for READ" o.ä. Oder auch beim WRITE - muss ich einmal schreiben um zu abbonnieren? Joachim S. schrieb: > Der "Write Request" hingegen macht im Grunde exakt das gleiche, nur dass > hier das BLE-Gerät den Empfang bestätigt - falls der Schreib-Befehl also > nicht erfolgreich übermittelt wurde, dann bekommt die Seite, die den > "Write Request" gesendet hat, das mit. > > In der Gegenrichtung gibt es das auch, als Unterschied zwischen "notify" > und "indicate": Es ist quasi das Gleiche, nur dass bei "notify" der > Empfang nicht quittiert wird. Verstanden! GitHub Issue checke ich mal und das hier... Joachim S. schrieb: > Bei diesem Abschnitt bin ich mir nicht sicher, ob ich Dich richtig > verstehe. z.B. der Screenshot: Soll das ein mitgesniffter Teil der > Kommunikation zwischen dem ESP32 und dem BLE-Gerät ESP32 sein? Und man > sieht da, dass die Firmware-Version und der Batterie-Stand abgefragt > wird, obwohl Du das in Deinem ESP32-Code gar nicht tust? sieht in der Tat so aus, aber ich muss auch aufpassen, das ich mich nicht verrenne bei den ganzen Baustellen - das checke ich lieber auch nochmal ;-) Torsten R. schrieb: > Ja, technisch besteht eine Characteristic auf die man sich abonnieren > kann aus mindestens 3 Attributen: Characteristic Description, > Characteristic Value und Characteristic Client Configuration Descriptor > (CCCD). Auf den letzten schreibt ein Client, damit der Server weis, dass > der Client abonniert ist. Sooo... Das ist neu für mich... Ich hatte es so verstanden, das der Descriptor quasi die Interpretation ist. Also bei BatLvl z.b. das % Zeichen oder bei anderen Werten eine Scalierung o.ä. Jetzt ist die Frage, wie ich auf den Characteristic Client Configuration Descriptor schreiben kann, bzw. was ich da schreiben muss. Das muss ich mir u.a. in der Lib mal genauer ansehen. Torsten R. schrieb: > Du kannst Dir die Details auch direkt in den entsprechenden > Spezifikationen angucken. Für ATT/GATT wäre das dann Core Spec. Vol 3; > Part F und Part G. Die Spezifikation ist sehr leserlich geschrieben. Aslo auf der Seite ist man ja erschlagen von Dokumenten. Bin jetzt in der GATT Specification Supplement, aber da ist kein Part F/G sondern nur Zahlen: 3 z.B. Characteristic, 4 Descriptor.. Kannst Du das von Dir genannte Dokument mal verlinken? Bei dem Thema Descriptor bin ich unsicher. Ich mache ja:
1 | BLERemoteService* pRemoteServiceBat = pClient->getService(serviceUUID_BatLvL); |
2 | |
3 | BLERemoteCharacteristic* pRemoteChar_Bat = pRemoteServiceBat->getCharacteristic(charUUID_BatLvL); |
4 | |
5 | BLERemoteDescriptor* BatLvLDes = pRemoteChar_Bat->getDescriptor(charUUID_BatLvLDes); |
6 | std::string BatLvLDesc = pRemoteChar_Bat->readValue(); |
In den Sektionen passiert natürlich das Wesentliche. Service suchen, prüfen ob da... Char suchen, prüfen ob Read oder Notify geht und dann lesen oder registieren. Descriptor suchen, prüfen und lesen - in dem Fall hier kommt aber nur HEX 3D3D03E0DE bei raus... ? in einem Beispiel im Internet habe ich das hier gefunden
1 | XYCharacteristic->getDescriptor(BLEUUID((uint16_t)0x2902))->writeValue((uint8_t*)notificationOn, 2, true); |
ist das dann das mitteilen an den Server, das hier ein notify passiert? Das habe ich ja in meinem Programm noch gar nicht eingebaut. BTW Ich finde Eure Antworten und die Art wie Ihr das hier erklärt wirklich super, vielen Dank an Euch, denn das ist nicht normal in diesem Forum. #credits!!!! ;) VG Carsten
C. L. schrieb: > Sooo... Das ist neu für mich... > Ich hatte es so verstanden, das der Descriptor quasi die Interpretation > ist. Also bei BatLvl z.b. das % Zeichen oder bei anderen Werten eine > Scalierung o.ä. Es gibt verschiedene Descriptors, die entsprechend unterschiedliche Aufgaben haben. Eine Characteristic muss einen CCCD haben, wenn sie als Characteristic Property Notify oder Indicate hat. > Jetzt ist die Frage, wie ich auf den Characteristic Client Configuration > Descriptor schreiben kann, bzw. was ich da schreiben muss. Du must da überhaupt nichts schreiben. Wenn Du in deiner Library die Funktion `registerForNotify()` aufrufst, dann sucht diese Funktion das Handle zur CCCD der Characteristic raus und schreibt dann den 16 Bit Wert 0x0001. > Aslo auf der Seite ist man ja erschlagen von Dokumenten. > Bin jetzt in der GATT Specification Supplement, aber da ist kein Part > F/G sondern nur Zahlen: 3 z.B. Characteristic, 4 Descriptor.. > Kannst Du das von Dir genannte Dokument mal verlinken? https://www.bluetooth.com/specifications/specs/core-specification-5-4/ gleich das erste Dokument. (ggf. muss Du da einen Account anlegen). > Bei dem Thema Descriptor bin ich unsicher. > Ich mache ja: Da ich die API nicht kenne, kann ich nichts dazu sagen. > in einem Beispiel im Internet habe ich das hier gefunden >
1 | > XYCharacteristic->getDescriptor(BLEUUID((uint16_t)0x2902))->writeValue((uint8_t*)notificationOn, |
2 | > 2, true); |
3 | >
|
Kann ich auch nichts zu sagen. Kenne die API nicht. Habe mal unter
Android was gemacht und da musste man erstaunlicherweise auch explizit
auf den Descriptor schreiben (Wert 1 für Notifications; 2 für
Indications),
> ist das dann das mitteilen an den Server, das hier ein notify passiert?
Nein, der Client empfängt die Notifications ja. Das Schreiben auf den
CCCD teilt dem Server mit, dass der Client Notifications empfangen
möchte. Der Application-Teil des Servers entscheidet dann in der Regel,
dass eine Notification für eine Characteristic gesendet werden soll.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.