/** * @file datarouter.c * @brief 数据路由库 —— 实现 * * 端口表:固定大小数组,每个端口存储报文类型 + handler 列表。 * 发送触发函数逐一调用端口上注册的全部 handler,实现一对多广播。 */ #include "datarouter.h" #include #include #if defined(__GNUC__) || defined(__clang__) #define DATAROUTER_WEAK __attribute__((weak)) #else #define DATAROUTER_WEAK #endif #ifndef DATAROUTER_MAX_PORTS #define DATAROUTER_MAX_PORTS 64 #endif /** * @struct port_entry_t * @brief 端口表条目 * * @var type 报文类型(DATAROUTER_CHANNEL_xxx / -1) * @var handlers 外设发送 handler 数组 * @var count 当前注册的 handler 数量 * @var in_use 1=已分配,0=空闲 */ typedef struct { int type; datarouter_send_handler_t handlers[DATAROUTER_MAX_HANDLERS_PER_PORT]; int count; uint8_t in_use; } port_entry_t; static port_entry_t ports[DATAROUTER_MAX_PORTS]; static uint8_t initialized; /* ---- 通道元数据(X-macro 展开) ---- */ static const char *channel_names[] = { #define DATAROUTER_CHANNEL(id, desc) #id, DATAROUTER_CHANNELS #undef DATAROUTER_CHANNEL }; static const char *channel_descs[] = { #define DATAROUTER_CHANNEL(id, desc) desc, DATAROUTER_CHANNELS #undef DATAROUTER_CHANNEL }; /* ---- 弱符号接收回调默认实现 ---- */ #define DATAROUTER_CHANNEL(id, desc) \ DATAROUTER_WEAK void datarouter_on_recv_##id( \ uint32_t port_id, const void *data, size_t len) \ { \ (void)port_id; (void)data; (void)len; \ } DATAROUTER_CHANNELS #undef DATAROUTER_CHANNEL /* ---- 发送触发函数实现 ---- */ #define DATAROUTER_CHANNEL(id, desc) \ int datarouter_send_##id(uint32_t port_id, const void *data, size_t len) \ { \ if (!initialized) return -1; \ if (port_id >= DATAROUTER_MAX_PORTS || !ports[port_id].in_use) return -2; \ if (ports[port_id].type != DATAROUTER_CHANNEL_##id) return -3; \ if (ports[port_id].count == 0) return -4; \ for (int _i = 0; _i < ports[port_id].count; _i++) \ ports[port_id].handlers[_i](port_id, data, len); \ return 0; \ } DATAROUTER_CHANNELS #undef DATAROUTER_CHANNEL /* ---- 端口管理 API ---- */ void datarouter_init(void) { if (initialized) return; memset(ports, 0, sizeof(ports)); initialized = 1; } void datarouter_reset(void) { initialized = 0; memset(ports, 0, sizeof(ports)); } datarouter_port_t datarouter_port_create(void) { if (!initialized) return DATAROUTER_INVALID_PORT; for (int i = 0; i < DATAROUTER_MAX_PORTS; i++) { if (!ports[i].in_use) { ports[i].in_use = 1; ports[i].type = -1; ports[i].count = 0; return (datarouter_port_t)i; } } return DATAROUTER_INVALID_PORT; } void datarouter_port_delete(datarouter_port_t port) { if (!initialized) return; if (port < 0 || port >= DATAROUTER_MAX_PORTS) return; ports[port].in_use = 0; } void datarouter_port_set_type(datarouter_port_t port, int channel_id) { if (!initialized) return; if (port < 0 || port >= DATAROUTER_MAX_PORTS || !ports[port].in_use) return; ports[port].type = channel_id; } int datarouter_port_get_type(datarouter_port_t port) { if (!initialized) return -1; if (port < 0 || port >= DATAROUTER_MAX_PORTS || !ports[port].in_use) return -1; return ports[port].type; } int datarouter_port_add_handler(datarouter_port_t port, datarouter_send_handler_t handler) { if (!initialized) return -1; if (port < 0 || port >= DATAROUTER_MAX_PORTS || !ports[port].in_use) return -1; if (ports[port].count >= DATAROUTER_MAX_HANDLERS_PER_PORT) return -2; for (int i = 0; i < ports[port].count; i++) if (ports[port].handlers[i] == handler) return -3; ports[port].handlers[ports[port].count++] = handler; return 0; } int datarouter_port_remove_handler(datarouter_port_t port, datarouter_send_handler_t handler) { if (!initialized) return -1; if (port < 0 || port >= DATAROUTER_MAX_PORTS || !ports[port].in_use) return -1; for (int i = 0; i < ports[port].count; i++) { if (ports[port].handlers[i] == handler) { ports[port].handlers[i] = ports[port].handlers[--ports[port].count]; return 0; } } return -2; } void datarouter_port_clear_handlers(datarouter_port_t port) { if (!initialized) return; if (port < 0 || port >= DATAROUTER_MAX_PORTS || !ports[port].in_use) return; ports[port].count = 0; } int datarouter_port_handler_count(datarouter_port_t port) { if (!initialized) return -1; if (port < 0 || port >= DATAROUTER_MAX_PORTS || !ports[port].in_use) return -1; return ports[port].count; } /* ---- 通道元数据查询 ---- */ int datarouter_channel_count(void) { return DATAROUTER_CHANNEL_COUNT; } const char *datarouter_channel_name(int channel_id) { if (channel_id < 0 || channel_id >= DATAROUTER_CHANNEL_COUNT) return NULL; return channel_names[channel_id]; } const char *datarouter_channel_desc(int channel_id) { if (channel_id < 0 || channel_id >= DATAROUTER_CHANNEL_COUNT) return NULL; return channel_descs[channel_id]; }