Initial commit: CCU621_M firmware project with BLE debug link support.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user