#include "stm32f4xx_hal.h" #include "lwip.h" #include "udp.h" #include "string.h" #include "udpclient.h" #include "socket.h" #include "sockets.h" #include "def.h" #include "encoder.h" #include "zport.h" #define cmd_checksum(data) \ if (computesum8((char *)data, recv_datalen - 1) != data->checksum) \ { \ printf("checksum error\r\n"); \ checksum_flag = false; \ } /* 定义端口号 */ #define UDP_REMOTE_PORT 8881 /* 远端端口 */ #define UDP_LOCAL_PORT 8880 /* 本地端口 */ #define SERVER_FAMILY AF_INET #define SOCKET_ERROR -1 #define BUFFER_SIZE 256 // 缓冲区大小 #define ACTIVE_CMD_ID 0XC003 #define TRIGGER_ID 0XC004 #define DEVICE_ID 0X01 #define AVTIVE_DISABLE 0 #define ACTIVE_ENABLE 1 #define TRIGGER_MOD_CLOSE 0 #define TRIGGER_MOD_GENLOCK_OPEN 1 #define CLEAR_ENCODER_ALL 0 #define CLEAR_ENCODER_1 1 #define CLEAR_ENCODER_2 2 #define ORDER_RECEIPT_INTERCONVERSION 0X8000 #define ACTIVE_MIN_REPORT_CYCLE 50 static bool udp_client_active_flag; static bool genlock_and_esync_active_flag; static uint16_t s_trigger_mode; static char s_sendBuf[BUFFER_SIZE]; // 发送数据的缓冲区 static char s_receBuf[BUFFER_SIZE]; // 接收数据的缓冲区 SOCKET sock_Client = 0; // 客户端用于通信的Socket static struct sockaddr_in addr_server; static struct sockaddr_in addr_client; static struct sockaddr_in sock; socklen_t sock_len = sizeof(sock); static protocol_active_and_trigger_report_t active_report_data_structer; static protocol_active_and_trigger_report_t trigger_report_data_structer; static int active_report_cycle; static void udp_client_all_encoder_light_set(encoder_light_state_t state) { if (state == STANDBY) { encoder_set_state(CAMERA_ENCODER, STANDBY); encoder_set_state(DRIVEN_ENCODER_GEAR, STANDBY); } else if (state == WORKING) { encoder_set_state(CAMERA_ENCODER, WORKING); encoder_set_state(DRIVEN_ENCODER_GEAR, WORKING); } } /* ===================================================================== */ static void active_report_data_structer_init(void) { /* index在每次上报一次主动上报数据后+1,时间戳在获取ESync命令时更新,编码器数值在 active_report_data_structer_update中更新,校验和在上传数据前(udp_client_active_response)进行更新*/ active_report_data_structer.index = 0; /* */ active_report_data_structer.cmd_id = ACTIVE_CMD_ID; /* 指令id */ active_report_data_structer.placeholder_1 = 0; active_report_data_structer.placeholder_2 = 0; active_report_data_structer.encoder1 = 0; active_report_data_structer.encoder2 = 0; } static void trigger_report_data_structer_init(void) { /* index在每次上报一次主动上报数据后+1,时间戳在获取ESync命令时更新,编码器数值在 active_report_data_structer_update中更新,校验和在上传数据前(udp_client_active_response)进行更新*/ trigger_report_data_structer.index = 0; /* */ trigger_report_data_structer.cmd_id = TRIGGER_ID; /* 指令id */ trigger_report_data_structer.placeholder_1 = 0; trigger_report_data_structer.placeholder_2 = 0; trigger_report_data_structer.encoder1 = 0; trigger_report_data_structer.encoder2 = 0; } static void active_report_data_structer_update(void) { /* 时间戳暂时先不管,后续完善 */ encoder_read_with_encoder(CAMERA_ENCODER, &active_report_data_structer.encoder1); encoder_read_with_encoder(DRIVEN_ENCODER_GEAR, &active_report_data_structer.encoder2); } static void trigger_report_data_structer_update(void) { /* 时间戳暂时先不管,后续完善 */ encoder_read_with_encoder(CAMERA_ENCODER, &trigger_report_data_structer.encoder1); encoder_read_with_encoder(DRIVEN_ENCODER_GEAR, &trigger_report_data_structer.encoder2); } /* 主动上报格式 */ static void udp_client_active_report(void) { active_report_data_structer.checksum = computesum8((char *)&active_report_data_structer, sizeof(protocol_active_and_trigger_report_t) - 1); if (sendto(sock_Client, &active_report_data_structer, sizeof(protocol_active_and_trigger_report_t), 0, (struct sockaddr *)&addr_server, sizeof(struct sockaddr_in)) == SOCKET_ERROR) { printf("send basic_response error\r\n"); } } /* 触发上报格式 */ static void udp_client_trigger_report(void) { trigger_report_data_structer.checksum = computesum8((char *)&trigger_report_data_structer, sizeof(protocol_active_and_trigger_report_t) - 1); if (sendto(sock_Client, &trigger_report_data_structer, sizeof(protocol_active_and_trigger_report_t), 0, (struct sockaddr *)&addr_server, sizeof(struct sockaddr_in)) == SOCKET_ERROR) { printf("send basic_response error\r\n"); } } /* 清除编码器数据指令回执 */ static void udp_client_clear_encoder_cmd_receipt(protocol_clear_encoder_order_t *order, protocol_status_code_type state_code) { protocol_clear_encoder_receipt_t receipt; receipt.index = order->index; receipt.cmd_id = order->cmd_id + ORDER_RECEIPT_INTERCONVERSION; receipt.status_code = state_code; receipt.checksum = computesum8((char *)&receipt, sizeof(protocol_clear_encoder_receipt_t) - 1); if (sendto(sock_Client, &receipt, sizeof(protocol_clear_encoder_receipt_t), 0, (struct sockaddr *)&addr_server, sizeof(struct sockaddr_in)) == SOCKET_ERROR) { printf("send basic_response error\r\n"); } } /* 读取编码器数据指令回执 */ static void udp_client_read_encoder_cmd_receipt(protocol_read_encoder_order_t *order) { protocol_read_encoder_receipt_t receipt; receipt.index = order->index; receipt.cmd_id = order->cmd_id + ORDER_RECEIPT_INTERCONVERSION; active_report_data_structer_update(); receipt.encoder1 = active_report_data_structer.encoder1; receipt.encoder2 = active_report_data_structer.encoder2; receipt.checksum = computesum8((char *)&receipt, sizeof(protocol_read_encoder_receipt_t) - 1); if (sendto(sock_Client, &receipt, sizeof(protocol_read_encoder_receipt_t), 0, (struct sockaddr *)&addr_server, sizeof(struct sockaddr_in)) == SOCKET_ERROR) { printf("send basic_response error\r\n"); } } /* 设置主动上报指令回执 */ static void udp_client_active_cmd_receipt(protocol_active_order_t *order, protocol_status_code_type state_code) { protocol_active_receipt_t receipt; receipt.index = order->index; receipt.cmd_id = order->cmd_id + ORDER_RECEIPT_INTERCONVERSION; receipt.active_report_flag = order->active_report_flag; receipt.report_cycle = order->report_cycle; receipt.status_code = state_code; receipt.checksum = computesum8((char *)&receipt, sizeof(protocol_active_receipt_t) - 1); if (sendto(sock_Client, &receipt, sizeof(protocol_active_receipt_t), 0, (struct sockaddr *)&addr_server, sizeof(struct sockaddr_in)) == SOCKET_ERROR) { printf("send basic_response error\r\n"); } } /* 设置触发上报指令回执 */ static void udp_client_trigger_cmd_receipt(protocol_trigger_order_t *order, protocol_status_code_type state_code) { protocol_trigger_receipt_t receipt; receipt.index = order->index; receipt.cmd_id = order->cmd_id + ORDER_RECEIPT_INTERCONVERSION; receipt.trigger_mode = order->trigger_mode; receipt.status_code = state_code; receipt.checksum = computesum8((char *)&receipt, sizeof(protocol_trigger_receipt_t) - 1); if (sendto(sock_Client, &receipt, sizeof(protocol_trigger_receipt_t), 0, (struct sockaddr *)&addr_server, sizeof(struct sockaddr_in)) == SOCKET_ERROR) { printf("send basic_response error\r\n"); } } /* ===================================================================== */ void udp_client_recv_data_dump(int recv_datalen) { /* debug使用 */ for (size_t i = 0; i < recv_datalen; i++) { printf("%d ", s_receBuf[i]); } printf("\r\n"); } void config_server(struct sockaddr_in *addr_server) { addr_server->sin_family = SERVER_FAMILY; addr_server->sin_port = htons(UDP_REMOTE_PORT); addr_server->sin_addr.s_addr = htonl(INADDR_BROADCAST); } void config_client(struct sockaddr_in *addr_client) { addr_client->sin_family = AF_INET; addr_client->sin_addr.s_addr = inet_addr("0.0.0.0"); addr_client->sin_port = htons(UDP_LOCAL_PORT); } void udp_client_send_string(char *pData) { memcpy(s_sendBuf, pData, strlen(pData)); if (sendto(sock_Client, s_sendBuf, strlen(pData), 0, (struct sockaddr *)&addr_server, sizeof(struct sockaddr_in)) == SOCKET_ERROR) { printf("send string error\n"); } } void udp_client_init(void) { active_report_data_structer_init(); trigger_report_data_structer_init(); // bool bOpt = true; struct timeval tv = {0, 1000}; config_server(&addr_server); config_client(&addr_client); // 创建客户端用于通信的Socket sock_Client = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if (sock_Client == SOCKET_ERROR) { printf("create socket error...\n"); } else { printf("create socket success!\n"); } // /* 开启广播 */ // if (lwip_setsockopt(sock_Client, SOL_SOCKET, SO_BROADCAST, (char *)&bOpt, sizeof(bOpt)) == SOCKET_ERROR) // { // printf("enable broadcast error...\n"); // } // else // { // printf("enable broadcast success!\n"); // } /* 设置超时 */ if (lwip_setsockopt(sock_Client, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(tv)) == SOCKET_ERROR) { printf("enable receive timeout error...\n"); } else { printf("enable receive timeout success!\n"); } /* 绑定 */ if (bind(sock_Client, (struct sockaddr *)&addr_client, sizeof(addr_client)) == SOCKET_ERROR) { printf("Bind failed"); return; } } void udp_client_recv(void) { int recv_datalen = recvfrom(sock_Client, s_receBuf, sizeof(s_receBuf), 0, (struct sockaddr *)&sock, &sock_len); if (recv_datalen > 0) { printf("udp recv data len:%d\r\n", recv_datalen); udp_client_parse(recv_datalen); } } void udp_client_parse(int recv_datalen) { bool checksum_flag = true; if (recv_datalen >= adwin_config_protocol_size) { /* 时码相关逻辑暂时不处理 */ // adwin_config_protocol_t *rxcmd = (adwin_config_protocol_t *)s_receBuf; // active_report_data_structer.time_stamp_s = rxcmd->time_stamp_s; // genlock_and_esync_active_flag = true; } else if (recv_datalen >= protocol_basic_size) { protocol_basic_t *protocol_basic_cmd = (protocol_basic_t *)s_receBuf; protocol_clear_encoder_order_t *protocol_clear_encoder_cmd = (protocol_clear_encoder_order_t *)s_receBuf; protocol_read_encoder_order_t *protocol_read_encoder_cmd = (protocol_read_encoder_order_t *)s_receBuf; protocol_active_order_t *protocol_active_cmd = (protocol_active_order_t *)s_receBuf; protocol_trigger_order_t *protocol_trigger_cmd = (protocol_trigger_order_t *)s_receBuf; // protocol_modify_network_configurations_order_t *protocol_modify_network_configurations_cmd = (protocol_modify_network_configurations_order_t *)s_receBuf; switch (protocol_basic_cmd->cmd_id) { case PROTOCOL_CMD_CLEAR_ENCODER: /* 清除编码器数据指令 */ cmd_checksum(protocol_clear_encoder_cmd); if (checksum_flag) { /* 校验通过 */ encoder_all_encoder_clear_counter_and_structer_count(); udp_client_clear_encoder_cmd_receipt(protocol_clear_encoder_cmd, PROTOCOL_STATUS_SUCCESS); } else { /* 校验未通过 */ udp_client_clear_encoder_cmd_receipt(protocol_clear_encoder_cmd, PROTOCOL_STATUS_PARAMETER_ERROR); } break; case PROTOCOL_CMD_READ_ENCODER: /* 读取编码器数据指令 */ cmd_checksum(protocol_read_encoder_cmd); if (checksum_flag) { /* 校验通过 */ udp_client_read_encoder_cmd_receipt(protocol_read_encoder_cmd); } else { /* 校验未通过 */ } break; case PROTOCOL_CMD_ACTIVE: /* 配置主动上报指令 */ cmd_checksum(protocol_active_cmd); if (checksum_flag) { /* 校验通过 */ if ((protocol_active_cmd->active_report_flag == AVTIVE_DISABLE) || (protocol_active_cmd->active_report_flag == ACTIVE_ENABLE)) { udp_client_active_flag = protocol_active_cmd->active_report_flag; if (udp_client_active_flag) { udp_client_all_encoder_light_set(WORKING); } else { udp_client_all_encoder_light_set(STANDBY); } } if (protocol_active_cmd->report_cycle >= ACTIVE_MIN_REPORT_CYCLE) { active_report_cycle = protocol_active_cmd->report_cycle; } else { active_report_cycle = ACTIVE_MIN_REPORT_CYCLE; } udp_client_active_cmd_receipt(protocol_active_cmd, PROTOCOL_STATUS_SUCCESS); } else { /* 校验未通过 */ udp_client_active_cmd_receipt(protocol_active_cmd, PROTOCOL_STATUS_PARAMETER_ERROR); } break; case PROTOCOL_CMD_TRIGGER: /* 配置触发上报指令 */ cmd_checksum(protocol_trigger_cmd); if (checksum_flag) { /* 校验通过 */ if ((protocol_trigger_cmd->trigger_mode == TRIGGER_MOD_CLOSE) || (protocol_trigger_cmd->trigger_mode == TRIGGER_MOD_GENLOCK_OPEN)) { s_trigger_mode = protocol_trigger_cmd->trigger_mode; } udp_client_trigger_cmd_receipt(protocol_trigger_cmd, PROTOCOL_STATUS_SUCCESS); } else { /* 校验未通过 */ udp_client_trigger_cmd_receipt(protocol_trigger_cmd, PROTOCOL_STATUS_PARAMETER_ERROR); } break; case PROTOCOL_CMD_MODIFY_NETWORK_CONFIGURATIONS: /* 配置网络相关指令 */ break; default: break; } } else { /* error */ } } void udp_client_active(void) { if (udp_client_active_flag) { static uint32_t lastprocess = 0; if (sys_haspassedms(lastprocess) > active_report_cycle) { lastprocess = HAL_GetTick(); active_report_data_structer_update(); udp_client_active_report(); active_report_data_structer.index += 1; } } } void udp_client_genlock_and_esync_active(void) { if (s_trigger_mode == TRIGGER_MOD_GENLOCK_OPEN) { if (genlock_and_esync_active_flag) { trigger_report_data_structer_update(); udp_client_trigger_report(); if (!udp_client_active_flag) { udp_client_all_encoder_light_set(STANDBY); } trigger_report_data_structer.index += 1; // active_report_data_structer.time_stamp_s = 0; genlock_and_esync_active_flag = false; } } } bool *udp_client_genlock_and_esync_active_flag_ret(void) { return &genlock_and_esync_active_flag; } protocol_active_and_trigger_report_t *udp_client_get_active_report_data_structer(void) { return &active_report_data_structer; }