HM-10 Bluetooth 4.0 LE mit dem Computer verbinden

Das UART Bluetooth 4.0 Modul HM-10 habe ich bisher nur mit meinem iPhone und einem weiteren HM-10 verbunden. Da auf lange Sicht jedoch auch eine Verbindung mit einem Computer nötig war, habe ich mir den CSR 4.0 USB Dongle für etwa 5 Euro aus China gekauft. Er ist vollständig Linux kompatibel und lässt sich auch, wenn man einmal weiß wie, problemlos mit einem HM-10 oder anderen Bluetooth 4.0 Geräten verbinden. Leider ist das dafür erforderliche Paket bluez in den letzten Jahren sehr schnell gewachsen und hat sich genauso stark verändert. Das schlägt sich nun in völlig abweichenden Konfigurationsabläufen für die einzelnen (Bluetooth) Versionen als auch in einem wunderbaren Versionschaos nieder.

Daher weise ich gleich zu Beginn des Artikels darauf hin, dass ich für meine Tests die bluez Version 5.23 verwendet habe. Um Bluetooth 4.0 LE nutzen zu können, ist mindestens Version 5 erforderlich. In Debian 8 (Jessie) kann bluez 5 problemlos über die Paketquellen installiert werden:

sudo apt-get install bluez

Auf einem meiner Linux Mint 17.2 Rechner, die ich derzeit auf Debian umstelle, ist in den Paketquellen lediglich die Version 4.101 vorhanden. Daher funktionierte die Einrichtung dort nicht. Benutzer einer Distribution mit veraltetem Bluez müssen wohl oder übel selbst kompillieren. Da ich das aufgrund des Umstiegs auf Debian nicht getestet habe, kann ich dazu keine Anleitung liefern.

Zusätzlich kann es noch erforderlich sein das Paket bluetooth zu installieren. Dies geschieht über

sudo apt-get install bluetooth

Jetzt kann die Verbindung im wesentlichen auch schon hergestellt werden. Dazu bringe ich das HM-10 Modul jedoch mittels AT Befehlen erstmal in die Werkeinstellungen zurück. Den Grund werde ich gleich erklären.

AT+RENEW
AT+RESET

Nun müssen wir als erstes die MAC Adresse des HM-10 erfahren. Die könnten wir natürlich per AT Befehl auslesen, besser ist es allerdings sie direkt per Scan abzufragen. So sind wir sicher, dass die Bluetooth Kommunikation grundsätzlich funktioniert. Dazu rufen wir auf der Kommandozeile das bluez tool bluetoothctl auf. Durch aktivieren des Scans mit scan on werden alle erreichbaren Bluetooth Geräte angezeigt. Es sollte auch das HM-10 mit dem Namen HMSoft auftauchen. Anschließend sollte der scan per scan off wieder abgeschaltet und bluetoothctl mit quit verlassen werden.

robin@t520-debian:~$ bluetoothctl
[NEW] Controller 00:1A:7D:DA:71:13 t520-debian [default]
[bluetooth]# scan on
Discovery started
[CHG] Controller 00:1A:7D:DA:71:13 Discovering: yes
[NEW] Device 54:4A:16:25:82:12 HMSoft
[bluetooth]# scan off
[CHG] Device 54:4A:16:25:82:12 RSSI is nil
Discovery stopped
[CHG] Controller 00:1A:7D:DA:71:13 Discovering: no
[bluetooth]# quit
[DEL] Controller 00:1A:7D:DA:71:13 t520-debian [default]
robin@t520-debian:~$ 

Wie zu erkennen ist, lautet die Mac Adresse des Moduls mit dem Namen HMSoft 54:4A:16:25:82:12.

Anschließend kann eine Verbindung über GATTTOOL aufgebaut werden. Ich verwende an dieser Stelle den Interactive Mode, der mit dem Parameter -I aktiviert wird. Dazu wird der Befehl gatttool unter Angabe der Mac Adresse aufgerufen:

gatttool -b <MAC Adresse> -I

In der nun bereitstehenden interaktiven Shell, kann die Verbindung mit dem Befehl connect aufgebaut werden. Wirklich nutzbar ist die Verbindung zur Kommunikation jetzt allerdings noch nicht. Lediglich Eingaben, die wir über einen USB UART Adapter und das HM-10 an den USB Dongle schicken, werden bereits als HEX Codes angezeigt. Zurückschreiben können wir noch nicht.

robin@t520-debian:~$ gatttool -b 54:4A:16:25:82:12 -I
[54:4A:16:25:82:12][LE]> connect
Attempting to connect to 54:4A:16:25:82:12
Connection successful
Notification handle = 0x0012 value: 68 74 74 70 3a 2f 2f 62 6c 6f 67 2e 73 6d 61 72 74 6e 6f 6f 
Notification handle = 0x0012 value: 62 2e 64 65 2f 
[54:4A:16:25:82:12][LE]> 

Wer als erstes den Inhalt der Daten entschlüsselt, erhält einen Eintrag in der dann einzurichtenden “Fall of Hame”. Ergebnisse gerne in den Kommentaren oder per Email. Schwer ist das nicht.

In vorherigen Bluetooth Versionen gab es spezifizierte und feste Profile, wie Internet Modems, Datenaustausch oder eine Serielle Konsole. Seit Bluetooth 4.0 ist das anders. Inzwischen gibt es zwar immer noch spezifierte Dienste, jedoch kann jeder seinen eigenen Dienst spezifizieren wie Apple mit ANCS. Dienste lassen sich nur noch über ihre UUID erkennen. So erfolgt der serielle Datenaustausch laut Datenblatt des HM-10 auf Seite 4 über Service: Central & Peripheral UUID FFE0,FFE1. Außerdem wird erwähnt, dass die UUID standardmäßg auf FFE1 eingestellt ist, sie aber per AT Befehl auf FFE0 gesetzt werden kann. Da wir in diesem Fall das HM-10 als Peripheral betreiben, interessiert uns die UUID FFE1. Wie unschwer zu erkennen handelt es sich dabei um eine hexadezimale Darstellung.

Zu jeder UUID wird ein handle erzeugt, auf dem wir Daten empfangen und senden können. Um nun also Daten senden zu können, müssen wir zunächst den zur UUID passenden handle herausfinden. Unter der Annahme, dass wir uns immer noch im interaktiven Modus von gatttool befinden, können wir jetzt über den Befehl primary die verwendeten Dienste abfragen. Sollte es zu Problemen kommen, muss die Verbindung erneut hergestellt werden, da das HM-10 die Verbindung nach kurzer Zeit wieder schließt, falls keine Abfrage nach den Diensten erfolgte.

[54:4A:16:25:82:12][LE]> primary
attr handle: 0x0001, end grp handle: 0x000b uuid: 00001800-0000-1000-8000-00805f9b34fb
attr handle: 0x000c, end grp handle: 0x000f uuid: 00001801-0000-1000-8000-00805f9b34fb
attr handle: 0x0010, end grp handle: 0xffff uuid: 0000ffe0-0000-1000-8000-00805f9b34fb

Der Dienst ist bereits in der letzten Zeile zu sehen. Über char-desc können wir nun die handles zu den UUIDs abfragen:

[54:4A:16:25:82:12][LE]> char-desc
handle: 0x0001, uuid: 00002800-0000-1000-8000-00805f9b34fb
handle: 0x0002, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x0003, uuid: 00002a00-0000-1000-8000-00805f9b34fb
handle: 0x0004, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x0005, uuid: 00002a01-0000-1000-8000-00805f9b34fb
handle: 0x0006, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x0007, uuid: 00002a02-0000-1000-8000-00805f9b34fb
handle: 0x0008, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x0009, uuid: 00002a03-0000-1000-8000-00805f9b34fb
handle: 0x000a, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x000b, uuid: 00002a04-0000-1000-8000-00805f9b34fb
handle: 0x000c, uuid: 00002800-0000-1000-8000-00805f9b34fb
handle: 0x000d, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x000e, uuid: 00002a05-0000-1000-8000-00805f9b34fb
handle: 0x000f, uuid: 00002902-0000-1000-8000-00805f9b34fb
handle: 0x0010, uuid: 00002800-0000-1000-8000-00805f9b34fb
handle: 0x0011, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x0012, uuid: 0000ffe1-0000-1000-8000-00805f9b34fb
handle: 0x0013, uuid: 00002902-0000-1000-8000-00805f9b34fb
handle: 0x0014, uuid: 00002901-0000-1000-8000-00805f9b34fb

Auf der Suche nach der UUID ffe1 fällt uns handle 0x0012 auf. Schreiben wir nun über char-write-req auf diesen handle, so können wir das Ergebnis in der seriellen Konsole des CP2012 sehen.

char-write-req <handle> <value>

Der Wert (value) muss ebenso wie der handle hexadezimal angegeben werden. Um die Ziffer 1 zu senden muss der entsprechende ASCII Code 31 gesendet werden. Konkret sähe dies so aus:

[54:4A:16:25:82:12][LE]> char-write-req 0x0012 303132
Characteristic value was written successfully

In diesem Fall wurde die Ziffernfolge 012 übertragen und das “Rätsel” sollte sich lösen lassen.

Pin Code

Bis hier hin war noch alles recht einfach. Nun erhöhe ich allerdings den Schwierigkeitsgrad und möchte einen Pin Code und Paring einsetzen. Dazu trenne ich die Verbindung erstmal über disconnect und verlasse gatttool dan per quit:

[54:4A:16:25:82:12][LE]> disconnect
[54:4A:16:25:82:12][LE]> quit
robin@t520-debian:~$ 

Nun konfiguiere ich den HM-10 über die serielle Konsole so, dass Pairing verwendet wird und ich einen Pin Code einsetze:

AT+TYPE3
AT+PASS536438
AT+RESET

Würden wir jetzt versuchen uns mit gatttool zu verbinden, würde die Verbindung fehlschlagen. Stattdessen müssen wir das Pairing durchführen. Dafür wird wieder bluetoothctl verwendet:

robin@t520-debian:~$ bluetoothctl
[NEW] Controller 00:1A:7D:DA:71:13 t520-debian [default]
[bluetooth]# agent on
Agent registered
[bluetooth]# default-agent
Default agent request successful
[bluetooth]# scan on
Discovery started
[CHG] Controller 00:1A:7D:DA:71:13 Discovering: yes
[NEW] Device 54:4A:16:25:82:12 HMSoft
[CHG] Device 54:4A:16:25:82:12 RSSI: -70
[CHG] Device 54:4A:16:25:82:12 RSSI: -61
[bluetooth]# scan off
[CHG] Device 54:4A:16:25:82:12 RSSI is nil
Discovery stopped
[CHG] Controller 00:1A:7D:DA:71:13 Discovering: no
[bluetooth]# connect 54:4A:16:25:82:12
Attempting to connect to 54:4A:16:25:82:12
[CHG] Device 54:4A:16:25:82:12 Connected: yes
Connection successful
[CHG] Device 54:4A:16:25:82:12 UUIDs:
    00001800-0000-1000-8000-00805f9b34fb
    00001801-0000-1000-8000-00805f9b34fb
    0000ffe0-0000-1000-8000-00805f9b34fb
[bluetooth]# pair 54:4A:16:25:82:12
Attempting to pair with 54:4A:16:25:82:12
[CHG] Device 54:4A:16:25:82:12 Paired: yes
Pairing successful
[bluetooth]# disconnect 54:4A:16:25:82:12
Attempting to disconnect from 54:4A:16:25:82:12
[bluetooth]# quit
Agent unregistered
[DEL] Controller 00:1A:7D:DA:71:13 t520-debian [default]

Ich weiß nicht warum, aber das Paring gelingt ohne Eingabe des Pin Codes. Auf dem iPhone muss er seltsamerweise eingegeben werden. Jetzt kann wieder eine Verbindung im gatttool aufgebaut werden:

robin@t520-debian:~$ gatttool -b 54:4A:16:25:82:12 -I
[54:4A:16:25:82:12][LE]> sec-level medium
[54:4A:16:25:82:12][LE]> connect
Attempting to connect to 54:4A:16:25:82:12
Connection successful
[54:4A:16:25:82:12][LE]> primary
attr handle: 0x0001, end grp handle: 0x000b uuid: 00001800-0000-1000-8000-00805f9b34fb
attr handle: 0x000c, end grp handle: 0x000f uuid: 00001801-0000-1000-8000-00805f9b34fb
attr handle: 0x0010, end grp handle: 0xffff uuid: 0000ffe0-0000-1000-8000-00805f9b34fb
[54:4A:16:25:82:12][LE]> char-desc
handle: 0x0001, uuid: 00002800-0000-1000-8000-00805f9b34fb
handle: 0x0002, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x0003, uuid: 00002a00-0000-1000-8000-00805f9b34fb
handle: 0x0004, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x0005, uuid: 00002a01-0000-1000-8000-00805f9b34fb
handle: 0x0006, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x0007, uuid: 00002a02-0000-1000-8000-00805f9b34fb
handle: 0x0008, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x0009, uuid: 00002a03-0000-1000-8000-00805f9b34fb
handle: 0x000a, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x000b, uuid: 00002a04-0000-1000-8000-00805f9b34fb
handle: 0x000c, uuid: 00002800-0000-1000-8000-00805f9b34fb
handle: 0x000d, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x000e, uuid: 00002a05-0000-1000-8000-00805f9b34fb
handle: 0x000f, uuid: 00002902-0000-1000-8000-00805f9b34fb
handle: 0x0010, uuid: 00002800-0000-1000-8000-00805f9b34fb
handle: 0x0011, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x0012, uuid: 0000ffe1-0000-1000-8000-00805f9b34fb
handle: 0x0013, uuid: 00002902-0000-1000-8000-00805f9b34fb
handle: 0x0014, uuid: 00002901-0000-1000-8000-00805f9b34fb
[54:4A:16:25:82:12][LE]> char-write-req 0x0012 303132
Characteristic value was written successfully
[54:4A:16:25:82:12][LE]> disconnect
[54:4A:16:25:82:12][LE]> quit
robin@t520-debian:~$ 

Im Grunde finden die gleichen Aufrufe wie vorhin statt, allerdings muss diesmal die Sicherheitsstufe mit sec-level medium auf medium gesetzt werden. Theoretisch sollte dies auch als Kommandozeilenparameter für gatttool möglich sein. In meinem Test funktionierte dies jedoch nicht.

Wer noch fragen oder Probleme hat, kann sich gerne in den Kommentaren melden. Gerne auch mit Lösung.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.