Files
RCU_C1P_Module/MCU_Driver/blv_netcomm_function.c
caocong 6e19d0b451 调试:CSIO继电器控制
CSIO继电器控制初步测试OK
2026-01-05 21:17:51 +08:00

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