Initial commit: CCU621_M firmware project with BLE debug link support.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-07-08 17:28:36 +08:00
commit 9ceb218f80
1597 changed files with 724159 additions and 0 deletions
+167
View File
@@ -0,0 +1,167 @@
#include "pos_vtk/vtk_tlv.h"
#include "publicdata/public_define.h"
#include <string.h>
#if (POS_VTK_EN)
/******************************************************************************
* 模块说明:VTK TLV 编解码工具
*
* - 仅支持简单的 TLV 格式:1 字节 Tag + 1 字节 Length + Value。
* - 用于构造 VTK 应用层 TLV 消息(例如 Message name、Operation number、Amount)。
*
* 对外接口:
* - vtk_tlv_append() :追加任意二进制 TLV。
* - vtk_tlv_append_ascii() :追加 ASCII 字符串 TLV。
* - vtk_tlv_append_ascii_uint(): 以十进制 ASCII 形式追加整数 TLV。
* - vtk_tlv_find_first() :在 TLV 缓冲中查找首个指定 Tag。
******************************************************************************/
U8_T vtk_tlv_append(U8_T tag, const U8_T *pVal, U16_T len,
U8_T *pBuf, U16_T bufMax, U16_T *pOffset)
{
U16_T offset;
if (!pBuf || !pOffset)
return 0;
offset = *pOffset;
/* 仅支持短格式长度(1 字节,len < 128 */
if (len > 127U)
return 0;
if ((U16_T)(offset + 2U + len) > bufMax)
return 0;
pBuf[offset++] = tag;
pBuf[offset++] = (U8_T)len;
if (len > 0U && pVal)
{
(void)memcpy(&pBuf[offset], pVal, len);
offset = (U16_T)(offset + len);
}
*pOffset = offset;
return 1;
}
U8_T vtk_tlv_append_ascii(U8_T tag, const char *str,
U8_T *pBuf, U16_T bufMax, U16_T *pOffset)
{
U16_T len;
if (!str)
return 0;
len = (U16_T)strlen(str);
return vtk_tlv_append(tag, (const U8_T *)str, len, pBuf, bufMax, pOffset);
}
/* 把无符号整数转换为十进制 ASCII(不带 '\0'),右对齐或自然长度 */
static U8_T vtk_utoa_dec(U32_T value, char *out, U8_T minWidth)
{
char buf[16];
U8_T i = 0U;
U8_T len;
if (!out)
return 0;
/* 生成反向字符串 */
do
{
buf[i++] = (char)('0' + (value % 10U));
value /= 10U;
} while (value != 0U && i < sizeof(buf));
/* 实际长度至少为 minWidth */
while (i < minWidth && i < sizeof(buf))
{
buf[i++] = '0';
}
len = i;
/* 反转到输出缓冲 */
while (i > 0U)
{
*out++ = buf[--i];
}
return len;
}
U8_T vtk_tlv_append_ascii_uint(U8_T tag, U32_T value, U8_T minWidth,
U8_T *pBuf, U16_T bufMax, U16_T *pOffset)
{
char tmp[16];
U8_T len;
len = vtk_utoa_dec(value, tmp, minWidth);
if (len == 0U)
return 0;
return vtk_tlv_append(tag, (const U8_T *)tmp, len, pBuf, bufMax, pOffset);
}
U8_T vtk_tlv_find_first(const U8_T *pBuf, U16_T bufLen, U8_T tag,
const U8_T **ppVal, U16_T *pValLen)
{
U16_T offset = 0U;
if (!pBuf || !ppVal || !pValLen)
return 0;
while (offset + 2U <= bufLen)
{
U8_T t = pBuf[offset];
U8_T l = pBuf[offset + 1U];
U16_T next;
next = (U16_T)(offset + 2U + l);
if (next > bufLen)
return 0; /* TLV 结构损坏 */
if (t == tag)
{
*ppVal = &pBuf[offset + 2U];
*pValLen = l;
return 1;
}
offset = next;
}
return 0;
}
/*
* 外部使用示例:
*
* // 构造 TLV 缓冲用于预扣款请求(CDP)
* U8_T tlvBuf[VTK_MAX_APP_LEN];
* U16_T tlvLen = 0;
*
* // Tag 0x01: Message name = "CDP"
* vtk_tlv_append_ascii(0x01, "CDP", tlvBuf, sizeof(tlvBuf), &tlvLen);
*
* // Tag 0x03: Operation number = "12345"
* vtk_tlv_append_ascii_uint(0x03, 12345U, 1U, tlvBuf, sizeof(tlvBuf), &tlvLen);
*
* // Tag 0x04: Amount = "5000" (单位:分)
* vtk_tlv_append_ascii_uint(0x04, 5000U, 1U, tlvBuf, sizeof(tlvBuf), &tlvLen);
*
* // 解析响应时查找结果码(假设结果码放在 Tag 0x0D 的 Simple data block 首字节)
* const U8_T *pVal;
* U16_T valLen;
* if (vtk_tlv_find_first(tlvBuf, tlvLen, 0x0D, &pVal, &valLen) && valLen > 0U)
* {
* U8_T resultCode = pVal[0];
* // 0=Approved, 1=Declined, 2=Timeout...
* }
*/
#endif /* POS_VTK_EN */