--- title: Изучаем протокол принтеров Niimbot description: Изучаем протокол принтеров Niimbot и печатаем этикетки, отправляя пакеты date: 2024-06-29T21:10:28+03:00 draft: false tags: - bluetooth - niimbot - термопечать - Niimbot B1 - Niimbot B110 - реверс-инжиниринг - javascript - typescript - web categories: - reverse-engineering featured_image: miniature.jpg lastmod: 2024-07-26T07:55:58+03:00 telegram_entry_id: "" type: default --- После того, как поигрались с [niimprint](/niimbot-d110-pc), захотелось чего-то большего. У меня появилась идея написать полноценный веб-интерфейс для печати, в котором можно будет и рисовать этикетки, и печатать. Для этого я решил изучить протокол принтеров. ## Структура пакета Сейчас в моём владении два принтера D110 и B1. Вооружившись Wireshark и Android телефоном, снял дампы обмена данными с принтером по bluetooth. Для этого нужно было включить опцию "Bluetooth HCI Snoop Log" в настройках разработчика, а потом на компьютере после печати запустить `adb bugreport `. Изучив пакеты и сверившись с другими открытыми источниками, получилась такая структура пакета: ![niimbot packet](packet.png) * **Prefix** – префикс `0x03`, присутствующий только при одной команде - **Connect**. * **Head** – всегда 2 байта `0x55` `0x55`. * **Command** – ID команды (пакета). * **Data length** – количество байтов данных, идущих далее. * **Data** – непосредственно данные в количестве **Data length**. * **Checksum** – вычисляется с помощью XOR всех байтов от **Command** до последнего байта **Data**. * **Tail** – всегда 2 байта `0xAA` `0xAA`. ## Важно знать ### Протокол обмена данным варьируется между разными моделями В основном это касается набора пакетов при непосредственно печати. Изучив код приложения, можно сделать вывод, что есть пять вариаций протокола + вариации для самих моделей. ![proto files](proto_files.png) ### Вероятно, протокол обмена данными может варьироваться даже в пределах ревизий одной модели Это можно увидеть в декомпилированном коде приложения: ![protocol tasks](protocol_tasks.png) ### Принтер искусственно занижает плотность печати при использовании неправильной или отсутствующей RFID метке Вот тут довольно интересно. Принтеры и приложения ведут себя по разному. **Метки нет вообще**: * **Niimbot Android** - Этикетку создать невозможно в принципе. * **Niimbot Windows** - D110 - не поддерживается, хоть и может печатать по usb. - B1 - печатать можно, игнорируя предупреждения, плотность очень низкая. * **Сторонние проекты** - D110 - печатает без проблем с нужной плотностью. - B1 - печатает с низкой плотностью. **Метка есть, но от бумаги размером, который не поддерживается принтером**: * **Niimbot Android** - D110 - печатать можно, игнорируя предупреждения, плотность очень низкая (подлость самого приложения). - B1 - аналогично с D110. * **Niimbot Windows** - D110 - печатать можно, игнорируя предупреждения, плотность очень низкая. - B1 - печатать можно, игнорируя предупреждения, плотность очень низкая. * **Сторонние проекты** - D110 - печатает без проблем с нужной плотностью. - B1 - аналогично с D110. Что касаемо самой метки - считывание происходит при закрытии крышки. Принтер видит метку даже если она снаружи корпуса. Так что можно просто приложить метку снаружи, закрыть корпус и печатать на чём попало. ## Источники * [Тут](https://github.com/DelphiTeacher/OrangeFreeSDK/tree/master/%E7%B2%BE%E8%87%A3%E6%99%BA%E6%85%A7%E6%A0%87%E7%AD%BE%E6%89%93%E5%8D%B0%E6%9C%BAJCPrint/Client/JCPrintSDK) и [тут](https://github.com/dadrum/niimbot_flutter_plugin/tree/main/Android/app/libs) нашлась библиотека jcprintersdk для Java. Библиотека обфусцирована. * [kjy00302/niimprint](https://github.com/kjy00302/niimprint) - утилита на Python для печати изображений на принтерах niimbot. * [AndBondStyle/niimprint](https://github.com/AndBondStyle/niimprint) - доработанный форк niimprint. Также благодаря автору и человеку с неизвестным мне ником удалось получить актуальную версию jcprintersdk с низкой обфускацией путём декомпиляции Android приложения. * [ayufan/niimprint-web](https://github.com/ayufan/niimprint-web) - малофункциональный, но полезный проект печати через браузер.