BJYmAs<#T-=n`&o5R8k*Qiz6qH@X
zZVqA6rR>iw7cEm)2Q3kh+K{9e#f<#^es>?$lhMyW}D?jHrBL!3Zd)%t%y`Lpf-
diff --git a/datarouter.c b/datarouter.c
index fd93586..b3064b3 100644
--- a/datarouter.c
+++ b/datarouter.c
@@ -1,6 +1,5 @@
/**
* @file datarouter.c
- * @brief 数据路由库 —— 实现
*/
#include "datarouter.h"
@@ -18,7 +17,6 @@
typedef struct {
int send_type;
- int recv_type;
datarouter_send_handler_t handlers[DATAROUTER_MAX_HANDLERS_PER_PORT];
int count;
uint8_t in_use;
@@ -27,7 +25,7 @@ typedef struct {
static port_entry_t ports[DATAROUTER_MAX_PORTS];
static uint8_t initialized;
-/* ---- 发送能力元数据 ---- */
+/* ---- 元数据 ---- */
static const char *send_names[] = {
#define DATAROUTER_SEND(id, desc) #id,
@@ -41,8 +39,6 @@ static const char *send_descs[] = {
#undef DATAROUTER_SEND
};
-/* ---- 接收能力元数据 ---- */
-
static const char *recv_names[] = {
#define DATAROUTER_RECV(id, desc) #id,
DATAROUTER_RECV_CAPABILITIES
@@ -55,29 +51,31 @@ static const char *recv_descs[] = {
#undef DATAROUTER_RECV
};
-/* ---- 弱符号接收回调默认实现 ---- */
+/* ---- 弱符号接收回调 ---- */
#define DATAROUTER_RECV(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; \
- }
+ { (void)port_id; (void)data; (void)len; }
DATAROUTER_RECV_CAPABILITIES
#undef DATAROUTER_RECV
-/* ---- 发送触发函数实现 ---- */
+/* ---- 发送触发函数 ---- */
#define DATAROUTER_SEND(id, desc) \
- int datarouter_send_##id(uint32_t port_id, const void *data, size_t len) \
+ int datarouter_send_##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].send_type != DATAROUTER_SEND_##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; \
+ int called = 0; \
+ for (uint32_t _p = 0; _p < DATAROUTER_MAX_PORTS; _p++) { \
+ if (!ports[_p].in_use) continue; \
+ if (ports[_p].send_type != DATAROUTER_SEND_##id) continue; \
+ for (int _h = 0; _h < ports[_p].count; _h++) { \
+ ports[_p].handlers[_h](_p, data, len); \
+ called = 1; \
+ } \
+ } \
+ return called ? 0 : -2; \
}
DATAROUTER_SEND_CAPABILITIES
#undef DATAROUTER_SEND
@@ -104,7 +102,6 @@ datarouter_port_t datarouter_port_create(void)
if (!ports[i].in_use) {
ports[i].in_use = 1;
ports[i].send_type = -1;
- ports[i].recv_type = -1;
ports[i].count = 0;
return (datarouter_port_t)i;
}
@@ -133,20 +130,6 @@ int datarouter_port_get_send_type(datarouter_port_t port)
return ports[port].send_type;
}
-void datarouter_port_set_recv_type(datarouter_port_t port, int cap_id)
-{
- if (!initialized) return;
- if (port < 0 || port >= DATAROUTER_MAX_PORTS || !ports[port].in_use) return;
- ports[port].recv_type = cap_id;
-}
-
-int datarouter_port_get_recv_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].recv_type;
-}
-
int datarouter_port_add_handler(datarouter_port_t port, datarouter_send_handler_t handler)
{
if (!initialized) return -1;
@@ -187,36 +170,10 @@ int datarouter_port_handler_count(datarouter_port_t port)
/* ---- 元数据查询 ---- */
-int datarouter_send_cap_count(void)
-{
- return DATAROUTER_SEND_CAP_COUNT;
-}
+int datarouter_send_cap_count(void) { return DATAROUTER_SEND_CAP_COUNT; }
+const char *datarouter_send_cap_name(int c) { return (c<0||c>=DATAROUTER_SEND_CAP_COUNT)?NULL:send_names[c]; }
+const char *datarouter_send_cap_desc(int c) { return (c<0||c>=DATAROUTER_SEND_CAP_COUNT)?NULL:send_descs[c]; }
-const char *datarouter_send_cap_name(int cap_id)
-{
- if (cap_id < 0 || cap_id >= DATAROUTER_SEND_CAP_COUNT) return NULL;
- return send_names[cap_id];
-}
-
-const char *datarouter_send_cap_desc(int cap_id)
-{
- if (cap_id < 0 || cap_id >= DATAROUTER_SEND_CAP_COUNT) return NULL;
- return send_descs[cap_id];
-}
-
-int datarouter_recv_cap_count(void)
-{
- return DATAROUTER_RECV_CAP_COUNT;
-}
-
-const char *datarouter_recv_cap_name(int cap_id)
-{
- if (cap_id < 0 || cap_id >= DATAROUTER_RECV_CAP_COUNT) return NULL;
- return recv_names[cap_id];
-}
-
-const char *datarouter_recv_cap_desc(int cap_id)
-{
- if (cap_id < 0 || cap_id >= DATAROUTER_RECV_CAP_COUNT) return NULL;
- return recv_descs[cap_id];
-}
+int datarouter_recv_cap_count(void) { return DATAROUTER_RECV_CAP_COUNT; }
+const char *datarouter_recv_cap_name(int c) { return (c<0||c>=DATAROUTER_RECV_CAP_COUNT)?NULL:recv_names[c]; }
+const char *datarouter_recv_cap_desc(int c) { return (c<0||c>=DATAROUTER_RECV_CAP_COUNT)?NULL:recv_descs[c]; }
diff --git a/datarouter.h b/datarouter.h
index 26aa877..ba1163b 100644
--- a/datarouter.h
+++ b/datarouter.h
@@ -4,20 +4,16 @@
*
* ## 概念
*
- * - **发送能力 (Send Capability)**:编译期声明的可发送报文类型
- * - **接收能力 (Recv Capability)**:编译期声明的可接收报文类型
- * - **端口 (Port)**:运行期连接点,独立设置 send_type + recv_type + 外设 handler 列表
+ * - **发送能力**:编译期声明的可发送报文类型,生成 datarouter_send_(data, len)
+ * - **接收能力**:编译期声明的可接收报文类型,生成 datarouter_on_recv_(port, data, len)
+ * - **端口**:运行期创建的连接点,包含 send_type + handler 列表
*
- * ## 使用流程
+ * ## 路由
*
- * 1. 创建 datarouter_config.h 声明发送和接收能力(见 datarouter_config_template.h)
- * 2. 编译时通过 -I 指向你的配置目录;若无,库使用内置默认配置
- * 3. datarouter_init() 初始化
- * 4. port_create() 创建端口
- * 5. port_set_send_type() 设置发送类型 / port_set_recv_type() 设置接收类型
- * 6. port_add_handler() 注册外设发送函数
- * 7. 调 datarouter_send_() 触发发送(库调用所有 handler)
- * 8. 实现 datarouter_on_recv_() 处理接收数据
+ * 调用 datarouter_send_(data, len) 时,库遍历所有端口,
+ * 找到 send_type 匹配的端口,逐一调用其全部 handler。无需指定从哪个端口发送。
+ *
+ * 接收侧由用户自行调用 datarouter_on_recv_(port, data, len) 处理外设收到的数据。
*/
#ifndef DATAROUTER_H
@@ -26,14 +22,6 @@
#include
#include
-/*
- * 配置加载策略:
- * 1. 优先从 include path 搜索 (用户提供的版本)
- * 2. 找不到则回退到库自带的 "datarouter_config.h"(默认配置)
- *
- * 用户只需将自己的 datarouter_config.h 放到项目目录,
- * 编译时添加 -I /path/to/your/config 即可覆盖内置配置。
- */
#if defined(__has_include)
# if __has_include()
# include
@@ -66,7 +54,7 @@ enum datarouter_recv_cap {
DATAROUTER_RECV_CAP_COUNT
};
-/* ========== 外设发送 handler 类型 ========== */
+/* ========== 外设发送 handler ========== */
typedef void (*datarouter_send_handler_t)(uint32_t port_id, const void *data, size_t len);
@@ -74,14 +62,14 @@ typedef void (*datarouter_send_handler_t)(uint32_t port_id, const void *data, si
#define DATAROUTER_MAX_HANDLERS_PER_PORT 4
#endif
-/* ========== 发送触发函数(每个发送能力生成一个) ========== */
+/* ========== 发送触发函数 ========== */
#define DATAROUTER_SEND(id, desc) \
- int datarouter_send_##id(uint32_t port_id, const void *data, size_t len);
+ int datarouter_send_##id(const void *data, size_t len);
DATAROUTER_SEND_CAPABILITIES
#undef DATAROUTER_SEND
-/* ========== 接收回调声明(每个接收能力生成一个,用户实现) ========== */
+/* ========== 接收回调声明 ========== */
#define DATAROUTER_RECV(id, desc) \
void datarouter_on_recv_##id(uint32_t port_id, const void *data, size_t len);
@@ -101,8 +89,6 @@ void datarouter_port_delete(datarouter_port_t port);
void datarouter_port_set_send_type(datarouter_port_t port, int cap_id);
int datarouter_port_get_send_type(datarouter_port_t port);
-void datarouter_port_set_recv_type(datarouter_port_t port, int cap_id);
-int datarouter_port_get_recv_type(datarouter_port_t port);
int datarouter_port_add_handler(datarouter_port_t port, datarouter_send_handler_t handler);
int datarouter_port_remove_handler(datarouter_port_t port, datarouter_send_handler_t handler);
diff --git a/example.c b/example.c
index 2760478..5895b5e 100644
--- a/example.c
+++ b/example.c
@@ -1,93 +1,73 @@
/**
* @file example.c
- * @brief 数据路由库使用示例
*
- * 展示:
- * - 发送能力和接收能力分开声明(sensor 只发送,rtcm 只接收)
- * - 端口独立设置 send_type 和 recv_type
- * - 一个端口可同时拥有发送和接收能力
+ * 调用 datarouter_send_sensor(data, len) 无需指定端口,
+ * 库自动广播到所有 send_type=sensor 的端口。
*/
#include "datarouter.h"
#include
-#include
-
-/* ---- 外设发送 handler ---- */
static void uart_send(uint32_t port_id, const void *data, size_t len)
{
- printf("[UART] port %u: %.*s\n", port_id, (int)len, (const char *)data);
+ printf("[UART port %u] %.*s\n", port_id, (int)len, (const char *)data);
}
static void tcp_send(uint32_t port_id, const void *data, size_t len)
{
- printf("[TCP] port %u: %.*s\n", port_id, (int)len, (const char *)data);
+ printf("[TCP port %u] %.*s\n", port_id, (int)len, (const char *)data);
}
-/* ---- 接收回调实现 ---- */
-
-void datarouter_on_recv_rtcm(uint32_t port_id, const void *data, size_t len)
+static void can_send(uint32_t port_id, const void *data, size_t len)
{
- printf("[RX:rtcm] port %u: %.*s\n", port_id, (int)len, (const char *)data);
+ printf("[CAN port %u] %.*s\n", port_id, (int)len, (const char *)data);
}
void datarouter_on_recv_command(uint32_t port_id, const void *data, size_t len)
{
- printf("[RX:cmd] port %u: %.*s\n", port_id, (int)len, (const char *)data);
+ printf("[RX:cmd port %u] %.*s\n", port_id, (int)len, (const char *)data);
}
int main(void)
{
datarouter_init();
- /* 查询能力 */
- printf("Send capabilities: %d\n", datarouter_send_cap_count());
+ printf("Capabilities:\n");
for (int i = 0; i < datarouter_send_cap_count(); i++)
printf(" SEND [%d] %s - %s\n", i,
datarouter_send_cap_name(i), datarouter_send_cap_desc(i));
- printf("Recv capabilities: %d\n", datarouter_recv_cap_count());
- for (int i = 0; i < datarouter_recv_cap_count(); i++)
- printf(" RECV [%d] %s - %s\n", i,
- datarouter_recv_cap_name(i), datarouter_recv_cap_desc(i));
-
/*
- * 端口 A:只有发送能力 —— 上报传感器数据
+ * 创建两个端口,都设 send_type=sensor,各绑不同外设。
+ * 调用 datarouter_send_sensor() 时两个端口同时触发。
*/
- datarouter_port_t tx_port = datarouter_port_create();
- datarouter_port_set_send_type(tx_port, DATAROUTER_SEND_sensor);
- datarouter_port_add_handler(tx_port, uart_send);
- datarouter_port_add_handler(tx_port, tcp_send);
+ datarouter_port_t p1 = datarouter_port_create();
+ datarouter_port_set_send_type(p1, DATAROUTER_SEND_sensor);
+ datarouter_port_add_handler(p1, uart_send);
+ datarouter_port_add_handler(p1, tcp_send);
- printf("\n--- send sensor (UART + TCP) ---\n");
- datarouter_send_sensor(tx_port, "temperature:25.3", 16);
- /* 该端口没有 recv_type,不能接收任何报文 */
+ datarouter_port_t p2 = datarouter_port_create();
+ datarouter_port_set_send_type(p2, DATAROUTER_SEND_sensor);
+ datarouter_port_add_handler(p2, can_send);
- /*
- * 端口 B:只有接收能力 —— 接收 RTCM 修正
- */
- datarouter_port_t rtcm_port = datarouter_port_create();
- datarouter_port_set_recv_type(rtcm_port, DATAROUTER_RECV_rtcm);
- /* 没有 send_type,也没有 handler —— 不能发送 */
+ /* 不指定端口,自动广播到所有 sensor 端口 */
+ printf("\n--- send_sensor (auto-route to ALL sensor ports) ---\n");
+ datarouter_send_sensor("temperature:25.3", 16);
- printf("\n--- simulate receive RTCM ---\n");
- datarouter_on_recv_rtcm(rtcm_port, "rtcm_data_v3.2", 14);
+ /* 运行时移除一个 handler,下次发送不再触发它 */
+ printf("\n--- remove TCP handler from p1, resend ---\n");
+ datarouter_port_remove_handler(p1, tcp_send);
+ datarouter_send_sensor("temperature:26.1", 16);
- /*
- * 端口 C:同时有收发能力 —— 接收命令 + 上报状态
- */
- datarouter_port_t bi_port = datarouter_port_create();
- datarouter_port_set_send_type(bi_port, DATAROUTER_SEND_status);
- datarouter_port_set_recv_type(bi_port, DATAROUTER_RECV_command);
- datarouter_port_add_handler(bi_port, uart_send);
+ /* 接收侧:用户自行调用回调 */
+ printf("\n--- recv command ---\n");
+ datarouter_on_recv_command(0, "reboot", 6);
- printf("\n--- bidirectional port ---\n");
- datarouter_send_status(bi_port, "status:OK", 9);
- datarouter_on_recv_command(bi_port, "reboot", 6);
+ /* 删除一个端口,触发时不再走它 */
+ printf("\n--- delete p2 (CAN), resend ---\n");
+ datarouter_port_delete(p2);
+ datarouter_send_sensor("temperature:27.0", 16);
- /* 清理 */
- datarouter_port_delete(tx_port);
- datarouter_port_delete(rtcm_port);
- datarouter_port_delete(bi_port);
+ datarouter_port_delete(p1);
return 0;
}
diff --git a/tests/test_datarouter.c b/tests/test_datarouter.c
index 8f895fa..9e81b7b 100644
--- a/tests/test_datarouter.c
+++ b/tests/test_datarouter.c
@@ -1,15 +1,5 @@
/**
* @file test_datarouter.c
- * @brief 数据路由库单元测试
- *
- * 覆盖:
- * - 端口管理
- * - send_type / recv_type 独立设置
- * - 多 handler 增删
- * - 发送调用(一对多广播)
- * - 接收回调
- * - 发送/接收能力元数据各自独立
- * - 错误处理
*/
#include "datarouter.h"
@@ -17,7 +7,7 @@
#include
/* ================================================================
- * 测试框架
+ * 框架
* ================================================================ */
static int _total_run, _total_pass, _total_fail;
@@ -66,19 +56,19 @@ cleanup: \
* ================================================================ */
static int _h_cnt;
-static void _h(uint32_t p, const void *d, size_t l) { (void)p; (void)d; (void)l; _h_cnt++; }
-static void _h_a(uint32_t p, const void *d, size_t l) { (void)p; (void)d; (void)l; _h_cnt++; }
-static void _h_b(uint32_t p, const void *d, size_t l) { (void)p; (void)d; (void)l; _h_cnt++; }
-static void _h_c(uint32_t p, const void *d, size_t l) { (void)p; (void)d; (void)l; _h_cnt++; }
-static void _h_d(uint32_t p, const void *d, size_t l) { (void)p; (void)d; (void)l; _h_cnt++; }
-static void reset_h(void) { _h_cnt = 0; }
+static int _h_port[16];
+static int _h_pos;
+static void _h(uint32_t p, const void *d, size_t l) { (void)d; (void)l; _h_cnt++; if (_h_pos<16) _h_port[_h_pos++]=p; }
+static void _h2(uint32_t p, const void *d, size_t l) { (void)d; (void)l; _h_cnt++; if (_h_pos<16) _h_port[_h_pos++]=p; }
+static void _h3(uint32_t p, const void *d, size_t l) { (void)d; (void)l; _h_cnt++; if (_h_pos<16) _h_port[_h_pos++]=p; }
+static void reset_h(void) { _h_cnt = 0; _h_pos = 0; }
/* ================================================================
* 1. 未初始化
* ================================================================ */
TEST_START(error_uninit)
- CHECK(datarouter_send_sensor(0, "d", 1) == -1, "expected -1");
+ CHECK(datarouter_send_sensor("d", 1) == -1, "expected -1");
TEST_END()
/* ================================================================
@@ -86,7 +76,7 @@ TEST_END()
* ================================================================ */
TEST_START(port_create_basic)
- CHECK(FIXTURE_CREATE(&_fix) >= 0, "create failed");
+ CHECK(FIXTURE_CREATE(&_fix) >= 0, NULL);
TEST_END()
TEST_START(port_create_max)
@@ -106,68 +96,28 @@ TEST_END()
TEST_START(port_default_state)
datarouter_port_t p = FIXTURE_CREATE(&_fix);
- CHECK(datarouter_port_get_send_type(p) == -1, "send_type should be -1");
- CHECK(datarouter_port_get_recv_type(p) == -1, "recv_type should be -1");
- CHECK(datarouter_port_handler_count(p) == 0, "handler count 0");
+ CHECK(datarouter_port_get_send_type(p) == -1, NULL);
+ CHECK(datarouter_port_handler_count(p) == 0, NULL);
TEST_END()
/* ================================================================
- * 3. send_type / recv_type 独立设置
+ * 3. send_type 与 handler
* ================================================================ */
TEST_START(send_type_set_get)
datarouter_port_t p = FIXTURE_CREATE(&_fix);
datarouter_port_set_send_type(p, DATAROUTER_SEND_sensor);
CHECK(datarouter_port_get_send_type(p) == DATAROUTER_SEND_sensor, NULL);
-TEST_END()
-
-TEST_START(recv_type_set_get)
- datarouter_port_t p = FIXTURE_CREATE(&_fix);
- datarouter_port_set_recv_type(p, DATAROUTER_RECV_rtcm);
- CHECK(datarouter_port_get_recv_type(p) == DATAROUTER_RECV_rtcm, NULL);
-TEST_END()
-
-TEST_START(types_independent)
- /* 一个端口同时设置 send_type 和 recv_type,互不干扰 */
- datarouter_port_t p = FIXTURE_CREATE(&_fix);
- datarouter_port_set_send_type(p, DATAROUTER_SEND_sensor);
- datarouter_port_set_recv_type(p, DATAROUTER_RECV_command);
- CHECK(datarouter_port_get_send_type(p) == DATAROUTER_SEND_sensor, NULL);
- CHECK(datarouter_port_get_recv_type(p) == DATAROUTER_RECV_command, NULL);
-TEST_END()
-
-TEST_START(send_type_clear)
- datarouter_port_t p = FIXTURE_CREATE(&_fix);
- datarouter_port_set_send_type(p, DATAROUTER_SEND_sensor);
datarouter_port_set_send_type(p, -1);
CHECK(datarouter_port_get_send_type(p) == -1, NULL);
TEST_END()
-TEST_START(recv_type_clear)
- datarouter_port_t p = FIXTURE_CREATE(&_fix);
- datarouter_port_set_recv_type(p, DATAROUTER_RECV_rtcm);
- datarouter_port_set_recv_type(p, -1);
- CHECK(datarouter_port_get_recv_type(p) == -1, NULL);
-TEST_END()
-
-TEST_START(types_from_invalid)
- CHECK(datarouter_port_get_send_type(-1) == -1, NULL);
- CHECK(datarouter_port_get_recv_type(-1) == -1, NULL);
- CHECK(datarouter_port_get_send_type(999) == -1, NULL);
- CHECK(datarouter_port_get_recv_type(999) == -1, NULL);
-TEST_END()
-
-/* ================================================================
- * 4. 多 handler
- * ================================================================ */
-
TEST_START(handler_add_remove)
datarouter_port_t p = FIXTURE_CREATE(&_fix);
- CHECK(datarouter_port_add_handler(p, _h_a) == 0, NULL);
- CHECK(datarouter_port_add_handler(p, _h_b) == 0, NULL);
- CHECK(datarouter_port_handler_count(p) == 2, NULL);
- CHECK(datarouter_port_remove_handler(p, _h_a) == 0, NULL);
+ CHECK(datarouter_port_add_handler(p, _h) == 0, NULL);
CHECK(datarouter_port_handler_count(p) == 1, NULL);
+ CHECK(datarouter_port_remove_handler(p, _h) == 0, NULL);
+ CHECK(datarouter_port_handler_count(p) == 0, NULL);
TEST_END()
TEST_START(handler_clear)
@@ -178,67 +128,93 @@ TEST_START(handler_clear)
TEST_END()
/* ================================================================
- * 5. 发送触发
+ * 4. 发送 — 自动广播
* ================================================================ */
-TEST_START(send_one_handler)
+TEST_START(send_no_match_port)
+ /* 没有端口配置该 send_type */
+ CHECK(datarouter_send_sensor("d", 1) == -2, "expected -2");
+TEST_END()
+
+TEST_START(send_one_port_one_handler)
datarouter_port_t p = FIXTURE_CREATE(&_fix);
datarouter_port_set_send_type(p, DATAROUTER_SEND_sensor);
datarouter_port_add_handler(p, _h);
reset_h();
- CHECK(datarouter_send_sensor(p, "d", 1) == 0, NULL);
- CHECK(_h_cnt == 1, "handler called %d times", _h_cnt);
+ CHECK(datarouter_send_sensor("d", 1) == 0, NULL);
+ CHECK(_h_cnt == 1, "cnt=%d", _h_cnt);
+ CHECK(_h_port[0] == (int)p, "port=%d", _h_port[0]);
TEST_END()
-TEST_START(send_multi_handlers)
- datarouter_port_t p = FIXTURE_CREATE(&_fix);
- datarouter_port_set_send_type(p, DATAROUTER_SEND_sensor);
- datarouter_port_add_handler(p, _h_a);
- datarouter_port_add_handler(p, _h_b);
- datarouter_port_add_handler(p, _h_c);
- reset_h();
- CHECK(datarouter_send_sensor(p, "d", 1) == 0, NULL);
- CHECK(_h_cnt == 3, "handler called %d times", _h_cnt);
-TEST_END()
-
-TEST_START(send_type_mismatch)
+TEST_START(send_one_port_multi_handler)
datarouter_port_t p = FIXTURE_CREATE(&_fix);
datarouter_port_set_send_type(p, DATAROUTER_SEND_sensor);
datarouter_port_add_handler(p, _h);
+ datarouter_port_add_handler(p, _h2);
reset_h();
- CHECK(datarouter_send_status(p, "d", 1) == -3, "expected -3");
- CHECK(_h_cnt == 0, NULL);
+ CHECK(datarouter_send_sensor("d", 1) == 0, NULL);
+ CHECK(_h_cnt == 2, "cnt=%d", _h_cnt);
TEST_END()
-TEST_START(send_no_handler)
- datarouter_port_t p = FIXTURE_CREATE(&_fix);
- datarouter_port_set_send_type(p, DATAROUTER_SEND_sensor);
- CHECK(datarouter_send_sensor(p, "d", 1) == -4, "expected -4");
+TEST_START(send_multi_ports_same_type)
+ /* 两个端口同类型,各一个 handler */
+ datarouter_port_t p1 = FIXTURE_CREATE(&_fix);
+ datarouter_port_t p2 = FIXTURE_CREATE(&_fix);
+ datarouter_port_set_send_type(p1, DATAROUTER_SEND_sensor);
+ datarouter_port_set_send_type(p2, DATAROUTER_SEND_sensor);
+ datarouter_port_add_handler(p1, _h);
+ datarouter_port_add_handler(p2, _h);
+ reset_h();
+ CHECK(datarouter_send_sensor("d", 1) == 0, NULL);
+ CHECK(_h_cnt == 2, "cnt=%d", _h_cnt);
+ /* p1 和 p2 各触发一次 */
+ CHECK((_h_port[0]==p1 && _h_port[1]==p2) ||
+ (_h_port[0]==p2 && _h_port[1]==p1), "ports %d,%d", _h_port[0], _h_port[1]);
TEST_END()
-TEST_START(send_no_send_type)
- /* 端口只有 recv_type,没有 send_type */
- datarouter_port_t p = FIXTURE_CREATE(&_fix);
- datarouter_port_set_recv_type(p, DATAROUTER_RECV_rtcm);
- CHECK(datarouter_send_sensor(p, "d", 1) == -3, "expected -3 (send_type unset)");
+TEST_START(send_multi_port_multi_handler)
+ datarouter_port_t p1 = FIXTURE_CREATE(&_fix);
+ datarouter_port_t p2 = FIXTURE_CREATE(&_fix);
+ datarouter_port_set_send_type(p1, DATAROUTER_SEND_sensor);
+ datarouter_port_set_send_type(p2, DATAROUTER_SEND_sensor);
+ datarouter_port_add_handler(p1, _h);
+ datarouter_port_add_handler(p1, _h2); /* p1 两个 */
+ datarouter_port_add_handler(p2, _h3); /* p2 一个 */
+ reset_h();
+ CHECK(datarouter_send_sensor("d", 1) == 0, NULL);
+ CHECK(_h_cnt == 3, "cnt=%d", _h_cnt);
TEST_END()
-TEST_START(send_remove_handler)
- datarouter_port_t p = FIXTURE_CREATE(&_fix);
- datarouter_port_set_send_type(p, DATAROUTER_SEND_sensor);
- datarouter_port_add_handler(p, _h_a);
- datarouter_port_add_handler(p, _h_b);
- reset_h(); datarouter_send_sensor(p, "d", 1); CHECK(_h_cnt == 2, NULL);
- datarouter_port_remove_handler(p, _h_a);
- reset_h(); datarouter_send_sensor(p, "d", 1); CHECK(_h_cnt == 1, NULL);
+TEST_START(send_type_filter)
+ /* 两个端口不同类型,只触发匹配的 */
+ datarouter_port_t p1 = FIXTURE_CREATE(&_fix);
+ datarouter_port_t p2 = FIXTURE_CREATE(&_fix);
+ datarouter_port_set_send_type(p1, DATAROUTER_SEND_sensor);
+ datarouter_port_set_send_type(p2, DATAROUTER_SEND_status);
+ datarouter_port_add_handler(p1, _h);
+ datarouter_port_add_handler(p2, _h);
+ reset_h();
+ CHECK(datarouter_send_sensor("d", 1) == 0, NULL);
+ CHECK(_h_cnt == 1, "cnt=%d", _h_cnt);
+ CHECK(_h_port[0] == (int)p1, "only p1 should fire");
TEST_END()
-TEST_START(send_clear_handlers)
+TEST_START(send_after_remove_handler)
datarouter_port_t p = FIXTURE_CREATE(&_fix);
datarouter_port_set_send_type(p, DATAROUTER_SEND_sensor);
datarouter_port_add_handler(p, _h);
- datarouter_port_clear_handlers(p);
- CHECK(datarouter_send_sensor(p, "d", 1) == -4, "expected -4");
+ reset_h(); datarouter_send_sensor("d", 1); CHECK(_h_cnt == 1, NULL);
+ datarouter_port_remove_handler(p, _h);
+ CHECK(datarouter_send_sensor("d", 1) == -2, "expected -2 after remove");
+TEST_END()
+
+TEST_START(send_after_delete_port)
+ datarouter_port_t p = FIXTURE_CREATE(&_fix);
+ datarouter_port_set_send_type(p, DATAROUTER_SEND_sensor);
+ datarouter_port_add_handler(p, _h);
+ datarouter_port_delete(p);
+ CHECK(datarouter_send_sensor("d", 1) == -2, "expected -2");
+ _fix.count--;
TEST_END()
TEST_START(send_zero_length)
@@ -246,7 +222,7 @@ TEST_START(send_zero_length)
datarouter_port_set_send_type(p, DATAROUTER_SEND_sensor);
datarouter_port_add_handler(p, _h);
reset_h();
- CHECK(datarouter_send_sensor(p, "x", 0) == 0, NULL);
+ CHECK(datarouter_send_sensor("x", 0) == 0, NULL);
CHECK(_h_cnt == 1, NULL);
TEST_END()
@@ -255,38 +231,47 @@ TEST_START(send_null_data)
datarouter_port_set_send_type(p, DATAROUTER_SEND_sensor);
datarouter_port_add_handler(p, _h);
reset_h();
- CHECK(datarouter_send_sensor(p, NULL, 0) == 0, NULL);
+ CHECK(datarouter_send_sensor(NULL, 0) == 0, NULL);
CHECK(_h_cnt == 1, NULL);
TEST_END()
-/* ================================================================
- * 6. 接收回调
- * ================================================================ */
-
-static int _rx_r, _rx_c;
-void datarouter_on_recv_rtcm(uint32_t p, const void *d, size_t l)
- { (void)p; (void)d; (void)l; _rx_r++; }
-void datarouter_on_recv_command(uint32_t p, const void *d, size_t l)
- { (void)p; (void)d; (void)l; _rx_c++; }
-
-TEST_START(recv_callbacks)
- _rx_r = _rx_c = 0;
- datarouter_on_recv_rtcm(0, "d", 1);
- CHECK(_rx_r == 1 && _rx_c == 0, "rtcm=%d cmd=%d", _rx_r, _rx_c);
- datarouter_on_recv_command(1, "d", 1);
- CHECK(_rx_r == 1 && _rx_c == 1, "rtcm=%d cmd=%d", _rx_r, _rx_c);
+TEST_START(send_multi_cap)
+ /* 发送 status 不影响 sensor 端口 */
+ datarouter_port_t p1 = FIXTURE_CREATE(&_fix);
+ datarouter_port_t p2 = FIXTURE_CREATE(&_fix);
+ datarouter_port_set_send_type(p1, DATAROUTER_SEND_sensor);
+ datarouter_port_set_send_type(p2, DATAROUTER_SEND_status);
+ datarouter_port_add_handler(p1, _h);
+ datarouter_port_add_handler(p2, _h);
+ reset_h();
+ CHECK(datarouter_send_sensor("d", 1) == 0, NULL);
+ CHECK(_h_cnt == 1, "sensor: cnt=%d", _h_cnt);
+ CHECK(datarouter_send_status("d", 1) == 0, NULL);
+ CHECK(_h_cnt == 2, "status: cnt=%d", _h_cnt);
TEST_END()
/* ================================================================
- * 7. 能力元数据(两组独立)
+ * 5. 接收回调
+ * ================================================================ */
+
+static int _rx_r;
+void datarouter_on_recv_rtcm(uint32_t p, const void *d, size_t l)
+ { (void)p; (void)d; (void)l; _rx_r++; }
+
+TEST_START(recv_callback)
+ _rx_r = 0;
+ datarouter_on_recv_rtcm(0, "d", 1);
+ CHECK(_rx_r == 1, "cnt=%d", _rx_r);
+TEST_END()
+
+/* ================================================================
+ * 6. 能力元数据
* ================================================================ */
TEST_START(send_cap_meta)
CHECK(datarouter_send_cap_count() == 2, NULL);
CHECK(strcmp(datarouter_send_cap_name(0), "sensor") == 0, NULL);
CHECK(strcmp(datarouter_send_cap_desc(0), "Sensor data report") == 0, NULL);
- CHECK(strcmp(datarouter_send_cap_name(1), "status") == 0, NULL);
- CHECK(strcmp(datarouter_send_cap_desc(1), "Device status report") == 0, NULL);
CHECK(datarouter_send_cap_name(-1) == NULL, NULL);
CHECK(datarouter_send_cap_name(99) == NULL, NULL);
TEST_END()
@@ -295,35 +280,15 @@ TEST_START(recv_cap_meta)
CHECK(datarouter_recv_cap_count() == 2, NULL);
CHECK(strcmp(datarouter_recv_cap_name(0), "rtcm") == 0, NULL);
CHECK(strcmp(datarouter_recv_cap_desc(0), "RTCM correction data") == 0, NULL);
- CHECK(strcmp(datarouter_recv_cap_name(1), "command") == 0, NULL);
- CHECK(strcmp(datarouter_recv_cap_desc(1), "Remote control command") == 0, NULL);
CHECK(datarouter_recv_cap_name(-1) == NULL, NULL);
CHECK(datarouter_recv_cap_desc(99) == NULL, NULL);
TEST_END()
-/* ================================================================
- * 8. 错误
- * ================================================================ */
-
-TEST_START(error_invalid_port)
- CHECK(datarouter_send_sensor(999, "d", 1) == -2, NULL);
- CHECK(datarouter_send_sensor(-1, "d", 1) == -2, NULL);
-TEST_END()
-
-TEST_START(error_deleted_port)
- datarouter_port_t p = FIXTURE_CREATE(&_fix);
- datarouter_port_set_send_type(p, DATAROUTER_SEND_sensor);
- datarouter_port_add_handler(p, _h);
- datarouter_port_delete(p);
- CHECK(datarouter_send_sensor(p, "d", 1) == -2, NULL);
- _fix.count--;
-TEST_END()
-
/* ================================================================
* 主函数
* ================================================================ */
-#define RUN(name) do { reset_h(); test_##name(); } while (0)
+#define RUN(name) do { reset_h(); _rx_r = 0; test_##name(); } while (0)
int main(void)
{
@@ -341,35 +306,29 @@ int main(void)
RUN(port_default_state);
printf("\n");
- datarouter_reset(); datarouter_init();
- printf("[send_type / recv_type]\n");
+ datarouter_reset(); datarouter_init();
+ printf("[send_type & handler]\n");
RUN(send_type_set_get);
- RUN(recv_type_set_get);
- RUN(types_independent);
- RUN(send_type_clear);
- RUN(recv_type_clear);
- RUN(types_from_invalid);
- printf("\n");
-
- printf("[handler add/remove]\n");
RUN(handler_add_remove);
RUN(handler_clear);
printf("\n");
- printf("[send trigger]\n");
- RUN(send_one_handler);
- RUN(send_multi_handlers);
- RUN(send_type_mismatch);
- RUN(send_no_handler);
- RUN(send_no_send_type);
- RUN(send_remove_handler);
- RUN(send_clear_handlers);
+ printf("[send — auto broadcast]\n");
+ RUN(send_no_match_port);
+ RUN(send_one_port_one_handler);
+ RUN(send_one_port_multi_handler);
+ RUN(send_multi_ports_same_type);
+ RUN(send_multi_port_multi_handler);
+ RUN(send_type_filter);
+ RUN(send_after_remove_handler);
+ RUN(send_after_delete_port);
RUN(send_zero_length);
RUN(send_null_data);
+ RUN(send_multi_cap);
printf("\n");
printf("[receive callback]\n");
- RUN(recv_callbacks);
+ RUN(recv_callback);
printf("\n");
printf("[capability metadata]\n");
@@ -377,11 +336,6 @@ int main(void)
RUN(recv_cap_meta);
printf("\n");
- printf("[error handling]\n");
- RUN(error_invalid_port);
- RUN(error_deleted_port);
- printf("\n");
-
printf("==============================\n");
printf(" total: %d | pass: %d | fail: %d\n\n",
_total_run, _total_pass, _total_fail);