/** ****************************************************************************** * @file net.c * @author BLW RCU development Team * @version * @date 2022年04月21日 * @brief * 网络服务函数 * @log SongHan 202204211130 TCP Disconnect TCP Timout 应MQTT重新连接 SongHan 202204211412 打印MQTT接收数据 SongHan 202204231150 将MQTT接收到的数据存储到日志 SongHan 202205091800 网络中断 关于MQTT的处理 增加 0x01 == mqtt_info.init_flag 的判断 SongHan 202205091800 MQTT连接失败 也不要free(mqtt_info.domain_name) SongHan 202205131055 MQTT域名IP变了之后,会产生TCP超时中断。如果网络状态机不变,MQTT会离线。 6分钟后,小概率会产生网络拔出事件。整个网络重新初始化。 在MQTT TCP超时和断开连接增加 server_info.init_flag = 0 保证域名重新解析 ****************************************************************************** */ #include "includes.h" #include "Udp_Internal_Protocol.h" #include /* 下面的缓冲区和全局变量必须要定义,库中调用 */ __align(16)UINT8 CH57xMACRxDesBuf[(RX_QUEUE_ENTRIES )*16] = {0}; /* MAC接收描述符缓冲区,16字节对齐 */ __align(4) UINT8 CH57xMACRxBuf[RX_QUEUE_ENTRIES*RX_BUF_SIZE]= {0}; /* MAC接收缓冲区,4字节对齐 */ __align(4) SOCK_INF SocketInf[CH57xNET_MAX_SOCKET_NUM]= {0}; /* Socket信息表,4字节对齐 */ UINT16 MemNum[8] = {CH57xNET_NUM_IPRAW, CH57xNET_NUM_UDP, CH57xNET_NUM_TCP, CH57xNET_NUM_TCP_LISTEN, CH57xNET_NUM_TCP_SEG, CH57xNET_NUM_IP_REASSDATA, CH57xNET_NUM_PBUF, CH57xNET_NUM_POOL_BUF }; UINT16 MemSize[8] = {CH57xNET_MEM_ALIGN_SIZE(CH57xNET_SIZE_IPRAW_PCB), CH57xNET_MEM_ALIGN_SIZE(CH57xNET_SIZE_UDP_PCB), CH57xNET_MEM_ALIGN_SIZE(CH57xNET_SIZE_TCP_PCB), CH57xNET_MEM_ALIGN_SIZE(CH57xNET_SIZE_TCP_PCB_LISTEN), CH57xNET_MEM_ALIGN_SIZE(CH57xNET_SIZE_TCP_SEG), CH57xNET_MEM_ALIGN_SIZE(CH57xNET_SIZE_IP_REASSDATA), CH57xNET_MEM_ALIGN_SIZE(CH57xNET_SIZE_PBUF) + CH57xNET_MEM_ALIGN_SIZE(0), CH57xNET_MEM_ALIGN_SIZE(CH57xNET_SIZE_PBUF) + CH57xNET_MEM_ALIGN_SIZE(CH57xNET_SIZE_POOL_BUF) }; __align(4)UINT8 Memp_Memory[CH57xNET_MEMP_SIZE] = {0}; __align(4)UINT8 Mem_Heap_Memory[CH57xNET_RAM_HEAP_SIZE] = {0}; __align(4)UINT8 Mem_ArpTable[CH57xNET_RAM_ARP_TABLE_SIZE] = {0}; /* CH57xNET库TCP的MSS长度为536字节,即一个TCP包里的数据部分最长为536字节 TCP协议栈采用滑动窗口进行流控,窗口最大值为socket的接收缓冲区长度。在设定 RX_QUEUE_ENTRIES时要考虑MSS和窗口之间的关系,例如窗口值为4*MSS,则远端一次会发送 4个TCP包,如果RX_QUEUE_ENTRIES小于4,则必然会导致数据包丢失,从而导致通讯效率降低 建议RX_QUEUE_ENTRIES要大于( 窗口/MSS ),如果多个socket同时进行大批量发送数据,则 建议RX_QUEUE_ENTRIES要大于(( 窗口/MSS )*socket个数) 在多个socket同时进行大批数据收发时 为了节约RAM,请将接收缓冲区的长度设置为MSS */ /* 网口灯定义 PB口低十六位有效 */ #if (USE_CORE_TYPE == 1) //使用C1F核心板 UINT16 CH57xNET_LEDCONN=0x0020; /* 连接指示灯 PB5*/ UINT16 CH57xNET_LEDDATA=0x0400; /* 通讯指示灯 PB10 */ #elif (USE_CORE_TYPE == 2) //使用C1核心板 UINT16 CH57xNET_LEDCONN=0x0020; /* 连接指示灯 PB5*/ UINT16 CH57xNET_LEDDATA=0x0040; /* 通讯指示灯 PB6*/ #endif //USE_CORE_TYPE == CORE_TYPE_C1F /* CH579相关定义 */ //UINT8 MACAddr[6] = {0x34,0xD0,0xB8,0x10,0xA3,0x1E}; /* CH579MAC地址 - 默认MAC地址*/ //UINT8 MACAddr[6] = {0x34,0xD0,0xB8,0x10,0xE0,0xF6}; /* CH579MAC地址 - 样机MAC地址*/ UINT8 MACAddr[6] = {0x34,0xD0,0xB8,0x10,0xE0,0xF9}; /* CH579MAC地址 - 样机2MAC地址*/ UINT8 SocketRecvBuf[RECE_BUF_LEN] = {0}; /* socket接收缓冲区 */ uint32_t SysTick_10ms = 0; uint8_t Global_Large_Buff[1100] = {0}; //用于套接字通讯组包、读写外部SRAM映射寄存器 NET_INFO net_info ={ .local_ip = {192,168,1,200}, /* CH579IP地址 */ .gwip_addr = {192,168,1,1}, /* CH579网关 */ .mask = {255,255,255,0}, /* CH579子网掩码 */ .SocketId = {0,0,0,0}, /* 套接字索引 */ .ServerDename = SERVER_NAME_DNS, /* 服务器域名 2025-10-11 */ }; /*网络服务信息*/ NET_SERVER_INFO server_info = { .init_flag = 0, /* 网络初始化标志位,用于套接字创建使用*/ .register_flag = 0, /* 网络注册标志位*/ .search_ack_flag = 0, /* 搜索命令应答ACK*/ .dhcp_en = 1, /* DHCP使能 */ .dns_sta = 0, /* DNS状态机当前状态 */ .dhcp_flg = 0, /* DHCP成功时在回调中置位*/ .dns_flg = 0, /* DNS成功时在回调中置位*/ .Udp_Internal_sta = 0, /* UDP状态机当前状态 */ .PHY_State = 0, /* NET PHY状态 */ .register_num = 0, /* 注册计数 */ .dns_fail = 0, /* */ .server_dns_flag = 0, /* DNS解析服务器域名标志位 */ .tftp_dns_flag = 0, /* DNS解析TFTP服务器域名标志位 */ .mqtt_dns_flag = 0, /* DNS解析MQTT服务器域名标志位 */ .online_state = 0, .sync_tick = 0, .udp_dns_flag = 0, /* udp服务器解析域名标志位 */ .server_select = 0, /* 服务器选择, 0x00:使用云端服务器,0x01:使用本地服务器*/ .net_retry_flag = 0, /* 网络重试标志位*/ .net_retry_num = 0, /* 网络重试次数 - 比如DHCP重试次数,DNS重试次数*/ .con_flag = 0, /* 网络直连标志位 */ .rcu_reboot_flag = 1, /* RCU启动标志位 - 用于上报启动原因使用 */ .udp_scan_cnt = 0, .active_cmd_flag = 0, .net_sta = 0, /* 网络状态机当前状态 */ .dis_ip = {106,75,37,225}, /* 云端服务器IP地址 */ .tftp_ip = {116,25,116,27}, /* TFTP服务器IP地址 */ .udp_ip = {0,0,0,0}, /* 用于搜索命令的回复 IP地址 */ .goal_ip = {192,168,101,31}, /* 发送数据的目标ip 用于云端升级使用*/ .local_port = 8000, /* 用于搜索命令的回复 端口号 */ .goal_port = 8080, /* 发送数据的目标port */ .dis_port = 3339, /* 云端服务器端口号 */ .frame_no = 0x8000, /* 云端服务器发送的帧号 */ .wait_cot = 0, /* 等待计数值赋0 */ .register_tick = 0, /* 注册等待回复计时 */ .search_ack_tick = 0, /* 搜索命令应答ACK时间戳 */ .udp_sta = 1, .udp_send_flag = 0, .udp_retry_cnt = 0, .udp_retry_num = 0, .ack_frame = 0, .udp_timesync_cnt = 0, .udp_periodic_cnt = 0, .udp_retry_tick = 0, .udp_retry_time = 2000, .con_tick = 0, #if TFTP_GET_IP .tftpip_gflag = 0, #endif .udp_idle_tick = 0, .udp_online_tick = 0, .udp_online_time = 0, }; TFTP_LOG tftp_log; //2024-04-08 #if INTERRUPT_RECV_EN UINT8 MyBuf[RECE_BUF_LEN] = {0}; /* 定义一个临时缓冲区 */ #endif //UINT8 Status; //当前网络状态 -- DNS /******************************************************************************* * Function Name : Timer0Init * Description : 定时器0初始化 * Input : time 定时时间 * Output : None * Return : None *******************************************************************************/ void Timer0Init(UINT32 time) { R8_TMR0_CTRL_MOD = RB_TMR_ALL_CLEAR; /* 清除所有计数值 */ R8_TMR0_CTRL_MOD = 0; /* 设置定时器模式 */ R32_TMR0_CNT_END = FREQ_SYS/1000000*time; /* 设置定时时间 */ R8_TMR0_INT_FLAG = R8_TMR0_INT_FLAG; /* 清除标志 */ R8_TMR0_INTER_EN = RB_TMR_IE_CYC_END; /* 定时中断 */ R8_TMR0_CTRL_MOD |= RB_TMR_COUNT_EN; NVIC_EnableIRQ(TMR0_IRQn); } /******************************************************************************* * Function Name : IRQ_Handler * Description : IRQ中断服务函数 * Input : None * Output : None * Return : None *******************************************************************************/ void ETH_IRQHandler( void ) /* 以太网中断 */ { CH57xNET_ETHIsr(); /* 以太网中断中断服务函数 */ } void TMR0_IRQHandler( void ) /* 定时器中断 */ { CH57xNET_TimeIsr(CH57xNETTIMEPERIOD); /* 定时器中断服务函数 */ R8_TMR0_INT_FLAG |= 0xff; /* 清除定时器中断标志 */ SysTick_10ms++; } /******************************************************************************* * Function Name : mStopIfError * Description : 调试使用,显示错误代码 * Input : iError 错误代码 * Output : None * Return : None *******************************************************************************/ void mStopIfError(UINT8 iError) { if (iError == CH57xNET_ERR_SUCCESS) return; /* 操作成功 */ Dbg_Println(DBG_BIT_NET_STATUS_bit,"mStopIfError: %02X", (UINT16)iError); /* 显示错误 */ } /******************************************************************************* * Function Name : CH57xNET_CreatTcpSocket * Description : 创建TCP Client socket * Input : socket索引保存地址 * Output : None * Return : None *******************************************************************************/ void CH57xNET_CreatTcpSocket_2(UINT8* S) { UINT8 i; SOCK_INF TmpSocketInf; /* 创建临时socket变量 */ memset((void *)&TmpSocketInf,0,sizeof(SOCK_INF)); /* 库内部会将此变量复制,所以最好将临时变量先全部清零 */ memcpy((void *)TmpSocketInf.IPAddr, server_info.dis_ip, 4); /* 设置目的IP地址 */ TmpSocketInf.DesPort = 1000; TmpSocketInf.SourPort = 2000; /* 设置源端口 */ TmpSocketInf.ProtoType = PROTO_TYPE_TCP; /* 设置socekt类型 */ TmpSocketInf.RecvStartPoint = (UINT32)SocketRecvBuf; /* 设置接收缓冲区的接收缓冲区 */ TmpSocketInf.RecvBufLen = RECE_BUF_LEN ; /* 设置接收缓冲区的接收长度 */ i = CH57xNET_SocketCreat(S,&TmpSocketInf); /* 创建socket,将返回的socket索引保存在SocketId中 */ mStopIfError(i); /* 检查错误 */ #ifdef KEEPLIVE_ENABLE CH57xNET_SocketSetKeepLive(*S, 1 ); /* 开启socket的KEEPLIVE功能(V06版本支持) */ #endif i = CH57xNET_SocketConnect(*S); /* TCP连接 */ mStopIfError(i); /* 检查错误 */ i = CH57xNET_SetSocketTTL(*S,128 ); mStopIfError(i); /* 检查错误 */ } /******************************************************************************* * Function Name : net_initkeeplive * Description : keeplive初始化 * Input : None * Output : None * Return : None *******************************************************************************/ #ifdef KEEPLIVE_ENABLE void net_initkeeplive(void) { struct _KEEP_CFG klcfg; klcfg.KLIdle = 20000; /* 空闲 */ klcfg.KLIntvl = 10000; /* 间隔 */ klcfg.KLCount = 5; /* 次数 */ CH57xNET_ConfigKeepLive(&klcfg); } #endif /******************************************************************************* * Function Name : CH57xNET_LibInit * Description : 库初始化操作 * Input : ip ip地址指针 * :gwip 网关ip地址指针 * : mask 掩码指针 * : macaddr MAC地址指针 * Output : None * Return : 执行状态 *******************************************************************************/ UINT8 CH57xNET_LibInit(/*const*/ UINT8 *ip,/*const*/ UINT8 *gwip,/*const*/ UINT8 *mask,/*const*/ UINT8 *macaddr) { UINT8 i; struct _CH57x_CFG cfg; if(CH57xNET_GetVer() != CH57xNET_LIB_VER)return 0xfc; /* 获取库的版本号,检查是否和头文件一致 */ CH57xNETConfig = LIB_CFG_VALUE; /* 将配置信息传递给库的配置变量 */ cfg.RxBufSize = RX_BUF_SIZE; cfg.TCPMss = CH57xNET_TCP_MSS; cfg.HeapSize = CH57x_MEM_HEAP_SIZE; cfg.ARPTableNum = CH57xNET_NUM_ARP_TABLE; cfg.MiscConfig0 = CH57xNET_MISC_CONFIG0; CH57xNET_ConfigLIB(&cfg); i = CH57xNET_Init(ip,gwip,mask,macaddr); #ifdef KEEPLIVE_ENABLE net_initkeeplive( ); #endif return (i); } /******************************************************************************* * Function Name : CH57xNET_HandleSockInt * Description : Socket中断处理函数 * Input : sockeid socket索引 * :initstat 中断状态 * Output : None * Return : None *******************************************************************************/ void CH57xNET_HandleSockInt(UINT8 sockeid,UINT8 initstat) { UINT32 len; UINT8 i; if(initstat & SINT_STAT_RECV) /* 接收中断 */ { len = CH57xNET_SocketRecvLen(sockeid,NULL); /* 查询长度 */ Dbg_Println(DBG_BIT_NET_STATUS_bit,"Receive Len = %ld,sockeid : %d",len,sockeid); if (len > 0) { if(server_info.dns_sta == DNS_WAIT_RECV) { CH57xNET_SocketRecv(sockeid,dns_buf,&len); Dbg_Println(DBG_BIT_NET_STATUS_bit,"DNS ReceiveLen = %ld",len); server_info.dns_flg = 1; //标记DNS获取服务器ip成功 i = CH57xNET_SocketClose( sockeid,TCP_CLOSE_NORMAL ); mStopIfError(i); memset(SocketRecvBuf, 0, len); //此处不清0将导致后面的套接字接收数据出错 } else { #if MQTT_EN if((0x01 == mqtt_info.init_flag) && (mqtt_info.mqtt_socket == sockeid)) //MQTT参数已初始化 mqtt套接字 { uint8_t* data = malloc(len); if(data == NULL) return; CH57xNET_SocketRecv(sockeid, data, &len); /* 将接收缓冲区的数据读到MyBuf中*/ Dbg_Print_Buff(DBG_BIT_NET_STATUS_bit,"mqtt rec data:",data,len); LOG_NET_COMM_Recv_Record(mqtt_info.mqtt_socket,mqtt_info.des_ip,1883,data,len); switch(data[0]>>4) { case FLAG_CONNACK: Dbg_Println(DBG_BIT_NET_STATUS_bit,"MQTT connack"); mqtt_info.con_flag=1; MQTT_Subscribe(sockeid, mqtt_info.sub_topic); //连接成功,发起订阅 break; case FLAG_PUBLISH: //接收到数据 { unsigned char dup; unsigned short packetid; int qos; unsigned char retained; MQTTString topicName; unsigned char* payload; int payloadlen; MQTTDeserialize_publish(&dup,&qos,&retained,&packetid,&topicName,&payload,&payloadlen,data,len); Dbg_Println(DBG_BIT_NET_STATUS_bit,"payloadlen=%d",(UINT16)payloadlen); if((payloadlen + 2) > SRAM_MQTT_RECEIVE_LEN) { Dbg_Print(DBG_BIT_NET_STATUS_bit,"MQTT Receive too long:%d", payloadlen); } else { Dbg_Print(DBG_BIT_NET_STATUS_bit,"MQTT Receive DataLen:%d", payloadlen); SRAM_Write_Word(payloadlen, mqtt_info.Sram_write_addr); //接收长度 SRAM_Write_Buff(payload, payloadlen, mqtt_info.Sram_write_addr +2); //数据内容 mqtt_info.Sram_write_addr += SRAM_MQTT_RECEIVE_LEN; if(mqtt_info.Sram_write_addr >= SRAM_MQTT_RECEIVE_END) { mqtt_info.Sram_write_addr = SRAM_MQTT_RECEIVE_START; } } // MQTT_Publish(sockeid, NET485_PUBLISH, (uint8_t*)payload, payloadlen, 0); // if(payloadlen > SIMPLEPROFILE_CHAR4_LEN) peripheralChar4Notify(payload, SIMPLEPROFILE_CHAR4_LEN); //发给主机的数据固定使用 特征4的NOTIFY // else peripheralChar4Notify(payload, payloadlen); //发给主机的数据固定使用 特征4的NOTIFY } break; case FLAG_SUBACK: //订阅成功 mqtt_info.sub_flag=1; #if 0 if(mqtt_info.domain_name) { free(mqtt_info.domain_name); mqtt_info.domain_name = NULL; } if(mqtt_info.clientID) { free(mqtt_info.clientID); mqtt_info.clientID = NULL; } if(mqtt_info.username) { free(mqtt_info.username); mqtt_info.username = NULL; } if(mqtt_info.password) { free(mqtt_info.password); mqtt_info.password = NULL; } if(mqtt_info.sub_topic) { free(mqtt_info.sub_topic); mqtt_info.sub_topic = NULL; } if(mqtt_info.pub_topic) { free(mqtt_info.pub_topic); mqtt_info.pub_topic = NULL; } #endif Dbg_Println(DBG_BIT_NET_STATUS_bit,"MQTT suback"); break; default: Dbg_Println(DBG_BIT_NET_STATUS_bit,"MQTT MyBuf:%02X %02X", data[0], data[1]); break; } free(data); } #endif } } } if(initstat & SINT_STAT_CONNECT) /* TCP连接中断 */ { /* 产生此中断表示TCP已经连接,可以进行收发数据 */ Dbg_Println(DBG_BIT_NET_STATUS_bit,"TCP Connect Success"); #if /*INTERRUPT_RECV_EN ||*/ MQTT_EN if((0x01 == mqtt_info.init_flag) && (mqtt_info.mqtt_socket == sockeid)) //MQTT参数已初始化 mqtt套接字 { MQTT_Connect(sockeid, mqtt_info.clientID, mqtt_info.username, mqtt_info.password, mqtt_info.keepAliveInterval); } #endif } if(initstat & SINT_STAT_DISCONNECT) /* TCP断开中断 */ { /* 产生此中断,CH579库内部会将此socket清除,置为关闭*/ Dbg_Println(DBG_BIT_NET_STATUS_bit,"TCP Disconnect"); /* 应用曾需可以重新创建连接 */ #if /*INTERRUPT_RECV_EN ||*/ MQTT_EN if((0x01 == mqtt_info.init_flag) && (mqtt_info.mqtt_socket == sockeid)) //MQTT参数已初始化 mqtt套接字 { //CH57xNET_CreatTcpSocket(); mqtt_info.con_flag = 0; //连接断开 Dbg_Println(DBG_BIT_NET_STATUS_bit,"MQTT Disconnect MQTT Need Reconnect"); // server_info.init_flag = 0; //网络环境变化 MQTT连接断开 需重新初始化网络 //Song mqtt_info.mqtt_sta = MQTT_RCON; //2023-03-17 mqtt_info.wait_cot = SysTick_10ms; //2023-03-17 LOG_SYS_PHY_Change_Record(0x03); //网络环境变化 MQTT TCP断开 } #endif } if(initstat & SINT_STAT_TIM_OUT) /* TCP超时中断 */ { /* 产生此中断,CH579库内部会将此socket清除,置为关闭*/ Dbg_Println(DBG_BIT_NET_STATUS_bit,"sockeid %d TCP Timout",sockeid); /* 应用曾需可以重新创建连接 */ #if /*INTERRUPT_RECV_EN ||*/ MQTT_EN if((0x01 == mqtt_info.init_flag) && (mqtt_info.mqtt_socket == sockeid)) //MQTT参数已初始化 mqtt套接字 { mqtt_info.con_flag = 0; //连接断开 Dbg_Println(DBG_BIT_NET_STATUS_bit,"MQTT Timout MQTT Need Reconnect"); // server_info.init_flag = 0; //网络环境变化 MQTT连接超时 需重新初始化网络 //Song mqtt_info.mqtt_sta = MQTT_RCON; //2023-03-17 mqtt_info.wait_cot = SysTick_10ms; //2023-03-17 LOG_SYS_PHY_Change_Record(0x02); //网络环境变化 MQTT TCP超时 } #endif } } /******************************************************************************* * Function Name : CH57xNET_HandleGloableInt * Description : 全局中断处理函数 * Input : None * Output : None * Return : None *******************************************************************************/ void CH57xNET_HandleGlobalInt(void) { UINT8 initstat; UINT8 i; UINT8 socketinit; initstat = CH57xNET_GetGlobalInt(); /* 读全局中断状态并清除 */ if(initstat & GINT_STAT_UNREACH) /* 不可达中断 */ { Dbg_Println(DBG_BIT_NET_STATUS_bit,"UnreachCode :%ld",CH57xInf.UnreachCode); /* 查看不可达代码 */ Dbg_Println(DBG_BIT_NET_STATUS_bit,"UnreachProto :%ld",CH57xInf.UnreachProto); /* 查看不可达协议类型 */ Dbg_Println(DBG_BIT_NET_STATUS_bit,"UnreachPort :%ld",CH57xInf.UnreachPort); /* 查询不可达端口 */ } if(initstat & GINT_STAT_IP_CONFLI) /* IP冲突中断 */ { server_info.init_flag = 0; //重新初始化网络 Dbg_Println(DBG_BIT_NET_STATUS_bit,"IP冲突中断",i); } if(initstat & GINT_STAT_PHY_CHANGE) /* PHY改变中断 */ { i = CH57xNET_GetPHYStatus(); /* 获取PHY状态 */ if(i == PHY_DISCONN) { Dbg_Println(DBG_BIT_NET_STATUS_bit,"PHY断开,需重新初始化网络"); server_info.init_flag = 0; //PHY断开,需重新初始化网络 LOG_SYS_PHY_Change_Record(0x00); //网线拔出 } Dbg_Println(DBG_BIT_NET_STATUS_bit,"GINT_STAT_PHY_CHANGE %02x",i); } if(initstat & GINT_STAT_SOCKET) /* Socket中断 */ { // Dbg_Print(DBG_BIT_NET_STATUS_bit,"GINT_STAT_SOCKET\n"); for(i = 0; i < CH57xNET_MAX_SOCKET_NUM; i ++) { socketinit = CH57xNET_GetSocketInt(i); /* 读socket中断并清零 */ if(socketinit) { //Dbg_Print(DBG_BIT_NET_STATUS_bit,"GINT_STAT_SOCKET, SOCKET_num:%d, socketinit:%d\n", i, socketinit); CH57xNET_HandleSockInt(i,socketinit); /* 如果有中断则清零 */ } } } } void UDPSocket1_AppCallBack(struct _SCOK_INF * SocketInf,UINT32 ipaddr,UINT16 port,UINT8 *buff,UINT32 len) { UINT8 ip[4]; ip[0] = ipaddr; ip[1] = ipaddr>>8; ip[2] = ipaddr>>16; ip[3] = ipaddr>>24; Dbg_Println(DBG_BIT_NET_STATUS_bit,"ip:%d.%d.%d.%d, port:%d",ip[0], ip[1], ip[2], ip[3], port); Dbg_Println(DBG_BIT_NET_STATUS_bit,"Socket1 len:%ld",len); Dbg_Print_Buff(DBG_BIT_NET_STATUS_bit,"data :",buff,len); //Udp_Internal_Analysis(buff, len, ip, port); if(buff[0] == 0xAA) { switch(buff[1]) { case 0x55: //旧的服务器协议 Udp_Internal_Analysis(buff, len, ip, port); break; case 0x66: //UDP服务协议 - 2022-05-31 //UDP_NetServer_Data_Analysis(buff, len, ip, port); break; } } } void UDPSocket2_AppCallBack(struct _SCOK_INF * SocketInf,UINT32 ipaddr,UINT16 port,UINT8 *buff,UINT32 len) { //printf("UDPSocket_AppCallBack %08lX,%d,",ipaddr, port); UINT8 ip[4]; ip[0] = ipaddr; ip[1] = ipaddr>>8; ip[2] = ipaddr>>16; ip[3] = ipaddr>>24; Dbg_Println(DBG_BIT_NET_STATUS_bit,"ip:%d.%d.%d.%d, port:%d",ip[0], ip[1], ip[2], ip[3], port); Dbg_Println(DBG_BIT_NET_STATUS_bit,"Socket2 len:%ld",len); TFTP_CMD_Analysis(buff, len, ip, port); } void UDPSocket3_AppCallBack(struct _SCOK_INF * SocketInf,UINT32 ipaddr,UINT16 port,UINT8 *buff,UINT32 len) { UINT8 ip[4]; ip[0] = ipaddr; ip[1] = ipaddr>>8; ip[2] = ipaddr>>16; ip[3] = ipaddr>>24; Dbg_Println(DBG_BIT_NET_STATUS_bit,"ip:%d.%d.%d.%d, port:%d",ip[0], ip[1], ip[2], ip[3], port); Dbg_Println(DBG_BIT_NET_STATUS_bit,"Socket3 len:%ld",len); TFTP_FILE_Analysis(buff, len, ip, port); } void UDPSocket4_AppCallBack(struct _SCOK_INF * SocketInf,UINT32 ipaddr,UINT16 port,UINT8 *buff,UINT32 len) { UINT8 temp[4]; temp[0] = ipaddr; temp[1] = ipaddr>>8; temp[2] = ipaddr>>16; temp[3] = ipaddr>>24; Dbg_Println(DBG_BIT_NET_STATUS_bit,"ip:%d.%d.%d.%d, port:%d",temp[0], temp[1], temp[2], temp[3], port); Dbg_Println(DBG_BIT_NET_STATUS_bit,"Socket4 Recive: %s",buff); } /******************************************************************************* * Function Name : UDPSocketParamInit * Description : 创建UDP socket * Input : socket索引值,源端口, * Output : None * Return : None *******************************************************************************/ void UDPSocketParamInit2(UINT8* S, UINT16 SourPort, AppCallBack cb) { UINT8 i; SOCK_INF TmpSocketInf; /* 创建临时socket变量 */ memset((void *)&TmpSocketInf,0,sizeof(SOCK_INF)); /* 库内部会将此变量复制,所以最好将临时变量先全部清零 */ //memcpy((void *)TmpSocketInf.IPAddr,addr,4); /* 设置目的IP地址 */ TmpSocketInf.IPAddr[0] = 255; TmpSocketInf.IPAddr[1] = 255; TmpSocketInf.IPAddr[2] = 255; TmpSocketInf.IPAddr[3] = 255; TmpSocketInf.DesPort = SourPort; /* 设置目的端口 */ TmpSocketInf.SourPort = SourPort; /* 设置源端口 */ TmpSocketInf.ProtoType = PROTO_TYPE_UDP; /* 设置socekt类型 */ TmpSocketInf.RecvStartPoint = (UINT32)SocketRecvBuf; /* 设置接收缓冲区的接收缓冲区 */ TmpSocketInf.RecvBufLen = RECE_BUF_LEN ; /* 设置接收缓冲区的接收长度 */ #if APPCALLBACK_RECV_EN TmpSocketInf.AppCallBack = cb; /* 设置接收回调函数 */ #endif i = CH57xNET_SocketCreat(S,&TmpSocketInf); /* 创建socket,将返回的socket索引保存在SocketId中 */ mStopIfError(i); /* 检查错误 */ } /******************************************************************************* * Function Name : DNS_SocketParamInit * Description : 创建UDP socket * Input : socket索引值,源端口,目的端口及目的IP * Output : None * Return : None *******************************************************************************/ UINT8 DNS_SocketParamInit(UINT8* S,UINT8 *addr,UINT16 SourPort,UINT16 DesPort ) { UINT8 i; SOCK_INF TmpSocketInf; /* 创建临时socket变量 */ memset((void *)&TmpSocketInf,0,sizeof(SOCK_INF)); /* 库内部会将此变量复制,所以最好将临时变量先全部清零 */ memcpy((void *)TmpSocketInf.IPAddr,addr,4); /* 设置目的IP地址 */ TmpSocketInf.DesPort = DesPort; /* 设置目的端口 */ TmpSocketInf.SourPort = SourPort; /* 设置源端口 */ TmpSocketInf.ProtoType = PROTO_TYPE_UDP; /* 设置socekt类型 */ TmpSocketInf.RecvStartPoint = (UINT32)SocketRecvBuf; /* 设置接收缓冲区的接收缓冲区 */ TmpSocketInf.RecvBufLen = RECE_BUF_LEN ; /* 设置接收缓冲区的接收长度 */ //TmpSocketInf.AppCallBack = UDPSocket_AppCallBack; /* 设置接收回调函数 */ i = CH57xNET_SocketCreat(S, &TmpSocketInf); /* 创建socket,将返回的socket索引保存在SocketId中 */ mStopIfError(i); /* 检查错误 */ return i; } /******************************************************************************* * Function Name : CH57xNET_DHCPCallBack * Description : DHCP回调函数 * Input : None * Output : None * Return : 执行状态 *******************************************************************************/ UINT8 CH57xNET_DHCPCallBack(UINT8 status,void *arg) { UINT8 *p; if(!status){ /* 成功*/ p = arg; /* 产生此中断,CH57xNET库内部会将此socket清除,置为关闭*/ Dbg_Println(DBG_BIT_NET_STATUS_bit,"DHCP Success"); memcpy(net_info.local_ip, p, 4); memcpy(net_info.gwip_addr, &p[4], 4); memcpy(net_info.mask, &p[8], 4); /* 产生此中断,CH57xNET库内部会将此socket清除,置为关闭*/ //memcpy(DNS_SERVER_IP, &p[12], 4); //2022-03-02 DNS服务器IP采用DHCP分配的 , 2022-08-09 取消使用DHCP分配的DNS服务器 Dbg_Println(DBG_BIT_NET_STATUS_bit,"IPAddr = %d.%d.%d.%d",(UINT16)net_info.local_ip[0], (UINT16)net_info.local_ip[1], (UINT16)net_info.local_ip[2], (UINT16)net_info.local_ip[3]); Dbg_Println(DBG_BIT_NET_STATUS_bit,"GWIPAddr = %d.%d.%d.%d",(UINT16)net_info.gwip_addr[0], (UINT16)net_info.gwip_addr[1], (UINT16)net_info.gwip_addr[2], (UINT16)net_info.gwip_addr[3]); Dbg_Println(DBG_BIT_NET_STATUS_bit,"IPAddr = %d.%d.%d.%d",(UINT16)net_info.mask[0], (UINT16)net_info.mask[1], (UINT16)net_info.mask[2], (UINT16)net_info.mask[3]); Dbg_Println(DBG_BIT_NET_STATUS_bit,"DNS1: %d.%d.%d.%d",DNS_SERVER_IP[0],DNS_SERVER_IP[1],DNS_SERVER_IP[2],DNS_SERVER_IP[3]); Dbg_Println(DBG_BIT_NET_STATUS_bit,"DNS2: %d.%d.%d.%d",p[16],p[17],p[18],p[19]); CH57xNET_DHCPStop(); server_info.net_retry_num = 0; CH57xNET_SocketClose(net_info.SocketId[0],0x00); //2023-05-27 server_info.net_sta = NET_SOCKET_WAIT; server_info.wait_cot = SysTick_1ms; return SUCCESS; } else{ Dbg_Println(DBG_BIT_NET_STATUS_bit,"DHCP Fail %02x",status); return FAILED; } } /******************************************************************************* * Function Name : GetMacAddr * Description : 系统获取MAC地址 * Input : pMAC:指向用来存储Mac地址的缓冲 * Output : None * Return : None *******************************************************************************/ void GetMacAddr(UINT8 *pMAC) { UINT8 transbuf[6],i; GetMACAddress(transbuf); for(i=0;i<6;i++) { pMAC[5-i]=transbuf[i]; } } /******************************************************************************* * Function Name : DNS_Restart * Description : 重启DNS,在DNS失败的情况下使用 * Input : None * Output : None * Return : 返回1状态机繁忙,返回0成功 * 用 法 : *******************************************************************************/ UINT8 DNS_Restart() { if(server_info.net_sta != NET_COMPLETE) return 1; server_info.net_sta = NET_DNS; //状态置为DNS return 0; } int is_valid_domain(const char *domain) { const char *c = domain; int parts = 0; int dashes = 0; Dbg_Println(DBG_BIT_NET_STATUS_bit,"is_valid_domain_0:%s",domain); // 检查是否有连续的点或连字符 if (strstr(domain, "..") || strstr(domain, "--")) { Dbg_Println(DBG_BIT_NET_STATUS_bit,"is_valid_domain_1"); return 0; } // 检查每个字符 while (*c) { if (isalpha(*c) || isdigit(*c) || *c == '-' || *c == '.') { if (*c == '-') { // 不允许在开头或结尾出现连字符 if (c == domain || *(c + 1) == '\0' || dashes == 0) { Dbg_Println(DBG_BIT_NET_STATUS_bit,"is_valid_domain_2"); return 0; } dashes = 0; } else { dashes = 1; } } else { // 非法字符 Dbg_Println(DBG_BIT_NET_STATUS_bit,"is_valid_domain_3:%c",*c); return 0; } if (*c == '.') { parts++; // 分隔符计数 if (c == domain || *(c + 1) == '\0') { // 不允许在开头、结尾或者在两个点之间为空 Dbg_Println(DBG_BIT_NET_STATUS_bit,"is_valid_domain_4"); return 0; } } c++; } // 至少需要两个部分(例如 example.com) Dbg_Println(DBG_BIT_NET_STATUS_bit,"is_valid_domain_5:%d",parts); return parts > 1; } /******************************************************************************* * Function Name : Data_Conver_To_Uint16 * Description : 将数组中的两位大端模式的数据转换为uint16_t的数据 * Input : * Return : None *******************************************************************************/ uint16_t Data_Conver_To_Uint16(uint8_t *data) { uint16_t temp_data = data[1]; temp_data <<= 8; temp_data |= data[0]; return temp_data; } /******************************************************************************* * Function Name : NetWork_Parameter_Get * Description : 网络任务 获取网络初始化参数以及网络初始化功能 * Input : None * Output : None * Return : None * 用 法 : 初始化调用 *******************************************************************************/ void NetWork_Parameter_Get(void) { uint8_t Arge_Flag = 0; uint32_t temp = 0; /*判断网络是否使用设置参数为默认IP地址*/ Arge_Flag = SRAM_Read_Byte(SRAM_Register_Start_ADDRESS + Register_NetInfo_EN_OFFSET + 1); if(Arge_Flag == 0x01) { Dbg_Println(DBG_BIT_NET_STATUS_bit,"NET 网络参数使用PC设置参数!"); SRAM_Read_Buff(net_info.local_ip,4,SRAM_Register_Start_ADDRESS + Register_NetIP_OFFSET); SRAM_Read_Buff(net_info.gwip_addr,4,SRAM_Register_Start_ADDRESS + Register_NetGateway_OFFSET); SRAM_Read_Buff(net_info.mask,4,SRAM_Register_Start_ADDRESS + Register_NetMask_OFFSET); SRAM_Read_Buff(DNS_SERVER_IP,4,SRAM_Register_Start_ADDRESS + Register_DNSServerIP_OFFSET); }else { Dbg_Println(DBG_BIT_NET_STATUS_bit,"NET 网络参数使用本机默认参数!"); //MCU初始化IP net_info.local_ip[0] = 192; net_info.local_ip[1] = 168; net_info.local_ip[2] = MACAddr[4]; //2023-03-17 net_info.local_ip[3] = MACAddr[5]; //2023-03-17 //MCU初始网关 net_info.gwip_addr[0] = 192; net_info.gwip_addr[1] = 168; net_info.gwip_addr[2] = MACAddr[4]; //2023-03-17 net_info.gwip_addr[3] = 1; //MCU初始子网掩码 net_info.mask[0] = 255; net_info.mask[1] = 255; net_info.mask[2] = 0; //2023-03-17 net_info.mask[3] = 0; //MCU DNS地址 DNS_SERVER_IP[0] = 223; DNS_SERVER_IP[1] = 5; DNS_SERVER_IP[2] = 5; DNS_SERVER_IP[3] = 5; } /*启用DHCP*/ if(SRAM_Read_Byte(SRAM_Register_Start_ADDRESS + Register_NetInfo_EN_OFFSET) != 0x02) { Dbg_Println(DBG_BIT_NET_STATUS_bit,"DHCP功能使能!"); server_info.dhcp_en = 0x01; }else{ /*不启用*/ Dbg_Println(DBG_BIT_NET_STATUS_bit,"不启用DHCP功能!"); server_info.dhcp_en = 0x00; } /*判断当前使用本地服务器还是云端服务器*/ temp = SRAM_Read_Byte(SRAM_Register_Start_ADDRESS + Register_NetInfo_EN_OFFSET + 2); if(temp == 0x01) //使用本地端服务器 { server_info.server_select = 0x01; Dbg_Println(DBG_BIT_NET_STATUS_bit,"使用本地端服务器"); }else //使用云端端服务器 { server_info.server_select = 0x00; Dbg_Println(DBG_BIT_NET_STATUS_bit,"使用云端端服务器"); } /*2024-04-08 start*/ memset(&tftp_log,0,sizeof(TFTP_LOG)); SRAM_Read_Buff((uint8_t*)&tftp_log.Time,2,SRAM_Register_Start_ADDRESS + Register_TFTPLOGTime_OFFSET); SRAM_Read_Buff((uint8_t*)&tftp_log.Port,2,SRAM_Register_Start_ADDRESS + Register_TFTPLOGPort_OFFSET); Dbg_Println(DBG_BIT_NET_STATUS_bit,"tftp log port:%d time:%dh",tftp_log.Port,tftp_log.Time); if((tftp_log.Port == 0xFFFF) || (tftp_log.Port == 0x00)) { tftp_log.Port = TFTP_Destination_Port; Dbg_Println(DBG_BIT_NET_STATUS_bit,"tftp log default port:%d",tftp_log.Port); } if((tftp_log.Time == 0x00) || (tftp_log.Time > 720)) { tftp_log.Time = 720; //1个月 Dbg_Println(DBG_BIT_NET_STATUS_bit,"tftp log default time:%dh",tftp_log.Time); } tftp_log.DN_Lens = SRAM_Read_Byte(SRAM_Register_Start_ADDRESS + Register_TFTPDmLens_OFFSET); Dbg_Println(DBG_BIT_NET_STATUS_bit,"tftp log domain name lens:%d",tftp_log.DN_Lens); if(tftp_log.DN_Lens < DOMAINNAME_MAX) { SRAM_Read_Buff((uint8_t*)tftp_log.DomainName,tftp_log.DN_Lens,SRAM_Register_Start_ADDRESS + Register_TFTPDmName_OFFSET); tftp_log.DomainName[tftp_log.DN_Lens] = '\0'; } if((tftp_log.DN_Lens == 0x00) || (is_valid_domain(tftp_log.DomainName) == 0x00)) //域名不合法使用默认 { tftp_log.DN_Lens = sizeof(TFTPSERVER_NAME_DNS); if(tftp_log.DN_Lens < DOMAINNAME_MAX) { memcpy(tftp_log.DomainName,(char*)TFTPSERVER_NAME_DNS,sizeof(TFTPSERVER_NAME_DNS)); tftp_log.DomainName[tftp_log.DN_Lens] = '\0'; } Dbg_Println(DBG_BIT_NET_STATUS_bit,"tftp domain name err,use default:%s",tftp_log.DomainName); } /*2024-04-08 end*/ //2025-10-11 读取服务器离线判定时间 server_info.udp_online_time = SRAM_Read_DW(SRAM_Register_Start_ADDRESS + Register_NetOfflineTime_OFFSET); if( (server_info.udp_online_time < 1000) || (server_info.udp_online_time > 7200000) ) { server_info.udp_online_time = 600000; } //2025-10-11 读取UDP 定期上报时间间隔 temp = SRAM_Read_DW(SRAM_Register_Start_ADDRESS + Register_UDPPeriodicTime_OFFSET); if( (temp < 10000) || (temp > 7200000) ) { server_info.udp_periodic_time = 60; }else { server_info.udp_periodic_time = temp / 1000; } //2025-10-11 读取服务器域名与端口 temp = SRAM_Read_DW(SRAM_Register_Start_ADDRESS + Register_WebServerPort_OFFSET); if( (temp == 0x00) || (temp >= 0xFFFF) ) { //服务器端口不合法,使用默认端口 3339 server_info.dis_port = 3339; }else { server_info.dis_port = temp & 0xFFFF; } temp = SRAM_Read_Byte(SRAM_Register_Start_ADDRESS + Register_BLVServerDmName_OFFSET); Dbg_Println(DBG_BIT_NET_STATUS_bit,"BLVServerDmName lens:%d",temp); if(temp < 64) { memset(net_info.ServerDename,0,sizeof(net_info.ServerDename)); SRAM_Read_Buff((uint8_t*)net_info.ServerDename,temp,SRAM_Register_Start_ADDRESS + Register_BLVServerDmName_OFFSET); net_info.ServerDename[temp] = '\0'; } if((temp == 0x00) || (is_valid_domain((char *)net_info.ServerDename) == 0x00)) //域名不合法使用默认 { temp = sizeof(SERVER_NAME_DNS); if(temp < 64) { memcpy(net_info.ServerDename,(char*)SERVER_NAME_DNS,sizeof(SERVER_NAME_DNS)); net_info.ServerDename[temp] = '\0'; } Dbg_Println(DBG_BIT_NET_STATUS_bit,"BLVServerDmName err,use default:%s",net_info.ServerDename); } Dbg_Println(DBG_BIT_NET_STATUS_bit,"MCU初始IP地址 : %d.%d.%d.%d",net_info.local_ip[0],net_info.local_ip[1],net_info.local_ip[2],net_info.local_ip[3]); Dbg_Println(DBG_BIT_NET_STATUS_bit,"MCU初始网关 : %d.%d.%d.%d",net_info.gwip_addr[0],net_info.gwip_addr[1],net_info.gwip_addr[2],net_info.gwip_addr[3]); Dbg_Println(DBG_BIT_NET_STATUS_bit,"MCU初始子网掩码 : %d.%d.%d.%d",net_info.mask[0],net_info.mask[1],net_info.mask[2],net_info.mask[3]); Dbg_Println(DBG_BIT_NET_STATUS_bit,"MCU DNS地址 : %d.%d.%d.%d",DNS_SERVER_IP[0],DNS_SERVER_IP[1],DNS_SERVER_IP[2],DNS_SERVER_IP[3]); Dbg_Println(DBG_BIT_NET_STATUS_bit,"TFTP Log Domain name:%s ",tftp_log.DomainName); Dbg_Println(DBG_BIT_NET_STATUS_bit,"BLVServerDmName : %s:%d ",net_info.ServerDename,server_info.dis_port); Dbg_Println(DBG_BIT_NET_STATUS_bit,"online_time:%d periodic_time:%d",server_info.udp_online_time,server_info.udp_periodic_time); LOG_SYS_NET_Argc_Init_Record(net_info.local_ip,net_info.gwip_addr,net_info.mask,DNS_SERVER_IP,Arge_Flag,server_info.dhcp_en,server_info.server_select); } /******************************************************************************* * Function Name : NetWork_Task * Description : 网络任务,包括库初始化,DHSP, DNS, socket创建, 发送数据 * Input : None * Output : None * Return : None * 用 法 : 主循环调用 *******************************************************************************/ uint8_t DNS_num = 0; void NetWork_Task(void) { //socket状态机,发送函数 switch(server_info.net_sta) { case NET_INIT: //网络初始化 { DNS_num = 0; server_info.init_flag = 0; //网络开始初始化 server_info.register_num = 0; server_info.dhcp_flg = 0; server_info.server_dns_flag = 0; server_info.tftp_dns_flag = 0; server_info.mqtt_dns_flag = 0; server_info.udp_sta = 0x01; server_info.Udp_Internal_sta = STA_INIT; //UDP套接字状态 server_info.online_state = 0; //2023-10-07 #if TFTP_GET_IP server_info.tftpip_gflag = 0x00; #endif #if MQTT_EN { mqtt_info.mqtt_sta = MQTT_DNS; //2023-03-17 } #endif NetWork_Parameter_Get(); //GetMacAddr(MACAddr); /* 获取自带的MAC地址 */ CH57xNET_OpenMac(); //打开网络时钟 Dbg_Println(DBG_BIT_NET_STATUS_bit,"MACAddr : %02X.%02X.%02X.%02X.%02X.%02X",MACAddr[0],MACAddr[1],MACAddr[2],MACAddr[3],MACAddr[4],MACAddr[5]); UINT8 ret = CH57xNET_LibInit(net_info.local_ip, net_info.gwip_addr, net_info.mask, MACAddr); /* 库初始化 */ mStopIfError(ret); /* 检查错误 */ if(ret != CH57xNET_ERR_SUCCESS) break; //网络库初始化失败 Dbg_Println(DBG_BIT_NET_STATUS_bit,"CH57xNETLibInit Success"); Timer0Init( 10000 ); /* 初始化定时器:10ms */ NVIC_EnableIRQ(ETH_IRQn); //开启以太网中断 server_info.wait_cot = SysTick_10ms; server_info.net_sta = NET_PHY_WAIT; server_info.con_tick = SysTick_1s; //2023-05-27 server_info.udp_sta = 0x01; server_info.register_num = 0x00; server_info.udp_timesync_cnt = 0x00; server_info.udp_periodic_cnt = 0x00; server_info.udp_idle_tick = SysTick_1ms; server_info.udp_send_flag = 0x00; } break; case NET_PHY_WAIT: //等待PHY协商,如果协商不成功,网络将不可用 if( CH57xInf.PHYStat < 2 ) { if(SysTick_10ms - server_info.wait_cot > 3000) { Dbg_Println(DBG_BIT_NET_STATUS_bit,"网络PHY协商失败,准备重新初始化网络"); server_info.net_sta = NET_START_TO_INIT; } break; }else { Dbg_Println(DBG_BIT_NET_STATUS_bit,"网线插入已插入,创建直连套接字"); UDPSocketParamInit2(&net_info.SocketId[0], 3341, UDPSocket1_AppCallBack); //创建套接字,局域网等待接收升级或配置发布等命令 server_info.online_state = 1; //2023-10-07 server_info.wait_cot = SysTick_10ms; server_info.net_sta = NET_CON_WAIT; LOG_SYS_PHY_Change_Record(0x01); //网线插入 } break; case NET_START_TO_INIT: CH57xNET_CloseMac(); //关闭网络时钟 server_info.wait_cot = SysTick_10ms; Dbg_Println(DBG_BIT_NET_STATUS_bit,"关闭MAC,准备重启网络"); server_info.net_sta = NET_WAIT_MAC_RESTART; break; case NET_WAIT_MAC_RESTART: if(SysTick_10ms - server_info.wait_cot > 100) { server_info.wait_cot = SysTick_10ms; Dbg_Println(DBG_BIT_NET_STATUS_bit,"重启网络中"); server_info.net_sta = NET_INIT; } break; case NET_CON_WAIT: //2023-05-26 if(SysTick_10ms - server_info.wait_cot > 20) { server_info.wait_cot = SysTick_10ms; if(server_info.dhcp_en == 0x01) { server_info.net_sta = NET_DHCP; }else { server_info.net_sta = NET_DNS; // CH57xNET_SocketClose(net_info.SocketId[0],0x00); //2023-05-27 } } break; case NET_DHCP: //启动DHCP分配ip Dbg_Println(DBG_BIT_NET_STATUS_bit,"启动DHCP分配..."); CH57xNET_DHCPStart(CH57xNET_DHCPCallBack); /* 启动DHCP */ server_info.wait_cot = SysTick_1ms; server_info.net_sta = NET_DHCP_WAIT; break; case NET_DHCP_WAIT: if(SysTick_1ms - server_info.wait_cot >= 10000) { Dbg_Println(DBG_BIT_NET_STATUS_bit,"DHCP 耗时:%dms", SysTick_1ms - server_info.wait_cot); server_info.wait_cot = SysTick_1ms; Dbg_Println(DBG_BIT_NET_STATUS_bit,"DHCP获取失败!"); CH57xNET_DHCPStop(); server_info.net_retry_num++; server_info.net_sta = NET_DHCP; if(server_info.net_retry_num >= 3) { server_info.net_retry_num = 0; Dbg_Println(DBG_BIT_NET_STATUS_bit,"DHCP重试次数已达上限!"); server_info.net_sta = NET_START_TO_INIT; //DHCP分配失败,直接重新初始化网络; CH57xNET_SocketClose(net_info.SocketId[0],0x00); //2023-05-27 } } break; case NET_SOCKET_WAIT: //2023-05-29 if(SysTick_1ms - server_info.wait_cot >= 200) { Dbg_Println(DBG_BIT_NET_STATUS_bit,"DHCP成功,重新创建通讯套接字"); UDPSocketParamInit2(&net_info.SocketId[0], 3341, UDPSocket1_AppCallBack); //创建套接字,局域网等待接收升级或配置发布等命令 server_info.net_sta = NET_DNS; } break; case NET_DNS: if(server_info.server_select == 0x00) { UINT8 ret = DnsQuery_Task(&net_info.SocketId[3], (UINT8*)net_info.ServerDename, server_info.dis_ip); /* DNS查询 */ if(ret == 1) //DNS查询成功 { server_info.dns_sta = DNS_INIT; Dbg_Println(DBG_BIT_NET_STATUS_bit,"Domain name:%s", net_info.ServerDename); Dbg_Println(DBG_BIT_NET_STATUS_bit," HTTPs_IP=%d.%d.%d.%d",server_info.dis_ip[0], server_info.dis_ip[1], server_info.dis_ip[2], server_info.dis_ip[3]); if((server_info.dis_ip[0] == 0x00) && (server_info.dis_ip[1] == 0x00)) //无效地址 { Dbg_Println(DBG_BIT_NET_STATUS_bit,"DNS 无效地址"); server_info.net_sta = NET_DNS; DNS_num++; if(DNS_num > 5) { DNS_num = 0; server_info.server_dns_flag = 0x00; server_info.net_sta = NET_DNS2; Dbg_Println(DBG_BIT_NET_STATUS_bit,"DNS失败"); if(dns_buf)//不为空指针则释放DNS空间 { free(dns_buf); //释放DNS空间 dns_buf = NULL; } } }else { /*服务器域名解析成功*/ server_info.server_dns_flag = 0x01; server_info.net_sta = NET_DNS2; if(dns_buf) { free(dns_buf); //释放DNS空间 dns_buf = NULL; } } } else if(ret == 2) //DNS失败将会使用初始化赋值的服务器ip地址 { server_info.dns_sta = DNS_INIT; Dbg_Println(DBG_BIT_NET_STATUS_bit,"DNS超时"); server_info.net_sta = NET_DNS; DNS_num++; if(DNS_num > 5) { DNS_num = 0; server_info.net_sta = NET_DNS2; Dbg_Println(DBG_BIT_NET_STATUS_bit,"DNS失败"); } } }else if(server_info.server_select == 0x01) { /*采用本地服务器 - 直接设置服务器IP地址,跳过解析服务器域名这一步,解析域名标志位暂时没用上*/ server_info.dis_ip[0] = SRAM_Read_Byte(SRAM_Register_Start_ADDRESS + Register_WebServerIP_OFFSET + 0); server_info.dis_ip[1] = SRAM_Read_Byte(SRAM_Register_Start_ADDRESS + Register_WebServerIP_OFFSET + 1); server_info.dis_ip[2] = SRAM_Read_Byte(SRAM_Register_Start_ADDRESS + Register_WebServerIP_OFFSET + 2); server_info.dis_ip[3] = SRAM_Read_Byte(SRAM_Register_Start_ADDRESS + Register_WebServerIP_OFFSET + 3); server_info.server_dns_flag = 0x00; server_info.net_sta = NET_DNS2; Dbg_Println(DBG_BIT_NET_STATUS_bit,"采用本地服务器:%d.%d.%d.%d",server_info.dis_ip[0],server_info.dis_ip[1],server_info.dis_ip[2],server_info.dis_ip[3]); } break; case NET_DNS2: /*解析额外的UDP服务器域名*/ { UINT8 ret = DnsQuery_Task(&net_info.SocketId[3], (UINT8*)UDPSERVER_NAME_DNS, server_info.udp_ip); /* DNS查询 */ if(ret == 1) //DNS查询成功 { server_info.dns_sta = DNS_INIT; Dbg_Println(DBG_BIT_NET_STATUS_bit,"Domain name:%s", UDPSERVER_NAME_DNS); Dbg_Println(DBG_BIT_NET_STATUS_bit," HTTPs_IP=%d.%d.%d.%d",server_info.udp_ip[0], server_info.udp_ip[1], server_info.udp_ip[2], server_info.udp_ip[3]); if((server_info.udp_ip[0] == 0x00) && (server_info.udp_ip[1] == 0x00)) //无效地址 { Dbg_Println(DBG_BIT_NET_STATUS_bit,"DNS 无效地址"); server_info.net_sta = NET_DNS2; DNS_num++; if(DNS_num > 5) { DNS_num = 0; server_info.server_dns_flag = 0x00; server_info.net_sta = NET_TFTP; Dbg_Println(DBG_BIT_NET_STATUS_bit,"DNS失败"); if(dns_buf) { free(dns_buf); //释放DNS空间 dns_buf = NULL; } } }else { /*服务器域名解析成功*/ server_info.server_dns_flag = 0x01; server_info.net_sta = NET_TFTP; if(dns_buf) { free(dns_buf); //释放DNS空间 dns_buf = NULL; } } } else if(ret == 2) //DNS失败将会使用初始化赋值的服务器ip地址 { server_info.dns_sta = DNS_INIT; Dbg_Println(DBG_BIT_NET_STATUS_bit,"DNS超时"); server_info.net_sta = NET_DNS2; DNS_num++; if(DNS_num > 5) { DNS_num = 0; server_info.net_sta = NET_TFTP; Dbg_Println(DBG_BIT_NET_STATUS_bit,"DNS失败"); } } } break; case NET_TFTP: { UINT8 ret = DnsQuery_Task(&net_info.SocketId[3], (UINT8*)tftp_log.DomainName, server_info.tftp_ip); /* DNS查询 */ if(ret == 1) //DNS查询成功 { server_info.dns_sta = DNS_INIT; Dbg_Println(DBG_BIT_NET_STATUS_bit,"Domain name:%s",tftp_log.DomainName); Dbg_Println(DBG_BIT_NET_STATUS_bit," HTTPs_IP=%d.%d.%d.%d",server_info.tftp_ip[0], server_info.tftp_ip[1], server_info.tftp_ip[2], server_info.tftp_ip[3]); if((server_info.tftp_ip[0] == 0x00) && (server_info.tftp_ip[1] == 0x00)) //无效地址 { Dbg_Println(DBG_BIT_NET_STATUS_bit,"DNS 无效地址"); server_info.net_sta = NET_TFTP; DNS_num++; if(DNS_num > 5) { DNS_num = 0; server_info.net_sta = NET_COMPLETE; Dbg_Println(DBG_BIT_NET_STATUS_bit,"DNS失败"); if(dns_buf) { free(dns_buf); //释放DNS空间 dns_buf = NULL; } } }else { /*TFTP服务器域名解析成功*/ server_info.tftp_dns_flag = 0x01; server_info.net_sta = NET_COMPLETE; if(dns_buf) { free(dns_buf); //释放DNS空间 dns_buf = NULL; } } } else if(ret == 2) //DNS失败将会使用初始化赋值的服务器ip地址 { Dbg_Println(DBG_BIT_NET_STATUS_bit,"DNS超时"); //server_info.net_sta = NET_SOCKET; server_info.dns_sta = DNS_INIT; server_info.net_sta = NET_TFTP; DNS_num++; if(DNS_num > 5) { DNS_num = 0; server_info.net_sta = NET_COMPLETE; Dbg_Println(DBG_BIT_NET_STATUS_bit,"DNS失败"); } } } break; case NET_COMPLETE: Udp_Internal_Task(); //内网处理任务(升级,发布配置) if(server_info.con_flag==0x01) //2023-05-27 { if(SysTick_1s - server_info.con_tick > 10) { server_info.con_flag = 0x00; server_info.con_tick = SysTick_1s; server_info.init_flag = 0x00; Dbg_Println(DBG_BIT_NET_STATUS_bit,"直连超时,重启网络"); } } if(server_info.init_flag == 0x00) //网络需要重新初始化 { Dbg_Println(DBG_BIT_NET_STATUS_bit,"网络重新初始化,关闭MAC"); server_info.net_sta = NET_START_TO_INIT; server_info.online_state = 0; //2023-10-07 DevActionGlobal.TimeSyncFlag = 0x00; //清除同步网络时间标记 2024-08-02 /*释放套接字*/ Dbg_Println(DBG_BIT_NET_STATUS_bit,"释放套接字"); CH57xNET_SocketClose(net_info.SocketId[0],0x00); if(IAPVarTypeStruct_Ptr != NULL) { if(IAPSTART == IAPVarTypeStruct_Ptr->IapState) { Dbg_Println(DBG_BIT_NET_STATUS_bit,"TFTP 释放套接字"); CH57xNET_SocketClose(net_info.SocketId[1],0x00); CH57xNET_SocketClose(net_info.SocketId[2],0x00); CH57xNET_CloseMac(); //关闭网络时钟 IAPVarTypeStruct_Ptr->IapState = IAPFINISH; free(IAPVarTypeStruct_Ptr); IAPVarTypeStruct_Ptr = NULL; } } } break; default: break; } } //2023-03-17 #if MQTT_EN void Mqtt_Task() { switch(mqtt_info.mqtt_sta) { case MQTT_DNS: { if((mqtt_info.init_flag == 0x01)&&(server_info.net_sta == NET_COMPLETE)) //2023-06-19 { UINT8 ret = DnsQuery_Task(&net_info.SocketId[3], (UINT8*)mqtt_info.domain_name, mqtt_info.des_ip); /* DNS查询 */ if(ret == 1) //DNS查询成功 { server_info.dns_sta = DNS_INIT; Dbg_Print(DBG_BIT_NET_STATUS_bit,"Domain name:%s \n", mqtt_info.domain_name); Dbg_Print(DBG_BIT_NET_STATUS_bit," HTTPs_IP=%d.%d.%d.%d\n\n",mqtt_info.des_ip[0], mqtt_info.des_ip[1], mqtt_info.des_ip[2], mqtt_info.des_ip[3]); if((mqtt_info.des_ip[0] == 0x00) && (mqtt_info.des_ip[1] == 0x00)) //无效地址 { Dbg_Println(DBG_BIT_NET_STATUS_bit,"DNS 无效地址"); mqtt_info.mqtt_sta = MQTT_DNS; DNS_num++; if(DNS_num > 5) { DNS_num = 0; mqtt_info.mqtt_sta = MQTT_RCON; Dbg_Print(DBG_BIT_NET_STATUS_bit,"DNS失败 - \n"); if(dns_buf) { free(dns_buf); //释放DNS空间 dns_buf = NULL; } } }else { /*服务器域名解析成功*/ mqtt_info.mqtt_sta = MQTT_INIT; if(dns_buf) { free(dns_buf); //释放DNS空间 dns_buf = NULL; } } } else if(ret == 2) //DNS失败将会使用初始化赋值的服务器ip地址 { Dbg_Print(DBG_BIT_NET_STATUS_bit,"DNS超时\n"); server_info.dns_sta = DNS_INIT; mqtt_info.mqtt_sta = MQTT_DNS; DNS_num++; if(DNS_num > 5) { DNS_num = 0; mqtt_info.mqtt_sta = MQTT_RCON; Dbg_Print(DBG_BIT_NET_STATUS_bit,"DNS失败 - \n"); } } } } break; case MQTT_INIT: Dbg_Print(DBG_BIT_NET_STATUS_bit,"mqtt_info.init_flag:%d",mqtt_info.init_flag); if(mqtt_info.init_flag) { mqtt_info.mqtt_socket = Transport_Open(&mqtt_info, mqtt_info.des_ip, 49506); //49506 Dbg_Print(DBG_BIT_NET_STATUS_bit,"MQTT发起连接:%d.%d.%d.%d\n",mqtt_info.des_ip[0], mqtt_info.des_ip[1], mqtt_info.des_ip[2], mqtt_info.des_ip[3]); Dbg_Print(DBG_BIT_NET_STATUS_bit,"mqtt_info.mqtt_socket:%d",mqtt_info.mqtt_socket); mqtt_info.wait_cot = SysTick_10ms; mqtt_info.mqtt_sta = MQTT_WAIT; } break; case MQTT_WAIT: if(mqtt_info.init_flag) { if(mqtt_info.con_flag == 0) //未连接 { if(SysTick_10ms - mqtt_info.wait_cot > 500) { mqtt_info.wait_cot = SysTick_10ms; Dbg_Print(DBG_BIT_NET_STATUS_bit,"MQTT连接超时\n"); if(mqtt_info.reconnect) { mqtt_info.reconnect--; mqtt_info.mqtt_sta = MQTT_INIT; CH57xNET_SocketClose(mqtt_info.mqtt_socket,SOCK_STAT_CLOSED ); Dbg_Print(DBG_BIT_NET_STATUS_bit,"MQTT等待重连...\n"); } else { mqtt_info.mqtt_sta = MQTT_RCON; //停止连接MQTT #if 0 // if(mqtt_info.domain_name) { free(mqtt_info.domain_name); mqtt_info.domain_name = NULL; } if(mqtt_info.clientID) { free(mqtt_info.clientID); mqtt_info.clientID = NULL; } if(mqtt_info.username) { free(mqtt_info.username); mqtt_info.username = NULL; } if(mqtt_info.password) { free(mqtt_info.password); mqtt_info.password = NULL; } if(mqtt_info.sub_topic) { free(mqtt_info.sub_topic); mqtt_info.sub_topic = NULL; } if(mqtt_info.pub_topic) { free(mqtt_info.pub_topic); mqtt_info.pub_topic = NULL; } #endif Dbg_Print(DBG_BIT_NET_STATUS_bit,"MQTT2连接失败\n"); } } } else { mqtt_info.mqtt_sta = MQTT_COMPLETE; //连接成功 } } // else if(mqtt_info2.init_flag) // { // if(mqtt_info2.con_flag == 0) //未连接 // { // if(SysTick_10ms - server_info.wait_cot > 500) // { // server_info.wait_cot = SysTick_10ms; // Dbg_Print(DBG_BIT_NET_STATUS_bit,"MQTT2连接超时\n"); // // if(mqtt_info2.reconnect) // { // mqtt_info2.reconnect--; // server_info.net_sta = NET_MQTT_INIT; // CH57xNET_SocketClose(mqtt_info2.mqtt_socket, SOCK_STAT_CLOSED); // Dbg_Print(DBG_BIT_NET_STATUS_bit,"MQTT2等待重连..."); // } // else // { // server_info.net_sta = NET_COMPLETE; //停止连接MQTT // mqtt_info2.init_flag = 0; // Dbg_Print(DBG_BIT_NET_STATUS_bit,"MQTT2连接失败"); // } // } // } // else // { // server_info.net_sta = NET_COMPLETE; //连接成功 // mqtt_info2.init_flag = 0; // } // } break; case MQTT_COMPLETE: MQTT_Receive_Processing(); break; case MQTT_RCON: mqtt_info.mqtt_cfail_num++; // Dbg_Print(DBG_BIT_NET_STATUS_bit,"MQTT连接失败%d\n",mqtt_info.mqtt_cfail_num); CH57xNET_SocketClose(mqtt_info.mqtt_socket, TCP_CLOSE_RST ); // Dbg_Print(DBG_BIT_NET_STATUS_bit,"MQTT连接失败,1准备进入定期重连%d",mqtt_info.mqtt_cfail_num); if(SysTick_10ms - mqtt_info.wait_cot > 1000) { mqtt_info.wait_cot = SysTick_10ms; mqtt_info.mqtt_sta = MQTT_DNS; } if(mqtt_info.mqtt_cfail_num>=4) { Dbg_Print(DBG_BIT_NET_STATUS_bit,"MQTT连接失败,准备进入定期重连%d\n",mqtt_info.mqtt_cfail_num); mqtt_info.mqtt_sta = MQTT_FAIL; mqtt_info.wait_cot = SysTick_1s; } break; case MQTT_FAIL: if(SysTick_1s - mqtt_info.wait_cot > 600) // 600 10分钟重新连接 { mqtt_info.wait_cot = SysTick_1s; mqtt_info.mqtt_cfail_num = 0; mqtt_info.mqtt_sta = MQTT_DNS; Dbg_Print(DBG_BIT_NET_STATUS_bit,"MQTT连接失败,定期重新连接\n"); } break; default: break; } } #endif