我需要将一个C结构转换为TLV格式并将其发送出去.有人可以帮我吗?我的结构是一个非常嵌套的结构,有很多向不同结构的方向(指针)和大量的void*.所以,我被困住了,可以使用帮助.
struct a {
char a[100];
char b;
struct b *tag;
struct c *value;
void *data;
};
struct b {
void *data;
int a;
};
struct c {
void *data;
char arr[100];
};
Run Code Online (Sandbox Code Playgroud)
TLV代表标签长度值,这正是它的本质.你可能会对这一点感到困惑.正常使用这种方法是当你获得一个大的字节缓冲区时,可能是从某个串行设备填充的,你需要知道该缓冲区中的内容.
例如,SIM卡和手机之间的通信.有许多明确定义的标签,每个标签对应于将被解码的消息类型.(这些都在规范中定义,例如ISO 7816-4),例如,如果要写入SIM卡中的二进制文件,则需要告诉SIM卡要发送多少字节的数据.所以你要构建一些消息,如:
A0 D0 00 00 0A 01 02 03 04 05 06 07 08 09 0A
+-----+ +-+ +---------------------------+
| | |
tag length Value
// A0D0 - the tag tells the SIM I want to "write a binary file to a GSM SIM card"
// 0A - Says the aforementioned write will be 10 bytes in Length
// 0102... - Then the Value follows the length
Run Code Online (Sandbox Code Playgroud)
所以在这种情况下我们使用TLV发送一个满字节的缓冲区,接收设备(在这种情况下为SIM卡)将解析Tag,已知期望长度然后知道在传输之前有多少字节的"Value".完成.请注意,这不是一个完整的真实TLV,因为每个数据都没有它自己的TL,有些只是已知的(例如00
"tag"和"length"之间的那些,这些是参数,它们被设置为是1个字节,并始终遵循指令是不需要有标签或长度)
这就是概述.现在,我们在哪里留下您的问题?首先,正如我希望你现在可以看到的那样,我们需要知道将要标记什么.这取决于谁在期待数据,这是你应该知道的.看看你的问题,我认为它是这样的:
为了使客户端B能够读取这些值,我们需要定义标签:
// Tags for structures
#define TAG_A 0x90 // These values are made up but it's important to note
#define TAG_B 0x91 // both Client A and Client B must know what the tags mean
#define TAG_C 0x92 // what what value they are set to
Run Code Online (Sandbox Code Playgroud)
理想情况下,由于您在每个结构中都嵌入了数据,因此您也可以使用子标记:
// Tags for struct A:
#define TAG_A_FIX_DATA 0x93
#define TAG_A_VAR_DATA 0x94
#define TAG_B_FIX_DATA 0x95
#define TAG_B_VAR_DATA 0x96
Run Code Online (Sandbox Code Playgroud)
因此,每个结构都将正常填充数据,然后当您将数据发送到缓冲区时,将数据解析.以下伪代码为您提供了这个想法
unsigned char *buffer = malloc(/*big enough for struct a+b+c+tags*/);
buffer[0] = TAG_A;
buffer[1] = /*size of your A structure*/
buffer[2] = TAG_A_FIX_DATA;
buffer[3] = 101; // for the array and the char.. if that's how you want to handle it
buffer[4-105] = a.a and a.b;
buffer[106] = TAG_B;
buffer[107] = /*length of struct B*/
...
Run Code Online (Sandbox Code Playgroud)
因此,当客户端B获取数据的大缓冲区,他们可以构建自己的地方struct a
,struct b
和struct c
然后解析出字段和填充.