263 lines
7.3 KiB
C
263 lines
7.3 KiB
C
|
|
|
|
#include "HProtocolBind.h"
|
|
#include "HDLog.h"
|
|
#include <string.h>
|
|
|
|
#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);
|
|
}
|
|
|