#include "HProtocolBind.h" #include "HDLog.h" #include #ifndef LogD #define LogD(...) #endif #define CREATE_INDEX(id, index) ((id << 8) | index) #define GET_ID(index) ((index >> 8) & 0xFF) #define GET_INDEX(index) (index & 0xFF) enum eEnableStatus { kNotEnable, ///< 未使能 kWaitEnable, ///< 等待使能 kEnable, ///< 使能 kCallEnable, ///< 回调时使能, 需要延迟使能 }; struct __attribute__((packed)) BindInfo { uint32_t enable : 1; ///< 绑定使能 uint32_t curr : 1; ///< 当前绑定 uint32_t isCallAdd : 1; ///< 在回调的时候添加 uint32_t useLen : 8; ///< 使用长度, 减少扫描次数 uint32_t len : 8; ///< 绑定个数 HProtocolBindInfo *binds; ///< 绑定 }; static struct BindInfo sBindRegisters[HPROTOCOL_BIND_MAX]; static void FreeItem(uint8_t id, HProtocolBind_t index) { if (sBindRegisters[id].enable) { --sBindRegisters[id].useLen; } memset(&sBindRegisters[id].binds[index], 0, sizeof(HProtocolBindInfo)); } static void ResetEnable(uint8_t id) { if (sBindRegisters[id].isCallAdd == 0) { return ; } sBindRegisters[id].isCallAdd = 0; for (uint16_t i = 0; i < sBindRegisters[id].len; ++i) { if (sBindRegisters[id].binds[i].enable == kCallEnable) { sBindRegisters[id].binds[i].enable = kEnable; } } } uint8_t HProtocolBindRegister(uint8_t id, HProtocolBindInfo *info, uint8_t infoLen) { if (id >= HPROTOCOL_BIND_MAX) { LogD("error id[%d], max[%d]", id, HPROTOCOL_BIND_MAX); return 0; } if (sBindRegisters[id].enable == 1) { LogD("id[%d] already register", id); return 0; } sBindRegisters[id].binds = info; sBindRegisters[id].len = infoLen; sBindRegisters[id].enable = 1; return 1; } HProtocolBind_t HProtocolBindAddTask(HProtocolBindId_t id, HProtocolBindFunc_t func, HProtocolBindCallback callback, uint8_t keepAlive) { if (id >= HPROTOCOL_BIND_MAX) { LogD("error id[%d], max[%d]", id, HPROTOCOL_BIND_MAX); return HPROTOCOL_BIND_INVALID; } if (sBindRegisters[id].enable == 0) { LogD("not enable, id[%d]", id); return HPROTOCOL_BIND_INVALID; } if (callback == NULL) { LogD("callback is null, id[%d]", id); return HPROTOCOL_BIND_INVALID; } for (uint16_t i = 0; i < sBindRegisters[id].len; ++i) { if (sBindRegisters[id].binds[i].enable) { continue; } // 防中断导致数据重叠 sBindRegisters[id].binds[i].enable = kWaitEnable; if (sBindRegisters[id].binds[i].enable != 1) { continue; } ++sBindRegisters[id].useLen; sBindRegisters[id].binds[i].enable = kEnable; sBindRegisters[id].binds[i].delayMs = HPROTOCOL_BIND_TIMEOUT; sBindRegisters[id].binds[i].isTimeout = 0; sBindRegisters[id].binds[i].func = func; sBindRegisters[id].binds[i].lastTime = HDLogGetTime(); sBindRegisters[id].binds[i].callback = callback; sBindRegisters[id].binds[i].keepAlive = keepAlive; // 当前在回调, 需要延迟使能 if (sBindRegisters[id].curr) { sBindRegisters[id].binds[i].enable = kCallEnable; sBindRegisters[id].isCallAdd = 1; } return CREATE_INDEX(id, i); } LogD("bind full, id[%d], len[%d]", id, sBindRegisters[id].len); return HPROTOCOL_BIND_INVALID; } void HProtocolBindSetTimeout(HProtocolBind_t index, uint32_t delayMs) { const uint8_t id = GET_ID(index); index = GET_INDEX(index); if (id >= HPROTOCOL_BIND_MAX) { LogD("error id[%d], max[%d]", id, HPROTOCOL_BIND_MAX); return ; } if (index < 0 || index >= sBindRegisters[id].len) { LogD("error index[%d], len[%d]", index, sBindRegisters[id].len); return ; } sBindRegisters[id].binds[index].delayMs = delayMs; } void HProtocolBindRemoveTask(HProtocolBind_t index) { const uint8_t id = GET_ID(index); index = GET_INDEX(index); if (id >= HPROTOCOL_BIND_MAX) { LogD("error id[%d], max[%d]", id, HPROTOCOL_BIND_MAX); return ; } if (index < 0 || index >= sBindRegisters[id].len) { LogD("error index[%d], len[%d]", index, sBindRegisters[id].len); return ; } FreeItem(id, index); } uint8_t HProtocolBindIsTimeout(HProtocolBind_t index) { const uint8_t id = GET_ID(index); index = GET_INDEX(index); if (id >= HPROTOCOL_BIND_MAX) { LogD("error id[%d], max[%d]", id, HPROTOCOL_BIND_MAX); return 0; } if (index < 0 || index >= sBindRegisters[id].len) { LogD("error index[%d], len[%d]", index, sBindRegisters[id].len); return 0; } return sBindRegisters[id].binds[index].isTimeout; } void HProtocolBindUpdateData(HProtocolBindId_t id, HProtocolBindFunc_t func, void* data, uint16_t len) { if (id >= HPROTOCOL_BIND_MAX) { LogD("error id[%d], max[%d]", id, HPROTOCOL_BIND_MAX); return ; } if (sBindRegisters[id].enable == 0) { LogD("not enable, id[%d]", id); return ; } // 减少扫描次数 if (sBindRegisters[id].useLen == 0) { return ; } for (uint16_t i = 0; i < sBindRegisters[id].len; ++i) { if (sBindRegisters[id].binds[i].enable == kNotEnable || sBindRegisters[id].binds[i].enable == kCallEnable) { continue; } if (sBindRegisters[id].binds[i].func != func) { continue; } if (sBindRegisters[id].binds[i].isTimeout) { continue; } // 可能是同一个功能码绑定多个回调 if (sBindRegisters[id].binds[i].callback) { sBindRegisters[id].curr = 1; sBindRegisters[id].binds[i].callback(CREATE_INDEX(id, i), (uint8_t*)data, len); sBindRegisters[id].curr = 0; } // 回调后立即释放 if (sBindRegisters[id].binds[i].keepAlive == 0) { FreeItem(id, i); } } } void HProtocolBindRun(HProtocolBindId_t id) { if (id >= HPROTOCOL_BIND_MAX) { LogD("error id[%d], max[%d]", id, HPROTOCOL_BIND_MAX); return ; } if (sBindRegisters[id].enable == 0) { LogD("not enable, id[%d]", id); return ; } // 减少扫描次数 if (sBindRegisters[id].useLen == 0) { return ; } for (uint16_t i = 0; i < sBindRegisters[id].len; ++i) { if (sBindRegisters[id].binds[i].enable == kNotEnable || sBindRegisters[id].binds[i].enable == kCallEnable) { continue; } if (sBindRegisters[id].binds[i].keepAlive) { continue; } if (sBindRegisters[id].binds[i].isTimeout) { continue; } if (HDLogGetTime() - sBindRegisters[id].binds[i].lastTime < sBindRegisters[id].binds[i].delayMs) { continue; } sBindRegisters[id].binds[i].isTimeout = 1; // 可能是同一个功能码绑定多个回调 if (sBindRegisters[id].binds[i].callback) { sBindRegisters[id].curr = 1; sBindRegisters[id].binds[i].callback(CREATE_INDEX(id, i), NULL, 0); sBindRegisters[id].curr = 0; } // 回调后立即释放 FreeItem(id, i); } ResetEnable(id); }