From ea78bce4820692bb60cf54c9aaa12c6e559f78a4 Mon Sep 17 00:00:00 2001 From: coffee Date: Wed, 10 Sep 2025 14:50:22 +0800 Subject: [PATCH] =?UTF-8?q?1.=20=E4=BF=AE=E6=94=B9RPC,=20=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E6=9C=AC=E5=9C=B0RPC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/HDRPC.h | 66 ++++++++++++++--- src/HDRPC.c | 191 +++++++++++++++++++++++++++++++++++++----------- 2 files changed, 201 insertions(+), 56 deletions(-) diff --git a/include/HDRPC.h b/include/HDRPC.h index d5295dd..d854543 100644 --- a/include/HDRPC.h +++ b/include/HDRPC.h @@ -19,10 +19,14 @@ #include // 设置超时时间 +#ifndef HDRPC_TIMEOUT #define HDRPC_TIMEOUT 3000 +#endif // 如果使用栈参数解析, 则最大支持的参数个数 -#define HDRPC_USE_SESSION_ARGS (9) +#ifndef HDRPC_USE_SESSION_ARGS +#define HDRPC_USE_SESSION_ARGS (0) +#endif // 使用64位 // #define HDRPC_USE_64 @@ -87,26 +91,33 @@ typedef struct __attribute__((packed)) HDRPCArgs }; } HDRPCArgs; -typedef struct __attribute__((packed)) HDRPCSession +typedef struct HDRPCSession { uint16_t func; ///< 调用功能, 用于解析数据得到 uint8_t index; ///< 当前添加到的参数索引 - uint8_t exceptionSkip : 1; ///< 异常时不要调用回调(默认0: 调用回调, 1: 不调用回调) + uint8_t exceptionNotSkip: 1; ///< 异常时跳过调用回调(默认0: 不调用回调, 1: 调用回调) uint8_t len : 7; ///< 参数总长度 HDRPCArgs *args; ///< 参数 } HDRPCSession; // 此宏用于其他回调的参数声明 -#define HDRPC_CALL_ARGS HDRPCSession *session, uint8_t exception +#define HDRPC_CALL_ARGS HDRPCSession *_session, uint8_t _exception +#define HDRPC_CALL_ARG_SESSION _session +#define HDRPC_CALL_ARG_EXCEPTION _exception #define HDRPC_IS_EXCEPTION() (exception != kHDRPCNotException) +// 发送RPC后得到数据的回调 typedef void (*HDRPCCallback)(HDRPCSession *session, uint8_t exception); -typedef void (*HDRPCSendData)(HDRPCSession *session); +// 发送RPC数据到对端 +typedef void (*HDRPCSendDataCall)(HDRPCSession *session); +// 对端发送RPC数据到本地端解析后的处理 +typedef void (*HDRPCReadDataCall)(HDRPCSession *session); // 调用缓存, 内存由用户提供 typedef struct __attribute__((packed)) HDRPCCallBuffer { uint8_t enbale : 1; ///< 是否启用 - uint8_t nameLen : 7; ///< 函数名长度 - uint32_t time; ///< 上次调用时间 + uint8_t skipExce: 1; ///< 跳过异常 + uint8_t nameLen : 6; ///< 函数名长度 + uint32_t lastTime; ///< 上次调用时间 const char *name; ///< 函数名 HDRPCCallback callback; ///< 回调 } HDRPCCallBuffer; @@ -126,14 +137,28 @@ void HDRPCInitSession(HDRPCSession *session, HDRPCArgs *args, uint8_t len); * @param callLen 回调缓存长度 * @param buffer 读取的RPC会话(如果不传递则使用栈分配) */ -void HDRPCInitCall(HDRPCSendData sendCall, HDRPCCallBuffer *callBuff, uint8_t callLen, HDRPCSession *buffer); +void HDRPCInitCall(HDRPCSendDataCall sendCall, HDRPCCallBuffer *callBuff, uint8_t callLen, HDRPCSession *buffer); + +/** + * @brief 初始化对端RPC调用本地 + * @param readCall 读取数据完成后的回调处理对于功能 + * @param buffer 读取的RPC会话(如果不传递则使用栈分配) + */ +void HDRPCInitReadCall(HDRPCReadDataCall readCall, HDRPCSession *session); + +/** + * @brief 设置异常时是否跳过回调 + * @param session 参数会话 + * @param enable 是否跳过 + */ +void HDRPCSetExceptionNotSkip(HDRPCSession *session, uint8_t enable); /** * @brief 使用这个来创建栈内参数包, 内部自增一个用于存储内部回调数据 * @param _name 参数包名称 * @param _len 参数包长度 */ -#define HDRPCCreate(_name, _len) HDRPCArgs _args##_name[_len + 1]; HDRPCSession _name; HDRPCInitSession(&_name, _args##_name, _len + 1) +#define HDRPCCreate(_name, _len) HDRPCArgs _args##_name[_len + 1]; HDRPCSession _session##_name; HDRPCInitSession(&_session##_name, _args##_name, _len + 1); HDRPCSession *_name = &_session##_name /** * @brief 用于辅助宏添加数据到session @@ -158,12 +183,21 @@ uint8_t _HDRPCAddArgs(HDRPCSession *session, uint8_t type, void *args, uint8_t l #define HDRPCAddU64(session, ...) _HDRPCUseAdd(session, 64, __VA_ARGS__) #endif +#define HDRPCAddException(session, ...) _HDRPCAdd((session), uint16_t, kHDRPCException, __VA_ARGS__) #define HDRPCAddBuffer(session, data, len) _HDRPCAddArgs((session), kHDRPCBuffer, (data), (len)) #define HDRPCAddString(session, data, len) _HDRPCAddArgs((session), kHDRPCString, (data), (len) * 2) // 注: 如果需要用户数据, 要求用户数据添加到所有参数后面 #define HDRPCAddUserData(session, data, len) _HDRPCAddArgs((session), kHDRPCUserData, (data), (len)) +/** + * @brief 添加参数到会话, 方便添加用户数据到会话 + * @param session 参数会话 + * @param args 参数 + * @return 1成功, 0失败 + */ +uint8_t HDRPCAddArgs(HDRPCSession *session, HDRPCArgs *args); + /** * @brief 将数据反序列化解析参数会话 * @param data 参数包数据 @@ -190,7 +224,7 @@ uint8_t _HDRPCCheckArgs(HDRPCSession *session, uint8_t *type, uint8_t len); * @param index 参数索引 * @return 参数 */ -HDRPCValue_t _HDRPCGetValue(HDRPCSession *session, uint8_t type, int index); +HDRPCValue_t _HDRPCGetValue(HDRPCSession *session, uint8_t type, uint8_t index); #define HDRPCGetValueU8(session, index) _HDRPCGetValue(session, kHDRPCU8, index) #define HDRPCGetValueU16(session, index) _HDRPCGetValue(session, kHDRPCU16, index) #define HDRPCGetValueU32(session, index) _HDRPCGetValue(session, kHDRPCU32, index) @@ -205,17 +239,25 @@ HDRPCValue_t _HDRPCGetValue(HDRPCSession *session, uint8_t type, int index); * @param index 参数索引 * @return 参数 */ -void *_HDRPCGetData(HDRPCSession *session, uint8_t type, int index, uint8_t *len); +void *_HDRPCGetData(HDRPCSession *session, uint8_t type, uint8_t index, uint8_t *len); #define HDRPCGetData(session, index, len) (uint8_t *)_HDRPCGetData(session, kHDRPCBuffer, index, len) +#define HDRPCGetUserData(session, index, len) (uint8_t *)_HDRPCGetData(session, kHDRPCUserData, index, len) #define HDRPCGetString(session, index, len) (uint16_t *)_HDRPCGetData(session, kHDRPCString, index, len) /** - * @brief 处理读取的数据调用回调 + * @brief 处理返回的数据调用回调 * @param data 数据 * @param len 数据长度 */ void HDRPCReadData(void *data, uint16_t len); +/** + * @brief 处理对方请求调用的数据 + * @param data 数据 + * @param len 数据长度 + */ +void HDRPCReadCallData(void *data, uint16_t len); + /** * @brief 发送数据 * @param session 参数会话 diff --git a/src/HDRPC.c b/src/HDRPC.c index 1a15024..13d9bbf 100644 --- a/src/HDRPC.c +++ b/src/HDRPC.c @@ -13,11 +13,15 @@ // 无效功能 #define HDRPC_INVAID_FUNC 0xFFFF -struct RPCInfo { - HDRPCSendData writeCall; - HDRPCCallBuffer *callback; - HDRPCSession *session; - uint8_t callLen; +struct __attribute__((packed)) RPCInfo { + HDRPCSendDataCall writeCall; ///< 发送数据回调 + HDRPCCallBuffer *localCallBuffer; ///< 本地RPC调用缓存 + HDRPCSession *session; ///< 本地RPC会话 + + HDRPCReadDataCall readCall; ///< 对端RPC调用回调 + HDRPCSession *readCallSession; ///< 对端RPC会话 + + uint8_t callLen; ///< 本地RPC调用缓存长度 }; static struct RPCInfo sInfo; @@ -33,7 +37,7 @@ static void UpdateTimeout(HDRPCCallBuffer *callBuff) { uint32_t curr = HDLogGetTime(); #ifdef HDRPC_TIMEOUT - if (curr - callBuff->time > HDRPC_TIMEOUT) { + if (curr - callBuff->lastTime > HDRPC_TIMEOUT) { callBuff->enbale = 0; LogD("Call[%s] Timeout", callBuff->name); } @@ -53,54 +57,76 @@ static void Call(HDRPCSession *session, uint16_t exception) { return ; } - for (int i = 0; i < sInfo.callLen; i++) { - UpdateTimeout(&sInfo.callback[i]); - if (sInfo.callback[i].enbale == 0) { + uint16_t i = 0; + for (; i < sInfo.callLen; ++i) { + UpdateTimeout(&sInfo.localCallBuffer[i]); + if (sInfo.localCallBuffer[i].enbale == 0) { continue; } - if (sInfo.callback[i].nameLen != session->args[index].buffer.len) { + if (sInfo.localCallBuffer[i].nameLen != session->args[index].buffer.len) { continue; } - if (strncmp(sInfo.callback[i].name, (char *)session->args[index].buffer.data, session->args[index].buffer.len) != 0) { + if (strncmp(sInfo.localCallBuffer[i].name, (char *)session->args[index].buffer.data, session->args[index].buffer.len) != 0) { continue; } - LogD("Call[%s]", sInfo.callback[i].name); - sInfo.callback[i].callback(session, exception); - LogD("Call[%s] End", sInfo.callback[i].name); + if (exception != kHDRPCNotException && sInfo.localCallBuffer[i].skipExce == 1) { + sInfo.localCallBuffer[i].enbale = 0; + LogD("Call[%s] Skip Exception", sInfo.localCallBuffer[i].name); + break; + } - sInfo.callback[i].enbale = 0; - sInfo.callback[i].nameLen = 0; - sInfo.callback[i].name = NULL; + LogD("Call[%s]", sInfo.localCallBuffer[i].name); + sInfo.localCallBuffer[i].callback(session, exception); + LogD("Call[%s] End", sInfo.localCallBuffer[i].name); + + sInfo.localCallBuffer[i].enbale = 0; + sInfo.localCallBuffer[i].nameLen = 0; + sInfo.localCallBuffer[i].name = NULL; break; } + + for (++i; i < sInfo.callLen; ++i) { + UpdateTimeout(&sInfo.localCallBuffer[i]); + } } -static int16_t AddCall(HDRPCCallback callBack, const char *funcName, uint8_t nameLen) { +static int16_t AddCall(HDRPCSession *session, HDRPCCallback callBack, const char *funcName, uint8_t nameLen) { if (callBack == NULL || nameLen == 0) { LogD("funcName[%s], len[%d] add Faild", funcName, nameLen); return -1; } - for (int i = 0; i < sInfo.callLen; i++) { - UpdateTimeout(&sInfo.callback[i]); - if (sInfo.callback[i].enbale == 1) { + int16_t result = -1; + int i = 0; + for (; i < sInfo.callLen; ++i) { + UpdateTimeout(&sInfo.localCallBuffer[i]); + if (sInfo.localCallBuffer[i].enbale == 1) { continue; } + sInfo.localCallBuffer[i].enbale = 1; + sInfo.localCallBuffer[i].skipExce = !session->exceptionNotSkip; + sInfo.localCallBuffer[i].callback = callBack; + sInfo.localCallBuffer[i].nameLen = nameLen; + sInfo.localCallBuffer[i].name = funcName; + sInfo.localCallBuffer[i].lastTime = HDLogGetTime(); - sInfo.callback[i].enbale = 1; - sInfo.callback[i].callback = callBack; - sInfo.callback[i].nameLen = nameLen; - sInfo.callback[i].name = funcName; - sInfo.callback[i].time = HDLogGetTime(); - return i; + result = i; + break; } - LogD("add call is full, callLen[%d]", sInfo.callLen); - return -1; + for (++i; i < sInfo.callLen; ++i) { + UpdateTimeout(&sInfo.localCallBuffer[i]); + } + + if (result == -1) { + LogD("add call is full, funcName[%s] faild, callLen[%d]", funcName, sInfo.callLen); + } + + return result; } static uint8_t GetArgLen(HDRPCArgs *args) @@ -243,7 +269,7 @@ static void ReadCall(HDRPCSession *session, void *data, uint16_t len) { return ; } - uint16_t exception = kHDRPCNotException;; + uint16_t exception = kHDRPCNotException; for (uint8_t i = 0; i < session->index; ++i) { if (session->args[i].type != kHDRPCException) { continue; @@ -251,16 +277,31 @@ static void ReadCall(HDRPCSession *session, void *data, uint16_t len) { exception = session->args[i].dataU16; LogD("Call type[0x%x] Exception[0x%x]", session->args[i].type, exception); - - // 开启异常跳过后, 出现异常不回调 - if (session->exceptionSkip) { - return ; - } + break; } Call(session, exception); } +static void ParseReadDataCall(HDRPCSession *session, void *data, uint16_t len) { + // 解析数据到参数会话 + if (HDRPCParseArgs(data, len, session) == 0) { + LogD("Parse args faild"); + } + + // 无效功能码 + if (session->func == HDRPC_INVAID_FUNC) { + LogD("Invalid Func[0x%x]", session->func); + return ; + } + + if (sInfo.readCall == NULL) { + return ; + } + + sInfo.readCall(session); +} + void HDRPCInitSession(HDRPCSession *session, HDRPCArgs *args, uint8_t len) { @@ -277,15 +318,15 @@ void HDRPCInitSession(HDRPCSession *session, HDRPCArgs *args, uint8_t len) session->len = 0; } - for (uint16_t i = 0; i < session->len; ++i) { + for (uint8_t i = 0; i < session->len; ++i) { memset(&session->args[i], 0, sizeof(HDRPCArgs)); } } -void HDRPCInitCall(HDRPCSendData writeCall, HDRPCCallBuffer *callBuff, uint8_t len, HDRPCSession *buffer) +void HDRPCInitCall(HDRPCSendDataCall writeCall, HDRPCCallBuffer *callBuff, uint8_t len, HDRPCSession *buffer) { sInfo.writeCall = writeCall; - sInfo.callback = callBuff; + sInfo.localCallBuffer = callBuff; sInfo.session = buffer; sInfo.callLen = len; if (callBuff == NULL && len > 0) { @@ -298,6 +339,21 @@ void HDRPCInitCall(HDRPCSendData writeCall, HDRPCCallBuffer *callBuff, uint8_t l } } +void HDRPCInitReadCall(HDRPCReadDataCall readCall, HDRPCSession *session) +{ + sInfo.readCallSession = session; + sInfo.readCall = readCall; +} + +void HDRPCSetExceptionNotSkip(HDRPCSession *session, uint8_t enable) +{ + if (session == NULL) { + return ; + } + + session->exceptionNotSkip = !!enable; +} + uint8_t _HDRPCAddArgs(HDRPCSession *session, uint8_t type, void *args, uint8_t len) { if (session == NULL) { @@ -350,6 +406,25 @@ uint8_t _HDRPCAddArgs(HDRPCSession *session, uint8_t type, void *args, uint8_t l return 1; } +uint8_t HDRPCAddArgs(HDRPCSession *session, HDRPCArgs *args) +{ + if (session == NULL || args == NULL) { + LogD("Session or args is nullptr"); + return 0; + } + + if (session->index >= session->len) { + LogD("Session is full"); + return 0; + } + + const uint8_t index = session->index; + ++session->index; + memcpy(&session->args[index], args, sizeof(HDRPCArgs)); + + return 1; +} + uint8_t HDRPCParseArgs(void *data, uint16_t len, HDRPCSession *session) { if (session == NULL) { @@ -396,7 +471,7 @@ uint8_t _HDRPCCheckArgs(HDRPCSession *session, uint8_t *type, uint8_t len) return 1; } -HDRPCValue_t _HDRPCGetValue(HDRPCSession *session, uint8_t type, int index) +HDRPCValue_t _HDRPCGetValue(HDRPCSession *session, uint8_t type, uint8_t index) { if (session == NULL) { LogD("Session is nullptr"); @@ -433,7 +508,7 @@ HDRPCValue_t _HDRPCGetValue(HDRPCSession *session, uint8_t type, int index) return 0; } -void *_HDRPCGetData(HDRPCSession *session, uint8_t type, int index, uint8_t *len) +void *_HDRPCGetData(HDRPCSession *session, uint8_t type, uint8_t index, uint8_t *len) { if (session == NULL) { LogD("Session is nullptr"); @@ -474,23 +549,51 @@ void *_HDRPCGetData(HDRPCSession *session, uint8_t type, int index, uint8_t *len void HDRPCReadData(void *data, uint16_t len) { - if (sInfo.callback == NULL || sInfo.callLen ==0) { + if (sInfo.localCallBuffer == NULL || sInfo.callLen ==0) { return ; } HDRPCSession *session = sInfo.session; if (session == NULL) { +#if HDRPC_USE_SESSION_ARGS HDRPCSession buff; session = &buff; HDRPCArgs args[HDRPC_USE_SESSION_ARGS]; HDRPCInitSession(session, args, HDRPC_USE_SESSION_ARGS); ReadCall(session, data, len); +#else + LogD("Session is nullptr"); +#endif return ; } ReadCall(session, data, len); } +void HDRPCReadCallData(void *data, uint16_t len) +{ + if (sInfo.readCall == NULL) { + LogD("Read Call is nullptr"); + return ; + } + + HDRPCSession *session = sInfo.readCallSession; + if (session == NULL) { +#if HDRPC_USE_SESSION_ARGS + HDRPCSession buff; + session = &buff; + HDRPCArgs args[HDRPC_USE_SESSION_ARGS]; + HDRPCInitSession(session, args, HDRPC_USE_SESSION_ARGS); + ParseReadDataCall(session, data, len); +#else + LogD("Session is nullptr"); +#endif + return ; + } + + ParseReadDataCall(session, data, len); +} + void _HDRPCSendData(HDRPCSession *session, uint16_t funcCode, HDRPCCallback callBack, const char *funcName, uint8_t nameLen) { if (sInfo.writeCall == NULL) { @@ -512,7 +615,7 @@ void _HDRPCSendData(HDRPCSession *session, uint16_t funcCode, HDRPCCallback call break; } - if (AddCall(callBack, funcName, nameLen) == -1) { + if (AddCall(session, callBack, funcName, nameLen) == -1) { LogD("Add Call[%s] faild", funcName); } } while (0); @@ -527,10 +630,10 @@ uint16_t HDRPCConvSendData(HDRPCSession *session, uint8_t *data, uint16_t len) return 0; } - int useLen = 0; + uint16_t useLen = 0; data[useLen++] = session->func >> 8; data[useLen++] = session->func & 0xFF; - for (int i = 0; i < session->index; ++i) { + for (uint16_t i = 0; i < session->index; ++i) { const uint8_t argLen = GetArgLen(&session->args[i]); if (useLen + 1 > len) { LogD("write Buffer Not enough, len[%d] useLen[%d]", len, useLen);