如何解析接收到的可变长度数据

How to parse received data with variable length

假设我正在接收一个具有可变长度数据负载的数据包。

**byte_num**    **size**     **type**
   0             1        Length
   1             1        SrcArsDev
   2             4        Src_ID
   6             1        DstArsDev
   7             4        Dst_ID
  11             4        Session
  15             1        CMD
  16             N        N bytes payload N<=96
 16+N            2        CRC

将通过SPI 通信接收数据。解析数据包以便我以后可以处理不同元素的一般方法是什么?

你能告诉我一个简单的 function/routine 填充结构元素吗?

一种方法是定义表示最大可能数据包大小的打包结构:

#pragma pack(push,1) // make sure everything is packed to byte level
typedef struct {
    uint8_t        Length;
    uint8_t        SrcArsDev;
    uint32_t       Src_ID;
    uint8_t        DstArsDev;
    uint32_t       Dst_ID;
    uint32_t       Session;
    uint8_t        CMD;
    uint8_t        payload[96 + 2]; // payload + CRC
} Message;
#pragma pack(pop)    // restore struct packing

您的读取例程然后直接读取到这样的结构,然后消息的所有元素随后都可以作为结构中的字段进行访问。

唯一棘手的部分是您需要计算出实际 CRC 字节基于 Length 的位置,然后从 payload[] 缓冲区中提取这些字节,但这并不难:

Message msg;

ssize_t n = read(fd, &msg, sizeof(msg));            // read data into `msg`

uint16_t crc = *(int16_t*)&msg.payload[msg.Length]; // extract CRC

// validate CRC + perhaps also verify that n is consistent with msg.Length

// then access elements as needed:

src_id = msg.Src_ID;
dst_id = msg.Dst_ID;

当你不介意用特殊函数校验CRC时,你可以像@Paul定义的那样转换一个struct。当你读取了inputbuf后,你可以使用

struct *Message payload;   
payload = (Message *) inputbuf;

现在您无需先复制有效负载成员即可访问它们。