Files
caocong 95916b9995 fix:修改UDP通讯中,取电变化上报机制
1、问题点:当RCU网络状态异常的情况下,网络还处于协商状态下,还未进入正常通讯环节时,取电变化不会进行判断。这会导致取电变化上报与实际产生取电状态时间点对不上。
2、将BLV_C1F_Module代码上传至Gitea,之前代码修改记录请查看 .\BasicCode\Readme.txt
2026-01-23 09:23:12 +08:00

1600 lines
57 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
******************************************************************************
* @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 <ctype.h>
/* 下面的缓冲区和全局变量必须要定义,库中调用 */
__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