Files
Ivan I. Ovchinnikov 20384a4dc5 will try to redo back
2026-07-28 22:28:06 +03:00

305 lines
14 KiB
Protocol Buffer
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* @file serial.proto
* @brief Протокол обмена между GUI‑клиентом и backend‑службой
* для работы с последовательным (UART/RS‑232/USBCDC) портом.
*
* Протокол построен на базе **Protocol Buffers 3** и **gRPC**.
* Он покрывает все типичные задачи:
* - перечисление доступных портов;
* - открытие/закрытие порта с полным набором параметров;
* - отправку и приём произвольных пакетов;
* - ведение журнала (лог‑стрим) всех переданных/полученных байтов
* – удобно для отладки и верификации протокола.
*
* Файл снабжён Doxygen‑комментариями, поэтому из него можно
* автоматически получить красивую HTML‑/PDF‑документацию.
*/
syntax = "proto3";
package serial;
/* -------------------------------------------------------------------------- */
/* Enums – вспомогательные типы */
/* -------------------------------------------------------------------------- */
/**
* @enum Parity
* @brief Возможные варианты чётности (parity) при работе с UART.
*
* Имена полностью совпадают с теми, что использует библиотека **pyserial**
* (и, в принципе, большинство C/C++‑библиотек для последовательных портов).
*/
enum Parity {
PARITY_NONE = 0; /// Без чётности.
PARITY_EVEN = 1; /// Чётность чётных битов.
PARITY_ODD = 2; /// Чётность нечётных битов.
PARITY_MARK = 3; /// Маркер (всегда 1).
PARITY_SPACE= 4; /// Пробел (всегда 0).
}
/**
* @enum StopBits
* @brief Конфигурация стоп‑битов.
*
* Значения соответствуют типичным настройкам UART‑контроллера.
*/
enum StopBits {
STOPBITS_ONE = 0; /// Один стоп‑бит.
STOPBITS_ONE_POINT_FIVE = 1; /// Полтора стоп‑бита (реже используется).
STOPBITS_TWO = 2; /// Два стоп‑бита.
}
/**
* @enum StatusCode
* @brief Универсальный набор кодов возврата для большинства RPC‑методов.
*
* При необходимости можно добавить новые коды, но текущего набора достаточно
* для базовых сценариев.
*/
enum StatusCode {
OK = 0; /// Операция выполнена успешно.
INVALID_ARGUMENT = 1; /// Переданы некорректные аргументы (например, отрицательная скорость).
NOT_FOUND = 2; /// Запрашиваемый объект (порт, файл и т.п.) не найден.
INTERNAL_ERROR = 3; /// Внутренняя ошибка сервера (исключение, недоступный ресурс).
NOT_CONNECTED = 4; /// Операция невозможна, т.к. порт не открыт.
}
/* -------------------------------------------------------------------------- */
/* Сообщения – описание данных, передаваемых по gRPC */
/* -------------------------------------------------------------------------- */
/**
* @message SerialDevice
* @brief Информация об одном последовательном порте, доступном в системе.
*
* @param port_name Системное имя порта (например, «COM3», «/dev/ttyUSB0»).
* @param description Человекочитаемое описание, если ОС его предоставляет.
* @param hardware_id Строка‑идентификатор устройства (VID/PID и т.п.).
*/
message SerialDevice {
string port_name = 1;
string description = 2;
string hardware_id = 3;
}
/**
* @message SerialConfig
* @brief Полный набор параметров, необходимый для открытия последовательного порта.
*
* @param port_name Должно совпадать с `SerialDevice.port_name`.
* @param baud_rate Скорость в бодах (например, 9600, 115200 …).
* @param data_bits Количество битов данных (5‑8, обычно 8).
* @param parity Чётность (см. enum @ref Parity).
* @param stop_bits Стоп‑биты (см. enum @ref StopBits).
* @param packet_size Фиксированный размер полезной нагрузки пакета.
* 0 → размер произвольный (по умолчанию).
*/
message SerialConfig {
string port_name = 1;
uint32 baud_rate = 2;
uint32 data_bits = 3;
Parity parity = 4;
StopBits stop_bits = 5;
uint32 packet_size = 6;
}
/**
* @message ConfigResponse
* @brief Ответ на запрос `Open`/`Close`. Содержит статус операции и,
* при ошибке, человекочитаемое сообщение.
*
* @param status Код статуса (см. enum @ref StatusCode).
* @param error Текстовое пояснение, заполнено только если `status != OK`.
*/
message ConfigResponse {
StatusCode status = 1;
string error = 2;
}
/**
* @message Packet
* @brief Описание логической "пакетной" единицы, которую GUI отправляет
* на backend, а backend – в последовательный порт.
*
* Полезная нагрузка (`payload`) передаётся «как есть» (raw‑bytes).
*
* @param seq_id Последовательный номер пакета, генерируется клиентом.
* Удобен для отладки и согласования запрос‑ответ.
* @param payload Бинарные данные, которые действительно окажутся на линии.
* @param tags Необязательная карта «ключ → значение», используемая
* только внутри программы (не попадает в кадр UART).
*/
message Packet {
uint64 seq_id = 1;
bytes payload = 2;
map<string, string> tags = 3;
}
/**
* @message SendResponse
* @brief Ответ на RPC `SendPacket`. Содержит статус, сообщение об ошибке и
* «эхо‑идентификатор», позволяющий клиенту убедиться, что ответ
* относится к конкретному запросу.
*
* @param status Код статуса (см. enum @ref StatusCode).
* @param error Текстовое описание ошибки (если есть).
* @param echo_seq_id Идентификатор пакета, пришедший в запросе.
*/
message SendResponse {
StatusCode status = 1;
string error = 2;
uint64 echo_seq_id = 3;
}
/**
* @message SerialLogEntry
* @brief Описание одного события (TX или RX) на уровне сырых байтов.
*
* Это «протокол‑верификация»: каждая запись сохраняется в журнал
* и может быть передана клиенту в реальном времени.
*
* @param dir Направление трафика (TX – передача, RX – приём).
* @param timestamp Время события в миллисекундах с начала эпохи Unix.
* @param raw_data Точные байты, полученные/отправленные в этом событии.
* @param note Необязательная строка‑комментарий (например,
* «checksum ok», «frame start», …).
*/
message SerialLogEntry {
/** @brief Направление трафика. */
enum Direction {
/** @brief Пакет был отправлен в порт. */
TX = 0;
/** @brief Пакет был получен из порта. */
RX = 1;
}
Direction dir = 1;
uint64 timestamp = 2;
bytes raw_data = 3;
string note = 4;
}
/**
* @message LogStreamRequest
* @brief Параметры подписки на поток журнала.
*
* @param from_start Если true – клиент получает *все* накопленные записи,
* иначе – только новые, появившиеся после установления
* соединения.
*/
message LogStreamRequest {
bool from_start = 1;
}
/**
* @message DeviceList
* @brief Обёртка, возвращающая список найденных последовательных портов.
*
* @param devices Список `SerialDevice`.
*/
message DeviceList {
repeated SerialDevice devices = 1;
}
/* -------------------------------------------------------------------------- */
/* Service definition набор RPC‑методов, которые реализует backend */
/* -------------------------------------------------------------------------- */
/**
* @service SerialService
* @brief gRPC‑сервис, предоставляющий весь функционал работы с
* последовательным портом и журналированием.
*
* Каждый метод описан ниже, вместе с его параметрами и возвращаемыми
* типами.
*/
service SerialService {
// ----------------------------------------------------------------------
// Device discovery
// ----------------------------------------------------------------------
/**
* @brief Возвращает список всех последовательных портов, обнаруженных в системе.
*
* @param request Пустое сообщение (`google.protobuf.Empty`).
* @return `DeviceList` массив `SerialDevice`.
*/
rpc ListDevices (google.protobuf.Empty) returns (DeviceList);
// ----------------------------------------------------------------------
// Connection handling
// ----------------------------------------------------------------------
/**
* @brief Открывает (или переоткрывает) последовательный порт с указанными
* параметрами.
*
* @param cfg Полный набор параметров соединения (`SerialConfig`).
* @return `ConfigResponse` статус операции.
*/
rpc Open (SerialConfig) returns (ConfigResponse);
/**
* @brief Закрывает текущий открытый порт (если он был открыт).
*
* @param request Пустое сообщение.
* @return `ConfigResponse` статус операции.
*/
rpc Close (google.protobuf.Empty) returns (ConfigResponse);
/**
* @brief Возвращает конфигурацию, с которой в данный момент открыт порт.
*
* Если порт закрыт, возвращается пустой `SerialConfig`.
*
* @param request Пустое сообщение.
* @return `SerialConfig`.
*/
rpc GetCurrentConfig (google.protobuf.Empty) returns (SerialConfig);
// ----------------------------------------------------------------------
// Packet transmission
// ----------------------------------------------------------------------
/**
* @brief Отправка одного пакета в открытый последовательный порт.
*
* Если в `SerialConfig.packet_size` задан фиксированный размер, то
* длина `payload` должна строго соответствовать этому размеру.
*
* @param pkt Пакет для отправки (`Packet`).
* @return `SendResponse` результат записи в порт.
*/
rpc SendPacket (Packet) returns (SendResponse);
/**
* @brief Получить один пакет из входящего буфера.
*
* Если буфер пуст, сервер возвращает gRPC‑ошибку `NOT_FOUND`.
*
* @param request Пустое сообщение.
* @return `Packet` (или ошибка).
*/
rpc ReceivePacket (google.protobuf.Empty) returns (Packet);
// ----------------------------------------------------------------------
// Logging / protocol verification
// ----------------------------------------------------------------------
/**
* @brief Прямо вставить произвольную запись в журнал.
*
* Полезно для отладки: можно «симулировать» приходящие данные,
* не взаимодействуя с реальным оборудованием.
*
* @param entry Запись журнала (`SerialLogEntry`).
* @return Пустое сообщение (`google.protobuf.Empty`).
*/
rpc LogRaw (SerialLogEntry) returns (google.protobuf.Empty);
/**
* @brief Подписка на поток всех событий журнала (TX и RX).
*
* Поток остаётся открытым до тех пор, пока клиент не отменит RPC.
*
* @param req Параметры подписки (`LogStreamRequest`).
* @return Поток `SerialLogEntry`.
*/
rpc StreamLog (LogStreamRequest) returns (stream SerialLogEntry);
}