Forum: Projekte & Code Open Source Bluetooth LE GATT Server


von Torsten R. (Firma: Torrox.de) (torstenrobitzki)


Lesenswert?

Hallo,
ich wollte euch mal meinen in C++ geschriebenen Open Source GATT Server 
vorstellen: https://github.com/TorstenRobitzki/bluetoe

Der GATT-Teil ist nahezu feature complete. Im Moment schreibe ich an 
einem L2CAP / Link Layer der auf einem nrf51422 laufen soll. Ich hoffe 
aber, dass sich große Teile des Link Layers relativ einfach auf andere 
32-Bit Mikrocontroller portieren lässt.

Hier ein kleines Beispiel, dass einen GATT Server definiert, der eine 
Temperatur als einzige characteristic hat:
1
#include <bluetoe/bindings/nrf51.hpp>
2
#include <bluetoe/server.hpp>
3
4
std::uint32_t temperature_value = 0x12345678;
5
static constexpr char server_name[] = "Temperature";
6
static constexpr char char_name[] = "Temperature Value";
7
8
typedef bluetoe::server<
9
    bluetoe::server_name< server_name >,
10
    bluetoe::service<
11
        bluetoe::service_uuid< 0x8C8B4094, 0x0000, 0x499F, 0xA28A, 0x4EED5BC73CA9 >,
12
        bluetoe::characteristic<
13
            bluetoe::characteristic_name< char_name >,
14
            bluetoe::characteristic_uuid< 0x8C8B4094, 0x0000, 0x499F, 0xA28A, 0x4EED5BC73CAA >,
15
            bluetoe::bind_characteristic_value< decltype( temperature_value ), &temperature_value >
16
        >
17
    >
18
> small_temperature_service;
19
20
int main()
21
{
22
    small_temperature_service                   gatt;
23
    bluetoe::nrf51< small_temperature_service > server;
24
25
    for ( ;; )
26
        server.run( gatt );
27
}

Ich hoffe der eine oder andere findet es nützlich :-)

mfg Torsten

: Bearbeitet durch User
von Gerd E. (robberknight)


Lesenswert?


von Torsten R. (Firma: Torrox.de) (torstenrobitzki)


Lesenswert?

Hallo Gerd,

Gerd E. schrieb:
> Kennst Du https://github.com/pauloborges/blessed ?

Ja, aber die sind nicht mal halb fertig und das Projekt scheint auch 
nicht mehr aktiv zu sein. Ausserdem ist es C. Ich habe mir aber ein paar 
wertvolle Tipps aus deren nrf51 layer abgeguckt :-)

Gerade Beispiele wie diese 
https://github.com/pauloborges/blessed/blob/devel/examples/radio-broadcaster/main.c 
möchte Bluetoe vermeiden. Die Bluetooth Core Specification hat 2700 
Seiten. Es ist total nervig, dass viele APIs davon ausgehen, dass man 
zumindest die LE relevanten Teile gelesen hat, damit man ein device dazu 
bringen kann, sein Namen richtig zu "advertisen".

Hier hatte ich mal was zu den Design-Zielen von Bluetoe geschrieben: 
http://robitzki.de/blog/Introducing_Bluetoe

mfg Torsten

von Torsten R. (Firma: Torrox.de) (torstenrobitzki)


Lesenswert?

Hier bei Nordic im Forum habe ich gerade wieder ein schönes Beispiel 
gefunden, für eine kaputte API: 
https://devzone.nordicsemi.com/question/50142/evt_write-values-after-long-write/. 
Die Kollegen wollen eigentlich nur Characteristics haben, die länger als 
20 Bytes lang sein können und müssen plötzlich Memory Handler zur 
Verfügung stellen und ATT Pakete parsen.

von Michael D. (nospam2000)


Lesenswert?

Hallo Torsten,

Mir ist noch nicht so richtig klar, welche Umgebung man benötigt um 
deinen Code einsetzen zu können, d.h. was genau als Basis benötigt wird. 
Läuft das dann auf einem "PC" und greift per HCI auf einen USB BLE 
Adapter zu oder läuft es auf einem BT SoC wie dem nrf51422?

Torsten R. schrieb:
> Im Moment schreibe ich an einem L2CAP / Link Layer
> der auf einem nrf51422 laufen soll.

Verstehe ich das richtig, dass man damit die Bluetooth Softdevice 
Implementierungen auf nrf51822 / nrf51422 komplett ersetzen kann oder 
baust du auf dem Softdevice auf?

  Michael

von Torsten R. (Firma: Torrox.de) (torstenrobitzki)


Lesenswert?

Hallo Michael,

Michael D. schrieb:

> Mir ist noch nicht so richtig klar, welche Umgebung man benötigt um
> deinen Code einsetzen zu können, d.h. was genau als Basis benötigt wird.

die Software teilt sich in zwei Teile auf:

Der GATT Server ist (weitgehend) unabhängig von der Hardware. Im 
wesentlich hat der GATT-Server nur eine Funktion, die der L2CAP Layer 
mit empfangenen Daten aufrufen muss.

Der L2CAP Layer ist hardware abhängig. Ich hatte die Hoffnung irgend wo 
einen nutzbaren zu finden und habe mit BlueNRG einen Versuch gestartet 
und versucht das Softdevice von Nordic zu hacken; beides ohne Erfolg. 
Ich hatte auch noch bei Nordic nachgefragt, ob ich von denen eine 
Version Ihres Softdevices haben könnte, wo ich auf den L2CAP Layer 
zugreifen könnte. Haben die aber leider abgelehnt.

Für erste Tests hatte ich mir mal den btstack angeguckt und ein 
rudimentären l2cap über HCI implementiert um mal den GATT Server mit 
einem echten GATT Client (mein iPad) zusammen zu bringen. Das hat ganz 
gut geklappt. Ich glaube, dass es relativ einfach wäre einen L2CAP Layer 
über HCI für bluetoe zu schreiben.

Dann hatte ich angefangen einen eigenen link layer zu implementieren, 
und habe dabei so weit es geht, die Hardware heraus extrahiert. Das 
macht das Testen ganz komfortabel. Und bin nun dabei diese 
Hardware-Abstraktion für den nrf51422 zu implementieren. Man kann da 
schon regen Austausch sehen, die Verbindung bricht aber recht häufig ab. 
Mir fehlt da leider das Equipment um da professionell zu verifizieren, 
wie weit der link layer die Spezifikationen einhält. Da suche ich noch 
nach einer guten und bezahlbaren Lösung.

> Verstehe ich das richtig, dass man damit die Bluetooth Softdevice
> Implementierungen auf nrf51822 / nrf51422 komplett ersetzen kann oder
> baust du auf dem Softdevice auf?

Ja, dass Softdevice wird nicht benötigt. Ich kann leider noch nicht so 
ganz sagen, wo Bluetoe bezüglich Resourcenverbrauch liegen wird. Ich 
könnte mir aber vorstellen, dass es zwei Szenarios gibt, in denen 
Bluetoe Vorteile hat:

1) Wenn man nur einen sehr kleinen Teil des LL/L2CAP/GATT/ATT/GAP 
"Gedöns" braucht, landen bei einer Library-Lösung auch nur die Teile im 
binary, die auch verwendet werden. Beispiel: Beacons oder ein bootloader 
über l2cap.

2) Wenn man sehr viele Attribute hat, dann ist es von Vorteil, wenn der 
Inhalt der allermeisten Teile der dafür nötigen Datenbank im flash liegt 
und nicht wie bei Nordic bei Programstart im RAM erzeugt wird.

Schönen Dank für die Fragen. Wenn man sich damit selbst beschäftigt, ist 
einem irgend wann gar nicht mehr so klar, was unverständlich ist :-)


mfg Torsten

von Michael D. (nospam2000)


Lesenswert?

Hallo Torsten,

Torsten R. schrieb:
> Der L2CAP Layer ist hardware abhängig. Ich hatte die Hoffnung irgend wo
> einen nutzbaren zu finden und habe mit BlueNRG einen Versuch gestartet
> und versucht das Softdevice von Nordic zu hacken; beides ohne Erfolg.
> Ich hatte auch noch bei Nordic nachgefragt, ob ich von denen eine
> Version Ihres Softdevices haben könnte, wo ich auf den L2CAP Layer
> zugreifen könnte. Haben die aber leider abgelehnt.

Ich befürchte die haben genau vor den Aktionen Angst die gerade hier im 
Forum und auf Heise.de diskutiert werden, Stichwort 
[http://www.heise.de/newsticker/meldung/Funkregulierung-Angriff-auf-alternative-Software-2803189.html 
"Funkregulierung"].

> Und bin nun dabei diese
> Hardware-Abstraktion für den nrf51422 zu implementieren.

Sind die für BLE benötigten Register alle ausreichend dokumentiert? Ich 
hatte vor einiger Zeit den Eindruck, dass sie die Beschreibung von ein 
paar Registern im Radio Bereich unterschlagen hatten.

  Michael

von Torsten R. (Firma: Torrox.de) (torstenrobitzki)


Lesenswert?

Guten Morgen,

Michael D. schrieb:

> Ich befürchte die haben genau vor den Aktionen Angst die gerade hier im
> Forum und auf Heise.de diskutiert werden, Stichwort "Funkregulierung".

Kann ich mir nicht vorstellen. Die stellen ja selbst keine Geräte her. 
Ich denke mal, die haben einfach keine Lust ein modifiziertes 
Softdevice, erst zu erstellen und dann später noch ständig 
support-Anfragen dazu zu bekommen, falls das weiter in Umlauf gerät.

> Sind die für BLE benötigten Register alle ausreichend dokumentiert? Ich
> hatte vor einiger Zeit den Eindruck, dass sie die Beschreibung von ein
> paar Registern im Radio Bereich unterschlagen hatten.

Ich finde die Dokumentation ja immer etwas spärlich. Aus Erfahrung mit 
Infineon und ST, weis ich jetzt aber, das die Dokumentation hervorragend 
ist ;-)

Es gibt ein paar Feinheiten, wenn die nicht dokumentiert wären, wäre es 
sehr schwierig, die nötigen Timings einzuhalten (z.B. die nötigen 150µs 
zwischen zwei Datenpaketen, oder shortcuts um das Radio über den Timer 
zu steuern). Ich denke aber, dass es mittlerweile vollständig 
dokumentiert ist.

Hier die Implementierung für nrf51 (ist aber noch ein bisschen 
Baustelle): 
https://github.com/TorstenRobitzki/bluetoe/blob/master/bluetoe/bindings/nrf51.cpp

mfg Torsten

von Michael D. (nospam2000)


Lesenswert?

Torsten R. schrieb:
> Hier die Implementierung für nrf51

Danke, ich schau es mir mal an. Ich stehe noch ganz am Anfang von BLE. 
Das einzige was ich bisher gemacht habe ist ein Scanner für ANT.

Was mir im Code ins Auge gestochen ist:
nrf_timer->BITMODE = TIMER_BITMODE_BITMODE_32Bit;

Der nrf51822 / 422 unterstützt keine 32-Bit Timer, sondern höchstens 24 
Bit. Das steht allerdings erst in der "Product Specification" und nicht 
im "nRF51 Series Reference Manual":
 * Two 16 bit and one 24 bit timers with counter mode

Hat mich schon Nerven gekostet, vor allem wenn man mit Zeit-Differenzen 
rechnen will und für die Berücksichtigung von Überlaufen nicht Modulo 
2^32 sondern 2^24 rechnen muss.

/edit:
In der delta_time Klasse musst du das entsprechend berücksichtigen, das 
fehlt noch.

  Michael

: Bearbeitet durch User
von Torsten R. (Firma: Torrox.de) (torstenrobitzki)


Lesenswert?

Michael D. schrieb:

> Danke, ich schau es mir mal an. Ich stehe noch ganz am Anfang von BLE.
> Das einzige was ich bisher gemacht habe ist ein Scanner für ANT.

das klingt spannend, dass hätte ich letztes Jahr gut gebrauchen können.

> Der nrf51822 / 422 unterstützt keine 32-Bit Timer, sondern höchstens 24
> Bit. Das steht allerdings erst in der "Product Specification"

Ich habe gerade noch mal in der PS V2.1 für nrf51422 geguckt, da steht 
keine solche Einschränkung (oder ich finde sie nicht). Vielleicht gilt 
das nur für den 51822, mit dem habe ich mich noch nicht beschäftigt.

> In der delta_time Klasse musst du das entsprechend berücksichtigen, das
> fehlt noch.

die delta_time Klasse ist von der Hardware los gelöst und ist eigentlich 
nicht viel mehr als ein typsicherer Integer zur Darstellung von Zeiten 
im µs-Bereich.

Da sich der link layer slave immer wieder auf den Master synchronisieren 
muss, wollte ich den timer immer wieder zu diesen 
Synchronisations-Punkte auf 0 setzen.

Dann müsste der Timer maximal das maximale Interval mal der maximalen 
slave latency (die erlaubte Anzahl an connection events, in denen der 
Slave nicht auf den Master antwortet) abdecken können. Interval kann 
maximal 4s sein, slave latency maximal 499.

Das wären dann 1996s bzw. 1996 * 10^6µs. lb(1996 * 10^6) = 30,89. Ups, 
wird knapp ;-) Muss also ein 32bit Zähler sein, ansonsten müsste man die 
Auflösung niedriger machen, oder auf slave latency verzichten, oder 
Zähler-Überläufe zählen.

von Michael D. (nospam2000)


Lesenswert?

Torsten R. schrieb:
> Ich habe gerade noch mal in der PS V2.1 für nrf51422 geguckt, da steht
> keine solche Einschränkung (oder ich finde sie nicht)

Stimmt, die stand nur in der Version 1.0 der Product Spec des nRF51822.
In den Product Change Notifications ("nRF51822-PCN v1 0.pdf") steht 
drin, dass sie die Kapitel geändert haben:
"Timer0 now supports bit modes 8,16,24, and 32. This will also affect 
the default bit mode."

Mein Chip hat den Build-Code QFAAC0, das entspricht der IC-Revision 1. 
Für diese Revision gilt laut 
"nRF51_Series_Compatibility_Matrix_v2.1.pdf" noch die Product Spec 1.3 
und das Reference Manual 1.1.

Ich hatte mich  gewundert, dass mein Code nicht funktioniert und mir 
dann die Timer-Werte ausgeben lassen, da waren die oberen 8 Bit immer 0.

Ein nRF51422 Modul hab ich noch keins um das zu testen, die sind auf 
ebay und AliExpress noch sehr rar.

Man muss daher wohl genau unterscheiden für welche IC Revision man 
entwickelt und die entsprechenden PSs und RMs verwenden. Das war mir 
bisher nicht klar. Die alten Versionen findet man auch garnicht mehr 
Online.

  Michael

von Torsten R. (Firma: Torrox.de) (torstenrobitzki)


Lesenswert?

Michael D. schrieb:
> Ein nRF51422 Modul hab ich noch keins um das zu testen, die sind auf
> ebay und AliExpress noch sehr rar.

Hier bei mouser gibt es welche: 
http://www.mouser.de/Search/ProductDetail.aspx?qs=4PbAv7ewtYzcFV5T1iMmMg%3d%3d

Kommt quasi mit JLink. Ich habe das Vorgänger-Model.

von Torsten R. (Firma: Torrox.de) (torstenrobitzki)


Lesenswert?

Juhu, der Link Layer läuft in der jetzigen Version recht stabil :-) 
Getestet habe ich das jetzt mit einem iOS Client und einem unter OS/X. 
Falls jemand die Möglichkeit hat, das erst Beispiel 
(https://github.com/TorstenRobitzki/bluetoe/tree/master/examples/nrf51; 
Target thermometer.elf) mal gegen einen anderen Client zu halten und zu 
berichten, würde ich mich riesig freuen :-)

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
Noch kein Account? Hier anmelden.