- Python 98.5%
- Shell 1.3%
- Dockerfile 0.2%
| app/modem_broker | ||
| catalog | ||
| config | ||
| deploy | ||
| docs | ||
| tests | ||
| .dockerignore | ||
| .gitignore | ||
| CHANGELOG.md | ||
| compose.yaml | ||
| Dockerfile | ||
| LICENSE | ||
| MANIFEST.sha256 | ||
| README.md | ||
| requirements-test.txt | ||
| requirements.txt | ||
| VERSION | ||
Modem Broker
Modem Broker — сервис-посредник для Huawei HiLink, который координирует работу нескольких приложений с одним физическим модемом.
Его основная задача — принимать запросы от разных клиентов, складывать их в общую ограниченную FIFO-очередь и выполнять через единственный обработчик очереди для каждого модема. Это исключает параллельные обращения к Huawei API и гонки при работе с общей сессией и проверочным токеном устройства.
Текущая версия: 1.0.3.
Зачем он нужен
Huawei HiLink использует общую сессию устройства. Когда несколько приложений независимо обращаются к одному модему — например, читают SMS, отправляют сообщения, получают состояние сети или выполняют служебные операции — они начинают конкурировать за одну и ту же сессию и проверочный токен.
Modem Broker выносит эту координацию в отдельный сервис:
- одна последовательная очередь на физический модем;
- один обработчик, выполняющий обращения к Huawei строго по очереди;
- каждый HTTP-клиент ждёт результат именно своей операции;
- сессионные данные Huawei (
SesTokInfo, cookie и проверочный токен) поддерживаются централизованно; - повтор одинаковой уже выполняющейся изменяющей операции может присоединиться к ней вместо второго фактического POST-запроса;
- состояния изменяющих операций хранятся в SQLite для повторной выдачи результата и ручного восстановления;
- операция с неоднозначным итогом не повторяется автоматически.
Дополнительно Modem Broker умеет разграничивать права клиентов: профили, разрешённые операции, ограничения SMS, строгая проверка XML и сетевое разделение позволяют использовать его не только как диспетчер очереди, но и как контролируемую точку доступа к API модема.
Архитектура
клиент A ─┐
клиент B ─┼──> Modem Broker ───> FIFO-очередь ───> обработчик ───> Huawei HiLink
клиент C ─┘ │
├── общая сессия
├── файлы cookie
└── токен проверки
Modem Broker ───> SQLite
└── состояние операций
До постановки в очередь Modem Broker определяет клиента, проверяет его разрешения и валидирует запрос. Эти механизмы дополняют основную задачу сериализации и позволяют разным клиентам иметь разные права.
Клиентский HTTP-интерфейс использует поддерживаемое подмножество маршрутов Huawei /api/....
Подробнее: docs/ARCHITECTURE.md.
Требования
Для рекомендуемого развёртывания через Docker нужен Docker Engine с модулем Docker Compose 2.33.1 или новее: compose.yaml использует параметр gw_priority.
Для запуска тестов и системного развёртывания через systemd нужен Python 3.11 или новее. На Debian 12/13 для создания виртуального окружения установите пакет python3-venv. Тестовые зависимости не следует устанавливать в системный Python через pip; используйте отдельное виртуальное окружение.
Варианты развёртывания
Поддерживаются два варианта.
Docker Compose — рекомендуемый
Схема использует отдельную RPC-сеть между Modem Broker и клиентами и отдельную сеть для выхода к модему. Так проще закрепить постоянные IPv4-адреса клиентов и отделить клиентский трафик от доступа к Huawei.
Установка через Docker Compose
systemd + виртуальное окружение Python
Modem Broker может работать как обычный системный сервис без Docker. Этот вариант подходит, если клиенты приходят к сервису с различимыми и постоянными IPv4-адресами, а доступ к модему отдельно регулируется межсетевым экраном.
Общие рекомендации по выбору варианта: docs/INSTALL.md.
Быстрый запуск Docker
cp config/broker.example.toml config/broker.toml
mcedit config/broker.toml
mkdir -p state
chown 10003:10003 state
chmod 0700 state
./deploy/preflight.sh
docker compose build
docker compose up -d
Перед запуском создайте сети по инструкции и согласуйте IP-адреса между compose.yaml, broker.toml и клиентскими контейнерами.
Конфигурация
Основной рабочий файл:
config/broker.toml
В репозитории есть два примера:
config/broker.example.toml пример для Docker Compose
config/broker.systemd.example.toml пример для systemd
Клиент определяется по фактическому исходному IPv4-адресу и получает профиль. Профиль задаёт разрешённые операции и дополнительные ограничения.
Пример ограниченного профиля:
[profiles.restricted]
allow = ["session", "sms.list", "sms.send", "sms.delete"]
sms_box_types = [2]
sms_delete_sent_only = true
sms_max_read_count = 50
sms_max_recipients = 1
sms_recipient_patterns = ['^\+[1-9][0-9]{7,14}$']
device_control_values = []
Описание всех параметров: docs/CONFIGURATION.md.
Очередь и состояния операций
Для каждого настроенного модема создаются одна ограниченная FIFO-очередь и один обработчик. Несколько HTTP-клиентов могут отправлять запросы одновременно, но обращения к Huawei выполняются последовательно.
Для изменяющих операций Modem Broker использует SQLite:
ожидает в памяти
↓
running — состояние сохранено перед фактическим POST-запросом
↓
succeeded / rejected / unknown
Если после фактического POST-запроса невозможно однозначно определить результат, операция получает состояние unknown. Автоматического повтора нет, потому что модем уже мог выполнить запрос.
Подробнее: docs/DATABASE.md.
Многострочные SMS
Многострочные SMS поддерживаются. Перед вычислением <Length> клиент должен нормализовать окончания строк до LF (\n).
XML 1.0 преобразует CRLF и одиночный CR в LF при разборе. Поэтому <Length>, вычисленный по исходному тексту с CRLF, может не совпасть с длиной строки после разбора и привести к ответу:
HTTP 400
sms_length_mismatch
Modem Broker намеренно не исправляет неверный <Length> автоматически.
Подробнее: docs/API.md.
Дополнительное разграничение доступа
Профили и разрешения позволяют ограничить клиенту доступное подмножество Huawei API, например:
- разрешить чтение только определённых ящиков SMS (
BoxType); - разрешить отправку только заданным получателям;
- запретить
device.control; - разрешить удаление только отправленных SMS.
При Docker-развёртывании RPC-сеть рекомендуется делать internal, назначать клиентам постоянные IPv4-адреса и удалять у клиентских контейнеров CAP_NET_RAW и CAP_NET_ADMIN.
Это дополнительный уровень контроля. Основная функция Modem Broker — корректная последовательная работа нескольких систем с одним модемом.
Подробнее: docs/SECURITY.md.
Тесты
python3 -m venv .test-venv
.test-venv/bin/pip install -r requirements-test.txt
PYTHONDONTWRITEBYTECODE=1 PYTHONPATH=app:tests \
.test-venv/bin/python -m unittest discover -s tests -v
Набор тестов проверяет правила доступа, XML-контракт, обработку HTTP-запросов, FIFO-очередь и сериализацию, восстановление SQLite, состояния UNKNOWN, ограничения получателей и интеграционный сценарий с тестовым Huawei API.
Документация
- Установка
- Docker Compose
- systemd
- Архитектура
- Конфигурация
- API
- SQLite и состояния операций
- Эксплуатация
- Дополнительные меры безопасности
- Каталог Huawei API
- История изменений
Лицензия
Проект распространяется по лицензии MIT.
Автор
Разработка: Виталий Егоров
Электронная почта: egorowitaliy@gmail.com