1. 修复RPC问题
This commit is contained in:
parent
70c8782467
commit
15f3b90f5a
225
include/HDRPC.h
Normal file
225
include/HDRPC.h
Normal file
@ -0,0 +1,225 @@
|
|||||||
|
/**
|
||||||
|
* 日期: 2025-09-04
|
||||||
|
* 作者: coffee
|
||||||
|
* 描述: ARM和MCU交互通信模块
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __HDRPC_H__
|
||||||
|
#define __HDRPC_H__
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
// 无效类型
|
||||||
|
#define HDRPC_INVAID_TYPE 0xFF
|
||||||
|
|
||||||
|
// 无效功能
|
||||||
|
#define HDRPC_INVAID_FUNC 0xFFFF
|
||||||
|
|
||||||
|
// 默认超时
|
||||||
|
#define HDRPC_TIMEOUT 3000
|
||||||
|
|
||||||
|
// 如果使用栈参数解析, 则最大支持的参数个数
|
||||||
|
#define HDRPC_USE_SESSION_ARGS (5)
|
||||||
|
|
||||||
|
// 使用64位
|
||||||
|
// #define HDRPC_USE_64
|
||||||
|
|
||||||
|
// 数值类型
|
||||||
|
#ifdef HDRPC_USE_64
|
||||||
|
typedef uint64_t HDRPCValue_t;
|
||||||
|
#else
|
||||||
|
typedef uint32_t HDRPCValue_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 类型数据, 多节字节按照大端解析:
|
||||||
|
* 0x00: 用户数据, 数据首个字节为长度
|
||||||
|
* 0x01: u8
|
||||||
|
* 0x02: u16
|
||||||
|
* 0x03: u32
|
||||||
|
* 0x04: u64(保留扩展)
|
||||||
|
* 0x10: 字符串/缓冲数据, 数据首个字节为长度
|
||||||
|
* 0x11: UTF-16BE字符串, 数据首个字节为长度
|
||||||
|
* 0x20: 异常类型, u16类型
|
||||||
|
*/
|
||||||
|
|
||||||
|
enum eHDRPCType
|
||||||
|
{
|
||||||
|
kHDRPCUserData = 0x00, ///< 用户数据
|
||||||
|
kHDRPCU8 = 0x01, ///< u8
|
||||||
|
kHDRPCU16 = 0x02, ///< u16
|
||||||
|
kHDRPCU32 = 0x03, ///< u32
|
||||||
|
kHDRPCU64 = 0x04, ///< u64(保留扩展, 不使用)
|
||||||
|
kHDRPCBuffer = 0x10, ///< 字符串/缓冲数据, 数据首个字节为长度
|
||||||
|
kHDRPCString = 0x11, ///< UTF-16BE字符串, 数据首个字节为长度
|
||||||
|
kHDRPCException = 0x20, ///< 异常, u16
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct __attribute__((packed)) _HDRPCBuffer
|
||||||
|
{
|
||||||
|
uint8_t len; ///< 数据长度
|
||||||
|
uint8_t *data; ///< 数据
|
||||||
|
} _HDRPCBuffer;
|
||||||
|
|
||||||
|
///< 参数包
|
||||||
|
typedef struct __attribute__((packed)) _HDRPCArgs
|
||||||
|
{
|
||||||
|
uint8_t type; ///< 类型数据
|
||||||
|
union __attribute__((packed))
|
||||||
|
{
|
||||||
|
uint8_t dataU8;
|
||||||
|
uint16_t dataU16;
|
||||||
|
uint32_t dataU32;
|
||||||
|
#ifdef HDRPC_USE_64
|
||||||
|
uint64_t dataU64;
|
||||||
|
#endif
|
||||||
|
_HDRPCBuffer buffer;
|
||||||
|
};
|
||||||
|
} HDRPCArgs;
|
||||||
|
|
||||||
|
typedef struct __attribute__((packed)) HDRPCSession
|
||||||
|
{
|
||||||
|
uint8_t index; ///< 当前添加到的参数索引
|
||||||
|
uint8_t len; ///< 参数总长度
|
||||||
|
uint16_t func; ///< 调用功能, 用于解析数据得到
|
||||||
|
HDRPCArgs *args;
|
||||||
|
} HDRPCSession;
|
||||||
|
|
||||||
|
// 此宏用于其他回调的参数声明
|
||||||
|
#define HDRPC_CALL_ARGS HDRPCSession *session
|
||||||
|
typedef void (*HDRPCCallback)(HDRPCSession *session);
|
||||||
|
typedef void (*HDRPCSendData)(HDRPCSession *session);
|
||||||
|
|
||||||
|
// 调用缓存, 数据由用户提供
|
||||||
|
typedef struct __attribute__((packed)) HDRPCCallBuffer {
|
||||||
|
uint8_t enbale : 1;
|
||||||
|
uint8_t nameLen : 7;
|
||||||
|
uint32_t time;
|
||||||
|
const char *name;
|
||||||
|
HDRPCCallback callback;
|
||||||
|
} HDRPCCallBuffer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 初始化RPC会话
|
||||||
|
* @param session 参数会话
|
||||||
|
* @param len 参数会话长度
|
||||||
|
*/
|
||||||
|
void HDRPCInitSession(HDRPCSession *session, HDRPCArgs *args, uint8_t len);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 初始化RPC调用
|
||||||
|
* @param sendCall 发送数据回调
|
||||||
|
* @param callback 回调缓存, 用于可注册RPC回调数量
|
||||||
|
* @param callLen 回调缓存长度
|
||||||
|
* @param buffer 参数会话(如果不传递则使用栈分配)
|
||||||
|
*/
|
||||||
|
void HDRPCInitCall(HDRPCSendData sendCall, HDRPCCallBuffer *callBuff, uint8_t callLen, HDRPCSession *buffer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 使用这个来创建栈内参数包, 内部自增一个用于存储内部需要使用的用户数据
|
||||||
|
* @param _name 参数包名称
|
||||||
|
* @param _len 参数包长度
|
||||||
|
*/
|
||||||
|
#define HDRPCCreate(_name, _len) HDRPCArgs _args##_name[_len + 1]; HDRPCSession _name; HDRPCInitSession(&_name, _args##_name, _len + 1)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 用于辅助宏添加数据到session
|
||||||
|
* @param session RPC参数会话
|
||||||
|
* @param type 数据类型
|
||||||
|
* @param args 数据
|
||||||
|
* @param len 数据长度
|
||||||
|
* @return 1成功, 0失败
|
||||||
|
*/
|
||||||
|
uint8_t _HDRPCAddArgs(HDRPCSession *session, uint8_t type, void *args, uint8_t len);
|
||||||
|
|
||||||
|
#define _HDRPCAdd(session, type, key, ...) do {type __args[] = {__VA_ARGS__}; _HDRPCAddArgs(session, key, __args, sizeof(__args) / sizeof(__args[0])); } while (0)
|
||||||
|
#define _HDRPCUseAdd(session, type, ...) _HDRPCAdd((session), uint##type##_t, kHDRPCU##type, __VA_ARGS__)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 添加参数到会话
|
||||||
|
*/
|
||||||
|
#define HDRPCAddU8(session, ...) _HDRPCUseAdd(session, 8, __VA_ARGS__)
|
||||||
|
#define HDRPCAddU16(session, ...) _HDRPCUseAdd(session, 16, __VA_ARGS__)
|
||||||
|
#define HDRPCAddU32(session, ...) _HDRPCUseAdd(session, 32, __VA_ARGS__)
|
||||||
|
#ifdef HDRPC_USE_64
|
||||||
|
#define HDRPCAddU64(session, ...) _HDRPCUseAdd(session, 64, __VA_ARGS__)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#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 data 参数包数据
|
||||||
|
* @param len 参数包长度
|
||||||
|
* @param session 参数会话
|
||||||
|
* @return 1成功, 0失败
|
||||||
|
*/
|
||||||
|
uint8_t HDRPCParseArgs(void *data, uint16_t len, HDRPCSession *session);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 检查参数类型是否匹配
|
||||||
|
* @param session 参数会话
|
||||||
|
* @param type 参数类型
|
||||||
|
* @param len 参数个数
|
||||||
|
* @return 1成功, 0失败
|
||||||
|
*/
|
||||||
|
uint8_t _HDRPCCheckArgs(HDRPCSession *session, uint8_t *type, uint8_t len);
|
||||||
|
#define HDRPCCheckArgs(session, ...) ({ uint8_t __type[] = {__VA_ARGS__}; uint8_t __ret = _HDRPCCheckArgs(session, __type, sizeof(__type) / sizeof(__type[0])); __ret; })
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 获取指定位置数值数据
|
||||||
|
* @param session 参数会话
|
||||||
|
* @param type 参数类型
|
||||||
|
* @param index 参数索引
|
||||||
|
* @return 参数
|
||||||
|
*/
|
||||||
|
HDRPCValue_t _HDRPCGetValue(HDRPCSession *session, uint8_t type, int 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)
|
||||||
|
#ifdef HDRPC_USE_64
|
||||||
|
#define HDRPCGetValueU64(session, index) _HDRPCGetValue(session, kHDRPCU64, index)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 获取指定位置缓存数据
|
||||||
|
* @param session 参数会话
|
||||||
|
* @param type 参数类型
|
||||||
|
* @param index 参数索引
|
||||||
|
* @return 参数
|
||||||
|
*/
|
||||||
|
void *_HDRPCGetData(HDRPCSession *session, uint8_t type, int index, uint8_t *len);
|
||||||
|
#define HDRPCGetData(session, index, len) (uint8_t *)_HDRPCGetData(session, kHDRPCBuffer, index, len)
|
||||||
|
#define HDRPCGetString(session, index, len) (uint16_t *)_HDRPCGetData(session, kHDRPCString, index, len)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 处理读取的数据调用回调
|
||||||
|
* @param data 数据
|
||||||
|
* @param len 数据长度
|
||||||
|
*/
|
||||||
|
void HDRPCReadData(void *data, uint16_t len);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 发送数据
|
||||||
|
* @param session 参数会话
|
||||||
|
* @param funcName 函数名称
|
||||||
|
* @param nameLen 名称长度
|
||||||
|
*/
|
||||||
|
void _HDRPCSendData(HDRPCSession *session, uint16_t funcCode, HDRPCCallback callBack, const char *funcName, uint8_t nameLen);
|
||||||
|
#define HDRPCSendData(session, code, func) _HDRPCSendData(session, code, func, #func, sizeof(#func) - 1)
|
||||||
|
#define HDRPCSendDataNotCall(session, code) _HDRPCSendData(session, code, NULL, NULL, 0)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 参数会话转换成发送数据
|
||||||
|
* @param session 参数会话
|
||||||
|
* @param data 写入缓存
|
||||||
|
* @param len 缓存长度
|
||||||
|
* return 写入长度
|
||||||
|
*/
|
||||||
|
uint16_t HDRPCConvSendData(HDRPCSession *session, uint8_t *data, uint16_t len);
|
||||||
|
|
||||||
|
#endif // __HDRPC_H__
|
||||||
526
src/HDRPC.c
Normal file
526
src/HDRPC.c
Normal file
@ -0,0 +1,526 @@
|
|||||||
|
|
||||||
|
|
||||||
|
#include "HDRPC.h"
|
||||||
|
#include "HDLog.h"
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#ifndef LogD
|
||||||
|
#include <stdio.h>
|
||||||
|
#define LogD(format, ...) printf("[%s:%s:%d]"format "\r\n", __FILE_NAME__, __FUNCTION__, __LINE__, ##__VA_ARGS__)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct RPCInfo {
|
||||||
|
HDRPCSendData writeCall;
|
||||||
|
HDRPCCallBuffer *callback;
|
||||||
|
HDRPCSession *session;
|
||||||
|
uint8_t callLen;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct RPCInfo sInfo;
|
||||||
|
|
||||||
|
static void UpdateTimeout(HDRPCCallBuffer *callBuff) {
|
||||||
|
if (callBuff == NULL) {
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (callBuff->enbale == 0) {
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t curr = HDLogGetTime();
|
||||||
|
if (curr - callBuff->time > HDRPC_TIMEOUT) {
|
||||||
|
callBuff->enbale = 0;
|
||||||
|
LogD("Call[%s] Timeout", callBuff->name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Call(HDRPCSession *session) {
|
||||||
|
if (session == NULL) {
|
||||||
|
LogD("Session is nullptr");
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 不是用户数据, 说明不需要回调
|
||||||
|
const uint8_t index = session->index - 1;
|
||||||
|
if (session->index > 0 && session->args[index].type != kHDRPCUserData) {
|
||||||
|
LogD("func type[0x%x] Not call", session->args[index].type);
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < sInfo.callLen; i++) {
|
||||||
|
UpdateTimeout(&sInfo.callback[i]);
|
||||||
|
if (sInfo.callback[i].enbale == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sInfo.callback[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) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
LogD("Call[%s]", sInfo.callback[i].name);
|
||||||
|
sInfo.callback[i].callback(session);
|
||||||
|
LogD("Call[%s] End", sInfo.callback[i].name);
|
||||||
|
|
||||||
|
sInfo.callback[i].enbale = 0;
|
||||||
|
sInfo.callback[i].nameLen = 0;
|
||||||
|
sInfo.callback[i].name = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int16_t AddCall(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) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
LogD("add call is full, callLen[%d]", sInfo.callLen);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8_t GetArgLen(HDRPCArgs *args)
|
||||||
|
{
|
||||||
|
switch (args->type) {
|
||||||
|
case kHDRPCUserData:
|
||||||
|
case kHDRPCBuffer:
|
||||||
|
case kHDRPCString:
|
||||||
|
return args->buffer.len + 1;
|
||||||
|
case kHDRPCU8:
|
||||||
|
return sizeof(uint8_t);
|
||||||
|
case kHDRPCException:
|
||||||
|
case kHDRPCU16:
|
||||||
|
return sizeof(uint16_t);
|
||||||
|
case kHDRPCU32:
|
||||||
|
return sizeof(uint32_t);
|
||||||
|
#ifdef HDRPC_USE_64
|
||||||
|
case kHDRPCU64:
|
||||||
|
return sizeof(uint64_t);
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
LogD("Not support type[0x%x]", args->type);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void AddArgToBuffer(HDRPCArgs *args, uint8_t *data)
|
||||||
|
{
|
||||||
|
switch (args->type) {
|
||||||
|
case kHDRPCUserData:
|
||||||
|
case kHDRPCBuffer:
|
||||||
|
case kHDRPCString:
|
||||||
|
data[0] = args->buffer.len;
|
||||||
|
memcpy(data + 1, args->buffer.data, args->buffer.len);
|
||||||
|
break;
|
||||||
|
case kHDRPCU8:
|
||||||
|
data[0] = args->dataU8;
|
||||||
|
break;
|
||||||
|
case kHDRPCException:
|
||||||
|
case kHDRPCU16:
|
||||||
|
data[0] = args->dataU16 >> 8;
|
||||||
|
data[1] = args->dataU16 & 0xFF;
|
||||||
|
break;
|
||||||
|
case kHDRPCU32:
|
||||||
|
data[0] = args->dataU32 >> 24;
|
||||||
|
data[1] = (args->dataU32 >> 16) & 0xFF;
|
||||||
|
data[2] = (args->dataU32 >> 8) & 0xFF;
|
||||||
|
data[3] = args->dataU32 & 0xFF;
|
||||||
|
break;
|
||||||
|
#ifdef HDRPC_USE_64
|
||||||
|
case kHDRPCU64:
|
||||||
|
data[0] = args->dataU64 >> 56;
|
||||||
|
data[1] = (args->dataU64 >> 48) & 0xFF;
|
||||||
|
data[2] = (args->dataU64 >> 40) & 0xFF;
|
||||||
|
data[3] = (args->dataU64 >> 32) & 0xFF;
|
||||||
|
data[4] = (args->dataU64 >> 24) & 0xFF;
|
||||||
|
data[5] = (args->dataU64 >> 16) & 0xFF;
|
||||||
|
data[6] = (args->dataU64 >> 8) & 0xFF;
|
||||||
|
data[7] = args->dataU64 & 0xFF;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
LogD("Not support type[0x%x]", args->type);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint16_t IconvReadData(HDRPCSession *session, uint16_t type, uint8_t *data, uint16_t len) {
|
||||||
|
if (session == NULL || data == NULL || len == 0) {
|
||||||
|
LogD("read error, type[0x%x], len[%d]", type, len);
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (session->index >= session->len) {
|
||||||
|
LogD("index[%d] len[%d] error", session->index, session->len);
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint8_t index = session->index++;
|
||||||
|
session->args[index].type = type;
|
||||||
|
switch (type) {
|
||||||
|
case kHDRPCUserData:
|
||||||
|
case kHDRPCBuffer:
|
||||||
|
case kHDRPCString:
|
||||||
|
if (len < 2) {
|
||||||
|
LogD("type[0x%x], len[%d] error", type, len);
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
session->args[index].buffer.len = data[0];
|
||||||
|
session->args[index].buffer.data = data + 1;
|
||||||
|
return session->args[index].buffer.len + 1;
|
||||||
|
case kHDRPCU8:
|
||||||
|
session->args[index].dataU8 = data[0];
|
||||||
|
return sizeof(uint8_t);
|
||||||
|
case kHDRPCException:
|
||||||
|
case kHDRPCU16:
|
||||||
|
if (len < sizeof(uint16_t)) {
|
||||||
|
LogD("type[0x%x], len[%d] error", type, len);
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
session->args[index].dataU16 = data[0] << 8 | data[1];
|
||||||
|
return sizeof(uint16_t);
|
||||||
|
case kHDRPCU32:
|
||||||
|
if (len < sizeof(uint32_t)) {
|
||||||
|
LogD("type[0x%x], len[%d] error", type, len);
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
session->args[index].dataU32 = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
|
||||||
|
return sizeof(uint32_t);
|
||||||
|
#ifdef HDRPC_USE_64
|
||||||
|
case kHDRPCU64:
|
||||||
|
if (len < sizeof(uint64_t)) {
|
||||||
|
LogD("type[0x%x], len[%d] error", type, len);
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
session->args[index].dataU64 = data[0] << 56 | data[1] << 48 | data[2] << 40 | data[3] << 32 | data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
|
||||||
|
return sizeof(uint64_t);
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
LogD("Not support type[0x%x]", type);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ReadCall(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 ;
|
||||||
|
}
|
||||||
|
|
||||||
|
Call(session);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void HDRPCInitSession(HDRPCSession *session, HDRPCArgs *args, uint8_t len)
|
||||||
|
{
|
||||||
|
if (session == NULL) {
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
|
||||||
|
session->index = 0;
|
||||||
|
session->len = len;
|
||||||
|
session->func = 0;
|
||||||
|
session->args = args;
|
||||||
|
if (args == NULL && len > 0) {
|
||||||
|
LogD("args is nullptr, len[%d] error", len);
|
||||||
|
session->len = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint16_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)
|
||||||
|
{
|
||||||
|
sInfo.writeCall = writeCall;
|
||||||
|
sInfo.callback = callBuff;
|
||||||
|
sInfo.session = buffer;
|
||||||
|
sInfo.callLen = len;
|
||||||
|
if (callBuff == NULL && len > 0) {
|
||||||
|
LogD("callBuff is nullptr, len[%d] error", len);
|
||||||
|
sInfo.callLen = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint16_t i = 0; i < sInfo.callLen; ++i) {
|
||||||
|
memset(&callBuff[i], 0, sizeof(HDRPCCallBuffer));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t _HDRPCAddArgs(HDRPCSession *session, uint8_t type, void *args, uint8_t len)
|
||||||
|
{
|
||||||
|
if (session == NULL) {
|
||||||
|
LogD("Session is nullptr");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (len == 0) {
|
||||||
|
LogD("type[0x%x], args len is 0", type);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint16_t i = 0; i < len; ++i) {
|
||||||
|
if (session->index >= session->len) {
|
||||||
|
LogD("Session type[0x%x] is full", type);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint8_t index = session->index;
|
||||||
|
++session->index;
|
||||||
|
session->args[index].type = type;
|
||||||
|
switch (type) {
|
||||||
|
case kHDRPCU8:
|
||||||
|
session->args[index].dataU8 = *(uint8_t *)args;
|
||||||
|
break;
|
||||||
|
case kHDRPCException:
|
||||||
|
case kHDRPCU16:
|
||||||
|
session->args[index].dataU16 = *(uint16_t *)args;
|
||||||
|
break;
|
||||||
|
case kHDRPCU32:
|
||||||
|
session->args[index].dataU32 = *(uint32_t *)args;
|
||||||
|
break;
|
||||||
|
#ifdef HDRPC_USE_64
|
||||||
|
case kHDRPCU64:
|
||||||
|
session->args[index].dataU64 = *(uint64_t *)args;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
case kHDRPCUserData:
|
||||||
|
case kHDRPCBuffer:
|
||||||
|
case kHDRPCString:
|
||||||
|
session->args[index].buffer.data = (uint8_t *)args;
|
||||||
|
session->args[index].buffer.len = len;
|
||||||
|
return 1;
|
||||||
|
default:
|
||||||
|
LogD("Not support type[0x%x]", type);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t HDRPCParseArgs(void *data, uint16_t len, HDRPCSession *session)
|
||||||
|
{
|
||||||
|
if (session == NULL) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
session->func = HDRPC_INVAID_FUNC;
|
||||||
|
if (len < 2) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1 - 2字节 - 调用功能ID
|
||||||
|
* 2 - 多字节 - 参数包
|
||||||
|
* 参数包根据1字节类型判断对应长度
|
||||||
|
*/
|
||||||
|
session->index = 0;
|
||||||
|
uint8_t *d = (uint8_t *)data;
|
||||||
|
session->func = d[0] << 8 | d[1];
|
||||||
|
uint16_t index = 2;
|
||||||
|
while (index < len) {
|
||||||
|
const uint8_t type = d[index++];
|
||||||
|
if (index >= len) {
|
||||||
|
LogD("func[%x], type[0x%x], index[%d] len[%d] error", session->func, type, index, len);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint8_t useLen = IconvReadData(session, type, d + index, len - index);
|
||||||
|
index += useLen;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t _HDRPCCheckArgs(HDRPCSession *session, uint8_t *type, uint8_t len)
|
||||||
|
{
|
||||||
|
for (uint16_t i = 0; i < len; ++i) {
|
||||||
|
if (session->args[i].type != type[i]) {
|
||||||
|
LogD("Check index[%d] Type[0x%x] faild", i, type[i]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
HDRPCValue_t _HDRPCGetValue(HDRPCSession *session, uint8_t type, int index)
|
||||||
|
{
|
||||||
|
if (session == NULL) {
|
||||||
|
LogD("Session is nullptr");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (index < 0 || index >= session->len) {
|
||||||
|
LogD("index[%d] len[%d] error", index, session->len);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (session->args[index].type != type) {
|
||||||
|
LogD("index[%d] type[0x%x][0x%x] Not match", index, session->args[index].type, type);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case kHDRPCU8:
|
||||||
|
return session->args[index].dataU8;
|
||||||
|
case kHDRPCException:
|
||||||
|
case kHDRPCU16:
|
||||||
|
return session->args[index].dataU16;
|
||||||
|
case kHDRPCU32:
|
||||||
|
return session->args[index].dataU32;
|
||||||
|
#ifdef HDRPC_USE_64
|
||||||
|
case kHDRPCU64:
|
||||||
|
return session->args[index].dataU64;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
LogD("Not match type[0x%x] index[%d]", type, index);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *_HDRPCGetData(HDRPCSession *session, uint8_t type, int index, uint8_t *len)
|
||||||
|
{
|
||||||
|
if (session == NULL) {
|
||||||
|
LogD("Session is nullptr");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (index < 0 || index >= session->len) {
|
||||||
|
LogD("index[%d] len[%d] error", index, session->len);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (session->args[index].type != type) {
|
||||||
|
LogD("index[%d] type[0x%x][0x%x] Not match", index, session->args[index].type, type);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case kHDRPCUserData:
|
||||||
|
case kHDRPCBuffer:
|
||||||
|
if (len) {
|
||||||
|
*len = session->args[index].buffer.len;
|
||||||
|
}
|
||||||
|
|
||||||
|
return session->args[index].buffer.data;
|
||||||
|
case kHDRPCString:
|
||||||
|
if (len) {
|
||||||
|
*len = session->args[index].buffer.len / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return session->args[index].buffer.data;
|
||||||
|
default:
|
||||||
|
LogD("Not match type[0x%x] index[%d]", type, index);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void HDRPCReadData(void *data, uint16_t len)
|
||||||
|
{
|
||||||
|
if (sInfo.callback == NULL || sInfo.callLen ==0) {
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
|
||||||
|
HDRPCSession *session = sInfo.session;
|
||||||
|
if (session == NULL) {
|
||||||
|
HDRPCSession buff;
|
||||||
|
session = &buff;
|
||||||
|
HDRPCArgs args[HDRPC_USE_SESSION_ARGS];
|
||||||
|
HDRPCInitSession(session, args, HDRPC_USE_SESSION_ARGS);
|
||||||
|
ReadCall(session, data, len);
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReadCall(session, data, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _HDRPCSendData(HDRPCSession *session, uint16_t funcCode, HDRPCCallback callBack, const char *funcName, uint8_t nameLen)
|
||||||
|
{
|
||||||
|
if (sInfo.writeCall == NULL) {
|
||||||
|
LogD("Write Call is nullptr");
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (session) {
|
||||||
|
session->func = funcCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
if (nameLen == 0 || callBack == NULL) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (HDRPCAddUserData(session, (void *)funcName, nameLen) == 0) {
|
||||||
|
LogD("Add Call Data[%s] faild", funcName);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (AddCall(callBack, funcName, nameLen) == -1) {
|
||||||
|
LogD("Add Call[%s] faild", funcName);
|
||||||
|
}
|
||||||
|
} while (0);
|
||||||
|
|
||||||
|
sInfo.writeCall(session);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint16_t HDRPCConvSendData(HDRPCSession *session, uint8_t *data, uint16_t len)
|
||||||
|
{
|
||||||
|
if (session == NULL || data == NULL || len < 2) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int useLen = 0;
|
||||||
|
data[useLen++] = session->func >> 8;
|
||||||
|
data[useLen++] = session->func & 0xFF;
|
||||||
|
for (int 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);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
data[useLen++] = session->args[i].type;
|
||||||
|
AddArgToBuffer(&session->args[i], data + useLen);
|
||||||
|
useLen += argLen;
|
||||||
|
}
|
||||||
|
|
||||||
|
return useLen;
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user