4

我需要将一种 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];    
};
4

1 回答 1

6

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 

所以在这种情况下,我们使用 TLV 发送一个充满字节的缓冲区,接收设备(在这种情况下是 SIM 卡)将解析标签,知道期望长度然后知道在传输之前有多少字节的“值”完全的。请注意,这不是一个完整的真正 TLV,因为每条数据都没有自己的 TL,有些只是已知的(例如00“标签”和“长度”之间的那些,这些是参数,它们被设置为为 1 个字节并始终遵循指令(不需要标签或长度)

这就是概述。现在你的问题在哪里?首先,我希望您现在可以看到,我们需要知道标记的内容。这取决于谁在期待数据,这是您应该知道的。看看你的问题,我认为它是这样的:

  1. 客户端 A 生成一个“struct a”发送给客户端 B。(必须有一个“struct a”标签)
  2. “struct a”由“struct b”和“struct c”组成,所以我们也需要这些标签

为了让客户端 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

理想情况下,由于您在每个结构中都嵌入了数据,因此您也将拥有子标签:

// 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

因此,您的每个结构都将正常填充数据,然后当您发送数据时,您会将值解构到缓冲区中。下面的伪代码给你的想法

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*/
...

因此,当客户端 B 获得大量数据缓冲区时,他们可以构建自己的本地struct a, struct bstruct c然后解析出字段并填充。

于 2013-08-06T17:33:10.420 回答