/** * @file etcp_api.h * @brief API для приёма-передачи пакетов через ETCP (per-instance bindings) * * Основные функции: * - etcp_send() - отправить пакет в очередь normalizer * - etcp_bind() - подписаться на пакеты с определенным ID * - etcp_int_recv() - коллбэк для сбора пакетов из всех подключений * * Формат кодограмм: * cmd = 0 - пакет для передачи адресату * cmd = 1 - модуль обмена роутинг-таблицами */ #ifndef ETCP_API_H #define ETCP_API_H #include #include "../lib/ll_queue.h" #define ETCP_MAX_BINDINGS 256 // ETCP packet IDs #define ETCP_ID_DATA 0x00 // Пакет для передачи адресату #define ETCP_ID_ROUTE_ENTRY 0x01 // Элемент роутинг-таблицы // Forward declarations struct ETCP_CONN; struct UTUN_INSTANCE; /** * @brief Тип коллбэка для приёма пакетов * @param conn ETCP соединение от которого получен пакет * @param entry Элемент очереди с данными пакета * * @note Коллбэк должен освободить entry через queue_entry_free() * и dgram через queue_dgram_free() после обработки */ typedef void (*etcp_recv_fn)(struct ETCP_CONN* conn, struct ll_entry* entry); // Forward declaration struct ETCP_CONN; struct UTUN_INSTANCE; typedef void (*etcp_cbk_fn)(struct ETCP_CONN* conn, void* arg); /** * @brief Установить callback при создании нового ETCP соединения * * @param instance UTUN instance * @param callback_fn Коллбэк который будет вызван при создании нового соединения * @param arg Аргумент для коллбэка */ void etcp_set_new_conn_cbk(struct UTUN_INSTANCE* instance, etcp_cbk_fn callback_fn, void* arg); /** * @brief Структура bindings для ETCP API (per-instance) */ struct ETCP_BINDINGS { etcp_recv_fn callbacks[ETCP_MAX_BINDINGS]; /**< Массив callbacks, NULL = не установлен */ }; /** * @brief Отправить пакет в очередь normalizer. первый байт кодограммы - cmd (на приёмной стороне bind выберет обработчик по cmd). * * @param conn ETCP соединение * @param entry Элемент очереди с данными для отправки * @return 0 при успехе, -1 при ошибке * * @note Функция забирает ownership entry - вызывающий код не должен * освобождать entry после вызова */ int etcp_send(struct ETCP_CONN* conn, struct ll_entry* entry); /** * @brief Подписаться на все пакеты с указанным ID для данного instance * * @param inst UTUN instance * @param id Идентификатор пакета (первый байт кодограммы, cmd) * @param callback Коллбэк для обработки пакетов с этим ID * @return 0 при успехе, -1 при ошибке * * @note ID=0 зарезервирован для обычных пакетов данных * @note Можно зарегистрировать только один коллбэк на каждый ID в пределах instance */ int etcp_bind(struct UTUN_INSTANCE* inst, uint8_t id, etcp_recv_fn callback); /** * @brief Отписаться от пакетов с указанным ID для данного instance * * @param inst UTUN instance * @param id Идентификатор пакета * @return 0 при успехе, -1 если binding не найден */ int etcp_unbind(struct UTUN_INSTANCE* inst, uint8_t id); /** * @brief Установить callback на событие готовности соединения * * После создания подключения надо дождаться conn_ready (соединение инициализировано). * Только после этого можно передавать сообщения. Иначе сообщения могут потеряться. * conn_ready может вызываться несколько раз (после каждого переподключения). * * @param conn ETCP соединение * @param callback_fn Коллбэк который будет вызван при готовности * @param arg Аргумент для коллбэка */ void etcp_conn_set_ready_cbk(struct ETCP_CONN* conn, etcp_cbk_fn callback_fn, void* arg); void etcp_conn_set_up_cbk (struct ETCP_CONN* conn, etcp_cbk_fn callback_fn, void* arg); void etcp_conn_set_down_cbk (struct ETCP_CONN* conn, etcp_cbk_fn callback_fn, void* arg); /** * @brief Внутренняя функция etcp: Коллбэк для очередей output ll_queue normalizer * * Собирает пакеты из всех подключений и отправляет в bind->cbk * по ID (первый байт кодограммы). * * @param queue Очередь из которой получен пакет * @param arg Аргумент - указатель на ETCP_CONN * * @note Этот коллбэк устанавливается автоматически при создании * ETCP подключения через pn_init() */ void etcp_int_recv(struct ll_queue* queue, void* arg); #endif // ETCP_API_H