/* * BLV_NETCOMM_Function.c * * Created on: Nov 3, 2025 * Author: cc */ #include "includes.h" #include uint8_t Global_Large_Buff[1100] = {0}; //用于套接字通讯组包、读写外部SRAM映射寄存器 uint32_t ProjectCode = 1001; //模拟项目编码 uint8_t Versions[4] = {0,0,0,0}; //模拟配置版本 /******************************************************************************* * Function Name : UDP_Add_Header * Description : 添加宝来威 - 通讯协议头 * Input : * data - 需要添加的数组 * cmd - 通讯命令 * length - 通讯长度 * frame_no - 通讯帧号 *******************************************************************************/ __attribute__((section(".non_0_wait"))) uint8_t UDP_Add_Header(uint8_t *data,uint8_t cmd,uint16_t length, uint16_t frame_no) { uint8_t len = 0x00; data[len++] = 0xAA; data[len++] = 0x55; data[len++] = length%256; data[len++] = length/256; data[len++] = 'T'; data[len++] = '3'; data[len++] = 'S'; data[len++] = 'A'; data[len++] = cmd; data[len++] = frame_no%256; data[len++] = frame_no/256; data[len++] = ProjectCode%256; data[len++] = ProjectCode/256; data[len++] = g_netinfo.device_ip[2]; //本机ip data[len++] = g_netinfo.device_ip[3]; return len; } /******************************************************************************* * Function Name : UDP_ADD_SoftwareVer * Description : 添加软件版本号 * Input : * data - 需要添加的数组 *******************************************************************************/ __attribute__((section(".non_0_wait"))) uint8_t UDP_ADD_SoftwareVer(uint8_t *data) { //软件版本号长度为20Byte uint8_t len = strlen(SoftwareVer); if(len > RCU_SoftwareVer) len = RCU_SoftwareVer; //防止版本号溢出死机 memcpy(data,SoftwareVer,len); //RCU_SoftwareVer return RCU_SoftwareVer; //固定20Byte } /******************************************************************************* * Function Name : UDP_ADD_ConfigVer * Description : 添加逻辑配置版本号 * Input : * data - 需要添加的数组 *******************************************************************************/ __attribute__((section(".non_0_wait"))) uint8_t UDP_ADD_ConfigVer(uint8_t *data) { //上电启动时,有赋值给Versions数组 添加配置版本 data[0] = Versions[0]; data[1] = Versions[1]; data[2] = Versions[2]; return 0x03; } /******************************************************************************* * Function Name : UDP_Add_ServerIp * Description : 添加服务器IP地址 * Input : * data - 需要添加的数组 *******************************************************************************/ __attribute__((section(".non_0_wait"))) uint8_t UDP_Add_ServerIp(uint8_t *data) { //上电启动时,有赋值给Versions数组 添加配置版本 data[0] = server_info.dis_ip[0]; data[1] = server_info.dis_ip[1]; data[2] = server_info.dis_ip[2]; data[3] = server_info.dis_ip[3]; return 0x04; } /******************************************************************************* * Function Name : UDP_Add_ServerPort * Description : 添加服务器通讯端口 * Input : * data - 需要添加的数组 *******************************************************************************/ __attribute__((section(".non_0_wait"))) uint8_t UDP_Add_ServerPort(uint8_t *data) { //上电启动时,有赋值给Versions数组 添加配置版本 data[0] = server_info.dis_port & 0xFF; data[1] = (server_info.dis_port >> 8) & 0xFF; //之前C1F中这个服务端口,是固定的3341,而网络配置工具使用的是这个端口,进行升级使用 data[0] = 0x0D; data[1] = 0x0D; return 0x02; } /******************************************************************************* * Function Name : UDP_Add_Subnet * Description : 添加子网掩码 * Input : * data - 需要添加的数组 *******************************************************************************/ __attribute__((section(".non_0_wait"))) uint8_t UDP_Add_Subnet(uint8_t *data) { //上电启动时,有赋值给Versions数组 添加配置版本 data[0] = g_netinfo.subnet[0]; data[1] = g_netinfo.subnet[1]; data[2] = g_netinfo.subnet[2]; data[3] = g_netinfo.subnet[3]; return 0x04; } /******************************************************************************* * Function Name : UDP_Add_Gateway * Description : 添加网关 * Input : * data - 需要添加的数组 *******************************************************************************/ __attribute__((section(".non_0_wait"))) uint8_t UDP_Add_Gateway(uint8_t *data) { //上电启动时,有赋值给Versions数组 添加配置版本 data[0] = g_netinfo.gateway[0]; data[1] = g_netinfo.gateway[1]; data[2] = g_netinfo.gateway[2]; data[3] = g_netinfo.gateway[3]; return 0x04; } /******************************************************************************* * Function Name : UDP_Add_Mac * Description : 添加MAC地址 * Input : * data - 需要添加的数组 *******************************************************************************/ __attribute__((section(".non_0_wait"))) uint8_t UDP_Add_Mac(uint8_t *data) { //上电启动时,有赋值给Versions数组 添加配置版本 data[0] = g_netinfo.mac_addr[0]; data[1] = g_netinfo.mac_addr[1]; data[2] = g_netinfo.mac_addr[2]; data[3] = g_netinfo.mac_addr[3]; data[4] = g_netinfo.mac_addr[4]; data[5] = g_netinfo.mac_addr[5]; return 0x06; } /******************************************************************************* * Function Name : UDP_Add_Port * Description : 添加端口号 * Input : * data - 需要添加的数组 *******************************************************************************/ __attribute__((section(".non_0_wait"))) uint8_t UDP_Add_Port(uint8_t *data) { data[0] = 0x0D; data[1] = 0x0D; return 0x02; } /******************************************************************************* * Function Name : UDP_Get_FrameNum * Description : 获取数据包中的帧号 * Input : * buff - 数据包 * Return :返回数据包中的帧号 *******************************************************************************/ uint16_t UDP_Get_FrameNum(uint8_t *buff) { uint16_t frame_id = 0; frame_id = buff[FRAME_NO_OFFSET + 1]; frame_id <<= 0x08; frame_id |= buff[FRAME_NO_OFFSET]; return frame_id; } /******************************************************************************* * Function Name : UDP_Search_Ack * Description : 主机向服务器发送注册函数 *******************************************************************************/ __attribute__((section(".non_0_wait"))) uint8_t UDP_Search_Ack(void) { uint32_t sendlen = BLV_UDP_HEAD_LEN; uint8_t rev = 0; memset(Global_Large_Buff,0,sizeof(Global_Large_Buff)); //处理要返回的数据帧 sendlen += UDP_Add_ServerIp(&Global_Large_Buff[BLV_UDP_HEAD_LEN]); //添加服务器IP地址 sendlen += UDP_Add_Subnet(&Global_Large_Buff[sendlen]); //添加子网掩码 sendlen += UDP_Add_Gateway(&Global_Large_Buff[sendlen]); //添加网关 sendlen += UDP_Add_ServerPort(&Global_Large_Buff[sendlen]); //添加RCU端口 sendlen += UDP_Add_Mac(&Global_Large_Buff[sendlen]); //添加Mac sendlen += UDP_ADD_SoftwareVer(&Global_Large_Buff[sendlen]); //添加固件版本 sendlen += UDP_ADD_ConfigVer(&Global_Large_Buff[sendlen]); //添加配置版本 Global_Large_Buff[sendlen++] = g_netinfo.dns_server_ip[0]; Global_Large_Buff[sendlen++] = g_netinfo.dns_server_ip[1]; Global_Large_Buff[sendlen++] = g_netinfo.dns_server_ip[2]; Global_Large_Buff[sendlen++] = g_netinfo.dns_server_ip[3]; SRAM_DMA_Read_Buff(&Global_Large_Buff[sendlen],16,SRAM_Register_Start_ADDRESS + Register_RoomTypeNote_OFFSET); sendlen += 16; SRAM_DMA_Read_Buff(&Global_Large_Buff[sendlen],16,SRAM_Register_Start_ADDRESS + Register_RoomNumNote_OFFSET); sendlen += 16; SRAM_DMA_Read_Buff(&Global_Large_Buff[sendlen],4,SRAM_Register_Start_ADDRESS + Register_HouseType_OFFSET); sendlen += 4; SRAM_DMA_Read_Buff(&Global_Large_Buff[sendlen],4,SRAM_Register_Start_ADDRESS + Register_RoomNumber_OFFSET); sendlen += 4; sendlen += 2; //先添加CRC16 数据长度2Byte UDP_Add_Header(Global_Large_Buff,In_Search_Cmd,sendlen,0xffff); //添加头部 NetCRC16(&Global_Large_Buff[0],sendlen); Dbg_Println(DBG_BIT_NET_STATUS_bit,"SocketId:%d , IP:%d.%d.%d.%d , port:%d",g_netinfo.SocketId[SocketIdnex_BLVSeriver],server_info.dis_ip[0],server_info.dis_ip[1],server_info.dis_ip[2],server_info.dis_ip[3],server_info.dis_port); rev = WCHNET_SocketUdpSendTo(g_netinfo.SocketId[SocketIdnex_BLVSeriver], &Global_Large_Buff[0], &sendlen, server_info.dis_ip, server_info.dis_port); Dbg_Println(DBG_BIT_NET_STATUS_bit,"%s rev:%d",__func__,rev); LOG_NET_COMM_Send_Record(0x01,server_info.dis_ip,server_info.dis_port,&Global_Large_Buff[0],sendlen); return rev; } /******************************************************************************* * Function Name : UDP_Subgroup_Cmd_Processing * Description : BLV通讯协议 - 子群发布命令 处理函数 * - 用于升级配置 *******************************************************************************/ uint8_t UDP_Subgroup_Cmd_Processing(uint8_t* data, uint16_t DataLen, uint8_t*ip, uint16_t port) { uint8_t state = 0x00; uint8_t Ret = 0x02; uint8_t buff[6]; uint32_t sendlen = 0; //校验长度 //if(DataLen != CONFIG_Cmd_Rev_Len) return Ret; memset(Global_Large_Buff,0,sizeof(Global_Large_Buff)); server_info.goal_port = port; memcpy(server_info.goal_ip, ip, 4); memcpy(buff, ip, 4); buff[4] = port; buff[5] = port >> 8; SRAM_DMA_Write_Buff(buff, 6, SRAM_IAP_IP_ADDRESS); //将配置工具的ip和port存入SRAM,回复升级结果时使用这个端口,而不是TFTP服务及文件传输的套接字 memset(&IAPVarTypeStruct_Ptr, 0, sizeof(IAPVarTypeStruct)); //清楚IAP升级结构体 IAPVarTypeStruct_Ptr.Md5[0] = data[BLV_UDP_HEAD_LEN+3]; IAPVarTypeStruct_Ptr.Md5[1] = data[BLV_UDP_HEAD_LEN+2]; IAPVarTypeStruct_Ptr.Md5[2] = data[BLV_UDP_HEAD_LEN+1]; IAPVarTypeStruct_Ptr.Md5[3] = data[BLV_UDP_HEAD_LEN+0]; IAPVarTypeStruct_Ptr.Md5[4] = data[BLV_UDP_HEAD_LEN+7]; IAPVarTypeStruct_Ptr.Md5[5] = data[BLV_UDP_HEAD_LEN+6]; IAPVarTypeStruct_Ptr.Md5[6] = data[BLV_UDP_HEAD_LEN+5]; IAPVarTypeStruct_Ptr.Md5[7] = data[BLV_UDP_HEAD_LEN+4]; IAPVarTypeStruct_Ptr.Md5[8] = data[BLV_UDP_HEAD_LEN+11]; IAPVarTypeStruct_Ptr.Md5[9] = data[BLV_UDP_HEAD_LEN+10]; IAPVarTypeStruct_Ptr.Md5[10] = data[BLV_UDP_HEAD_LEN+9]; IAPVarTypeStruct_Ptr.Md5[11] = data[BLV_UDP_HEAD_LEN+8]; IAPVarTypeStruct_Ptr.Md5[12] = data[BLV_UDP_HEAD_LEN+15]; IAPVarTypeStruct_Ptr.Md5[13] = data[BLV_UDP_HEAD_LEN+14]; IAPVarTypeStruct_Ptr.Md5[14] = data[BLV_UDP_HEAD_LEN+13]; IAPVarTypeStruct_Ptr.Md5[15] = data[BLV_UDP_HEAD_LEN+12]; IAPVarTypeStruct_Ptr.BlockSize = data[BLV_UDP_HEAD_LEN+16] + (data[BLV_UDP_HEAD_LEN+17]<<8); IAPVarTypeStruct_Ptr.IapFileType = TFTP_IAP_DataType_CONFIG; if( (0 < IAPVarTypeStruct_Ptr.BlockSize) && ( IAPVarTypeStruct_Ptr.BlockSize <= CONFIG_BLOCK_MAX )) { Ret = 0x01; state = TFTP_IAP_Status_Ready; //发布就绪 IAPVarTypeStruct_Ptr.enable = 0x01; //TFTP IAP升级开始 }else{ Ret = 0x02; state = TFTP_IAP_Status_Error_Block; } sendlen = BLV_UDP_HEAD_LEN; Global_Large_Buff[sendlen++] = state; sendlen += 0x02; UDP_Add_Header(Global_Large_Buff, In_Subgroup_Cmd, sendlen, 0xffff); NetCRC16(&Global_Large_Buff[0], sendlen); WCHNET_SocketUdpSendTo(g_netinfo.SocketId[SocketIdnex_BLVSeriver], Global_Large_Buff, &sendlen, ip, port); return Ret; } /******************************************************************************* * Function Name : UDP_IAP_CMD_Processing * Description : BLV通讯协议 - IAP APP命令接收处理函数 *******************************************************************************/ uint8_t Udp_Internal_BLVIAP_Logic(uint8_t* data,uint16_t DataLen, uint8_t *ip,uint16_t port) { uint8_t offset = 0x00; uint8_t Ret = 0x02; uint8_t buff[6]; uint16_t frame_num = 0; uint32_t sendlen = 0; //校验长度 //if(DataLen != CONFIG_Cmd_Rev_Len) return Ret; Dbg_Println(DBG_BIT_NET_STATUS_bit,"%s",__func__); memset(Global_Large_Buff,0,sizeof(Global_Large_Buff)); frame_num = UDP_Get_FrameNum(data); server_info.goal_port = port; memcpy(server_info.goal_ip, ip, 4); memcpy(buff, ip, 4); buff[4] = port; buff[5] = port >> 8; SRAM_DMA_Write_Buff(buff, 6, SRAM_IAP_IP_ADDRESS); //将配置工具的ip和port存入SRAM,回复升级结果时使用这个端口,而不是TFTP服务及文件传输的套接字 memset(&IAPVarTypeStruct_Ptr, 0, sizeof(IAPVarTypeStruct)); //清楚IAP升级结构体 /*数据包中字段解析 - * IP:4Byte * Port: 2Byte * MD5:16Byte * File Block:2Byte * */ offset = BLV_UDP_HEAD_LEN + 6; IAPVarTypeStruct_Ptr.Md5[0] = data[offset+3]; IAPVarTypeStruct_Ptr.Md5[1] = data[offset+2]; IAPVarTypeStruct_Ptr.Md5[2] = data[offset+1]; IAPVarTypeStruct_Ptr.Md5[3] = data[offset+0]; IAPVarTypeStruct_Ptr.Md5[4] = data[offset+7]; IAPVarTypeStruct_Ptr.Md5[5] = data[offset+6]; IAPVarTypeStruct_Ptr.Md5[6] = data[offset+5]; IAPVarTypeStruct_Ptr.Md5[7] = data[offset+4]; IAPVarTypeStruct_Ptr.Md5[8] = data[offset+11]; IAPVarTypeStruct_Ptr.Md5[9] = data[offset+10]; IAPVarTypeStruct_Ptr.Md5[10] = data[offset+9]; IAPVarTypeStruct_Ptr.Md5[11] = data[offset+8]; IAPVarTypeStruct_Ptr.Md5[12] = data[offset+15]; IAPVarTypeStruct_Ptr.Md5[13] = data[offset+14]; IAPVarTypeStruct_Ptr.Md5[14] = data[offset+13]; IAPVarTypeStruct_Ptr.Md5[15] = data[offset+12]; offset += 16; IAPVarTypeStruct_Ptr.BlockSize = data[offset + 1] << 8; IAPVarTypeStruct_Ptr.BlockSize <<= 8; IAPVarTypeStruct_Ptr.BlockSize |= data[offset]; IAPVarTypeStruct_Ptr.IapFileType = TFTP_IAP_DataType_CONFIG; Dbg_Println(DBG_BIT_NET_STATUS_bit,"BlockSize:%d",IAPVarTypeStruct_Ptr.BlockSize); sendlen = BLV_UDP_HEAD_LEN; if( (0 < IAPVarTypeStruct_Ptr.BlockSize) && ( IAPVarTypeStruct_Ptr.BlockSize <= CONFIG_BLOCK_MAX )) { Ret = 0x01; Global_Large_Buff[sendlen++] = TFTP_IAP_Status_Ready; //发布就绪 IAPVarTypeStruct_Ptr.enable = 0x01; //TFTP IAP升级开始 IAPVarTypeStruct_Ptr.FunType = TFTP_FUNTYPE_LocalIAP; IAPVarTypeStruct_Ptr.Write_Block = 0x00; }else{ Ret = 0x02; Global_Large_Buff[sendlen++] = TFTP_IAP_Status_Error_Block; } sendlen += UDP_ADD_SoftwareVer(&Global_Large_Buff[sendlen]); //添加固件版本 sendlen += 0x02; UDP_Add_Header(Global_Large_Buff, In_IAP_Cmd, sendlen, frame_num); NetCRC16(&Global_Large_Buff[0], sendlen); WCHNET_SocketUdpSendTo(g_netinfo.SocketId[SocketIdnex_BLVSeriver], Global_Large_Buff, &sendlen, ip, port); return Ret; } /******************************************************************************* * Function Name : UDP_IAP_CMD_Processing * Description : BLV通讯协议 - IAP APP命令接收处理函数 *******************************************************************************/ uint8_t UDP_IAP_Cmd_Processing(uint8_t* data, uint16_t DataLen, uint8_t *ip,uint16_t port) { uint16_t frameno = UDP_Get_FrameNum(data); UINT32 sendlen = 0x00; uint8_t buff[6]; //校验数据长度 //if(DataLen != IAP_Cmd_Rev_Len) return Ret; memset(Global_Large_Buff,0,sizeof(Global_Large_Buff)); server_info.goal_port = port; memcpy(server_info.goal_ip, ip, 4); memcpy(buff, ip, 4); buff[4] = port; buff[5] = port >> 8; SRAM_DMA_Write_Buff(buff, 6, SRAM_IAP_IP_ADDRESS); memset(&IAPVarTypeStruct_Ptr, 0, sizeof(IAPVarTypeStruct)); IAPVarTypeStruct_Ptr.IapFileType = TFTP_IAP_DataType_APP; //文件类型 //IAP 升级APP对应的MD5 校验 IAPVarTypeStruct_Ptr.Md5[0] = data[24]; IAPVarTypeStruct_Ptr.Md5[1] = data[23]; IAPVarTypeStruct_Ptr.Md5[2] = data[22]; IAPVarTypeStruct_Ptr.Md5[3] = data[21]; IAPVarTypeStruct_Ptr.Md5[4] = data[28]; IAPVarTypeStruct_Ptr.Md5[5] = data[27]; IAPVarTypeStruct_Ptr.Md5[6] = data[26]; IAPVarTypeStruct_Ptr.Md5[7] = data[25]; IAPVarTypeStruct_Ptr.Md5[8] = data[32]; IAPVarTypeStruct_Ptr.Md5[9] = data[31]; IAPVarTypeStruct_Ptr.Md5[10] = data[30]; IAPVarTypeStruct_Ptr.Md5[11] = data[29]; IAPVarTypeStruct_Ptr.Md5[12] = data[36]; IAPVarTypeStruct_Ptr.Md5[13] = data[35]; IAPVarTypeStruct_Ptr.Md5[14] = data[34]; IAPVarTypeStruct_Ptr.Md5[15] = data[33]; IAPVarTypeStruct_Ptr.BlockSize = data[38]; IAPVarTypeStruct_Ptr.BlockSize <<= 0x08; IAPVarTypeStruct_Ptr.BlockSize |= data[37]; Dbg_Println(DBG_BIT_NET_STATUS_bit,"UDP Md5:%X,%X,%X,%X,%X,%X,%X,%X,%X,%X,%X,%X,%X,%X,%X,%X",\ IAPVarTypeStruct_Ptr.Md5[0],IAPVarTypeStruct_Ptr.Md5[1],\ IAPVarTypeStruct_Ptr.Md5[2],IAPVarTypeStruct_Ptr.Md5[3],\ IAPVarTypeStruct_Ptr.Md5[4],IAPVarTypeStruct_Ptr.Md5[5],\ IAPVarTypeStruct_Ptr.Md5[6],IAPVarTypeStruct_Ptr.Md5[7],\ IAPVarTypeStruct_Ptr.Md5[8],IAPVarTypeStruct_Ptr.Md5[9],\ IAPVarTypeStruct_Ptr.Md5[10],IAPVarTypeStruct_Ptr.Md5[11],\ IAPVarTypeStruct_Ptr.Md5[12],IAPVarTypeStruct_Ptr.Md5[13],\ IAPVarTypeStruct_Ptr.Md5[14],IAPVarTypeStruct_Ptr.Md5[15]); sendlen = BLV_UDP_HEAD_LEN; if( (0 < IAPVarTypeStruct_Ptr.BlockSize) || (IAPVarTypeStruct_Ptr.BlockSize <= APP_BLOCK_MAX) ) { Global_Large_Buff[sendlen++] = TFTP_IAP_Status_Ready; IAPVarTypeStruct_Ptr.enable = 0x01; }else { Global_Large_Buff[sendlen++] = TFTP_IAP_Status_Error_Block; } sendlen += 2; UDP_Add_Header(Global_Large_Buff, In_IAP_Cmd, sendlen, frameno); NetCRC16(Global_Large_Buff,sendlen); WCHNET_SocketUdpSendTo(g_netinfo.SocketId[SocketIdnex_BLVSeriver], Global_Large_Buff, &sendlen, ip, port); return 0x00; } /******************************************************************************* * Function Name : UDP_Search_Cmd_Processing * Description : BLV通讯协议 - 搜索命令接收处理函数 *******************************************************************************/ uint8_t UDP_Search_Cmd_Processing(uint8_t* data, uint16_t DataLen, uint8_t *ip,uint16_t port) { uint8_t Ret = 0x03; uint16_t search_rxno = 0; uint16_t src_port = 0; uint32_t sendlen = 0; memset(Global_Large_Buff,0,sizeof(Global_Large_Buff)); if( (DataLen != 17) && (DataLen != 28) ) return Ret; search_rxno = UDP_Get_FrameNum(data); if(DataLen == 17) { Dbg_Println(DBG_BIT_NET_STATUS_bit,"注册命令回复!"); server_info.udp_sta = 0x02; server_info.active_cmd_flag |= UDP_ActSend_TimeSync_Flag; //注册成功后,向服务器获取时间 server_info.active_cmd_flag |= UDP_ActSend_RoomState_Flag; //注册成功后,向服务器获取房态 server_info.register_flag = 0x00; server_info.register_num = 0x00; server_info.register_tick = SysTick_1s; server_info.udp_timesync_cnt = 0x00; server_info.udp_periodic_cnt = 0x00; server_info.udp_online_tick = SysTick_1ms; if(0xffff == search_rxno) //云端服务器发过来的帧号 { LOG_SYS_Server_Comm_State_Record(0x02); //RCU云端服务器 server_info.online_state = 3; }else{ LOG_SYS_Server_Comm_State_Record(0x01); //RCU本地服务器 server_info.online_state = 2; } }else if(DataLen == 28) { //帧号或长度不对就返回 if(search_rxno >= 0x8000) return 0x02; src_port = data[25]; src_port <<= 0x08; src_port |= data[24]; if( data[19] == 0x01) { if((data[20] != server_info.dis_ip[0]) || (data[21] != server_info.dis_ip[1]) || (data[22] != server_info.dis_ip[2]) || (data[23] != server_info.dis_ip[3]) || (src_port != server_info.dis_port)) { server_info.dis_port = src_port; server_info.dis_ip[0] = data[20]; server_info.dis_ip[1] = data[21]; server_info.dis_ip[2] = data[22]; server_info.dis_ip[3] = data[23]; } } Dbg_Println(DBG_BIT_NET_STATUS_bit,"收到搜索命令!"); sendlen = BLV_UDP_HEAD_LEN; sendlen += UDP_Add_ServerIp(&Global_Large_Buff[sendlen]); //将此四个字节的用户码改成服务器IP地址 sendlen += UDP_Add_Subnet(&Global_Large_Buff[sendlen]); //添加子网掩码 sendlen += UDP_Add_Gateway(&Global_Large_Buff[sendlen]); //添加网关 sendlen += UDP_Add_Port(&Global_Large_Buff[sendlen]); //添加RCU端口 sendlen += UDP_Add_Mac(&Global_Large_Buff[sendlen]); //添加Mac sendlen += UDP_ADD_SoftwareVer(&Global_Large_Buff[sendlen]); //添加固件版本 sendlen += UDP_ADD_ConfigVer(&Global_Large_Buff[sendlen]); //添加配置版本 NetCRC16(&Global_Large_Buff[0],sendlen); //添加CRC16 sendlen += 0x02; UDP_Add_Header(Global_Large_Buff,In_Search_Cmd,sendlen,0xffff); //添加头部 WCHNET_SocketUdpSendTo(g_netinfo.SocketId[SocketIdnex_BLVSeriver], &Global_Large_Buff[0], &sendlen, ip, port); } return 0x00; } /******************************************************************************* * Function Name : UDP_Read_MCUSystem_Cmd_Processing * Description : 主机向服务器发送心跳包 函数 *******************************************************************************/ uint8_t UDP_Read_MCUSystem_Cmd_Processing(uint8_t* data, uint16_t DataLen, uint8_t *ip,uint16_t port) { uint16_t pack_frame = UDP_Get_FrameNum(data); if( data[15] == 0x01 ) { WCHNET_DHCPStop(); server_info.register_tick = SysTick_1s; server_info.register_num = 0x00; Dbg_Println(DBG_BIT_NET_STATUS_bit,"搜索命令,init_flag:%d",server_info.init_flag); if(server_info.init_flag ==0x00) { Dbg_Println(DBG_BIT_NET_STATUS_bit,"直连模式,跳过DHCP和DNS"); server_info.net_sta = NET_COMPLETE; server_info.con_flag = 0x01; } server_info.con_tick = SysTick_1s; } //延时回复数据 server_info.ack_frame = pack_frame; server_info.search_ack_flag = 0x01; server_info.search_ack_tick = SysTick_1ms; server_info.goal_ip[0] = ip[0]; server_info.goal_ip[1] = ip[1]; server_info.goal_ip[2] = ip[2]; server_info.goal_ip[3] = ip[3]; server_info.goal_port = port; return 0x00; } /******************************************************************************* * Function Name : UDP_Heart_Send * Description : 主机向服务器发送心跳包 函数 *******************************************************************************/ __attribute__((section(".non_0_wait"))) uint8_t UDP_Heart_Send(void) { uint32_t sendlen = 0x00; uint8_t rev = 0; if((server_info.frame_no < 0xfffe) && (server_info.frame_no >= 0x8000)) { server_info.frame_no++; }else{ server_info.frame_no = 0x8000; } memset(Global_Large_Buff,0,sizeof(Global_Large_Buff)); sendlen = SocketIdnex_BLVSeriver; //2025-9-25 修改心跳包参数内容 Global_Large_Buff[sendlen++] = g_netinfo.mac_addr[0]; Global_Large_Buff[sendlen++] = g_netinfo.mac_addr[1]; Global_Large_Buff[sendlen++] = g_netinfo.mac_addr[2]; Global_Large_Buff[sendlen++] = g_netinfo.mac_addr[3]; Global_Large_Buff[sendlen++] = g_netinfo.mac_addr[4]; Global_Large_Buff[sendlen++] = g_netinfo.mac_addr[5]; sendlen += 0x06; sendlen += 0x02; //添加CRC校验长度 UDP_Add_Header(Global_Large_Buff,In_Heart_Cmd,sendlen,server_info.frame_no); //添加头部 NetCRC16(&Global_Large_Buff[0],sendlen); Dbg_Println(DBG_BIT_NET_STATUS_bit,"%s..",__func__); rev = WCHNET_SocketUdpSendTo(g_netinfo.SocketId[SocketIdnex_BLVSeriver], &Global_Large_Buff[0], &sendlen, server_info.dis_ip, server_info.dis_port); LOG_NET_COMM_Send_Record(0x01,server_info.dis_ip,server_info.dis_port,&Global_Large_Buff[0],sendlen); return rev; } /******************************************************************************* * Function Name : Udp_Internal_GetTime_Data * Description : 向服务器获取时间 *******************************************************************************/ __attribute__((section(".non_0_wait"))) uint8_t Udp_Internal_GetTime_CMD(void) { uint32_t sendlen = BLV_UDP_PACK_LEN; uint8_t rev = 0; Dbg_Println(DBG_BIT_NET_STATUS_bit,"%s",__func__); memset(Global_Large_Buff,0,sizeof(Global_Large_Buff)); if(server_info.udp_retry_cnt == 0x00) { if((server_info.frame_no < 0xfffe) && (server_info.frame_no >= 0x8000)) { server_info.frame_no++; }else{ server_info.frame_no = 0x8000; } } UDP_Add_Header(Global_Large_Buff,In_QueryTime_Cmd,sendlen,server_info.frame_no); NetCRC16(&Global_Large_Buff[0],sendlen); rev = WCHNET_SocketUdpSendTo(g_netinfo.SocketId[SocketIdnex_BLVSeriver], &Global_Large_Buff[0], &sendlen, server_info.dis_ip, server_info.dis_port); LOG_NET_COMM_Send_Record(0x01,server_info.dis_ip,server_info.dis_port,&Global_Large_Buff[0],sendlen); return rev; } /******************************************************************************* * Function Name : Udp_QueryTime_Cmd_Process * Description : 向服务器获取时间 - 回复数据处理函数 *******************************************************************************/ uint8_t Udp_QueryTime_Cmd_Process(uint8_t *data, uint16_t DataLen, uint8_t *ip,uint16_t port) { uint16_t temp = 0; S_RTC pro_rtc; uint32_t temp_systick = 0; uint16_t data_crc = 0x00; data_crc = data[DataLen-1]; data_crc <<= 0x08; data_crc |= data[DataLen-2]; if(NetCRC16_2(data,DataLen-2) != data_crc) return 0xF0; //判断帧号是否一致 data_crc = data[FRAME_NO_OFFSET + 1]; data_crc <<= 0x08; data_crc |= data[FRAME_NO_OFFSET]; if(data_crc != server_info.frame_no) return 0x01; memset(&pro_rtc,0,sizeof(pro_rtc)); temp = data[BLV_UDP_HEAD_LEN+1]; temp <<= 8; temp |= data[BLV_UDP_HEAD_LEN]; pro_rtc.year = temp - 2000; pro_rtc.month = data[BLV_UDP_HEAD_LEN+2]; pro_rtc.day = data[BLV_UDP_HEAD_LEN+3]; pro_rtc.week = data[BLV_UDP_HEAD_LEN+4]; pro_rtc.hour = data[BLV_UDP_HEAD_LEN+5]; pro_rtc.minute = data[BLV_UDP_HEAD_LEN+6]; pro_rtc.second = data[BLV_UDP_HEAD_LEN+7]; if(DataLen >= 27) { DevActionGlobal.DayStart = data[BLV_UDP_HEAD_LEN+8]; //白天起始时间 2024-08-02 DevActionGlobal.DayEnd = data[BLV_UDP_HEAD_LEN+9]; //白天结束时间 2024-08-02 } /*将格式转化为RTC数据格式*/ pro_rtc.year = DEV_Conversion_To_HEX(pro_rtc.year); pro_rtc.month = DEV_Conversion_To_HEX(pro_rtc.month); pro_rtc.day = DEV_Conversion_To_HEX(pro_rtc.day); pro_rtc.week = DEV_Conversion_To_HEX(pro_rtc.week); pro_rtc.hour = DEV_Conversion_To_HEX(pro_rtc.hour); pro_rtc.minute = DEV_Conversion_To_HEX(pro_rtc.minute); pro_rtc.second = DEV_Conversion_To_HEX(pro_rtc.second); DevActionGlobal.TimeGetFlag++; Dbg_Println(DBG_BIT_NET_STATUS_bit,"同步时间:20%X-%X-%X %X %X:%X:%X",pro_rtc.year,pro_rtc.month,pro_rtc.day,pro_rtc.week,pro_rtc.hour,pro_rtc.minute,pro_rtc.second); Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"白天时间:%d ~ %d 偏移:%d",DevActionGlobal.DayStart,DevActionGlobal.DayEnd,g_time_info.timezone); //加上时区偏移量 if(g_time_info.timezone != 0x00){ temp_systick = RTC_Conversion_To_Unix(&pro_rtc); temp_systick += (int)(g_time_info.timezone * 3600); Unix_Conversion_To_RTC(&pro_rtc,temp_systick); Dbg_Println(DBG_BIT_NET_STATUS_bit,"加上时区 时间:20%X-%X-%X %X %X:%X:%X",pro_rtc.year,pro_rtc.month,pro_rtc.day,pro_rtc.week,pro_rtc.hour,pro_rtc.minute,pro_rtc.second); } NetRTC_WriteDate(pro_rtc); //设置RTC时间 server_info.sync_tick = 0x01; //2023-10-08 用于同步LCD时间 DevActionGlobal.TimeSyncFlag = 0x03; //2024-08-02 用于白天黑夜时间判断和设置CSIO RTC server_info.udp_send_flag = 0x00; //清楚发送标志位 server_info.active_cmd_flag &= ~UDP_ActSend_TimeSync_Flag; //清楚标志位 server_info.udp_online_tick = SysTick_1ms; return 0; } /******************************************************************************* * Function Name : Udp_Internal_GetRoomRent_CMD * Description : 向服务器获取房态 *******************************************************************************/ __attribute__((section(".non_0_wait"))) uint8_t Udp_Internal_GetRoomRent_CMD(void) { uint32_t sendlen = BLV_UDP_PACK_LEN; uint8_t rev = 0; Dbg_Println(DBG_BIT_NET_STATUS_bit,"%s",__func__); memset(Global_Large_Buff,0,sizeof(Global_Large_Buff)); if(server_info.udp_retry_cnt == 0x00) { if((server_info.frame_no < 0xfffe) && (server_info.frame_no >= 0x8000)) { server_info.frame_no++; }else{ server_info.frame_no = 0x8000; } } UDP_Add_Header(Global_Large_Buff,In_Get_RoomRent_Cmd,sendlen,server_info.frame_no); NetCRC16(&Global_Large_Buff[0],sendlen); Dbg_Print_Buff(DBG_BIT_NET_STATUS_bit,"向服务器 获取房态请求",Global_Large_Buff,sendlen); rev = WCHNET_SocketUdpSendTo(g_netinfo.SocketId[SocketIdnex_BLVSeriver], &Global_Large_Buff[0], &sendlen, server_info.dis_ip, server_info.dis_port); LOG_NET_COMM_Send_Record(0x01,server_info.dis_ip,server_info.dis_port,&Global_Large_Buff[0],sendlen); return rev; } /******************************************************************************* * Function Name : Udp_Internal_Reboot_Reason_Report_CMD * Description : RCU重启原因 *******************************************************************************/ __attribute__((section(".non_0_wait"))) uint8_t Udp_Internal_Reboot_Reason_Report_CMD(void) { uint8_t temp_data[24] = {0}; uint32_t sendlen = 0x00; uint8_t rev = 0; memset(Global_Large_Buff,0,sizeof(Global_Large_Buff)); if( server_info.udp_retry_cnt == 0x00 ) { if((server_info.frame_no < 0xfffe) && (server_info.frame_no >= 0x8000)) { server_info.frame_no++; }else { server_info.frame_no = 0x8000; } }else { //数据包重发中,帧号不改变 } sendlen = BLV_UDP_HEAD_LEN; /*Launcher版本 只有Launcher_C1F_V04 以上版本才可以读取到Launcher版本,以下版本是读取乱码 2022-08-04*/ //MCU_Flash_Read((uint8_t *)&temp_data,20,Launcher_SoftwareVer_Addr); if(strncmp((char *)temp_data,"Launcher_",strlen("Launcher_")) == 0x00) { memcpy(&Global_Large_Buff[BLV_UDP_HEAD_LEN],temp_data,20); }else { /*读取不到Launcher_ 前缀的字符串默认为Launcher_C1F_V02*/ memset(temp_data,0,sizeof(temp_data)); snprintf((char *)temp_data,sizeof(temp_data),"Launcher_C1F_V02 "); memcpy(&Global_Large_Buff[BLV_UDP_HEAD_LEN],temp_data,20); } sendlen += 20; Global_Large_Buff[sendlen++] = SRAM_Read_DW(SRAM_LOG_RCU_Reboot_Reason) & 0xFF; //重启原因 sendlen += 0x02; //添加CRC校验长度 UDP_Add_Header(Global_Large_Buff,In_Reboot_Reason_Cmd,sendlen,server_info.frame_no); NetCRC16(&Global_Large_Buff[0],sendlen); //Dbg_Print_Buff(DBG_BIT_NET_STATUS_bit,"RCU重启原因: ",Global_Large_Buff,sendlen); rev = WCHNET_SocketUdpSendTo(g_netinfo.SocketId[SocketIdnex_BLVSeriver], &Global_Large_Buff[0], &sendlen, server_info.dis_ip, server_info.dis_port); LOG_NET_COMM_Send_Record(0x01,server_info.dis_ip,server_info.dis_port,&Global_Large_Buff[0],sendlen); return rev; } /******************************************************************************* * Function Name : Udp_Internal_Power_Change_Report_CMD * Description : 取电变化上报 *******************************************************************************/ __attribute__((section(".non_0_wait"))) uint8_t Udp_Internal_Power_Change_Report_CMD(void) { uint32_t sendlen = 0x00; uint8_t temp_flag = 0,rev = 0; memset(Global_Large_Buff,0,sizeof(Global_Large_Buff)); if( server_info.udp_retry_cnt == 0x00 ) { if((server_info.frame_no < 0xfffe) && (server_info.frame_no >= 0x8000)) { server_info.frame_no++; }else { server_info.frame_no = 0x8000; } } temp_flag = SRAM_Read_Byte(SRAM_UDP_ELEReport_Action); sendlen = BLV_UDP_HEAD_LEN; if( (temp_flag & 0x01) != 0x00 ) { Global_Large_Buff[sendlen++] = SRAM_Read_Byte(SRAM_UDP_ELEReport_EleState_Last); //取电动作 }else { Global_Large_Buff[sendlen++] = 0x00; } if( (temp_flag & 0x02) != 0x00 ) { Global_Large_Buff[sendlen++] = SRAM_Read_Byte(SRAM_UDP_ELEReport_CardState_Last); //插卡动作 }else { Global_Large_Buff[sendlen++] = 0x00; } if( (temp_flag & 0x04) != 0x00 ) { Global_Large_Buff[sendlen++] = SRAM_Read_Byte(SRAM_UDP_ELEReport_CardType_Last); //身份变化 }else { Global_Large_Buff[sendlen++] = 0x00; } if( (temp_flag & 0x08) != 0x00 ) { Global_Large_Buff[sendlen++] = SRAM_Read_Byte(SRAM_UDP_ELEReport_VirtualCard_Last); //无卡事件动作 }else { Global_Large_Buff[sendlen++] = 0x00; } sendlen += 0x02; //添加CRC校验长度 UDP_Add_Header(Global_Large_Buff,In_Power_Change_Cmd,sendlen,server_info.frame_no); NetCRC16(&Global_Large_Buff[0],sendlen); rev = WCHNET_SocketUdpSendTo(g_netinfo.SocketId[SocketIdnex_BLVSeriver], &Global_Large_Buff[0], &sendlen, server_info.dis_ip, server_info.dis_port); LOG_NET_COMM_Send_Record(0x01,server_info.dis_ip,server_info.dis_port,&Global_Large_Buff[0],sendlen); return rev; } /******************************************************************************* * Function Name : Find_TempDevice_List_Information * Description : 查找到设备列表中的所有温控器,并按照数据组包 * Input : * buff - 填充数据地址 * dev_num_max - 填充温控器最大数量 *******************************************************************************/ __attribute__((section(".non_0_wait"))) uint32_t Find_TempDevice_List_Information(uint8_t *buff,uint8_t dev_num_max) { uint32_t read_addr = SRAM_Device_List_Start_Addr; uint32_t end_addr = SRAM_Read_DW(SRAM_NORMAL_Device_List_Addr); Device_Public_Information_G BUS_Public; RS485_TEMP_INFO Rs485Temp; uint8_t dev_num = 0; uint8_t data_offset = 0; uint16_t temp_val = 0; memset(&BUS_Public,0,sizeof(Device_Public_Information_G)); memset(&Rs485Temp,0,sizeof(RS485_TEMP_INFO)); if((end_addr < SRAM_Device_List_Start_Addr) || (end_addr > SRAM_Device_List_End_Addr)) end_addr = SRAM_Device_List_End_Addr; for(uint32_t i=SRAM_Device_List_Start_Addr;i> 8) & 0xFF; dev_num++; if(dev_num >= dev_num_max) return dev_num; //超出上限,直接退出 } } read_addr += SRAM_Device_List_Size; i+= SRAM_Device_List_Size; if(read_addr >= end_addr) { return dev_num; } } return dev_num; } /******************************************************************************* * Function Name : Udp_Scan_Roomstate * Description : 添加房间设备状态变化数据 - 向上报缓冲区中写入数据 *******************************************************************************/ __attribute__((section(".non_0_wait"))) void Udp_Addtion_Roomstate(uint8_t type,uint8_t addr,uint16_t loop,uint16_t start) { uint8_t len = 0x00; uint8_t back_data[8]; uint32_t write_addr = SRAM_Read_DW(SRAM_UDP_SendData_Writeaddr),read_addr = SRAM_Read_DW(SRAM_UDP_SendData_Readaddr); memset(back_data,0,8); /*判断地址是否在范围内*/ if( (write_addr < SRAM_UDP_SendData_Startaddr) || (write_addr > SRAM_UDP_SendData_Endaddr) \ || (read_addr < SRAM_UDP_SendData_Startaddr) || (read_addr > SRAM_UDP_SendData_Endaddr) ) { write_addr = SRAM_UDP_SendData_Startaddr; read_addr = SRAM_UDP_SendData_Startaddr; SRAM_Write_DW(write_addr,SRAM_UDP_SendData_Writeaddr); SRAM_Write_DW(read_addr,SRAM_UDP_SendData_Readaddr); SRAM_Write_DW(read_addr,SRAM_UDP_SendData_Tempaddr); } back_data[0] = type; back_data[1] = addr; back_data[2] = (loop & 0xFF); back_data[3] = ((loop >> 8) & 0xFF); back_data[4] = (start & 0xFF); back_data[5] = ((start >> 8) & 0xFF); if( (write_addr + 6) > SRAM_UDP_SendData_Endaddr) { Dbg_Println(DBG_BIT_NET_STATUS_bit,"%s overstep_1 %08X!!!",__func__,write_addr); len = SRAM_UDP_SendData_Endaddr - write_addr; SRAM_DMA_Write_Buff(back_data,len,write_addr); write_addr = SRAM_UDP_SendData_Startaddr; SRAM_DMA_Write_Buff(&back_data[len],(6-len),write_addr); write_addr += (6-len); } else{ SRAM_DMA_Write_Buff(back_data,0x06,write_addr); write_addr += 0x06; //地址偏移 } if(write_addr > SRAM_UDP_SendData_Endaddr) { Dbg_Println(DBG_BIT_NET_STATUS_bit,"%s overstep %08X!!!",__func__,write_addr); write_addr = SRAM_UDP_SendData_Startaddr; } SRAM_Write_DW(write_addr,SRAM_UDP_SendData_Writeaddr); } /******************************************************************************* * Function Name : Udp_Internal_Read_MCU_System_SendAck * Description : 搜索命令 - 回复ACK数据 *******************************************************************************/ __attribute__((section(".non_0_wait"))) uint8_t Udp_Internal_Read_MCU_System_SendAck(uint8_t *ip,uint16_t port,uint16_t frame_id) { UINT32 back_len = BLV_UDP_HEAD_LEN + 449 + 2; //整包数据长度 uint8_t temp_data[34] = {0}; uint8_t temp_rev = 0,rev = 0; memset(Global_Large_Buff,0,sizeof(Global_Large_Buff)); /*数据打包*/ UDP_Add_Header(Global_Large_Buff,In_Read_MCUSystem_Cmd,back_len,frame_id); //添加头部 Global_Large_Buff[BLV_UDP_HEAD_LEN] = SRAM_Read_Byte(SRAM_Register_Start_ADDRESS + Register_NetInfo_EN_OFFSET); //IP类型 2022-12-02 memcpy(&Global_Large_Buff[BLV_UDP_HEAD_LEN + 1],MCU_TYPE,sizeof(MCU_TYPE)); //机型编号 memcpy(&Global_Large_Buff[BLV_UDP_HEAD_LEN + 17],g_netinfo.device_ip,4); //IP地址 memcpy(&Global_Large_Buff[BLV_UDP_HEAD_LEN + 21],server_info.dis_ip,4); //服务器IP地址 memcpy(&Global_Large_Buff[BLV_UDP_HEAD_LEN + 25],g_netinfo.subnet,4); //子网掩码 memcpy(&Global_Large_Buff[BLV_UDP_HEAD_LEN + 29],g_netinfo.gateway,4); //网关 UDP_Add_ServerPort(&Global_Large_Buff[BLV_UDP_HEAD_LEN + 33]); //MCU主机默认端口为3341 Global_Large_Buff[BLV_UDP_HEAD_LEN + 35] = 0; //后两个字节没用 Global_Large_Buff[BLV_UDP_HEAD_LEN + 36] = 0; memcpy(&Global_Large_Buff[BLV_UDP_HEAD_LEN + 37],g_netinfo.dns_server_ip,4); //网关 UDP_ADD_SoftwareVer(&Global_Large_Buff[BLV_UDP_HEAD_LEN+41]); //机型编号 - 软件版本号 /*RTC时间*/ Global_Large_Buff[BLV_UDP_HEAD_LEN+61] = HEX_Conversion_To_DEC(RTC_Raw_Data.year); Global_Large_Buff[BLV_UDP_HEAD_LEN+62] = HEX_Conversion_To_DEC(RTC_Raw_Data.month); Global_Large_Buff[BLV_UDP_HEAD_LEN+63] = HEX_Conversion_To_DEC(RTC_Raw_Data.day); Global_Large_Buff[BLV_UDP_HEAD_LEN+64] = HEX_Conversion_To_DEC(RTC_Raw_Data.hour); Global_Large_Buff[BLV_UDP_HEAD_LEN+65] = HEX_Conversion_To_DEC(RTC_Raw_Data.minute); Global_Large_Buff[BLV_UDP_HEAD_LEN+66] = HEX_Conversion_To_DEC(RTC_Raw_Data.second); /*Launcher版本 只有Launcher_C1F_V04 以上版本才可以读取到Launcher版本,以下版本是读取乱码 2022-08-04*/ //MCU_Flash_Read((uint8_t *)&temp_data,20,Launcher_SoftwareVer_Addr); if(strncmp((char *)temp_data,"Launcher_",strlen("Launcher_")) == 0x00) { memcpy(&Global_Large_Buff[BLV_UDP_HEAD_LEN+67],temp_data,20); }else { /*读取不到Launcher_ 前缀的字符串默认为Launcher_C1F_V02*/ memset(temp_data,0,sizeof(temp_data)); snprintf((char *)temp_data,sizeof(temp_data),"Launcher_C1F_V02 "); memcpy(&Global_Large_Buff[BLV_UDP_HEAD_LEN+67],temp_data,20); } UDP_Add_Mac(&Global_Large_Buff[BLV_UDP_HEAD_LEN+87]); //MAC地址 SRAM_DMA_Read_Buff(&Global_Large_Buff[BLV_UDP_HEAD_LEN+93],4,SRAM_Register_Start_ADDRESS + Register_ProjectCode_OFFSET); //项目编码 SRAM_DMA_Read_Buff(&Global_Large_Buff[BLV_UDP_HEAD_LEN+97],4,SRAM_Register_Start_ADDRESS + Register_RoomNumber_OFFSET); SRAM_DMA_Read_Buff(&Global_Large_Buff[BLV_UDP_HEAD_LEN+101],4,SRAM_Register_Start_ADDRESS + Register_HouseType_OFFSET); SRAM_DMA_Read_Buff(&Global_Large_Buff[BLV_UDP_HEAD_LEN+105],4,SRAM_Register_Start_ADDRESS + Register_ConfigVersion_OFFSET); //配置软件版本 SRAM_DMA_Read_Buff(&Global_Large_Buff[BLV_UDP_HEAD_LEN+109],4,SRAM_Register_Start_ADDRESS + Register_RoomRent_OFFSET); SRAM_DMA_Read_Buff(&Global_Large_Buff[BLV_UDP_HEAD_LEN+113],4,SRAM_Register_Start_ADDRESS + Register_SeasonStatus_OFFSET); Global_Large_Buff[BLV_UDP_HEAD_LEN+117] = Get_Authorize_Lock_Status(); //获取授权状态 SRAM_DMA_Read_Buff(&Global_Large_Buff[BLV_UDP_HEAD_LEN+121],4,SRAM_Register_Start_ADDRESS + Register_MandateUTC_OFFSET); SRAM_DMA_Read_Buff(&Global_Large_Buff[BLV_UDP_HEAD_LEN+125],4,SRAM_Register_Start_ADDRESS + Register_MandateExpiresTime_OFFSET); SRAM_DMA_Read_Buff(&Global_Large_Buff[BLV_UDP_HEAD_LEN+129],128,SRAM_Register_Start_ADDRESS + Register_RoomNumNote_OFFSET); //临时测试使用 memset(temp_data,0,sizeof(temp_data)); snprintf((char *)temp_data,sizeof(temp_data),"BLV-C1"); memcpy(&Global_Large_Buff[BLV_UDP_HEAD_LEN+257],temp_data,32); memset(temp_data,0,sizeof(temp_data)); snprintf((char *)temp_data,sizeof(temp_data),"BLV-V9"); memcpy(&Global_Large_Buff[BLV_UDP_HEAD_LEN+321],temp_data,32); //读取Flash中的模块与模型 //Flash_Read(&Global_Large_Buff[BLV_UDP_HEAD_LEN+257],64,SPIFLASH_MCU_Model_Revision_ADDRESS); //Flash_Read(&Global_Large_Buff[BLV_UDP_HEAD_LEN+321],64,SPIFLASH_MCU_Control_Revision_ADDRESS); temp_rev = Read_LogicFile_Information(0x04,(uint8_t *)&temp_data); //查询LOGIC文件中的酒店别名 - 32Byte if(temp_rev == 0x00) { memcpy(&Global_Large_Buff[BLV_UDP_HEAD_LEN+385],temp_data,32); }else { memset(temp_data,0,32); memcpy(&Global_Large_Buff[BLV_UDP_HEAD_LEN+385],temp_data,32); } temp_rev = Read_LogicFile_Information(0x07,(uint8_t *)&temp_data); //查询LOGIC文件中的房型名称 - 32Byte if(temp_rev == 0x00) { memcpy(&Global_Large_Buff[BLV_UDP_HEAD_LEN+417],temp_data,32); }else { memset(temp_data,0,32); memcpy(&Global_Large_Buff[BLV_UDP_HEAD_LEN+417],temp_data,32); } Dbg_Println(DBG_BIT_NET_STATUS_bit,"%s ip:%d:%d:%d:%d Port:%d",__func__,ip[0],ip[1],ip[2],ip[3],port); memcpy(server_info.goal_ip, ip, 4); server_info.goal_port = port; Dbg_Print_Buff(DBG_BIT_NET_STATUS_bit, "Send Buff", Global_Large_Buff, back_len); //数据打包 NetCRC16(Global_Large_Buff,back_len); rev = WCHNET_SocketUdpSendTo(g_netinfo.SocketId[SocketIdnex_BLVSeriver], Global_Large_Buff, &back_len, ip, port); //SOCK_UDPS, LOG_NET_COMM_Send_Record(0x01,ip,port,&Global_Large_Buff[0],back_len); return rev; } /************************* **函数名:Udp_Internal_PC_Testing_Reply **参 数:data:接受到的数据 len:长度 ip:网络地址 port:端口 **作 用:UDP网络PC测试设备输入输出回复 **返回值: 0x00:数据处理成功 0xF0:接收数据的CRC校验失败 ************************/ __attribute__((section(".non_0_wait"))) uint8_t Udp_Internal_PC_Testing_Reply(uint8_t *reply_data,uint16_t reply_len,uint16_t pack_frame,uint8_t *ip,uint16_t port) { UINT32 back_len = BLV_UDP_HEAD_LEN + reply_len + 3; memset(Global_Large_Buff,0,sizeof(Global_Large_Buff)); UDP_Add_Header(Global_Large_Buff,In_BLVPCTestDevice_Cmd,back_len,pack_frame); //添加头部 for(uint16_t i=0;i= 0x8000)) { server_info.frame_no++; } else { server_info.frame_no = 0x8000; } UDP_Add_Header(Global_Large_Buff,In_BLVPCTestDevice_Cmd,back_len,server_info.frame_no); //添加头部 for(uint16_t i=0;i SRAM_Device_List_End_Addr)) return 0xF0; switch(control_dev) { case DEV_C5IO_Type: //C5IO 数据处理 control_cmd = data[BLV_UDP_HEAD_LEN+3]; if(control_cmd == BLV_C5IO_Set_Relay_CMD) //继电器控制 { control_num = DataLen - BLV_UDP_HEAD_LEN - 2 - 4; if(control_num >= 6) control_num = 6; //目前最长6Byte的控制数据 //Dbg_Println(DBG_OPT_DEVICE_STATUS,"NET PC Test C5IO_Control Len %d,Control_NUM:%d",DataLen,control_num); for(uint8_t i = 0;i> j*2) & 0x03; //控制状态 if(temp1 != 0x00) { //Dbg_Println(DBG_BIT_NET_STATUS_bit,"PC Test C5IO_Control_RelayCH%d status:%d",temp2,temp1); uint8_t control[6]; control[0] = Dev_Host_HVout; control[1] = 0x00; control[2] = temp2; //回路 control[3] = 0x00; control[4] = temp1; //控制状态 control[5] = 0x00; DevActionCtrl(control, 6); //继电器 } } } }else if(control_cmd == BLV_C5IO_Set_Do_CMD) //DO控制 { for(uint8_t i = 0;i<2;i++) { temp = data[BLV_UDP_HEAD_LEN + 4 + i]; for(uint8_t j = 0;j<4;j++) { temp2 = i*4+j; //控制回路 temp1 = (temp >> j*2) & 0x03; //控制状态 if(temp1 != 0x00) { //Dbg_Println(DBG_BIT_Debug_STATUS_bit,"PC Test C5IO_Control_DoCH%d status:%d",temp2,temp1); BUS_C5IO_Control_Do(device_listaddr,temp2,temp1); } } } } return 0x00; case DEV_C5MUSIC_Type: control_cmd = data[BLV_UDP_HEAD_LEN + 3]; if(control_cmd == BLV_C5MUSIC_Specify_Play_CMD) { temp = data[BLV_UDP_HEAD_LEN + 4]; //播放状态 temp1 = data[BLV_UDP_HEAD_LEN + 5]; //播放文件夹 temp2 = data[BLV_UDP_HEAD_LEN + 6]; //播放ID //Dbg_Println(DBG_BIT_NET_STATUS_bit,"PC Test C5Music_Control dir:%d id:%d status:%d",temp1,temp2,temp); BUS_C5MUSIC_Playback(device_listaddr,temp1,temp,temp2); } { /*回复数据打包*/ uint8_t ack_buff[4] = {0}; ack_buff[0] = g_pc_test.test_flag; ack_buff[1] = g_pc_test.test_dev; ack_buff[2] = g_pc_test.test_addr; ack_buff[3] = 0x01; //执行结果 Udp_Internal_PC_Testing_Reply(ack_buff,0x04,ack_frame,g_pc_test.pc_ip,g_pc_test.pc_port); } break; case DEV_RS485_PWM: control_cmd = data[BLV_UDP_HEAD_LEN + 3]; if(control_cmd == C12_SET_LIGHT_CMD) { temp = data[BLV_UDP_HEAD_LEN + 4]; //设置回路 temp1 = data[BLV_UDP_HEAD_LEN + 5]; //亮度值 temp2 = data[BLV_UDP_HEAD_LEN + 6]; //渐变时间 Dbg_Println(DBG_BIT_NET_STATUS_bit,"PC Test C12Dimming:%d light:%d fade:%d",temp1,temp2,temp); if(temp) { UINT8 control[6]; control[0] = DEV_RS485_PWM; control[1] = 0x00; control[2] = temp-1; //回路 control[3] = 0x00; control[4] = 0x01; //控制状态 control[5] = temp1; //亮度值 DevActionCtrl(control, 6); //继电器 } } break; default: break; } return 0x00; } /************************* **函数名:Udp_Internal_BLVPCTestDevice_Process **参 数:data:接受到的数据 len:长度 ip:网络地址 port:端口 **作 用:BLV-C1PC下发设备输入输出测试数据处理 **返回值: 0x00:数据处理成功 0xF0:接收数据的CRC校验失败 ************************/ __attribute__((section(".non_0_wait"))) uint8_t Udp_Internal_BLVPCTestDevice_Process(uint8_t* data, uint16_t DataLen, uint8_t *ip,uint16_t port) { /*CRC校验*/ uint16_t data_crc = data[DataLen-2] + (data[DataLen-1] << 8); if(NetCRC16_2(data,DataLen-2) != data_crc) return 0xF0; uint8_t temp1 = 0; uint32_t dev_addr = 0; Dbg_Println(DBG_BIT_NET_STATUS_bit,"%s",__func__); dev_addr = Find_Device_List_Information(DEV_PCTEST_TYPE,DEV_PCTEST_Addr); Device_Public_Information_G BUS_Public; PC_TEST_DEVICE_INFO PC_Test_Info; SRAM_DMA_Read_Buff((uint8_t *)&BUS_Public,sizeof(Device_Public_Information_G),dev_addr); SRAM_DMA_Read_Buff((uint8_t *)&PC_Test_Info,sizeof(PC_TEST_DEVICE_INFO),dev_addr+Dev_Privately); /*测试数据内容*/ temp1 = data[BLV_UDP_HEAD_LEN]; if(temp1 == 0x01) //测试输入 - 同时检测时间 { g_pc_test.test_flag = 0x11; g_pc_test.test_dev = data[BLV_UDP_HEAD_LEN + 1]; //输入检测设备类型 g_pc_test.test_addr = data[BLV_UDP_HEAD_LEN + 2]; //输入检测设备地址 PC_Test_Info.test_time = data[BLV_UDP_HEAD_LEN + 3]; //测试时间,单位:分钟 PC_Test_Info.test_flag = g_pc_test.test_flag; PC_Test_Info.test_tick = SysTick_1ms; PC_Test_Info.test_time *= 60000; g_pc_test.pc_ip[0] = ip[0]; //2022-07-12 g_pc_test.pc_ip[1] = ip[1]; g_pc_test.pc_ip[2] = ip[2]; g_pc_test.pc_ip[3] = ip[3]; g_pc_test.pc_port = port; } else if(temp1 == 0x02) //测试输出 { g_pc_test.test_flag = 0x12; PC_Test_Info.test_flag = g_pc_test.test_flag; PC_Test_Info.test_tick = SysTick_1ms; PC_Test_Info.test_time = 120000; Udp_Internal_PC_Testing_DataDeal(data,DataLen,ip,port); }else if(temp1 == 0x03) //开启巡回测试 - 测试485端口 { g_pc_test.test_flag = 0x13; PC_Test_Info.test_flag = g_pc_test.test_flag; g_pc_test.tour_num = 0; g_pc_test.tour_succ = 0; g_pc_test.pc_ip[0] = ip[0]; g_pc_test.pc_ip[1] = ip[1]; g_pc_test.pc_ip[2] = ip[2]; g_pc_test.pc_ip[3] = ip[3]; g_pc_test.pc_port = port; } BUS_Public.check = 0x00; BUS_Public.check = DoubleData_CheckSum((uint8_t *)&BUS_Public, sizeof(Device_Public_Information_G), (uint8_t *)&PC_Test_Info, sizeof(PC_TEST_DEVICE_INFO)); SRAM_DMA_Write_Buff((uint8_t *)&BUS_Public, sizeof(Device_Public_Information_G),dev_addr);/*将数据保存*/ SRAM_DMA_Write_Buff((uint8_t *)&PC_Test_Info,sizeof(PC_TEST_DEVICE_INFO),dev_addr+Dev_Privately); return 0x00; } /************************* **函数名:UDP_Conversion_Baud **参 数:data:接受到的数据 **作 用:将数据转换为对应的波特率 **返回值:对应的波特率 ************************/ __attribute__((section(".non_0_wait"))) uint32_t UDP_Conversion_Baud(uint8_t data) { uint32_t baud = 0; switch(data) { case 0x01: baud = 9600; break; case 0x02: baud = 14400; break; case 0x03: baud = 19200; break; case 0x04: baud = 38400; break; case 0x05: baud = 56000; break; case 0x06: baud = 57600; break; case 0x07: baud = 115200; break; } return baud; } /************************* **函数名:UDP_Conversion_Baud **参 数:data:接受到的数据 **作 用:将数据转换为对应的波特率 **返回值:对应的波特率 ************************/ __attribute__((section(".non_0_wait"))) uint8_t UDP_Baud_Conversion_Data(uint32_t data) { uint8_t re_data = 0; switch(data) { case 9600: re_data = 0x01; break; case 14400: re_data = 0x02; break; case 19200: re_data = 0x03; break; case 38400: re_data = 0x04; break; case 56000: re_data = 0x05; break; case 57600: re_data = 0x06; break; case 115200: re_data = 0x07; break; } return re_data; } /************************* **函数名:Udp_Internal_SeriaNet_Process **参 数:data:接受到的数据 len:长度 ip:网络地址 port:端口 **作 用:BLV-C1透传数据设置数据处理 **返回值: 0x00:数据处理成功 0xF0:接收数据的CRC校验失败 ************************/ __attribute__((section(".non_0_wait"))) uint8_t Udp_Internal_SeriaNet_Process(uint8_t* data, uint16_t DataLen, uint8_t *ip,uint16_t port) { /*CRC校验*/ uint16_t data_crc = data[DataLen-2] + (data[DataLen-1] << 8); if(NetCRC16_2(data,DataLen-2) != data_crc) return 0xF0; uint8_t back_data[SeriaNet_Cmd_Send_Len]={0}; UINT32 sendlen = SeriaNet_Cmd_Send_Len; uint8_t temp = 0; uint16_t pack_frame = 0,temp_len = 0; pack_frame = data[FRAME_NO_OFFSET] + (data[FRAME_NO_OFFSET+1]<<8); //帧号 SRAM_DMA_Write_Buff(ip,4,SRAM_IAP_IP_ADDRESS); //保存PC IP地址 SRAM_Write_Word(port,SRAM_IAP_PORT_ADDRESS); //保存PC 端口号 /*接收到透传设置命令*/ Dbg_Println(DBG_BIT_NET_STATUS_bit,"%s IP:%02X.%02X.%02X.%02X Port:%d\r\n",__func__,ip[0],ip[1],ip[2],ip[3],port); /*透传设置处理*/ temp = data[BLV_UDP_HEAD_LEN]; switch(temp) { case 0x01: //透传状态查询 - 立即回复 UDP_Add_Header(back_data,In_SeriaNet_Cmd,SeriaNet_Cmd_Send_Len,pack_frame); //添加头部 back_data[BLV_UDP_HEAD_LEN] = 0x01; if(data[BLV_UDP_HEAD_LEN+1] == 0x01) //端口1 { back_data[BLV_UDP_HEAD_LEN+1] = Poll485_Info.port_mode; Poll485_Info.mode_tick = SysTick_1s; }else if(data[BLV_UDP_HEAD_LEN+1] == 0x02) //端口2 { back_data[BLV_UDP_HEAD_LEN+1] = Act485_Info.port_mode; Act485_Info.mode_tick = SysTick_1s; }else if(data[BLV_UDP_HEAD_LEN+1] == 0x03) //端口3 { back_data[BLV_UDP_HEAD_LEN+1] = BUS485_Info.port_mode; BUS485_Info.mode_tick = SysTick_1s; } NetCRC16(&back_data[0],SeriaNet_Cmd_Send_Len); WCHNET_SocketUdpSendTo(g_netinfo.SocketId[SocketIdnex_BLVSeriver], &back_data[0], &sendlen, ip, port); break; case 0x02: //透传设置 - 立即回复 UDP_Add_Header(back_data,In_SeriaNet_Cmd,SeriaNet_Cmd_Send_Len,pack_frame); //添加头部 back_data[BLV_UDP_HEAD_LEN] = 0x02; back_data[BLV_UDP_HEAD_LEN+1] = 0x01; if(data[BLV_UDP_HEAD_LEN+1] == 0x01) //端口1 { Poll485_Info.baud = UDP_Conversion_Baud(data[BLV_UDP_HEAD_LEN+2]); //设置的波特率 if(Poll485_Info.baud != Polling_Baud) //设置波特率 { Poll485_Info.BaudRateCfg(Poll485_Info.baud); } Poll485_Info.mode_outtime = data[BLV_UDP_HEAD_LEN+3]*2; //设置模式超时时间 Poll485_Info.port_mode = data[BLV_UDP_HEAD_LEN+4]; //设置端口模式 Poll485_Info.mode_tick = SysTick_1s; }else if(data[BLV_UDP_HEAD_LEN+1] == 0x02) //端口2 { Act485_Info.baud = UDP_Conversion_Baud(data[BLV_UDP_HEAD_LEN+2]); //设置的波特率 if(Act485_Info.baud != Active_Baud) //设置波特率 { Act485_Info.BaudRateCfg(Act485_Info.baud); } Act485_Info.mode_outtime = data[BLV_UDP_HEAD_LEN+3]*2; //设置模式超时时间 Act485_Info.port_mode = data[BLV_UDP_HEAD_LEN+4]; //设置端口模式 Act485_Info.mode_tick = SysTick_1s; Dbg_Println(DBG_BIT_NET_STATUS_bit,"Act485_Info.baud:%d",Act485_Info.baud ); Dbg_Println(DBG_BIT_NET_STATUS_bit,"Act485_Info.pass_outtime:%d",Act485_Info.mode_outtime ); Dbg_Println(DBG_BIT_NET_STATUS_bit,"Act485_Info.port_mode:%d",Act485_Info.port_mode ); }else if(data[BLV_UDP_HEAD_LEN+1] == 0x03) //端口3 { BUS485_Info.baud = UDP_Conversion_Baud(data[BLV_UDP_HEAD_LEN+2]); //设置的波特率 if(BUS485_Info.baud != Bus_Baud) //设置波特率 { } BUS485_Info.mode_outtime = data[BLV_UDP_HEAD_LEN+3]*2; //设置模式超时时间 BUS485_Info.port_mode = data[BLV_UDP_HEAD_LEN+4]; //设置端口模式 BUS485_Info.mode_tick = SysTick_1s; }else { back_data[BLV_UDP_HEAD_LEN+1] = 0x02; } NetCRC16(&back_data[0],SeriaNet_Cmd_Send_Len); WCHNET_SocketUdpSendTo(g_netinfo.SocketId[SocketIdnex_BLVSeriver], &back_data[0], &sendlen, ip, port); break; case 0x03: //透传数据传输 - 设备回复或设备没回复,主机回复 if(data[BLV_UDP_HEAD_LEN+1] == 0x01) { Poll485_Info.mode_tick = SysTick_1s; }else if(data[BLV_UDP_HEAD_LEN+1] == 0x02) { Act485_Info.mode_tick = SysTick_1s; }else if(data[BLV_UDP_HEAD_LEN+1] == 0x03) { BUS485_Info.mode_tick = SysTick_1s; } /*将透传数据放到发送缓冲区*/ temp_len = DataLen - 15 - 2 - 3; //Dbg_Println(DBG_BIT_NET_STATUS_bit,"NET temp_len:%d ",temp_len ); Write_Uart_SendBuff(data[BLV_UDP_HEAD_LEN+1],data[BLV_UDP_HEAD_LEN+2],&data[BLV_UDP_HEAD_LEN+3],temp_len); break; } return 0x00; } /************************* **函数名:Udp_Internal_SeriaNet_Uploading **参 数:data_addr:需要上报处理 - 串口数据缓冲区 前2byte字节为数据长度 - 透传数据最长为480Byte **作 用:BLV-C1透传数据上发 **返回值: 0x00:数据处理成功 0xF0:接收数据的CRC校验失败 ************************/ __attribute__((section(".non_0_wait"))) uint8_t Udp_Internal_SeriaNet_Uploading(uint8_t port,uint32_t baud,uint32_t data_addr) { uint8_t pc_ip[4]; uint16_t pc_port = 0; uint32_t write_addr = data_addr; UINT32 data_len = SRAM_Read_Word(data_addr); if(data_len > Passthrough_DataLen_Max) data_len = Passthrough_DataLen_Max; memset(pc_ip,0,sizeof(pc_ip)); memset(Global_Large_Buff,0,sizeof(Global_Large_Buff)); if((server_info.frame_no < 0xfffe) && (server_info.frame_no >= 0x8000)) { server_info.frame_no++; } else { server_info.frame_no = 0x8000; } /*读取PC IP地址*/ SRAM_DMA_Read_Buff(pc_ip,4,SRAM_IAP_IP_ADDRESS); pc_port = SRAM_Read_Word(SRAM_IAP_PORT_ADDRESS); Dbg_Println(DBG_BIT_NET_STATUS_bit,"Udp_Internal_SeriaNet_Uploading IP:%02X.%02X.%02X.%02X Port:%d",pc_ip[0],pc_ip[1],pc_ip[2],pc_ip[3],pc_port); write_addr = data_addr+2; SRAM_DMA_Read_Buff(&Global_Large_Buff[BLV_UDP_HEAD_LEN + 2],data_len,write_addr); Dbg_Println(DBG_BIT_NET_STATUS_bit,"Udp_Internal_SeriaNet_Uploading Len:%d",data_len); data_len += 19; //加上包头长度15Byte及包尾CRC2Byte /**/ UDP_Add_Header(Global_Large_Buff,In_SeriaNetReported_Cmd,data_len,server_info.frame_no); //添加头部 Global_Large_Buff[BLV_UDP_HEAD_LEN] = port; //当前数据端口号 Global_Large_Buff[BLV_UDP_HEAD_LEN + 1] = UDP_Baud_Conversion_Data(baud); //当前数据波特率 NetCRC16(&Global_Large_Buff[0],data_len); WCHNET_SocketUdpSendTo(g_netinfo.SocketId[SocketIdnex_BLVSeriver], &Global_Large_Buff[0], &data_len, pc_ip, pc_port); return 0x00; } /************************* **函数名:Udp_Internal_SeriaNet_Uploading **参 数:data_addr:需要上报处理 - 串口数据缓冲区 前2byte字节为数据长度 - 透传数据最长为480Byte **作 用:BLV-C1透传数据上发 **返回值: 0x00:数据处理成功 0xF0:接收数据的CRC校验失败 ************************/ __attribute__((section(".non_0_wait"))) uint8_t Udp_Internal_SeriaNet_Uploading2(uint8_t port,uint32_t baud,uint8_t* data, uint16_t DataLen) { uint8_t pc_ip[4]; uint16_t pc_port = 0; UINT32 data_len = DataLen + 19; if(data_len > Passthrough_DataLen_Max) data_len = Passthrough_DataLen_Max; memset(pc_ip,0,sizeof(pc_ip)); memset(Global_Large_Buff,0,sizeof(Global_Large_Buff)); if((server_info.frame_no < 0xfffe) && (server_info.frame_no >= 0x8000)) { server_info.frame_no++; }else{ server_info.frame_no = 0x8000; } /*读取PC IP地址*/ SRAM_DMA_Read_Buff(pc_ip,4,SRAM_IAP_IP_ADDRESS); pc_port = SRAM_Read_Word(SRAM_IAP_PORT_ADDRESS); UDP_Add_Header(Global_Large_Buff,In_SeriaNetReported_Cmd,data_len,server_info.frame_no); //添加头部 Global_Large_Buff[BLV_UDP_HEAD_LEN] = port; //当前数据端口号 Global_Large_Buff[BLV_UDP_HEAD_LEN + 1] = UDP_Baud_Conversion_Data(baud); //当前数据波特率 for(uint16_t i = 0;i= 0x8000)) { server_info.frame_no++; } else { server_info.frame_no = 0x8000; } /*读取PC IP地址*/ SRAM_DMA_Read_Buff(pc_ip,4,SRAM_IAP_IP_ADDRESS); pc_port = SRAM_Read_Word(SRAM_IAP_PORT_ADDRESS); UDP_Add_Header(back_data,In_SeriaNet_Cmd,data_len,server_info.frame_no); //添加头部 back_data[BLV_UDP_HEAD_LEN] = 0x03; //透传回复 back_data[BLV_UDP_HEAD_LEN + 1] = 0x03; //超时状态 NetCRC16(&back_data[0],data_len); WCHNET_SocketUdpSendTo(g_netinfo.SocketId[SocketIdnex_BLVSeriver], &back_data[0], &data_len, pc_ip, pc_port); return 0x00; } /******************************************************************************* * Function Name : Udp_Scan_Roomstate * Description : 扫描房间设备状态是否变化 *******************************************************************************/ void Udp_Scan_Roomstate(void) { uint8_t temp1 = 0,temp2 = 0; uint8_t back_data[20]; //一次发生最大长度 uint32_t write_addr = SRAM_Read_DW(SRAM_UDP_SendData_Writeaddr),read_addr = SRAM_Read_DW(SRAM_UDP_SendData_Readaddr); memset(back_data,0,20); //如果读取地址任何一个出错,读写地址直接复位 if( (write_addr < SRAM_UDP_SendData_Startaddr) || (write_addr > SRAM_UDP_SendData_Endaddr) \ || (read_addr < SRAM_UDP_SendData_Startaddr) || (read_addr > SRAM_UDP_SendData_Endaddr) ) { write_addr = SRAM_UDP_SendData_Startaddr; read_addr = SRAM_UDP_SendData_Startaddr; SRAM_Write_DW(write_addr,SRAM_UDP_SendData_Writeaddr); SRAM_Write_DW(read_addr,SRAM_UDP_SendData_Readaddr); } /*继电器变化标志位 - 3Byte*/ for(uint8_t i = 0;i<3;i++) { temp1 = SRAM_Read_Byte(SRAM_LOG_Device_C5IO_Relay_Status + i); temp2 = SRAM_Read_Byte(SRAM_UDP_Device_C5IO_Relay_Status + i); if(temp1 == temp2) continue; Dbg_Println(DBG_BIT_NET_STATUS_bit,"LOG_C5IO:%d,UDP_C5IO:%d",temp1,temp2); for(uint8_t j=0;j<8;j++) { if( (temp1 & (0x01<= SRAM_UDP_SendData_Endaddr) { Dbg_Println(DBG_BIT_NET_STATUS_bit,"SRAM_UDP_SendData_Writeaddr overstep_2 %08X!!!\r\n",write_addr); write_addr = SRAM_UDP_SendData_Startaddr; } SRAM_Write_DW(write_addr,SRAM_UDP_SendData_Writeaddr); } } /*比较完成后,保存变量状态*/ SRAM_Write_Byte(temp1,SRAM_UDP_Device_C5IO_Relay_Status + i); } if( write_addr != read_addr) { server_info.active_cmd_flag |= UDP_ActSend_DevState_Flag; //设置设备状态上报 标志位 return ; } /*设备故障上报 - */ write_addr = SRAM_Read_DW(SRAM_DEVICE_ONLINE_STATE_WRITE_ADDR); read_addr = SRAM_Read_DW(SRAM_DEVICE_ONLINE_STATE_READ_ADDR); if( (write_addr < SRAM_DEVICE_ONLINE_STATE_START_ADDR) || (write_addr > SRAM_DEVICE_ONLINE_STATE_END_ADDR) \ || (read_addr < SRAM_DEVICE_ONLINE_STATE_START_ADDR) || (read_addr > SRAM_DEVICE_ONLINE_STATE_END_ADDR) ) { write_addr = SRAM_DEVICE_ONLINE_STATE_START_ADDR; read_addr = SRAM_DEVICE_ONLINE_STATE_START_ADDR; SRAM_Write_DW(write_addr,SRAM_DEVICE_ONLINE_STATE_WRITE_ADDR); SRAM_Write_DW(read_addr,SRAM_DEVICE_ONLINE_STATE_READ_ADDR); } if( write_addr != read_addr) { server_info.active_cmd_flag |= UDP_ActSend_DevState_Flag; //设置设备状态上报 标志位 } } /******************************************************************************* * Function Name : Udp_Internal_RoomState * Description : 房间设备动作上报 *******************************************************************************/ void Udp_Internal_RoomState(void) { uint32_t write_addr = 0x00,write_addr_2 = 0x00; uint32_t read_addr = 0x00,read_addr_2 = 0x00; uint16_t dev_state_len = 0,dev_online_len = 0,remaining_len = 0; UINT32 len = 0; if(server_info.udp_retry_cnt == 0x00) { //不是重发数据包 if((server_info.frame_no < 0xfffe) && (server_info.frame_no >= 0x8000)) { server_info.frame_no++; }else { server_info.frame_no = 0x8000; } //读取设备状态 缓冲区读写地址 write_addr = SRAM_Read_DW(SRAM_UDP_SendData_Writeaddr); read_addr = SRAM_Read_DW(SRAM_UDP_SendData_Readaddr); //如果读取地址任何一个出错,读写地址直接复位 if( (write_addr < SRAM_UDP_SendData_Startaddr) || (write_addr > SRAM_UDP_SendData_Endaddr) \ || (read_addr < SRAM_UDP_SendData_Startaddr) || (read_addr > SRAM_UDP_SendData_Endaddr) ) { write_addr = SRAM_UDP_SendData_Startaddr; read_addr = SRAM_UDP_SendData_Startaddr; SRAM_Write_DW(write_addr,SRAM_UDP_SendData_Writeaddr); SRAM_Write_DW(read_addr,SRAM_UDP_SendData_Readaddr); SRAM_Write_DW(read_addr,SRAM_UDP_SendData_Tempaddr); } //读取设备故障 缓冲区读写地址 write_addr_2 = SRAM_Read_DW(SRAM_DEVICE_ONLINE_STATE_WRITE_ADDR); read_addr_2 = SRAM_Read_DW(SRAM_DEVICE_ONLINE_STATE_READ_ADDR); //如果读取地址任何一个出错,读写地址直接复位 if( (write_addr_2 < SRAM_DEVICE_ONLINE_STATE_START_ADDR) || (write_addr_2 > SRAM_DEVICE_ONLINE_STATE_END_ADDR) \ || (read_addr_2 < SRAM_DEVICE_ONLINE_STATE_START_ADDR) || (read_addr_2 > SRAM_DEVICE_ONLINE_STATE_END_ADDR) ) { write_addr_2 = SRAM_DEVICE_ONLINE_STATE_START_ADDR; read_addr_2 = SRAM_DEVICE_ONLINE_STATE_START_ADDR; SRAM_Write_DW(write_addr_2,SRAM_DEVICE_ONLINE_STATE_WRITE_ADDR); SRAM_Write_DW(read_addr_2,SRAM_DEVICE_ONLINE_STATE_READ_ADDR); SRAM_Write_DW(read_addr_2,SRAM_DEVICE_ONLINE_STATE_TEMP_ADDR); } }else { //重发数据包 - 读取缓冲区读写地址 write_addr = SRAM_Read_DW(SRAM_UDP_SendData_Tempaddr); //读取上一次 读取数据数据的结束地址 read_addr = SRAM_Read_DW(SRAM_UDP_SendData_Readaddr); //如果读取地址任何一个出错,读写地址直接复位 if( (write_addr < SRAM_UDP_SendData_Startaddr) || (write_addr > SRAM_UDP_SendData_Endaddr) \ || (read_addr < SRAM_UDP_SendData_Startaddr) || (read_addr > SRAM_UDP_SendData_Endaddr) ) { write_addr = SRAM_UDP_SendData_Startaddr; read_addr = SRAM_UDP_SendData_Startaddr; SRAM_Write_DW(write_addr,SRAM_UDP_SendData_Writeaddr); SRAM_Write_DW(read_addr,SRAM_UDP_SendData_Readaddr); SRAM_Write_DW(read_addr,SRAM_UDP_SendData_Tempaddr); } //读取设备故障 缓冲区读写地址 write_addr_2 = SRAM_Read_DW(SRAM_DEVICE_ONLINE_STATE_TEMP_ADDR); read_addr_2 = SRAM_Read_DW(SRAM_DEVICE_ONLINE_STATE_READ_ADDR); //如果读取地址任何一个出错,读写地址直接复位 if( (write_addr_2 < SRAM_DEVICE_ONLINE_STATE_START_ADDR) || (write_addr_2 > SRAM_DEVICE_ONLINE_STATE_END_ADDR) \ || (read_addr_2 < SRAM_DEVICE_ONLINE_STATE_START_ADDR) || (read_addr_2 > SRAM_DEVICE_ONLINE_STATE_END_ADDR) ) { write_addr_2 = SRAM_DEVICE_ONLINE_STATE_START_ADDR; read_addr_2 = SRAM_DEVICE_ONLINE_STATE_START_ADDR; SRAM_Write_DW(write_addr_2,SRAM_DEVICE_ONLINE_STATE_WRITE_ADDR); SRAM_Write_DW(read_addr_2,SRAM_DEVICE_ONLINE_STATE_READ_ADDR); SRAM_Write_DW(read_addr_2,SRAM_DEVICE_ONLINE_STATE_TEMP_ADDR); } } if( (write_addr == read_addr) && (write_addr_2 == read_addr_2) ) return ; memset(Global_Large_Buff,0,sizeof(Global_Large_Buff)); //判断设备状态数量长度是否超长 if(write_addr > read_addr) { dev_state_len = write_addr - read_addr; if(dev_state_len > SRAM_UDP_SendData_Size) dev_state_len = SRAM_UDP_SendData_Size; } else if(write_addr < read_addr) { dev_state_len = SRAM_UDP_SendData_Endaddr - read_addr; dev_state_len += write_addr - SRAM_UDP_SendData_Startaddr; if(dev_state_len > SRAM_UDP_SendData_Size) dev_state_len = SRAM_UDP_SendData_Size; } //判断设备离线数量长度是否超长 if(write_addr_2 > read_addr_2) { dev_online_len = write_addr_2 - read_addr_2; if(dev_online_len > SRAM_UDP_SendData_Size) dev_online_len = SRAM_UDP_SendData_Size; } else if(write_addr_2 < read_addr_2) { dev_online_len = SRAM_DEVICE_ONLINE_STATE_END_ADDR - read_addr_2; dev_online_len += write_addr_2 - SRAM_DEVICE_ONLINE_STATE_START_ADDR; if(dev_online_len > SRAM_UDP_SendData_Size) dev_online_len = SRAM_UDP_SendData_Size; } if( (dev_state_len == 0x00) && (dev_online_len == 0x00) ) return ; //无数据发送 Dbg_Println(DBG_BIT_NET_STATUS_bit,"设备状态变化上报 %d 帧号:%04x 写:%8X 读:%8X",server_info.udp_retry_cnt,server_info.frame_no,write_addr,read_addr); Dbg_Println(DBG_BIT_NET_STATUS_bit,"设备故障上报 写:%8X 读:%8X",write_addr_2,read_addr_2); len = BLV_UDP_HEAD_LEN; Global_Large_Buff[len++] = Get_Authorize_Lock_Status(); //系统锁 Global_Large_Buff[len++] = 0x00; //保留 Global_Large_Buff[len++] = 0x00; //保留 Global_Large_Buff[len++] = 0x00; //保留 Global_Large_Buff[len++] = 0x00; //保留 Global_Large_Buff[len++] = 0x00; //保留 Global_Large_Buff[len++] = 0x00; //保留 Global_Large_Buff[len++] = (dev_state_len / 6); //RCU上报的设备数量 if(read_addr + dev_state_len > SRAM_UDP_SendData_Endaddr) { remaining_len = SRAM_UDP_SendData_Endaddr - read_addr; SRAM_DMA_Read_Buff(&Global_Large_Buff[len],remaining_len,read_addr); len += remaining_len; remaining_len = dev_state_len - remaining_len; read_addr = SRAM_UDP_SendData_Startaddr; SRAM_DMA_Read_Buff(&Global_Large_Buff[len],remaining_len,read_addr); read_addr += remaining_len; len += remaining_len; }else { SRAM_DMA_Read_Buff(&Global_Large_Buff[len],dev_state_len,read_addr); read_addr += dev_state_len; len += dev_state_len; if(read_addr > SRAM_UDP_SendData_Endaddr) read_addr = SRAM_UDP_SendData_Startaddr; } Global_Large_Buff[len++] = (dev_online_len / 6); //RCU上报的设备离线数量 if(read_addr_2 + dev_online_len > SRAM_DEVICE_ONLINE_STATE_END_ADDR) { remaining_len = SRAM_DEVICE_ONLINE_STATE_END_ADDR - read_addr_2; SRAM_DMA_Read_Buff(&Global_Large_Buff[len],remaining_len,read_addr_2); len += remaining_len; remaining_len = dev_online_len - remaining_len; read_addr_2 = SRAM_DEVICE_ONLINE_STATE_START_ADDR; SRAM_DMA_Read_Buff(&Global_Large_Buff[len],remaining_len,read_addr_2); read_addr_2 += remaining_len; len += remaining_len; }else { SRAM_DMA_Read_Buff(&Global_Large_Buff[len],dev_online_len,read_addr_2); read_addr_2 += dev_online_len; len += dev_online_len; if(read_addr_2 > SRAM_DEVICE_ONLINE_STATE_END_ADDR) read_addr_2 = SRAM_DEVICE_ONLINE_STATE_START_ADDR; } SRAM_Write_DW(read_addr,SRAM_UDP_SendData_Tempaddr); //先临时保存读取地址,当收到回复报文时才将读取地址复位 SRAM_Write_DW(read_addr_2,SRAM_DEVICE_ONLINE_STATE_TEMP_ADDR); //先临时保存读取地址,当收到回复报文时才将读取地址复位 len += 2; UDP_Add_Header(Global_Large_Buff,In_DevState_Cmd,len,server_info.frame_no); //最后添加头部 NetCRC16(&Global_Large_Buff[0],len); Dbg_Print_Buff(DBG_BIT_NET_STATUS_bit,"房间设备动作上报数据:",Global_Large_Buff,len); WCHNET_SocketUdpSendTo(g_netinfo.SocketId[SocketIdnex_BLVSeriver], &Global_Large_Buff[0], &len, server_info.dis_ip, server_info.dis_port); LOG_NET_COMM_Send_Record(0x01,server_info.dis_ip,server_info.dis_port,&Global_Large_Buff[0],len); } /******************************************************************************* * Function Name : Udp_Internal_RoomState_Process * Description : 向服务器房间设备状态 回复数据 *******************************************************************************/ uint8_t Udp_Internal_RoomState_Process(uint8_t *data, uint16_t DataLen, uint8_t *ip,uint16_t port) { /*CRC校验*/ uint16_t data_crc = 0x00; uint32_t temp_val = 0x00; data_crc = data[DataLen-1]; data_crc <<= 0x08; data_crc |= data[DataLen-2]; if(NetCRC16_2(data,DataLen-2) != data_crc) return 0xF0; //判断帧号是否一致 data_crc = data[FRAME_NO_OFFSET + 1]; data_crc <<= 0x08; data_crc |= data[FRAME_NO_OFFSET]; if(data_crc != server_info.frame_no) return 0x01; temp_val = SRAM_Read_DW(SRAM_UDP_SendData_Tempaddr); SRAM_Write_DW(temp_val, SRAM_UDP_SendData_Readaddr); //读地址复位 Dbg_Println(DBG_BIT_NET_STATUS_bit,"%s Dev 读:%8X",__func__,temp_val); temp_val = SRAM_Read_DW(SRAM_DEVICE_ONLINE_STATE_TEMP_ADDR); //读临时保存的故障读取地址 SRAM_Write_DW(temp_val, SRAM_DEVICE_ONLINE_STATE_READ_ADDR); //故障读地址重新赋值 Dbg_Println(DBG_BIT_NET_STATUS_bit,"%s Dev Err 读:%8X",__func__,temp_val); //无数据处理上报成功,清楚一下标志位而已 server_info.udp_send_flag = 0x00; //清楚发送标志位 server_info.active_cmd_flag &= ~UDP_ActSend_DevState_Flag; //清楚标志位 server_info.udp_online_tick = SysTick_1ms; return 0x00; } /******************************************************************************* * Function Name : ServiceInfo_Get_ALL_Loop_State * Description : 服务信息 - 获取全部回路的开关状态 *******************************************************************************/ uint8_t ServiceInfo_Get_ALL_Loop_State(uint8_t *read_buff) { uint32_t dev_addr = Find_AllDevice_List_Information(Dev_Host_Service,0x00); Device_Public_Information_G BUS_Public; //共用 NOR_SERVICE_INFO DevServiceInfo; //服务信息局部变量 uint8_t loop_offset = 0; uint8_t loop_ide = 0; if(dev_addr == 0x00) return 0x01; //未找到设备 SRAM_DMA_Read_Buff((uint8_t *)&BUS_Public,sizeof(Device_Public_Information_G),dev_addr); //拷贝所有共有数据 SRAM_DMA_Read_Buff((uint8_t *)&DevServiceInfo,sizeof(NOR_SERVICE_INFO),dev_addr+Dev_Privately); if( DevServiceInfo.ServiceLoopValidNum >= ServiceNumMAX ) DevServiceInfo.ServiceLoopValidNum = ServiceNumMAX; for(uint8_t i=0;i= 0x8000)) { server_info.frame_no++; }else{ server_info.frame_no = 0x8000; } memset(Global_Large_Buff,0,sizeof(Global_Large_Buff)); sendlen = BLV_UDP_HEAD_LEN; Global_Large_Buff[sendlen++] = 0x01; //解析参数版本 Global_Large_Buff[sendlen++] = DevActionGlobal.DevActionU64Cond.EleState; //取电状态 Global_Large_Buff[sendlen++] = SRAM_Read_Byte(SRAM_UDP_ELEReport_CardType); //身份信息 Global_Large_Buff[sendlen++] = SRAM_Read_Byte(SRAM_UDP_ELEReport_VirtualCard); //无卡逻辑状态(对应事件状态) ServiceInfo_Get_ALL_Loop_State(&Global_Large_Buff[sendlen]); sendlen += 8; Global_Large_Buff[sendlen++] = SRAM_Read_Byte( SRAM_Register_Start_ADDRESS + Register_RoomRent_OFFSET ); //PMS状态 - 0x01:入住,0x02:退房 服务器给RCU主机发送的 //Global_Large_Buff[sendlen++] = 0x01; //测试使用 Global_Large_Buff[sendlen++] = SRAM_Read_Byte(SRAM_UDP_Report_CarbonSatet); //碳达人状态 - 0x01:开,0x00:关 /*查找能耗监测设备 - 默认:1地址 - 回路 1*/ temp_dev = Find_AllDevice_List_Information(Dev_Energy_Monitor,0x01); if(temp_dev != 0x00) { /*当前能耗设备已存在 */ RS485_ENERGYMONITOR_INFO Rs485EnergyInfo; SRAM_DMA_Read_Buff((uint8_t *)&Rs485EnergyInfo,sizeof(RS485_ENERGYMONITOR_INFO),temp_dev+Dev_Privately); Global_Large_Buff[sendlen++] = 0x01; //上报数据个数 Global_Large_Buff[sendlen++] = Dev_Energy_Monitor; //设备类型 - 能耗检测 Global_Large_Buff[sendlen++] = 0x01; //设备地址 - 能耗检测 设备默认0x01 Global_Large_Buff[sendlen++] = 0x01; //设备回路 - 能耗检测 设备默认0x01 Global_Large_Buff[sendlen++] = 0x00; //设备回路 - 能耗检测 设备默认0x01 Global_Large_Buff[sendlen++] = 0x10; //设备数据长度 //能耗检测 - 电压 单位:10mV Global_Large_Buff[sendlen++] = Rs485EnergyInfo.voltage & 0xFF; Global_Large_Buff[sendlen++] = (Rs485EnergyInfo.voltage >> 8) & 0xFF; //能耗检测 - 电流 单位:10mA Global_Large_Buff[sendlen++] = Rs485EnergyInfo.current & 0xFF; Global_Large_Buff[sendlen++] = (Rs485EnergyInfo.current >> 8) & 0xFF; //能耗检测 - 有功功率 单位:mW Global_Large_Buff[sendlen++] = Rs485EnergyInfo.active_power & 0xFF; Global_Large_Buff[sendlen++] = (Rs485EnergyInfo.active_power >> 8) & 0xFF; Global_Large_Buff[sendlen++] = (Rs485EnergyInfo.active_power >> 16) & 0xFF; Global_Large_Buff[sendlen++] = (Rs485EnergyInfo.active_power >> 24) & 0xFF; //能耗检测 - 能耗 单位:Wh Global_Large_Buff[sendlen++] = Rs485EnergyInfo.phase_energy & 0xFF; Global_Large_Buff[sendlen++] = (Rs485EnergyInfo.phase_energy >> 8) & 0xFF; Global_Large_Buff[sendlen++] = (Rs485EnergyInfo.phase_energy >> 16) & 0xFF; Global_Large_Buff[sendlen++] = (Rs485EnergyInfo.phase_energy >> 24) & 0xFF; //能耗检测 - 总能耗 单位:Wh Global_Large_Buff[sendlen++] = Rs485EnergyInfo.total_energy & 0xFF; Global_Large_Buff[sendlen++] = (Rs485EnergyInfo.total_energy >> 8) & 0xFF; Global_Large_Buff[sendlen++] = (Rs485EnergyInfo.total_energy >> 16) & 0xFF; Global_Large_Buff[sendlen++] = (Rs485EnergyInfo.total_energy >> 24) & 0xFF; }else{ /*没找到能耗设备*/ Global_Large_Buff[sendlen++] = 0x00; //上报数据个数 } /*添加空调设备状态 - 先要找到有几个空调,然后进行数据组包*/ temp_dev = Find_TempDevice_List_Information(&Global_Large_Buff[sendlen],0x05); //目前最多5个空调 sendlen = sendlen + (temp_dev * 0x07); Global_Large_Buff[29] += temp_dev; //更新上报设备个数 sendlen += 0x02; //添加CRC校验长度 UDP_Add_Header(Global_Large_Buff,In_PeriodicReport_Cmd,sendlen,server_info.frame_no); //添加头部 NetCRC16(&Global_Large_Buff[0],sendlen); Dbg_Println(DBG_BIT_NET_STATUS_bit,"%s Len:%d",__func__,sendlen); Dbg_Print_Buff(DBG_BIT_NET_STATUS_bit,"定期上报: ",Global_Large_Buff,sendlen); WCHNET_SocketUdpSendTo(g_netinfo.SocketId[SocketIdnex_BLVSeriver], &Global_Large_Buff[0], &sendlen, server_info.dis_ip, server_info.dis_port); LOG_NET_COMM_Send_Record(0x01,server_info.dis_ip,server_info.dis_port,&Global_Large_Buff[0],sendlen); } /******************************************************************************* * Function Name : Udp_Internal_Periodic_Report_Process * Description : 向服务器定期上报 回复数据 *******************************************************************************/ uint8_t Udp_Internal_Periodic_Report_Process(uint8_t *data, uint16_t DataLen, uint8_t *ip,uint16_t port) { /*CRC校验*/ uint16_t data_crc = 0x00; data_crc = data[DataLen-1]; data_crc <<= 0x08; data_crc |= data[DataLen-2]; if(NetCRC16_2(data,DataLen-2) != data_crc) return 0xF0; //判断帧号是否一致 data_crc = data[FRAME_NO_OFFSET + 1]; data_crc <<= 0x08; data_crc |= data[FRAME_NO_OFFSET]; if(data_crc != server_info.frame_no) return 0x01; //无数据处理上报成功,清楚一下标志位而已 server_info.udp_send_flag = 0x00; //清楚发送标志位 server_info.active_cmd_flag &= ~UDP_ActSend_Periodic_Flag; //清楚标志位 server_info.udp_online_tick = SysTick_1ms; return 0x00; } /******************************************************************************* * Function Name : Udp_Internal_Analysis * Description : BLV通讯协议 - 接收数据处理函数 * Input : * data - 接收到的数据 * len - 接收到的数据长度 * ip - 数据的IP地址 * port - 数据的Port端口 *******************************************************************************/ void Udp_Internal_Analysis(uint8_t *data, uint32_t len, uint8_t* ip, uint16_t port) { //uint8_t rev = 0; uint16_t temp_val = 0; if( len < BLV_UDP_PACK_LEN ) return ; //长度不足,直接退出 /*BLV通讯协议 - 校验数据头 AA 55 */ if( (data[FRAME_HEAD_OFFSET] == 0xAA) && (data[FRAME_HEAD_OFFSET + 1] == 0x55) ) { /*BLV通讯协议 - 校验特征 T3SA */ if( (data[SYSTEM_ID_OFFSET] == 'T') && (data[SYSTEM_ID_OFFSET + 1] == '3') && (data[SYSTEM_ID_OFFSET + 2] == 'S') && (data[SYSTEM_ID_OFFSET + 3] == 'A') ) { /*BLV通讯协议 - 校验数据接收长度 */ temp_val = data[FRAME_LEN_OFFSET +1]; temp_val <<= 8; temp_val |= data[FRAME_LEN_OFFSET]; if( temp_val == len ) { /*BLV通讯协议 - 校验CRC值 */ temp_val = data[len-1]; temp_val <<= 0x08; temp_val |= data[len-2]; if(NetCRC16_2(data,len-2) != temp_val) return ; //CRC校验失败,直接退出 switch(data[CMD_OFFSET]) { case In_Search_Cmd: //搜索命令 UDP_Search_Cmd_Processing(data, len, ip, port); break; // case In_IAP_Cmd: //IAP APP升级命令 // UDP_IAP_Cmd_Processing(data, len, ip, port); // break; // case In_Subgroup_Cmd: //IAP 固件升级命令 -- 取消没有使用 // UDP_Subgroup_Cmd_Processing(data, len, ip, port); // break; case In_Read_MCUSystem_Cmd: //读取MCU参数命令 - 也是搜索命令 UDP_Read_MCUSystem_Cmd_Processing(data, len, ip, port); break; case In_QueryTime_Cmd: //获取时间命令 Udp_QueryTime_Cmd_Process(data, len, ip, port); break; case In_DevState_Cmd: //上报设备状态命令 Udp_Internal_RoomState_Process(data, len, ip, port); break; case In_PeriodicReport_Cmd: //定期上报命令 Udp_Internal_Periodic_Report_Process(data, len, ip, port); break; case In_BLVIAPLogic_Cmd: Udp_Internal_BLVIAP_Logic(data, len, ip, port); break; default: Dbg_Println(DBG_BIT_NET_STATUS_bit,"UDP CMD %X",data[CMD_OFFSET]); break; } } } } } /******************************************* * 函数名:BLV_UDP_Comm_Task * 参 数: * 作 用:局域网相关的任务处理 * 返回值:无 * 调用方式:主循环中调用 ********************************************/ __attribute__((section(".non_0_wait"))) void BLV_UDP_Comm_Task(void) { static uint32_t udp_state_tick = 0; uint32_t temp_val = 0; /*函数主要任务 - 主动发送数据*/ if( SysTick_1ms - udp_state_tick >= 100 ) { udp_state_tick = SysTick_1ms; if( (WCHNET_Get_PHY_Linked_Status() == 0x01) || (server_info.init_flag == 0x00) ) return ; //DNS解析域名失败直接退出 /*并且不再TFTP任务中*/ // if(IAPVarTypeStruct_Ptr != NULL) // { // if(IAPSTART == IAPVarTypeStruct_Ptr->IapState) // { // Dbg_Println(DBG_BIT_NET_STATUS_bit,"RoomState_Cmd暂停,IAP任务中.."); // return; // } // } server_info.udp_scan_cnt++; if(server_info.udp_scan_cnt >= 9) { server_info.udp_scan_cnt = 0x00; server_info.udp_timesync_cnt++; server_info.udp_periodic_cnt++; //判断时间同步 - 有没有到时间 if(server_info.udp_timesync_cnt >= 7200){ server_info.udp_timesync_cnt = 0x00; server_info.active_cmd_flag |= UDP_ActSend_TimeSync_Flag; } //判断定期上报 - 有没有到时间 if(server_info.udp_periodic_cnt >= server_info.udp_periodic_time){ server_info.udp_periodic_cnt = 0x00; server_info.active_cmd_flag |= UDP_ActSend_Periodic_Flag; } //判断RCU启用原因标志位成不成立 if(server_info.rcu_reboot_flag == 0x01){ server_info.rcu_reboot_flag = 0x00; server_info.active_cmd_flag |= UDP_ActSend_Reboot_Flag; //上报RCU启动原因 } //UDP_ActSend_PowerChange_Scan_State(); //扫描取电主动上报命令 //Udp_Scan_Roomstate(); //扫描房间设备状态 } switch(server_info.udp_sta) { case 0x01: //注册 if(server_info.register_flag == 0x01) { if(SysTick_1s - server_info.register_tick > USER_NET_Register_Timeout) //每30S 发送一次注册命令 { Dbg_Println(DBG_BIT_NET_STATUS_bit,"UDP注册数据发送超时 %d",server_info.register_num); server_info.register_tick = SysTick_1s; server_info.register_num++; server_info.register_flag = 0x00; if(server_info.register_num >= USER_NET_Register_Times) server_info.init_flag = 0x00; } return ; } Dbg_Println(DBG_BIT_NET_STATUS_bit,"UDP注册数据发送"); UDP_Search_Ack(); //如果不在服务器就一直注册 server_info.udp_idle_tick = SysTick_1ms; server_info.register_flag = 0x01; server_info.register_tick = SysTick_1s; break; case 0x02: //判断数据包是否需要发送 /*UDP 判断是否达到空闲状态*/ if(SysTick_1ms - server_info.udp_idle_tick >= 30000) { server_info.udp_idle_tick = SysTick_1ms; //发送心跳包 server_info.active_cmd_flag |= UDP_ActSend_Heart_Flag; } /*UDP 网络离线判断*/ if(SysTick_1ms - server_info.udp_online_tick >= server_info.udp_online_time) { server_info.udp_online_tick = SysTick_1ms; server_info.init_flag = 0x00; //UDP网络离线 //LOG_SYS_Server_Comm_State_Record(RCU_NO_SERVER); return ; } for(uint8_t i=0;i<7;i++) { if( ( server_info.active_cmd_flag & (0x01 << i) ) != 0x00 ) { server_info.udp_send_flag = 0x01 << i; server_info.udp_sta = 0x03; server_info.udp_retry_cnt = 0x00; server_info.udp_retry_time = 2000; break; } } break; case 0x03: //数据包发送 switch(server_info.udp_send_flag) { case 0x01: //取断电上报 - 优先级最高 Udp_Internal_Power_Change_Report_CMD(); server_info.udp_retry_num = 0x02; //一共发送3次 server_info.udp_retry_tick = SysTick_1ms; server_info.udp_idle_tick = SysTick_1ms; server_info.udp_sta = 0x04; //进入发送等待 break; case 0x02: //设备状态上报 - Udp_Internal_RoomState(); server_info.udp_retry_num = 0x02; //一共发送3次 server_info.udp_retry_tick = SysTick_1ms; server_info.udp_idle_tick = SysTick_1ms; server_info.udp_sta = 0x04; //进入发送等待 break; case 0x04: //定期上报 - 只发送一次 Udp_Internal_Periodic_Report_PackSend(); server_info.udp_idle_tick = SysTick_1ms; server_info.udp_send_flag = 0x00; server_info.active_cmd_flag &= ~UDP_ActSend_Periodic_Flag; server_info.udp_sta = 0x02; break; case 0x08: //上报RCU重启原因 - //Udp_Internal_Reboot_Reason_Report_CMD(); server_info.udp_retry_num = 0x02; //一共发送3次 server_info.udp_retry_tick = SysTick_1ms; server_info.udp_idle_tick = SysTick_1ms; server_info.udp_sta = 0x04; //进入发送等待 break; case 0x10: //获取房态 - Udp_Internal_GetRoomRent_CMD(); server_info.udp_retry_num = 0x02; //一共发送3次 server_info.udp_retry_tick = SysTick_1ms; server_info.udp_idle_tick = SysTick_1ms; server_info.udp_sta = 0x04; //进入发送等待 break; case 0x20: //时间同步 - Udp_Internal_GetTime_CMD(); server_info.udp_retry_num = 0x02; //一共发送3次 server_info.udp_retry_tick = SysTick_1ms; server_info.udp_idle_tick = SysTick_1ms; server_info.udp_sta = 0x04; //进入发送等待 break; case 0x40: //心跳包 - 空闲30S 发送一次 UDP_Heart_Send(); server_info.udp_idle_tick = SysTick_1ms; server_info.udp_send_flag = 0x00; server_info.active_cmd_flag &= ~UDP_ActSend_Heart_Flag; server_info.udp_sta = 0x02; break; default: server_info.udp_sta = 0x02; break; } return ; //发送数据完毕直接退出 case 0x04: //等待数据ACK if(server_info.udp_send_flag == 0x00) { server_info.udp_sta = 0x02; //接收到回复数据了,结束发送 break; } if( server_info.udp_retry_cnt <= server_info.udp_retry_num ) { if( SysTick_1ms - server_info.udp_retry_tick >= server_info.udp_retry_time) { server_info.udp_retry_tick = SysTick_1ms; //发送超时 server_info.udp_retry_cnt++; if(server_info.udp_retry_cnt > server_info.udp_retry_num) { //数据重发已达上限,清楚发送标志位 if(server_info.udp_send_flag == 0x02) //如果是设备状态发送失败,清楚发送缓冲区内容 { temp_val = SRAM_Read_DW(SRAM_UDP_SendData_Tempaddr); SRAM_Write_DW(temp_val, SRAM_UDP_SendData_Readaddr); //读地址复位 Dbg_Println(DBG_BIT_NET_STATUS_bit,"上报设备状态失败 读:%X",temp_val); temp_val = SRAM_Read_DW(SRAM_DEVICE_ONLINE_STATE_TEMP_ADDR); //读临时保存的故障读取地址 SRAM_Write_DW(temp_val, SRAM_DEVICE_ONLINE_STATE_READ_ADDR); //故障读地址重新赋值 Dbg_Println(DBG_BIT_NET_STATUS_bit,"上报设备故障失败 读:%X",temp_val); } server_info.active_cmd_flag &= ~server_info.udp_send_flag; server_info.udp_sta = 0x02; //结束发送 }else { server_info.udp_sta = 0x03; //数据发送 server_info.udp_retry_time += 2000; } Dbg_Println(DBG_BIT_NET_STATUS_bit,"udp_retry:%x - %d - %d",server_info.udp_send_flag,server_info.udp_retry_cnt,server_info.udp_retry_time); } }else { //数据重发已达上限,清楚发送标志位 server_info.active_cmd_flag &= ~server_info.udp_send_flag; server_info.udp_sta = 0x02; //结束发送 } break; default: server_info.udp_sta = 0x02; break; } } /*函数附带任务 - 搜索命令的被动回复 增加随机延时 随机延时采用MAC地址最后一位 * 2ms */ if(server_info.search_ack_flag == 0x01) { uint32_t temp_tick = 0; temp_tick = g_netinfo.mac_addr[5]; temp_tick = temp_tick * 2; if( SysTick_1ms - server_info.search_ack_tick >= temp_tick ) { server_info.search_ack_tick = SysTick_1ms; server_info.search_ack_flag = 0x00; Udp_Internal_Read_MCU_System_SendAck(server_info.goal_ip,server_info.goal_port,server_info.ack_frame); } } }