You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

462 lines
17 KiB

#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"
#include "config.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 20
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 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");
}
}
/* 修改网络相关配置指令回执 */
static void udp_client_modify_network_configurations_cmd_receipt(protocol_modify_network_configurations_order_t *order, protocol_status_code_type state_code)
{
protocol_modify_network_configurations_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_modify_network_configurations_receipt_t) - 1);
if (sendto(sock_Client, &receipt, sizeof(protocol_modify_network_configurations_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_clear_counter();
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 (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: /* 配置网络相关指令 */
cmd_checksum(protocol_modify_network_configurations_cmd);
if (checksum_flag)
{
switch (protocol_modify_network_configurations_cmd->configuration_option)
{
case OPTION_IP:
config_get()->ip = protocol_modify_network_configurations_cmd->data;
break;
case OPTION_GW:
config_get()->gw = protocol_modify_network_configurations_cmd->data;
break;
case OPTION_NETMASK:
config_get()->netmask = protocol_modify_network_configurations_cmd->data;
break;
default:
break;
}
if (config_flash_write() == 0)
{
udp_client_modify_network_configurations_cmd_receipt(protocol_modify_network_configurations_cmd, PROTOCOL_STATUS_SUCCESS);
}
else
{ /* 存在修改了配置,但是写入到flash失败的问题,暂时不处理,处理的话就整一个temp,保存修改前的数据,
然后写入失败,把temp的数据赋值给修改的字段,通过指令的option来确定修改了啥字段 */
udp_client_modify_network_configurations_cmd_receipt(protocol_modify_network_configurations_cmd, PROTOCOL_STATUS_HARDWARE_ERROR);
}
}
else
{
udp_client_modify_network_configurations_cmd_receipt(protocol_modify_network_configurations_cmd, PROTOCOL_STATUS_PARAMETER_ERROR);
}
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();
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;
}