#include "includes.h"   


/*******************************************************************************
* Function Name  : Addtion_Regular_Service_State
* Description    : 添加服务状态到BUFF
*******************************************************************************/
void Addtion_Regular_Service_State(uint8_t *data,uint8_t type,uint8_t addr,uint16_t loop,uint16_t start)
{
	data[0] = type;
	data[1] = addr;
	data[2] = (loop & 0xFF);
	data[3] = ((loop >> 8) & 0xFF);
	data[4] = (start & 0xFF);
	data[5] = ((start >> 8) & 0xFF);
}

/*******************************************************************************
* Function Name  : Udp_Internal_GetTime_Data
* Description    : 向服务器获取时间 - 重发3次
*******************************************************************************/
void Udp_Internal_GetTime_CMD(void)
{
	uint8_t back_data[Heart_Cmd_Send_Len];  	//一次发生最大长度
	UINT32 sendlen = Heart_Cmd_Send_Len;
	
	Dbg_Println(DBG_BIT_NET_STATUS_bit,"%s",__func__);
	
	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(back_data,In_QueryTime_Cmd,Heart_Cmd_Send_Len,server_info.frame_no);
	NetCRC16(&back_data[0],Heart_Cmd_Send_Len);
	
	CH57xNET_SocketUdpSendTo(net_info.SocketId[0], &back_data[0], &sendlen, server_info.dis_ip, server_info.dis_port);
	
	LOG_NET_COMM_Send_Record(0x01,server_info.dis_ip,server_info.dis_port,&back_data[0],sendlen);
}

/*******************************************************************************
* Function Name  : Udp_Internal_GetTime_Process
* Description    : 向服务器获取时间 - 回复数据处理函数
*******************************************************************************/
uint8_t Udp_Internal_GetTime_Process(uint8_t *data, uint16_t DataLen, uint8_t *ip,uint16_t port)
{
	/*CRC校验*/
	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[HEAD_LEN+1];
	temp <<= 8;
	temp |= data[HEAD_LEN];
	
	pro_rtc.year = temp - 2000;
	pro_rtc.month = data[HEAD_LEN+2];
	pro_rtc.day = data[HEAD_LEN+3];
	pro_rtc.week = data[HEAD_LEN+4];
	pro_rtc.hour = data[HEAD_LEN+5];
	pro_rtc.minute = data[HEAD_LEN+6];
	pro_rtc.second = data[HEAD_LEN+7];
	
	if(DataLen >= 27)
	{
		DevActionGlobal.DayStart = data[HEAD_LEN+8];     //白天起始时间   2024-08-02
		DevActionGlobal.DayEnd = data[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,"服务器相应时间同步请求 len:%d，当次同步计数:%d",DataLen, DevActionGlobal.TimeGetFlag);   
	Dbg_Println(DBG_BIT_NET_STATUS_bit,"同步时间：20%02X-%02X-%02X %02X %02X:%02X:%02X",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%02X-%02X-%02X %02X %02X:%02X:%02X",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    : 向服务器获取房态
*******************************************************************************/
void Udp_Internal_GetRoomRent_CMD(void)
{
	uint8_t back_data[Heart_Cmd_Send_Len];  	//一次发生最大长度
	UINT32 sendlen = Heart_Cmd_Send_Len;
	
	Dbg_Println(DBG_BIT_NET_STATUS_bit,"%s",__func__);
	
	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(back_data,In_Get_RoomRent_Cmd,Heart_Cmd_Send_Len,server_info.frame_no);
	NetCRC16(&back_data[0],Heart_Cmd_Send_Len);
	
	//Dbg_Print_Buff(DBG_BIT_NET_STATUS_bit,"向服务器 获取房态请求",back_data,sendlen);
	
	CH57xNET_SocketUdpSendTo(net_info.SocketId[0], &back_data[0], &sendlen, server_info.dis_ip, server_info.dis_port);
	
	LOG_NET_COMM_Send_Record(0x01,server_info.dis_ip,server_info.dis_port,&back_data[0],sendlen);
}

/*******************************************************************************
* Function Name  : Udp_Internal_DayTimeSet_Process
* Description    : 向服务器获取房态信息 回复数据
*******************************************************************************/
uint8_t Udp_Internal_GetRoomRent_Process(uint8_t *data, uint16_t DataLen, uint8_t *ip,uint16_t port)
{
	/*CRC校验*/
	uint16_t data_crc = 0x00;
	uint32_t read_register = 0,temp_data = 0;
	
	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;
	
	read_register = SRAM_Register_Start_ADDRESS + Register_RoomRent_OFFSET;
	temp_data = SRAM_Read_DW(read_register);
	
	//Dbg_Println(DBG_BIT_NET_STATUS_bit,"服务器获取房态:%d ",data[HEAD_LEN]);   
	
	if(data[HEAD_LEN] == 0x02)
	{
		Dbg_Println(DBG_BIT_NET_STATUS_bit,"房间出租");
		/*房态发生变化 - 出租与退房，置位首次取电标志位 RCU中存储PMS状态 0x01:入住，0x02:退房*/
		if(temp_data != 0x02)
		{
			ServiceInfo_Set_first_power_on(0x01);
			temp_data = 0x02;
			SRAM_Write_DW(temp_data,read_register);
		}
		
		DevActionGlobal.DevActionU64Cond.RoomState = 0x01;	//给执行动作判断条件使用 
	}else if(data[HEAD_LEN] == 0x04)
	{
		Dbg_Println(DBG_BIT_NET_STATUS_bit,"房间待租");
		
		if(temp_data != 0x04)
		{
			temp_data = 0x04;
			SRAM_Write_DW(temp_data,read_register);
		}
		
		DevActionGlobal.DevActionU64Cond.RoomState = 0x03;	//给执行动作判断条件使用 
	}else if(data[HEAD_LEN] == 0x08)
	{
		Dbg_Println(DBG_BIT_NET_STATUS_bit,"房间退房");
		/*房态发生变化 - 出租与退房，置位首次取电标志位 RCU中存储PMS状态 0x01:入住，0x02:退房*/
		if(temp_data != 0x08)
		{
			ServiceInfo_Set_first_power_on(0x01);
			temp_data = 0x08;
			SRAM_Write_DW(temp_data,read_register);
		}
		
		DevActionGlobal.DevActionU64Cond.RoomState = 0x02;	//给执行动作判断条件使用 
	}else if(data[HEAD_LEN] == 0x10)
	{
		Dbg_Println(DBG_BIT_NET_STATUS_bit,"空房");
		
		if(temp_data != 0x10)
		{
			temp_data = 0x10;
			SRAM_Write_DW(temp_data,read_register);
		}
		
		DevActionGlobal.DevActionU64Cond.RoomState = 0x04;	//给执行动作判断条件使用 
	}

	server_info.udp_send_flag = 0x00;					//清楚发送标志位
	server_info.active_cmd_flag &= ~UDP_ActSend_RoomState_Flag;		//清楚标志位
	server_info.udp_online_tick = SysTick_1ms;
	
	return 0;
}

/*******************************************************************************
* Function Name  : Udp_Internal_Reboot_Reason_Report_CMD
* Description    : RCU重启原因
*******************************************************************************/
void Udp_Internal_Reboot_Reason_Report_CMD(void)
{
	uint8_t temp_data[24] = {0};
	UINT32 sendlen = 0x00;
	
	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 = 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[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[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);
	
	CH57xNET_SocketUdpSendTo(net_info.SocketId[0], &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_DayTimeSet_Process
* Description    : 向服务器获取房态信息 回复数据
*******************************************************************************/
uint8_t Udp_Internal_Reboot_Reason_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_Reboot_Flag;		//清楚标志位
	server_info.udp_online_tick = SysTick_1ms;
	
	return 0x00;
}

/*******************************************************************************
* Function Name  : Udp_Internal_Power_Change_Report_CMD
* Description    : 取电变化上报
*******************************************************************************/
void Udp_Internal_Power_Change_Report_CMD(void)
{
	uint8_t back_data[30];  	//一次发生最大长度
	UINT32 sendlen = 0x00;
	uint8_t temp_flag = 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;
		}
	}
	
	temp_flag = SRAM_Read_Byte(SRAM_UDP_ELEReport_Action);
	
	sendlen = HEAD_LEN;
	if( (temp_flag & 0x01) != 0x00 )
	{
		back_data[sendlen++] = SRAM_Read_Byte(SRAM_UDP_ELEReport_EleState_Last);		//取电动作
	}else {
		back_data[sendlen++] = 0x00;
	}
	
	if( (temp_flag & 0x02) != 0x00 )
	{
		back_data[sendlen++] = SRAM_Read_Byte(SRAM_UDP_ELEReport_CardState_Last);		//插卡动作
	}else {
		back_data[sendlen++] = 0x00;
	}

	if( (temp_flag & 0x04) != 0x00 )
	{
		back_data[sendlen++] = SRAM_Read_Byte(SRAM_UDP_ELEReport_CardType_Last);		//身份变化
	}else {
		back_data[sendlen++] = 0x00;
	}
	
	if( (temp_flag & 0x08) != 0x00 )
	{
		back_data[sendlen++] = SRAM_Read_Byte(SRAM_UDP_ELEReport_VirtualCard_Last);		//无卡事件动作
	}else {
		back_data[sendlen++] = 0x00;
	}
	
	sendlen += 0x02;	//添加CRC校验长度
	UDP_Add_Header(back_data,In_Power_Change_Cmd,sendlen,server_info.frame_no);
	
	NetCRC16(&back_data[0],sendlen);
	
	//Dbg_Print_Buff(DBG_BIT_NET_STATUS_bit,"取电变化上报: ",back_data,sendlen);
	
	CH57xNET_SocketUdpSendTo(net_info.SocketId[0], &back_data[0], &sendlen, server_info.dis_ip, server_info.dis_port);
	
	LOG_NET_COMM_Send_Record(0x01,server_info.dis_ip,server_info.dis_port,&back_data[0],sendlen);
	
}

/*******************************************************************************
* Function Name  : Udp_Internal_Power_Change_Report_Process
* Description    : 向服务器上报取电状态 回复数据
*******************************************************************************/
uint8_t Udp_Internal_Power_Change_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;
	
	SRAM_Write_Byte(0x00,SRAM_UDP_ELEReport_Action);		//2026-01-20 清除标志位
	
	//无数据处理上报成功，清楚一下标志位而已
	server_info.udp_send_flag = 0x00;					//清楚发送标志位
	server_info.active_cmd_flag &= ~UDP_ActSend_PowerChange_Flag;		//清楚标志位
	server_info.udp_online_tick = SysTick_1ms;
	
	return 0x00;
}

/*查找到设备列表中的所有温控器，并按照数据组包*/
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<end_addr;)
	{
		if(SRAM_Read_Byte(read_addr + Dev_Type) == DEV_RS485_TEMP)
		{
			if(Device_Data_Check(read_addr) == 0)
			{
				SRAM_DMA_Read_Buff((uint8_t *)&BUS_Public,sizeof(Device_Public_Information_G),read_addr);	
				SRAM_DMA_Read_Buff((uint8_t *)&Rs485Temp,sizeof(RS485_TEMP_INFO),read_addr+Dev_Privately);
				
				Dbg_Println(DBG_BIT_NET_STATUS_bit,"%s Type:%d Addr:%d",__func__,BUS_Public.type,BUS_Public.addr);
				
				buff[data_offset++] = BUS_Public.type;				//设备类型 - 空调设备
				buff[data_offset++] = BUS_Public.addr;				//设备地址 - 
				buff[data_offset++] = 0x00;							//设备回路 - 空调设备默认0x00
				buff[data_offset++] = 0x00;							//设备回路 - 空调默认0x00
				buff[data_offset++] = 0x03;							//设备数据长度
				//空调状态
				temp_val = Dev_Temp_State_Data(Rs485Temp.TemStateLast);
				buff[data_offset++] = temp_val & 0xFF;	
				buff[data_offset++] = (temp_val >> 8) & 0xFF;
				buff[data_offset++] = Rs485Temp.indoor_dec_temp;
				//Dbg_Println(DBG_BIT_NET_STATUS_bit,"%Rs485Temp.indoor_dec_temp:%d",Rs485Temp.indoor_dec_temp);
				
				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_Internal_Periodic_Report_PackSend 
* Description    : 定期向服务器上报 - 不重发
*******************************************************************************/
void Udp_Internal_Periodic_Report_PackSend(void)
{
	UINT32 sendlen = 0x00;
	uint32_t temp_dev = 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 = HEAD_LEN;

	Global_Large_Buff[sendlen++] = 0x04;		//解析参数版本
	
	/*
		判定插卡取电设备是否存在，如果不存在的话，便上报插卡取电状态为0x00 - 表示插卡状态无效
			插卡取电的插卡状态：
				0x00 : 无效
				0x01 : 插卡
				0x02 : 拔卡
	*/
	if(Find_AllDevice_List_Information(DEV_RS485_CARD,0x01) != 0x00)
	{
		temp_dev = SRAM_Read_Byte(SRAM_UDP_ELEReport_CardState) & 0x03;		//插卡取电的插卡状态
		temp_dev <<= 2;
		temp_dev |=  DevActionGlobal.DevActionU64Cond.EleState & 0x03;		//服务信息中的取电服务状态
	}else {
		//插卡取电设备不存在
		temp_dev = 0x00;		//插卡取电的插卡状态 - 无效
		temp_dev <<= 2;
		temp_dev |=  DevActionGlobal.DevActionU64Cond.EleState & 0x03;		//服务信息中的取电服务状态
	}

	Global_Large_Buff[sendlen++] = temp_dev & 0xFF;			// 插卡状态(bit2~bit3) & 取电状态(bit0~bit1)
	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;
	
	if( (SRAM_Read_Byte( SRAM_Register_Start_ADDRESS + Register_RoomRent_OFFSET ) == 0x02) || \
		(SRAM_Read_Byte( SRAM_Register_Start_ADDRESS + Register_RoomRent_OFFSET ) == 0x04) || \
		(SRAM_Read_Byte( SRAM_Register_Start_ADDRESS + Register_RoomRent_OFFSET ) == 0x08) || \
		(SRAM_Read_Byte( SRAM_Register_Start_ADDRESS + Register_RoomRent_OFFSET ) == 0x10)){
		Global_Large_Buff[sendlen++] = SRAM_Read_Byte( SRAM_Register_Start_ADDRESS + Register_RoomRent_OFFSET );		//PMS状态 - 0x01:入住，0x02:退房 服务器给RCU主机发送的 02 04 08 10
	}
	else{
		Global_Large_Buff[sendlen++] = 0x00;		//PMS状态 - 0x00 无数据
	}
	
	Global_Large_Buff[sendlen++] = SRAM_Read_Byte(SRAM_UDP_Report_CarbonSatet);		//碳达人状态 - 0x01:开，0x00:关
	
	Global_Large_Buff[sendlen++] = DevActionGlobal.DimGlobalValue;			//2026-01-27 增加全局调光，同时保留3个字节
	Global_Large_Buff[sendlen++] = 0x00;
	Global_Large_Buff[sendlen++] = 0x00;
	Global_Large_Buff[sendlen++] = 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++] = 0x02;							//上报数据个数,2026-01-04,双通道改为2
		
		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;
        
        
        //通道B
		Global_Large_Buff[sendlen++] = Dev_Energy_Monitor;				//设备类型 - 能耗检测
		Global_Large_Buff[sendlen++] = 0x01;							//设备地址 - 能耗检测 设备默认0x01
		Global_Large_Buff[sendlen++] = 0x02;							//设备回路 - 能耗检测 设备默认0x01
		Global_Large_Buff[sendlen++] = 0x00;							//设备回路 - 能耗检测 设备默认0x01
		Global_Large_Buff[sendlen++] = 0x10;							//设备数据长度
		//能耗检测 - 电压 单位:10mV	
		Global_Large_Buff[sendlen++] =  Rs485EnergyInfo.voltage_B & 0xFF;	
		Global_Large_Buff[sendlen++] = (Rs485EnergyInfo.voltage_B >> 8) & 0xFF;
		//能耗检测 - 电流 单位:10mA
		Global_Large_Buff[sendlen++] =  Rs485EnergyInfo.current_B & 0xFF;								
		Global_Large_Buff[sendlen++] = (Rs485EnergyInfo.current_B >> 8) & 0xFF;
		//能耗检测 - 有功功率 单位:mW	
		Global_Large_Buff[sendlen++] =  Rs485EnergyInfo.active_power_B & 0xFF;
		Global_Large_Buff[sendlen++] = (Rs485EnergyInfo.active_power_B >> 8) & 0xFF;
		Global_Large_Buff[sendlen++] = (Rs485EnergyInfo.active_power_B >> 16) & 0xFF;
		Global_Large_Buff[sendlen++] = (Rs485EnergyInfo.active_power_B >> 24) & 0xFF;
		//能耗检测 - 能耗 单位:Wh	
		Global_Large_Buff[sendlen++] =  Rs485EnergyInfo.phase_energy_B & 0xFF;
		Global_Large_Buff[sendlen++] = (Rs485EnergyInfo.phase_energy_B >> 8) & 0xFF;
		Global_Large_Buff[sendlen++] = (Rs485EnergyInfo.phase_energy_B >> 16) & 0xFF; 
		Global_Large_Buff[sendlen++] = (Rs485EnergyInfo.phase_energy_B >> 24) & 0xFF; 
		//能耗检测 - 总能耗 单位:Wh
		Global_Large_Buff[sendlen++] =  Rs485EnergyInfo.total_energy_B & 0xFF;
		Global_Large_Buff[sendlen++] = (Rs485EnergyInfo.total_energy_B >> 8) & 0xFF;
		Global_Large_Buff[sendlen++] = (Rs485EnergyInfo.total_energy_B >> 16) & 0xFF; 
		Global_Large_Buff[sendlen++] = (Rs485EnergyInfo.total_energy_B >> 24) & 0xFF;        
        
	}else{
		/*没找到能耗设备*/
		Global_Large_Buff[sendlen++] = 0x00;							//上报数据个数
	}

	/*添加空调设备状态 - 先要找到有几个空调，然后进行数据组包*/
	temp_dev = Find_TempDevice_List_Information(&Global_Large_Buff[sendlen],0x05);		//目前最多5个空调
	sendlen = sendlen + (temp_dev * 0x08);
	
	Global_Large_Buff[33] += 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);
	
	CH57xNET_SocketUdpSendTo(net_info.SocketId[0], &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_Scan_Roomstate 
* Description    : 添加房间设备状态变化数据 - 向上报缓冲区中写入数据
*******************************************************************************/
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_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<<j)) != (temp2 & (0x01<<j)) )
			{
				Dbg_Println(DBG_BIT_NET_STATUS_bit,"Device Relay :%d",i*8+j+1);
				/*将数据写入设备动作缓冲区*/
				back_data[0] = Dev_Host_HVout;	//继电器设备类型
				back_data[1] = 0x00;			//继电器设备地址
				back_data[2] = i*8+j+1;			//继电器回路
				back_data[3] = 0x00;			//继电器回路
				if((temp1 & (0x01<<j)) == 0x00)
				{
					Dbg_Println(DBG_BIT_NET_STATUS_bit,"Device Relay :%d 继电器关",back_data[2]);
					back_data[4] = 0x02;	//继电器关状态
					back_data[5] = 0x00;
				}else
				{
					Dbg_Println(DBG_BIT_NET_STATUS_bit,"Device Relay :%d 继电器开",back_data[2]);
					back_data[4] = 0x01;	//继电器开状态
					back_data[5] = 0x00;
				}
				
				SRAM_DMA_Write_Buff(back_data,0x06,write_addr);
				write_addr += 0x06;			//地址偏移
				SRAM_DMA_Read_Buff(back_data,0x06,read_addr);
				
				if(write_addr >= 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 = UDP_PackData;
	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);
	
	CH57xNET_SocketUdpSendTo(net_info.SocketId[0], &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  : Udp_Internal_Read_MCU_System_SendAck
* Description    : 搜索命令 - 回复ACK数据
*******************************************************************************/
uint8_t Udp_Internal_Read_MCU_System_SendAck(uint8_t *ip,uint16_t port,uint16_t frame_id)
{
	UINT32 back_len = HEAD_LEN + 449 + 2;			//整包数据长度		
	
	uint8_t temp_data[34] = {0};
	uint8_t temp_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[HEAD_LEN] = SRAM_Read_Byte(SRAM_Register_Start_ADDRESS + Register_NetInfo_EN_OFFSET);		//IP类型   2022-12-02	
	
	memcpy(&Global_Large_Buff[HEAD_LEN + 1],MCU_TYPE,sizeof(MCU_TYPE));   	//机型编号
	memcpy(&Global_Large_Buff[HEAD_LEN + 17],net_info.local_ip,4);   		//IP地址
	memcpy(&Global_Large_Buff[HEAD_LEN + 21],server_info.dis_ip,4);   		//服务器IP地址
	memcpy(&Global_Large_Buff[HEAD_LEN + 25],net_info.mask,4);   			//子网掩码
	memcpy(&Global_Large_Buff[HEAD_LEN + 29],net_info.gwip_addr,4);   		//网关
	UDP_Add_Port(&Global_Large_Buff[HEAD_LEN + 33]);						//MCU主机默认端口为3341
	Global_Large_Buff[HEAD_LEN + 35] = 0;	//后两个字节没用
	Global_Large_Buff[HEAD_LEN + 36] = 0;
	memcpy(&Global_Large_Buff[HEAD_LEN + 37],DNS_SERVER_IP,4);   			//网关
	UDP_ADD_SoftwareVer(&Global_Large_Buff[HEAD_LEN+41]);					//机型编号 - 软件版本号
	
	/*RTC时间*/
	Global_Large_Buff[HEAD_LEN+61] = HEX_Conversion_To_DEC(RTC_Raw_Data.year);
	Global_Large_Buff[HEAD_LEN+62] = HEX_Conversion_To_DEC(RTC_Raw_Data.month);
	Global_Large_Buff[HEAD_LEN+63] = HEX_Conversion_To_DEC(RTC_Raw_Data.day);
	Global_Large_Buff[HEAD_LEN+64] = HEX_Conversion_To_DEC(RTC_Raw_Data.hour);
	Global_Large_Buff[HEAD_LEN+65] = HEX_Conversion_To_DEC(RTC_Raw_Data.minute);
	Global_Large_Buff[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[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[HEAD_LEN+67],temp_data,20);
	}
	
	UDP_Add_Mac(&Global_Large_Buff[HEAD_LEN+87]);			//MAC地址
	SRAM_Read_Buff(&Global_Large_Buff[HEAD_LEN+93],4,SRAM_Register_Start_ADDRESS + Register_ProjectCode_OFFSET);		//项目编码
	SRAM_Read_Buff(&Global_Large_Buff[HEAD_LEN+97],4,SRAM_Register_Start_ADDRESS + Register_RoomNumber_OFFSET);
	SRAM_Read_Buff(&Global_Large_Buff[HEAD_LEN+101],4,SRAM_Register_Start_ADDRESS + Register_HouseType_OFFSET);
	SRAM_Read_Buff(&Global_Large_Buff[HEAD_LEN+105],4,SRAM_Register_Start_ADDRESS + Register_ConfigVersion_OFFSET);		//配置软件版本
	SRAM_Read_Buff(&Global_Large_Buff[HEAD_LEN+109],4,SRAM_Register_Start_ADDRESS + Register_RoomRent_OFFSET);
	SRAM_Read_Buff(&Global_Large_Buff[HEAD_LEN+113],4,SRAM_Register_Start_ADDRESS + Register_SeasonStatus_OFFSET);
	//SRAM_Read_Buff(&back_data[HEAD_LEN+117],4,SRAM_Register_Start_ADDRESS + Register_MandateLock_OFFSET);
	Global_Large_Buff[HEAD_LEN+117] = Get_Authorize_Lock_Status();		//获取授权状态
	SRAM_Read_Buff(&Global_Large_Buff[HEAD_LEN+121],4,SRAM_Register_Start_ADDRESS + Register_MandateUTC_OFFSET);
	SRAM_Read_Buff(&Global_Large_Buff[HEAD_LEN+125],4,SRAM_Register_Start_ADDRESS + Register_MandateExpiresTime_OFFSET);
	SRAM_Read_Buff(&Global_Large_Buff[HEAD_LEN+129],128,SRAM_Register_Start_ADDRESS + Register_RoomNumNote_OFFSET);
	Flash_Read(&Global_Large_Buff[HEAD_LEN+257],64,FLASH_MCU_Model_Revision_ADDRESS);
	Flash_Read(&Global_Large_Buff[HEAD_LEN+321],64,FLASH_MCU_Control_Revision_ADDRESS);
	//新增配置的酒店名称和房型名称 2022-07-13
	temp_rev = Read_LogicFile_Information(0x04,(uint8_t *)&temp_data);	//查询LOGIC文件中的酒店别名 - 32Byte
	if(temp_rev == 0x00)
	{
		memcpy(&Global_Large_Buff[HEAD_LEN+385],temp_data,32);
	}else {
		memset(temp_data,0,32);
		memcpy(&Global_Large_Buff[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[HEAD_LEN+417],temp_data,32);
	}else {
		memset(temp_data,0,32);
		memcpy(&Global_Large_Buff[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);
	
	//数据打包
	NetCRC16(&Global_Large_Buff[0],back_len);
	CH57xNET_SocketUdpSendTo(net_info.SocketId[0], Global_Large_Buff, &back_len, ip, port);    //SOCK_UDPS,
	LOG_NET_COMM_Send_Record(0x01,ip,port,&Global_Large_Buff[0],back_len);
	
	return 0;
}


/*************************
**函数名：Udp_Internal_Read_MCU_System_Process
**参  数：data：接受到的数据   len：长度   ip：网络地址  port：端口
**作  用：UDP 读取主机系统参数信息 数据处理       
**返回值：无        
************************/
uint8_t Udp_Internal_Read_MCU_System_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;
	
	uint16_t pack_frame = 0;
	pack_frame = data[FRAME_NO_OFFSET] + (data[FRAME_NO_OFFSET+1]<<8);   //帧号
	
	if(data[15]==0x01)         //处于直连模式       2023-05-27
	{
		CH57xNET_DHCPStop();       //2023-05-31
		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.udp_ip[0] = ip[0];
	server_info.udp_ip[1] = ip[1];
	server_info.udp_ip[2] = ip[2];
	server_info.udp_ip[3] = ip[3];
	
	server_info.local_port = port;
	
	//Udp_Internal_Read_MCU_System_SendAck(ip,port,pack_frame);
	return 0;
}

/*************************
**函数名：Udp_Internal_Device_Control_Process
**参  数：data：接受到的数据   len：长度   ip：网络地址  port：端口
**作  用：UDP 网络控制设备 数据处理       
**返回值：无        
************************/
uint8_t Udp_Internal_Device_Control_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;
	
	uint16_t temp = 0,frame_id = 0;
	static uint16_t last_frame_id = 0;
	uint32_t read_addr = 0;
	
	temp = DataLen - 16 - 2;
	Dbg_Println(DBG_BIT_NET_STATUS_bit,"服务器下发设备控制数：%d,数据长度：%d",data[CMD_OFFSET + 7],temp);
	
	frame_id = data[FRAME_NO_OFFSET];
	frame_id |= data[FRAME_NO_OFFSET + 1] << 8;
	
	if(last_frame_id != frame_id)
	{
		last_frame_id = frame_id;
		/*将数据拷贝到SRAM缓冲区中*/
		SRAM_Write_Byte(data[CMD_OFFSET + 7],SRAM_UDP_RecvData_ControlNum);
		SRAM_DMA_Write_Buff(&data[CMD_OFFSET + 8],temp,SRAM_UDP_RecvData_Startaddr);
		read_addr = SRAM_UDP_RecvData_Startaddr + temp;
		SRAM_Write_DW(read_addr,SRAM_UDP_RecvData_Writeaddr);
		Retain_Flash_Register_Data();		//将数据保存到Flash中
	}
	
	Udp_Internal_Process_Ack(In_DevCtr_Cmd,frame_id,ip,port);
	
	return 0;
}

/**
	* @name 服务器控制温控器单个信息
	* @para 
                       空调号      季节CMD    季节内容
	*   dat 下发的数据包 dat[0]      dat[1]     dat[2]
	*   len 长度
	* @return 无
  * @attention 对内协议温控器单控将会被取消
	*/
uint8_t Udp_Internal_SingleTempCtrl_dis(uint8_t *dat, uint16_t len, uint8_t *ip,uint16_t port)
{	
	uint16_t frame_id = 0;
	uint32_t Season = 0;
	
	
	frame_id = dat[FRAME_NO_OFFSET];
	frame_id |= dat[FRAME_NO_OFFSET + 1] << 8;	
	switch(dat[HEAD_LEN+1])
	{			
		case 0x17:  Season = dat[HEAD_LEN+2]+(dat[HEAD_LEN+3]<<2)+(dat[HEAD_LEN+4]<<4)+(dat[HEAD_LEN+5]<<6)+(dat[HEAD_LEN+6]<<8)+(dat[HEAD_LEN+7]<<10)
																	 +(dat[HEAD_LEN+8]<<12)+(dat[HEAD_LEN+9]<<14)+(dat[HEAD_LEN+10]<<16)+(dat[HEAD_LEN+11]<<18)+(dat[HEAD_LEN+12]<<20)+(dat[HEAD_LEN+13]<<22); 
					SRAM_Write_DW(Season,SRAM_Register_Start_ADDRESS + Register_SeasonStatus_OFFSET);
					Dbg_Println(DBG_BIT_NET_STATUS_bit,"服务器下发季节2：%4x", Season);

					Retain_Flash_Register_Data();		//将数据保存到Flash中
					break;
		default: 		break;
	}
	Udp_Internal_Process_Ack(In_SingleAirCtrl_Cmd,frame_id,ip,port);
	
	return 1;
}

/*
 * @name 电源控制
 * @para 
 *   data 报文
 *   len  长度
 * @return 1 正确   2 错误
 */
uint8_t Udp_Internal_sys_key(uint8_t *dat, uint16_t len, uint8_t *ip,uint16_t port)
{
	uint16_t frame_id = 0;
	frame_id = dat[FRAME_NO_OFFSET];
	frame_id |= dat[FRAME_NO_OFFSET + 1] << 8;	
	
	switch(dat[HEAD_LEN])
	{
		case 0x00:
		case 0x01:
			Set_Authorize_Lock_Status(dat[HEAD_LEN]);
			SRAM_Write_DW(dat[HEAD_LEN],SRAM_Register_Start_ADDRESS + Register_MandateLock_OFFSET);
			Retain_Flash_Register_Data();		//将数据保存到Flash中		
			Dbg_Println(DBG_BIT_NET_STATUS_bit,"服务器下发锁定：%d", dat[HEAD_LEN]);			
			break;
	}
			

	Udp_Internal_Process_Ack(In_Sys_Key_Cmd,frame_id,ip,port);

	return 1;
}

/*************************
**函数名：Udp_Internal_ReadRegister_Process
**参  数：data：接受到的数据   len：长度   ip：网络地址  port：端口
**作  用：UDP 读取映射寄存器 数据处理       
**返回值：无        
************************/
uint8_t Udp_Internal_ReadRegister_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 i = 0;
	uint32_t read_register = 0,temp_offset = 0,temp_data = 0;
	uint16_t pack_frame = 0;
	UINT32 back_len = 0;
	
	/*判断接收数据长度是否一致*/
	back_len = data[FRAME_LEN_OFFSET] + (data[FRAME_LEN_OFFSET+1]<<8);   //判断包格式是否正确
	if(back_len != DataLen)	return 0xF0;
	
	back_len = data[UDP_PackData]*4+18;		//判断数据参数是否正确
	if(back_len != DataLen)	return 0xF0;
	
	back_len = data[UDP_PackData]*8+18;		//回复的整包数据长度
	if(back_len > 512) back_len=512;				
	
	memset(Global_Large_Buff,0,sizeof(Global_Large_Buff));
	
	pack_frame = data[FRAME_NO_OFFSET] + (data[FRAME_NO_OFFSET+1]<<8);   //帧号
	
	/*数据打包*/
	UDP_Add_Header(Global_Large_Buff,In_ReadRegister_Cmd,back_len,pack_frame);            	//添加头部
	
	if(data[UDP_PackData] > 35)	Global_Large_Buff[UDP_PackData] = 35;	//读取寄存器个数,最大35个
	else Global_Large_Buff[UDP_PackData] = data[UDP_PackData];		
	/*读取寄存器内容*/
	for(i = 0;i<Global_Large_Buff[UDP_PackData];i++)
	{
		temp_offset = data[UDP_PackData+i*4+4];
		temp_offset <<= 8;
		temp_offset |= data[UDP_PackData+i*4+3];
		temp_offset <<= 8;
		temp_offset |= data[UDP_PackData+i*4+2];
		temp_offset <<= 8;
		temp_offset |= data[UDP_PackData+i*4+1];
		
		Global_Large_Buff[UDP_PackData+i*8+4] = data[UDP_PackData+i*4+4];
		Global_Large_Buff[UDP_PackData+i*8+3] = data[UDP_PackData+i*4+3];
		Global_Large_Buff[UDP_PackData+i*8+2] = data[UDP_PackData+i*4+2];
		Global_Large_Buff[UDP_PackData+i*8+1] = data[UDP_PackData+i*4+1];
		
		read_register = SRAM_Register_Start_ADDRESS + temp_offset;
		
		if(read_register > SRAM_Register_End_ADDRESS)	
		{
			Dbg_Println(DBG_BIT_NET_STATUS_bit,"Not In The Right Range");
			continue;
		}
		
		temp_data = SRAM_Read_DW(read_register);					//读取寄存器内容
		Dbg_Println(DBG_BIT_NET_STATUS_bit,"temp_offset:%08X data:%08X",read_register,temp_data);
		Global_Large_Buff[UDP_PackData+i*8+8] = ((temp_data >> 24) & 0xFF);		
		Global_Large_Buff[UDP_PackData+i*8+7] = ((temp_data >> 16) & 0xFF);
		Global_Large_Buff[UDP_PackData+i*8+6] = ((temp_data >> 8) & 0xFF);
		Global_Large_Buff[UDP_PackData+i*8+5] = (temp_data & 0xFF);
	}
	
	//数据打包
	NetCRC16(&Global_Large_Buff[0],back_len);
	CH57xNET_SocketUdpSendTo(net_info.SocketId[0], &Global_Large_Buff[0], &back_len, ip, port);    //SOCK_UDPS,
	
	return 0x00;
}

/*************************
**函数名：Udp_Internal_WriteRegister_Process
**参  数：data：接受到的数据   len：长度   ip：网络地址  port：端口
**作  用：UDP 设置映射寄存器 数据处理       
**返回值：无        
************************/
uint8_t Udp_Internal_WriteRegister_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 i = 0,temp = 0,temp_num = 0;
	uint32_t read_register = 0,temp_offset = 0,temp_data = 0;
	uint16_t pack_frame = 0;
	UINT32 back_len = WriteRegister_Cmd_Send_Len;		//整包数据长度				
	uint8_t back_data[24];						//这数据长度根据需要读取的数据长度来决定
	
	memset(back_data,0,sizeof(back_data));
	
	pack_frame = data[FRAME_NO_OFFSET] + (data[FRAME_NO_OFFSET+1]<<8);   //帧号
	
	/*数据打包*/
	UDP_Add_Header(back_data,In_WriteRegister_Cmd,back_len,pack_frame);            	//添加头部

	/*设置寄存器内容*/
	temp = 0x01;
	
	if(data[UDP_PackData] > 35)	temp_num = 35;		//设置寄存器个数,最大35个
	else temp_num = data[UDP_PackData];	
	
	for(i = 0;i<temp_num;i++)
	{
		temp_offset = data[UDP_PackData+i*8+4];
		temp_offset <<= 8;
		temp_offset |= data[UDP_PackData+i*8+3];
		temp_offset <<= 8;
		temp_offset |= data[UDP_PackData+i*8+2];
		temp_offset <<= 8;
		temp_offset |= data[UDP_PackData+i*8+1];
		
		temp_data = data[UDP_PackData+i*8+8];
		temp_data <<= 8;
		temp_data |= data[UDP_PackData+i*8+7];
		temp_data <<= 8;
		temp_data |= data[UDP_PackData+i*8+6];
		temp_data <<= 8;
		temp_data |= data[UDP_PackData+i*8+5];
		
		read_register = SRAM_Register_Start_ADDRESS + temp_offset;
		Dbg_Println(DBG_BIT_NET_STATUS_bit,"temp_offset:%08X data:%08X",read_register,temp_data);
		
		if(read_register > SRAM_Register_End_ADDRESS)	
		{
			temp = 0x02;		//写入失败
			Dbg_Println(DBG_BIT_NET_STATUS_bit,"Not In The Right Range");
			continue;
		}
		
		/*授权时间写入时，重新设置一下本地时间 如果本地没有RTC时间则将直接使用UTC时间保存在本地*/
		if(read_register == (SRAM_Register_Start_ADDRESS + Register_MandateUTC_OFFSET))
		{
			S_RTC write_rtc;
			memset(&write_rtc,0,sizeof(write_rtc));
			Unix_Conversion_To_RTC(&write_rtc,temp_data);
			RTC_WriteDate(write_rtc);
		}
		
		/*授权到期时间刷新*/
		if(read_register == (SRAM_Register_Start_ADDRESS + Register_MandateExpiresTime_OFFSET))
		{
			BLV_Set_Authorize_Status(temp_data,0);		
		}
		
		/*设置MCU锁定状态*/
		if(read_register == (SRAM_Register_Start_ADDRESS + Register_MandateLock_OFFSET))
		{
			Dbg_Println(DBG_BIT_NET_STATUS_bit,"Set_Authorize_Lock_Status:%08X",temp_data);
			if(temp_data == 0x00000001)
			{
				Set_Authorize_Lock_Status(0x01);
			}else if(temp_data == 0x00000000)
			{
				Set_Authorize_Lock_Status(0x00);
			}		
		}
		
		SRAM_Write_DW(temp_data,read_register);
		if(temp_data != SRAM_Read_DW(read_register))	temp = 0x02;		//写入失败
	}
	
	Retain_Flash_Register_Data();		//将数据保存到Flash中
	
	back_data[UDP_PackData] = temp;		//写入结果
	
	//数据打包
	NetCRC16(&back_data[0],back_len);
	CH57xNET_SocketUdpSendTo(net_info.SocketId[0], &back_data[0], &back_len, ip, port);    //SOCK_UDPS,
	
	return 0x00;
}

/*************************
**函数名：Udp_Internal_BLVPCTest_Process
**参  数：data：接受到的数据   len：长度   ip：网络地址  port：端口
**作  用：PC 下发测试命令处理 
	该函数主要是将MCU管理的设备在线状态回复PC端，测试主要是检测的设备线路是否正常
**返回值：无        
************************/
uint8_t Udp_Internal_BLVPCTest_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;
	
	uint16_t pack_frame = 0;
	uint8_t device_num = Find_The_Number_Of_Device_In_The_List();
	UINT32 back_len = device_num * 3 + 18;
	
	memset(Global_Large_Buff,0,sizeof(Global_Large_Buff));
	
	pack_frame = data[FRAME_NO_OFFSET] + (data[FRAME_NO_OFFSET+1]<<8);   //帧号
	
	UDP_Add_Header(Global_Large_Buff,In_BLVPCTest_Cmd,back_len,pack_frame);            	//添加头部
	Global_Large_Buff[UDP_PackData] = device_num;
	/*获取设备数*/
	Gets_the_state_of_all_devices(&Global_Large_Buff[UDP_PackData + 1],device_num);
	
	NetCRC16(&Global_Large_Buff[0],back_len);
	CH57xNET_SocketUdpSendTo(net_info.SocketId[0], &Global_Large_Buff[0], &back_len, ip, port);    //SOCK_UDPS,
	
	return 0x00;
}

/*查找到设备列表中的所有温控器，并按照数据组包*/
uint32_t Find_TempDevice_Set_NetCtrlFlag(uint8_t *buff)
{
	uint32_t read_addr = 0x00;
	uint32_t end_addr = SRAM_Read_DW(SRAM_NORMAL_Device_List_Addr);
	Device_Public_Information_G BUS_Public;
	RS485_TEMP_INFO Rs485Temp;

	
	memset(&BUS_Public,0,sizeof(Device_Public_Information_G));
	memset(&Rs485Temp,0,sizeof(RS485_TEMP_INFO));
	
	read_addr = Find_AllDevice_List_Information(buff[0],buff[1]);
	
	if( read_addr != 0x00)
	{
		SRAM_DMA_Read_Buff((uint8_t *)&BUS_Public,sizeof(Device_Public_Information_G),read_addr);	
		SRAM_DMA_Read_Buff((uint8_t *)&Rs485Temp,sizeof(RS485_TEMP_INFO),read_addr+Dev_Privately);
		
		Rs485Temp.TemStateNetState = buff[5];
		Rs485Temp.TemStateNetState <<= 8;
		Rs485Temp.TemStateNetState |= buff[4];
		
		Rs485Temp.TemStateNetFlag = 0x01;
		Rs485Temp.TemStateNetCnt = 0x00;
		
		Dbg_Println(DBG_BIT_NET_STATUS_bit,"%s %04x",__func__,Rs485Temp.TemStateNetState);
		
		BUS_Public.check = 0x00;
		BUS_Public.check = DoubleData_CheckSum((uint8_t *)&BUS_Public, sizeof(Device_Public_Information_G), (uint8_t *)&Rs485Temp, sizeof(RS485_TEMP_INFO));
		SRAM_DMA_Write_Buff((uint8_t *)&BUS_Public, sizeof(Device_Public_Information_G),read_addr);/*将数据保存*/
		SRAM_DMA_Write_Buff((uint8_t *)&Rs485Temp,sizeof(RS485_TEMP_INFO),read_addr+Dev_Privately);
		
		return 0x00;		//设置成功
	}
	
	return 0x01;	//设置失败
}

/**
  * @name  		服务器下发设备动作处理函数
  * @param          无
  * @retval 		无
  */
void Udp_Internal_Dev_Control_Processing(void)
{
	static uint32_t udp_dev_Control_tick = 0;
	if(SysTick_1ms - udp_dev_Control_tick > 10)
	{
		udp_dev_Control_tick = SysTick_1ms;
		
		uint32_t write_addr = SRAM_Read_DW(SRAM_UDP_RecvData_Writeaddr);
//		uint32_t dev_addr;
		uint8_t num = 0;
//		, temp = 0,temp1 = 0,temp2 = 0;
//		uint16_t temp3 = 0;
		
		if(write_addr != SRAM_UDP_RecvData_Startaddr)	//写地址不为空表示缓冲区中有数据
		{
			num = SRAM_Read_Byte(SRAM_UDP_RecvData_ControlNum);
			for(uint8_t i=0;i<num;i++)
			{
				{
					uint8_t temp[6];    //设备绝对回路加控制
					
					SRAM_Read_Buff((uint8_t *)&temp, 0x06, SRAM_UDP_RecvData_Startaddr + i*6); //拷贝6个字节
					switch(temp[0])
					{
						case Dev_Host_Invalid:  //场景
						//case Dev_Host_Service:	//控制服务信息
							LOG_LogicInfo_DebugRecord("UDP Control:%02x-%02x-%02x-%02x-%02x-%02x",temp[0],temp[1],temp[2],temp[3],temp[4],temp[5]);
							break;
						case DEV_RS485_TEMP:
							/*2026-02-28 服务器控制温控器，如果当前启用了提示音，本次控制不响应提示音*/
							Find_TempDevice_Set_NetCtrlFlag(temp);
						default:           //其他设备，只要回路不为0，就减1
							
							if(0x00 != temp[2])  //回路不为0
							{
								temp[2]--;
							}
							break;
					}
					DevActionCtrl(temp, 0x06);    //设备场景控制
				}

			}
			
			/*数据处理完毕，写地址归位*/
			write_addr = SRAM_UDP_RecvData_Startaddr;
			SRAM_Write_DW(write_addr,SRAM_UDP_RecvData_Writeaddr);
		}
	}
}

/*************************
**函数名：Udp_Internal_RoomRent_Process
**参  数：data：接受到的数据   len：长度   ip：网络地址  port：端口
**作  用：PC 下发测试命令处理 
	该函数主要是将房态信息保存在映射寄存器中
**返回值：无        
************************/
uint8_t Udp_Internal_RoomRent_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);
	uint16_t frame_id = 0,data_len = 0;
	if(NetCRC16_2(data,DataLen-2) != data_crc) return 0xF0;
	
	uint32_t read_register = 0,temp_data = 0;
	
	frame_id = data[FRAME_NO_OFFSET];
	frame_id |= data[FRAME_NO_OFFSET + 1] << 8;

	data_len = data[FRAME_LEN_OFFSET];
	data_len |= data[FRAME_LEN_OFFSET + 1] << 8;
	
	if(data_len != DataLen)	return 0xF0;		//数据长度不对
	if(data_len < 19)	return 0xF0;			//参数长度不对

	read_register = SRAM_Register_Start_ADDRESS + Register_RoomRent_OFFSET;
	temp_data = SRAM_Read_DW(read_register);
	
	Dbg_Println(DBG_BIT_NET_STATUS_bit,"%s 房态:%d",__func__,data[HEAD_LEN]);
	
	if(data[HEAD_LEN] == 0x02)
	{
		Dbg_Println(DBG_BIT_NET_STATUS_bit,"房间出租");
		
		/*房态发生变化 - 出租与退房，置位首次取电标志位 RCU中存储PMS状态 0x01:入住，0x02:退房 0x03:待租 0x04:空房
			2025-10-27 对应PMS推送的房态信息，设置对应的服务信息回路状态，用于产生对应的事件
		*/
		if(data[HEAD_LEN + 1] == 0x01)	//PMS导致的房态切换，置位首次取电
		{
			ServiceInfo_Set_RoomState(0x01);
		}
		if(temp_data != 0x02)
		{
			temp_data = 0x02;
			SRAM_Write_DW(temp_data,read_register);		//给服务器定期上报房态使用
		}
		
		DevActionGlobal.DevActionU64Cond.RoomState = 0x01;	//给执行动作判断条件使用
	}else if(data[HEAD_LEN] == 0x04)
	{
		Dbg_Println(DBG_BIT_NET_STATUS_bit,"房间待租");
		
		/*房态发生变化 - 出租与退房，置位首次取电标志位 RCU中存储PMS状态 0x01:入住，0x02:退房 0x03:待租 0x04:空房
			2025-10-27 对应PMS推送的房态信息，设置对应的服务信息回路状态，用于产生对应的事件
		*/
		if(data[HEAD_LEN + 1] == 0x01)	//PMS导致的房态切换，
		{
			ServiceInfo_Set_RoomState(0x03);
		}
		if(temp_data != 0x04)
		{
			temp_data = 0x04;
			SRAM_Write_DW(temp_data,read_register);		//给服务器定期上报房态使用
		}
		
		DevActionGlobal.DevActionU64Cond.RoomState = 0x03;	//给执行动作判断条件使用
	}else if(data[HEAD_LEN] == 0x08)
	{
		Dbg_Println(DBG_BIT_NET_STATUS_bit,"房间退房");
		
		/*房态发生变化 - 出租与退房，置位首次取电标志位 RCU中存储PMS状态 0x01:入住，0x02:退房 0x03:待租 0x04:空房
			2025-10-27 对应PMS推送的房态信息，设置对应的服务信息回路状态，用于产生对应的事件
		*/
		if(data[HEAD_LEN + 1] == 0x01)	//PMS导致的房态切换，置位首次取电
		{
			ServiceInfo_Set_RoomState(0x02);
		}
		if(temp_data != 0x08)
		{
			temp_data = 0x08;
			SRAM_Write_DW(temp_data,read_register);		//给服务器定期上报房态使用,服务器下发的状态是什么，定期上报中就一样发送
		}
		
		DevActionGlobal.DevActionU64Cond.RoomState = 0x02;	//给执行动作判断条件使用
	}else if(data[HEAD_LEN] == 0x10)
	{
		Dbg_Println(DBG_BIT_NET_STATUS_bit,"空房");
		
		/*房态发生变化 - 出租与退房，置位首次取电标志位 RCU中存储PMS状态 0x01:入住，0x02:退房 0x03:待租 0x04:空房
			2025-10-27 对应PMS推送的房态信息，设置对应的服务信息回路状态，用于产生对应的事件
		*/
		if(data[HEAD_LEN + 1] == 0x01)	//PMS导致的房态切换
		{
			ServiceInfo_Set_RoomState(0x04);
		}
		if(temp_data != 0x10)
		{
			temp_data = 0x10;
			SRAM_Write_DW(temp_data,read_register);		//给服务器定期上报房态使用
		}
		
		DevActionGlobal.DevActionU64Cond.RoomState = 0x04;	//给执行动作判断条件使用
	}
	
	//Retain_Flash_Register_Data();		//将数据保存到Flash中,房态改变不保存Flash
	
	Udp_Internal_Process_Ack(In_Set_RoomRent_Cmd,frame_id,ip,port);
	
	return 0x00;
}



