Дозиметри Терра-Н, Стора, Gamma Sapiens львівської компанії мають можливість зчитувати інформацію і керувати режимами через Bluetooth. Потрібно зробити станцію моніторингу і передавати дані на сервер, тому розбираємося із протоколом.
Є офіційний додаток, але він немає потрібного функціоналу: логування показників без переміщення і передачі показників на зовнішній сервер.
Опис протоколу розміщений на сайті виробника. Обмін даними відбувається через SPP (Serial Port Profile). Дозиметр виступає ініціатором з’єднання, і підключається до пристрою із назвою, у якого назва починається із CHECKPOINT, далі можуть бути інші символи.
Пакети даних містять переважно заголовок пакету (0x55, 0xAA), код команди, номер пристрою, дані, контрольну суму.
Із алгоритму підрахунку з документація неясно, як рахується.
Опис неповний, є деякі неясності. Тому ідемо у Google Play і завантажуємо GS Ecotest. Активуємо режим розробника, і активуємо Журнал відслідковування Bluetooth HCI.
Запускаємо додаток, підключаємо пристрій, робимо заміри, і відключаємося.
Вимикаємо режим запису, і залежно від версії ос і виробника забираємо журнал. У Samsung набираємо:
*#9900#
Тиснемо RUN DUMPSTATE/LOGCAT/MODEM LOG і COPY TO SDCARD і знаходимо у папці log файл такої назви btsnoop_hci_201907261710.cfa.
Тепер запускаємо Wireshark і відкриваємо файл дампу. Нас цікавить протокол SPP (фільтруємо btspp), який працює поверх RFCOMM, нижче L2CAP.
Назбирали контрольні суми з пакетів, но на CRCCALC жодна не збігається. Запустив дебагер dex файлу і найшов код просто скопіював код. Звичайне сумування. Якщо десь один біт став з 0 на 1, а десь з 1 на 0, то контрольна співпаде.
byte crc(byte arrays[], int sizes){ byte crc = 0; for (int i=0; i<sizes; i++){ int calc = crc + ( arrays[i] & 0xFF); if (calc>255){ crc = calc - 255; }else{ crc = calc; }; }; return crc; }
Пишемо прошивку на ESP32. В процесі дослідження виявлено, що дозиметр шле до 50 пакетів початку обміну, якщо немає відповіді відображається Er06. Якщо не знайдено хоста, відображається помилка Er07. Якщо немає пакета підтвердження в визначений час, то відображається помилка Er04. Помилка Er03 – ?.
Пристрій запам’ятовує mac адресу останнього пристрою, з якого прийшла команда “переключення режиму”(01) із параметром виключення (01):
55 AA 01 00 00 00 00 01 ZZ
Тому при зміні пристроїв час підключення 20 секунд, а не пару секунд, оскільки запускається discovery і шукаються пристрої з назвою CHECKPOINT*.
MAC мого пристрою 33:17:AB:20:09:18 (ECOTEST). В базі виробників префікс не знайдено.
Ловимо пакет “Початок обміну”, даємо на нього відповідь “Підтвердження початку обміну”. Як дозиметр відповість на пакет, шлемо пакет “Переключення режиму роботи” із параметром 02 – вимірювання фону.
55 AA 01 00 00 00 00 02 ZZ
Після цього періодично з періодом до 20 секунд надсилаємо пакет “Запит результатів виміру”:
55 AA 00 00 00 00 00 00 ZZ
на нього з буфера результатів приходить дані у пакеті розміром 22 байти. Його парсимо і виводимо результат вимірів.
Цифри фону, похибки, заряду батареї приходять у 4 байтах у форматі float, який використовується у процесорах TI (MSP430). Формат називається TMS320C30.
В документації написано про тип (зразу розпишемо біти):
Пристрій використовує 32-х бітний формат с плаваючою точкою (назвемо його float MSP430). MSB.31 .23 LSB.0 ┏╍╍╍╍╍╍╍┳╍╍╍╍┳╍╍╍╍╍╍╍╍╍╍╍╍┓ ┃ e.7... e.0 ┃ знак ┃ m.22 ......... m.0 ┃ ┗╍╍╍╍╍╍╍┻╍╍╍╍┻╍╍╍╍╍╍╍╍╍╍╍╍┛ В цьому форматі мантиса представлена 23-ма молодшими бітами. 24-й біт мантиси в представлені числа відсутній. За визначенням цей біт завжди рівний 1 (нормалізоване число). Порядок представлений 8-ми старшими бітами. Порядок «зміщений» на 0x7F. Приклад представлення чисел с плаваючою комою: 0 = 00 00 00 00 = 00000000 00000000 00000000 00000000 +0.5 = 7F 00 00 00 = 01111111 00000000 00000000 00000000 +1 = 80 00 00 00 = 10000000 00000000 00000000 00000000 -1 = 80 80 00 00 = 10000000 10000000 00000000 00000000 +2 = 81 00 00 00 = 10000001 00000000 00000000 00000000 +3 = 81 40 00 00 = 10000001 01000000 00000000 00000000 -3 = 81 C0 00 00 = 10000001 11000000 00000000 00000000
Для переведення у формат IEEE 754 перепакуємо байти, переставивши біти. Використаємо конструкцію
union u_tag{ byte bin[4]; float num; } u;
Запишемо у u.num тестові цифри, і отримаємо у u.bin, байти йдуть у зворотному порядку.
+0.50=00000000 00000000 00000000 00111111 +1.00=00000000 00000000 10000000 00111111 -1.00=00000000 00000000 10000000 10111111 +2.00=00000000 00000000 00000000 01000000 +3.00=00000000 00000000 01000000 01000000 -3.00=00000000 00000000 01000000 11000000
Також в протоколі байти приходять в порядку:
мантисса ст. байт (i+1) порядок (i) мантисса мл. байт (i+3) мантисса ср. байт (i+2)
Вибираємо потрібні дані із пакету, обробляємо і передаємо куди потрібно. Під час підключення:
[BT] Client Connected [BT] dosimeter init: 1800000 type: 7 [br] radiation: 0.19 mkSv 141.42 % 2.41 V 50 % NOT VALID [br] radiation: 0.19 mkSv 100.00 % 2.39 V 50 % NOT VALID [br] radiation: 0.13 mkSv 37.14 % 2.40 V 50 % NOT VALID [br] radiation: 0.14 mkSv 32.44 % 2.38 V 50 % NOT VALID [br] radiation: 0.13 mkSv 30.15 % 2.39 V 50 % NOT VALID [br] radiation: 0.13 mkSv 29.81 % 2.39 V 50 % [br] radiation: 0.12 mkSv 24.08 % 2.38 V 50 % [br] radiation: 0.10 mkSv 24.39 % 2.39 V 50 % [br] radiation: 0.11 mkSv 22.09 % 2.33 V 25 % [br] radiation: 0.10 mkSv 23.45 % 2.35 V 25 % [br] radiation: 0.10 mkSv 23.14 % 2.36 V 50 %
Біт малодостовірності даних зникає десь через 2 хвилини.
При живленні від 3.3 вольта, в протоколі відображається рівень заряду 2.89V. На екрані відображається коректно заряд: всі 4 сегменти.
Тепер дані можна передавати на сервер і відображати на домашньому екрані.
Що я б зробив в такій комунікації:
- Додав підтримку BT4.0 BLE, результат виміру зчитував з регістра. Батареї вистарчало б надовше, ніж на 1 день.
- Дозиметр зробив би сервером, щоб телефон підключався до дозиметра. В меню просто додав би on/off Bluetooth.
- Використав би стандартизований протокол, типу modbus-rtu.
- Контрольну суму 2 байти з Modbus.
- Відмовитися на більшості змінних від float типу.
UPD: ESP32 (TTGO T-Display ESP32) – зчитування через Bluetooth і передача даних на сервер через WebSocket.
UPD: метеостанції із дозиметром у Прип’яті: http://pripyachka.com/data/?info&n=72
UPD: код на GitHub.
adb shell dumpsys bluetooth_manager
Юрій Р. ◯ 0009-0005-3702-9223. (2019). Протокол Терра – підключаємо дозиметр через Bluetooth. Блог UA ID. Взято з: https://blog.uaid.net.ua/connect-dosimeter-bluetooth