接口定义

// b429.h

struct b429_msg_d5 {
  int field1;
  int field2;
}

struct b429_msg {
	int type; // d5, f2, etc
	union {
    struct b429_payload_d5 payload_d5;
    struct b429_payload_f2 pyaload_f2;
  }
};

// 另一种方案:使用指针
struct b429_msg {
	int type; // d5, f2, etc
	void* payload;
};

/*
 * 参数:
 *   buf : 传入参数。需要反序列化(de-serialize)的429总线读取到的原始数据字节流。
 *   len : 传入参数。buf 里有效数据的长度。
 *   msg : 传出参数。*msg 为序列化后生成的信息。为 malloc 动态分配的内存,由接口调用方负责释放(free)。
 * 返回值: 成功时,返回 buf 里已经读取并处理完成的字节流部分长度。失败时,返回 <0 错误码。
 *
 * 如果当前传入的 buf 里无法读取到1个完整 msg,接口实现方可以选择:
 *   a. 读取buf里已有的全部或部分内容暂存到自己的内部缓存区里,返回已读取的长度。返回的 *msg 置为 NULL。
 *   b. (推荐)直接返回 0 。调用方会在从总线读取到更多数据后再次尝试调用此接口并重新传入此 buf 的开头指针。推荐使用这种方式。实现简单,无需维护内部状态。
 * 如果当前传入的 buf 里包含完整的多个 msg,只读取并解析出第1个消息。调用方会循环调用接口直到无法读取出更多消息。
 * 如果当前传入的 buf 里包含无效数据(校验或协议解析失败),读取并丢弃无效数据部分,其长度应包含在返回值里。
 *
 * Thread safety: 尚不明确。目前设计调用方应该不会在多个线程里同时调用接口。
 */
ssize_t b429_readmsg(char* buf, size_t len, struct b429_msg** msg);

/*
 * 参数:
 *   buf : 传出参数。*buf 为传入的 msg 消息生成的序列化后(serialize)数据。为 malloc 动态分配的内存,由接口调用方负责释放。
 *   msg : 传入参数。需要序列化的消息。
 * 返回值: 成功时,返回序列化生成的 buf 有效数据长度。失败时返回 <0 错误码。
 *
 * TS : 尚不明确。
 */
ssize_t b429_serialize(char** buf, struct b429_msg* msg);

/*
 * 如果 struct b429_msg 内部存在动态分配的指针类型字段,需要实现这个释放内存接口
 * 否则,可以直接使用标准 libc 的 free。
 *
 */
void b429_msg_free(struct b429_msg* msg);

内部实现

429 protocol interface