Files
DataRouter/datarouter.c
T
2026-07-26 01:40:05 +08:00

189 lines
5.2 KiB
C
Raw 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 datarouter.c
* @brief 数据路由库 —— 实现
*
* 端口表:固定大小数组,每个端口存储报文类型 + handler 列表。
* 发送触发函数逐一调用端口上注册的全部 handler,实现一对多广播。
*/
#include "datarouter.h"
#include <string.h>
#include <stdio.h>
#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];
}