2024-07-25 21:06:25 +03:00
---
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
2024-07-26 07:56:18 +03:00
lastmod: 2024-07-26T07:55:58+03:00
2024-07-25 21:06:25 +03:00
telegram_entry_id: ""
type: default
---
После того, как поигрались с [niimprint ](/niimbot-d110-pc ), захотелось чего-то большего. У меня появилась идея написать полноценный веб-интерфейс для печати, в котором можно будет и рисовать этикетки, и печатать. Для этого я решил изучить протокол принтеров.
<!-- more -->
2024-07-25 21:35:25 +03:00
## Структура пакета
Сейчас в моём владении два принтера D110 и B1.
2024-07-25 21:06:25 +03:00
Вооружившись Wireshark и android телефоном, снял дампы обмена данными с принтером по bluetooth. Для этого нужно было включить опцию "Bluetooth HCI Snoop Log" в настройках разработчика, а потом на компьютере после печати запустить `adb bugreport <filename>` .
2024-07-26 07:56:18 +03:00
Изучив пакеты и сверившись с другими открытыми источниками, получилась такая структура пакета:
2024-07-25 21:06:25 +03:00
![niimbot packet ](packet.png )
* **Prefix** – префикс `0x03` , присутствующий только при одной команде - **Connect** .
* **Head** – всегда 2 байта `0x55` `0x55` .
* **Command** – ID команды (пакета).
* **Data length** – количество байтов данных, идущих далее.
* **Data** – непосредственно данные в количестве **Data length** .
* **Checksum** – вычисляется с помощью XOR всех байтов от **Command** до последнего байта **Data** .
2024-07-25 21:35:25 +03:00
* **Tail** – всегда 2 байта `0xAA` `0xAA` .
## Важно знать
### Протокол обмена данным варьируется между разными моделями
2024-07-25 21:40:53 +03:00
В основном это касается набора пакетов при непосредственно печати. Изучив код приложения, можно сделать вывод, что есть пять вариаций протокола + вариации для самих моделей.
![proto files ](proto_files.png )
2024-07-25 21:35:25 +03:00
2024-07-26 07:56:18 +03:00
### Вероятно, протокол обмена данными может варьироваться даже в пределах ревизий одной модели
2024-07-25 21:35:25 +03:00
Это можно увидеть в декомпилированном коде приложения:
2024-07-25 21:40:53 +03:00
![protocol tasks ](protocol_tasks.png )
2024-07-25 21:35:25 +03:00
### Принтер искусственно занижает плотность печати при использовании неправильной или отсутствующей RFID метке
Вот тут довольно интересно. Принтеры и приложения ведут себя по разному.
**Метки нет вообще**:
* **Niimbot Android**
- Этикетку создать невозможно в принципе.
* **Niimbot Windows**
- D110 - не поддерживается, хоть и может печатать по usb.
- B1 - печатать можно, игнорируя предупреждения, плотность очень низкая.
* **Сторонние проекты**
- D110 - печатает без проблем с нужной плотностью.
- B1 - печатает с низкой плотностью.
**Метка есть, но от бумаги размером, который не поддерживается принтером**:
2024-07-26 07:56:18 +03:00
* **Niimbot Android**
2024-07-25 21:35:25 +03:00
- D110 - печатать можно, игнорируя предупреждения, плотность очень низкая (подлость самого приложения).
- B1 - аналогично с D110.
* **Niimbot Windows**
- D110 - печатать можно, игнорируя предупреждения, плотность очень низкая.
- B1 - печатать можно, игнорируя предупреждения, плотность очень низкая.
* **Сторонние проекты**
- D110 - печатает без проблем с нужной плотностью.
- B1 - аналогично с D110.
2024-07-25 21:40:53 +03:00
Что касаемо самой метки - считывание происходит при закрытии крышки.
Принтер видит метку даже если она снаружи корпуса. Так что можно просто приложить метку снаружи, закрыть корпус и печатать на чём попало.