Files
kunlun/app/utils/iot_app_meta_buffer_handle.c

250 lines
9.6 KiB
C
Raw Normal View History

2024-09-28 14:24:04 +08:00
/****************************************************************************
Copyright(c) 2019 by Aerospace C.Power (Chongqing) Microelectronics. ALL RIGHTS RESERVED.
This Information is proprietary to Aerospace C.Power (Chongqing) Microelectronics and MAY NOT
be copied by any method or incorporated into another program without
the express written consent of Aerospace C.Power. This Information or any portion
thereof remains the property of Aerospace C.Power. The Information contained herein
is believed to be accurate and Aerospace C.Power assumes no responsibility or
liability for its use in any way and conveys no license or title under
any patent or copyright and makes no representation or warranty that this
Information is free from patent or copyright infringement.
****************************************************************************/
#include "os_timer_api.h"
#include "os_lock_api.h"
#include "iot_io_api.h"
#include "iot_pkt_api.h"
#include "iot_plc_msg_api.h"
#include "iot_app_pib_api.h"
#include "iot_board_api.h"
#include "iot_errno_api.h"
#include "iot_app_meta_handle.h"
#include "iot_app_meta_buffer_handle.h"
#include "iot_version_api.h"
/* length of meta cmd buffer */
#define META_BUF_LENGTH 264
#pragma pack(push) // save the pack status
#pragma pack(1) // 1 byte align
typedef struct _meta_buf_ctr_t
{
/* mutex for meta bufer */
os_mutex_h meta_mutex;
/* point to the buffer head */
uint8_t * buf_head;
/* how many space left in the buffer */
int16_t buf_rest;
/* point to the max used position in the buffer */
uint8_t * buf_used;
/* point to the buffer end */
uint8_t * buf_end;
/* point to the check position, next cmd will use the position */
uint8_t * buf_check_pos;
/* point to the buffer pkt */
iot_pkt_t * buf;
} meta_buf_ctr_t;
#pragma pack(pop) /* restore the pack status */
meta_buf_ctr_t g_meta_buf;
void iot_meta_bin_dump(uint8_t *data, uint32_t dlen)
{
uint32_t i = 0;
uint32_t offset = 0;
iot_cus_printf("[dump count is %d]:", dlen);
for (i = 0; i < dlen; ++i) {
offset += iot_cus_printf("%02X ", data[i]);
}
iot_cus_printf("\n");
return;
}
/**
* @brief iot_meta_put_cmd_to_buf() - put meta cmd to the buffer
* @param cmd:point to the meta cmd data
* @return: ERR_OK, or error reason
*/
/* 把meta指令数据放进meta bufferbuffer里面有这几个指针
head buffer头
position
used 使
end buffer尾
head <= position <= used <= end
1.position在取数据时可能向后移动buffer里的head和position之间的
()
2.buffer的used后面空间足够的情况下copy次数
3.buffer的used后面空间不够时position到used之间的数据copy到head
position之前的空间
4.buffer剩余空间不够*/
uint8_t iot_meta_put_cmd_to_buf(meta_cmd_t *cmd)
{
uint8_t ret = ERR_OK;
os_acquire_mutex(g_meta_buf.meta_mutex);
iot_cus_printf("cmd->datalen = %d, buf_rest = %d, front = %d\n",
cmd->datalen + MIN_META_CMD_LEN, g_meta_buf.buf_rest,
g_meta_buf.buf_check_pos - g_meta_buf.buf_head);
if (cmd->datalen + MIN_META_CMD_LEN > g_meta_buf.buf_rest +
g_meta_buf.buf_check_pos - g_meta_buf.buf_head) {
iot_cus_printf("no space for id_group=0x%X, id=0x%X\n", cmd->id_group,
cmd->id);
os_release_mutex(g_meta_buf.meta_mutex);
ret = ERR_FAIL;
goto out;
}
/* 当后面的空间不够了就把之前的删除把后面的copy前来取数据基本改成指针偏移
buffer快满或隔着取的情况下需要copy */
if (cmd->datalen + MIN_META_CMD_LEN > g_meta_buf.buf_rest) {
os_mem_set(g_meta_buf.buf_head, 0,
g_meta_buf.buf_check_pos - g_meta_buf.buf_head);
os_mem_cpy(g_meta_buf.buf_head, g_meta_buf.buf_check_pos,
g_meta_buf.buf_used - g_meta_buf.buf_check_pos);
g_meta_buf.buf_used -= (g_meta_buf.buf_check_pos - g_meta_buf.buf_head);
g_meta_buf.buf_check_pos = g_meta_buf.buf_head;
g_meta_buf.buf_rest = g_meta_buf.buf_end - g_meta_buf.buf_used;
}
os_mem_cpy(g_meta_buf.buf_used, cmd, MIN_META_CMD_LEN + cmd->datalen);
g_meta_buf.buf_used += (MIN_META_CMD_LEN + cmd->datalen);
g_meta_buf.buf_rest -= (MIN_META_CMD_LEN + cmd->datalen);
os_release_mutex(g_meta_buf.meta_mutex);
iot_cus_printf("%s data\n", __FUNCTION__);
iot_meta_bin_dump(g_meta_buf.buf_head, g_meta_buf.buf_used -
g_meta_buf.buf_head);
out:
return ret;
}
/* 接收方通过while循环处理每一个meta命令从buffer的position开始直到meta命令
meta剩余空间不够(
meta空间不够)
1meta命令长度来position值
2position不再增加meta取走
*/
uint16_t iot_meta_get_cmd_from_buf(uint8_t *meta_data, uint16_t datalen)
{
uint8_t *data = meta_data;
uint8_t *data_buf;
/* 记录一次中间提取meta指令的开始 */
uint8_t *data_get_start = NULL;
/* meta不够标志只要发现一次meta不够就置位
g_meta_buf.buf_check_pos不能再变 */
uint8_t meta_small = false;
uint8_t pick_cnt = 0;
uint16_t pick_data_len = 0;
/* 为了减少copy次数连续取走的数据所占空间一起处理
buffer里的起始地址和长度 */
uint16_t data_get_len = 0;
uint16_t meta_len = datalen;
uint16_t cmd_len;
meta_cmd_t *cmd;
os_acquire_mutex(g_meta_buf.meta_mutex);
data_buf = g_meta_buf.buf_check_pos;
cmd = (meta_cmd_t *)data_buf;
cmd_len = MIN_META_CMD_LEN + cmd->datalen;
while ((meta_len >= MIN_META_CMD_LEN) && cmd->id_group &&
(data_buf + MIN_META_CMD_LEN <= g_meta_buf.buf_used)) {
iot_cus_printf("%s meta_len = %d, cmd_len =%d\n", __FUNCTION__,
meta_len, cmd_len);
iot_meta_bin_dump(meta_data, datalen);
if (meta_len >= cmd_len) {
os_mem_cpy(data, (uint8_t *)cmd, cmd_len);
meta_len -= cmd_len;
pick_cnt += 1;
pick_data_len += cmd_len;
/* 本cmd空间不够但下一个够的情况,使用 */
if ((data_get_start == NULL) &&
(g_meta_buf.buf_check_pos != data_buf)) {
/* 本次从哪里开始提取 */
data_get_start = (uint8_t *)cmd;
}
data_get_len += cmd_len;
data_buf += cmd_len;
data += cmd_len;
if (meta_small == false) {
g_meta_buf.buf_check_pos = data_buf;
}
iot_meta_bin_dump(meta_data, datalen);
} else {
/* 这里这段用于处理本cmd空间不够但下一个够的情况这种情况下
copy */
iot_cus_printf("meta_len : %d < cmd_len : %d\n", meta_len, cmd_len);
if (data_get_start != NULL) {
os_mem_cpy(data_get_start, data_buf,
g_meta_buf.buf_used - data_buf);
os_mem_set(g_meta_buf.buf_used - data_get_len, 0, data_get_len);
data_buf = data_get_start + cmd_len;
g_meta_buf.buf_used -= data_get_len;
g_meta_buf.buf_rest += data_get_len;
data_get_start = NULL;
} else {
data_buf += cmd_len;
}
data_get_len = 0;
meta_small = true;
}
/* 指向下一个cmd */
cmd = (meta_cmd_t *)data_buf;
cmd_len = MIN_META_CMD_LEN + cmd->datalen;
}
if (data_get_start != NULL) {
os_mem_cpy(data_get_start, data_buf, g_meta_buf.buf_used - data_buf);
os_mem_set(g_meta_buf.buf_used - data_get_len, 0, data_get_len);
g_meta_buf.buf_used -= data_get_len;
g_meta_buf.buf_rest += data_get_len;
}
os_release_mutex(g_meta_buf.meta_mutex);
iot_cus_printf("g_meta_buf.head = %d, g_meta_buf.pos = %d\n",
g_meta_buf.buf_head, g_meta_buf.buf_check_pos);
iot_meta_bin_dump(g_meta_buf.buf_head, g_meta_buf.buf_used -
g_meta_buf.buf_head);
iot_cus_printf(" %d meta cmd has been get, total %d bytes\n", pick_cnt, pick_data_len);
return pick_data_len;
}
/**
* @brief iot_meta_buf_init() - initalize meta buffer
* @param module_id: module id
* @return: ERR_OK, or error reason
*/
uint8_t iot_meta_buf_init(uint16_t module_id)
{
uint8_t ret = ERR_OK;
os_mem_set(&g_meta_buf, 0, sizeof(meta_buf_ctr_t));
g_meta_buf.buf = iot_pkt_alloc(META_BUF_LENGTH, module_id);
if (g_meta_buf.buf == NULL) {
iot_cus_printf("meta buffer alloc fail\n");
ret = ERR_FAIL;
goto out;
}
g_meta_buf.buf_head = iot_pkt_put(g_meta_buf.buf, META_BUF_LENGTH);
os_mem_set(g_meta_buf.buf_head, 0, META_BUF_LENGTH);
g_meta_buf.buf_used = g_meta_buf.buf_head;
g_meta_buf.buf_rest = META_BUF_LENGTH;
g_meta_buf.buf_end = g_meta_buf.buf_head + META_BUF_LENGTH;
g_meta_buf.buf_check_pos = g_meta_buf.buf_head;
g_meta_buf.meta_mutex = os_create_mutex(module_id);
out:
return ret;
}