基于UDS的DoIp实现(六) -- 通信协议实现:Socket 通信
ISO14229、UDS诊断服务文档,都说明UDS是基于Can通信实现,其接收的数据格式,也是Can数据格式。但是,一方面是在本地模拟Can通信比较麻烦,另一方面,也是想单独的将UDS抽出来,不依赖于通信协议,仅仅作为一个单独的功能进行实现,所以,这里才使用比较简单的Socket通信进行数据收发。
void SocketPeriodicTask(void) { //创建socket ID socket_create(&mSocket) //绑定ID socket_bind(&mSocket) //监听ID socket_listen(mSocket.id, 5) //等待客户端数据 socket_accept(&mSocket) while (1) { //读取数据 len = socket_read(mSocket.conn_sock, buf, MSG_RECEIVE_SIZE); //对接收的数据进行处理 ReceiveMsg(buf, len) sleep(1); } }
- 构造测试数据:
const u_uint8_t firstFrame[] = {0x10, 0x20, 0x2E, 0xF1, 0x8C, 0x00, 0x00, 0x00}; const u_uint8_t continuationFrames[][8] = { {0x21, 0x08, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06}, {0x22, 0x08, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D}, {0x23, 0x08, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14}, {0x24, 0x08, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B} };
continuationFrames:连续帧数据。 - 发送接收流程:
while (remaining_data_len > 0) { // 接收流控帧 int byte_count; if (uds_recv_flow_control(sock, &byte_count) < 0) { printf("Error \r\n"); break; } remaining_data_len -= byte_count; // 发送连续帧数据 printf("send consecutive len:%d \r\n", send_data_len); for (int id = 0; id < 8; id++) { printf("0x%02X ", continuationFrames[i][id]); } printf("\r\n"); write(sock, continuationFrames[i++], send_data_len); }
其中,服务器端去掉了客户端的第一个字节0x20 | 块数。最后输出的CallBack_F18C,去掉了前三个字节(0x2E、0xF1、0x8C),0xF1与0x8C是CallBack_F18C标记,也就是客户需求。