#include "main.h"
#include "Public.h"
#include "RS485Task.h"
#include "LoraTask.h"
#include "spiflash.h"
#include "CatOneTask.h"
#include <stdlib.h>

//传感器对应的数据长度
const uint8_t SensorTypeDataLen[] = {
	0, 		//0x0000-保留
	30, 		//0x0001-应力场检测单元
	12, 		//0x0002-渗透压检测单元
	14, 		//0x0003-弹性波导检测单元
	10, 		//0x0004-介电质普检测单元
	6,			//0x0005-微振动
	6, 		//0x0006-三维连续变形检测单元
	3,			//0x0007-通讯单元
	18,		//0x0008-三维应力检测单元
	9,			//0x0009-激光示踪(主设备)
	12,		//0x000A-水位计
	0,			//0x000B-保留
	0,			//0x000C-保留
	14,		//0x000D-二维应力场检测单元
	9,			//0x000E-裂缝检测单元
	8,			//0x0010-姿态检测单元
	4,			//0x0011-激光位移检测单元
};

/*****************************************************************************************
* 函数名称: CRC_Modbus
* 功能描述: CRC16计算函数
* 参    数: wBase, 多项式
						Para，校验数据入口
						Data, 校验数据长度入口
* 返 回 值: crc16校验值
*****************************************************************************************/
uint16_t CRC_Modbus(uint16_t wBase, __IO uint8_t *para, uint16_t length)
{
 uint16_t crc = 0xffff;         

 uint16_t index,i;

 for(index = 0 ; index < length;index++) {
   crc ^= para[index];
   for(i = 0; i < 8; i++) {
    if(crc & 1) {
     crc >>= 1;
     crc ^= wBase;
    }
    else
     crc >>= 1;
   }
 }
 return crc;
}

/*****************************************************************************************
* 函数名称: HexToAscii
* 功能描述: HEX转换为ASCII字符串函数
* 参    数: HexData, 16进制数据入口
						ASCData，转换后的ASCII数据
						sLen, 需要转的16进制数据长度
* 返 回 值: 无
*****************************************************************************************/
void HexToAscii(uint8_t *HexData, char *ASCData, uint8_t sLen)
{
	uint8_t temp;
	
	for(int i = 0; i < sLen; i++) {
		temp = (HexData[i] >> 4) & 0x0f;
		if(temp < 10)
			temp += '0';
		else 
			temp = (temp - 10) + 'A';
		
		ASCData[i * 2] = temp;
		
		temp = HexData[i] & 0x0f;
		if(temp < 10)
			temp += '0';
		else 
			temp = (temp - 10) + 'A';
		
		ASCData[i * 2 + 1] = temp;
	}
	ASCData[sLen * 2] = 0;
}

/*****************************************************************************************
* 函数名称: AsciiToHex
* 功能描述: AscII字符串转换为16进制数组
* 参    数: ASCData, AscII字符串入口
						HexData，转换后的数据
						sLen, 需要转的字符串长度
* 返 回 值: 无
*****************************************************************************************/
uint8_t AsciiToHex(char *ASCData, uint8_t *HexData, uint8_t sLen)
{
	char chr;
	uint8_t HexLen = 0;
	
	if(sLen % 2 == 1)
		return 0;
	
	for(int i = 0; i < sLen; i++) {
		chr = ASCData[i];
		if(chr >= '0' && chr <= '9') {
			 HexData[HexLen] |= chr - '0';
		}
		else if(chr >= 'A' && chr <= 'F') {
			HexData[HexLen] |= chr - 'A' + 0x0A;
		}
		else if(chr >= 'a' && chr <= 'f') {
			HexData[HexLen] |= chr - 'a' + 0x0A;
		}
		if(i % 2 == 0) {
			HexData[HexLen] <<= 4;
		}
		else {
			HexLen++;
		}
	}
	return HexLen;
} 

/*****************************************************************************************
* 函数名称: ReadHistoryData
* 功能描述: 读取历史数据
* 参    数: rData,输入数据
            rLen, 输入数据长度
* 返 回 值: 无
*****************************************************************************************/
int ReadHistoryData(LogHeader LogH, uint8_t **Data, int Idx)
{
	return ReadLog(LogH, Data, Idx);
}

/*****************************************************************************************
* 函数名称: NetCommOrgData
* 功能描述: 上报数据组织
* 参    数: MegData, 消息队列数据
						OutData, 输出数据出口
* 返 回 值: 数据长度
*****************************************************************************************/
int NetCommOrgData(GateWayPara GateWay, uint8_t *MegData, uint8_t *OutData)
{
	uint8_t Cmd, *Meg;
	uint16_t check;
	uint16_t Len;
	uint16_t	PayloadLen;
	
	PayloadLen = MegData[0] | (MegData[1] << 8);
	Cmd = MegData[2];
	Meg = &MegData[3];
	
	NetCommFrameHeader NCHeader = (NetCommFrameHeader)OutData;
	
	NCHeader->Header = 0x7A;
	memcpy(NCHeader->GWMac, GateWay->ConfigPara.GwMac, 6);
	//memcpy(NCHeader->SvrMac, GateWay->SvrMac, 6);
	NCHeader->Cmd = Cmd;
	NCHeader->BatLevel = GateWay->Battery;
	NCHeader->Timestamp = TimeTs();
	
	NCHeader->PacketNum = 1;
	NCHeader->PacketIdx = 1;
	NCHeader->PayloadLen = PayloadLen;
	
	Len = sizeof(NetCommFrameHeader_t);
	
	memcpy(&OutData[Len], Meg, NCHeader->PayloadLen);
	Len += NCHeader->PayloadLen;
	
	check =  CRC_Modbus(0xA001, OutData, Len);
	OutData[Len++] = check & 0x00ff;
	OutData[Len++] = (check >> 8) & 0x00ff;
	
	return Len;
}

/*****************************************************************************************
* 函数名称: CheckCommUnitReg
* 功能描述: 检查设备是否注册
* 参    数: GateWay,网关句柄
            CommUnitMac, 待检查的设备MAC
* 返 回 值: 已注册返回true,没注册返回false
*****************************************************************************************/
int CheckCommUnitReg(GateWayPara GateWay, uint8_t *CommUnitMac)
{
	for(int i = 0; i < COMMUNIT_NUM_MAX; i++) {
		if(memcmp(GateWay->ConfigPara.CommUnitArray[i].Mac[0], CommUnitMac, 6) == 0) {
			if(GateWay->ConfigPara.CommUnitArray[i].RegFlag == true)
				return i;
		}
	}
	return -1;
}


/*****************************************************************************************
* 函数名称: CommUnitSendCmd
* 功能描述: 网关下发通讯单元指令函数
* 参    数: GateWay, 网关句柄
						CommUnitMac，通讯单元MAC地址
            Cmd, 命令字
						Payload, 下发数据
						PayloadLen， 下发数据长度
* 返 回 值: 无
*****************************************************************************************/
void CommUnitCmdSend(GateWayPara GateWay, uint8_t *CommUnitMac, CommUnitCmd_m Cmd, uint8_t *Payload, uint16_t PayloadLen, SendData Send)
{
	uint8_t SendBuff[50];
	uint8_t SendLen;
	
	if(PayloadLen > 10)
		return;
	CommUnitFrameHeader CUHeader = (CommUnitFrameHeader)SendBuff;
	
	CUHeader->Header = 0x7B;
	memcpy(CUHeader->GWMac, GateWay->ConfigPara.GwMac, 6);
	if(CommUnitMac == NULL) {
		memset(CUHeader->DevMac, 0x00, 6);
		//CUHeader->DevType = 0x0000;
	}
	else {
		int ret = CheckCommUnitReg(GateWay, CommUnitMac);
		if(ret < 0)
			return;
		memcpy(CUHeader->DevMac, CommUnitMac, 6);
		//CUHeader->DevType = GateWay->ConfigPara.CommUnitArray[ret].CUType;
	}
	CUHeader->Cmd = Cmd;
	CUHeader->PayloadLen = PayloadLen;
	SendLen = sizeof(CommUnitFrameHeader_t);
	if(PayloadLen > 0) {
		memcpy(&SendBuff[SendLen], Payload, PayloadLen);
		SendLen += PayloadLen;
	}
	uint16_t crc16 = CRC_Modbus(0xA001, SendBuff, SendLen);
	SendBuff[SendLen++] = crc16 & 0x00ff;
	SendBuff[SendLen++] = (crc16 >> 8) & 0x00ff;
	
	if(Send != NULL) {
		Send(SendBuff, SendLen);
	}
}

/*****************************************************************************************
* 函数名称: CommUintOrgData
* 功能描述: 上传传感器数据函数
* 参    数: GWMac,网关mac地址
            CUPara, 通讯单元参数
						sData, 数据入口
* 返 回 值: 数据长度
*****************************************************************************************/
int CommUintOrgData(GateWayPara GateWay, CommUnitPara CUPara, CommUnitData CUData, uint8_t *sData)
{
	uint16_t Len = 0;
	uint8_t SensorN = 0;
	
	Len = 3;
	memcpy(&sData[3], CUPara->Mac[0], 6);
	Len += 6;
	sData[Len++] = CUPara->CommStatus;
//	sData[Len++] = CUPara->BatLevel;
//	sData[Len++] = CUPara->SensorN;
	
//	for(int i = 0; i < SENSOR_NUM_MAX; i++) {
//		if(CUPara->SensorType[i] != 0x0000) {
//			sData[Len++] = CUPara->SensorType[i] & 0x00ff;
//			sData[Len++] = (CUPara->SensorType[i] >> 8) & 0x00ff;
//			SensorN++;
//		}
//		if(SensorN >= CUPara->SensorN)
//			break;
//	}
//	SensorN = 0;
	for(int i = 0; i < SENSOR_NUM_MAX; i++) {
		if(CUPara->SensorType[i] != 0x0000) {
			switch(CUPara->SensorType[i]) {
				case FORCE_6D:
					memcpy(&sData[Len], CUData->Data[i], sizeof(Force6D_T));
					Len += sizeof(Force6D_T);
					break;
				case OSMOTIC_PRESSURE:
					break;
				case ELASTIC_WAVEGUIDE:
					break;
				case DIELECTRIC_MASS:
					break;
				case VIBRATE_SENSOR:
					break;
				case CONT_DEFOR_3D:
					break;
				case COMM_UNIT:
					break;
				case FORCE_3D:
					break;
				case LASER_TRACING:
					memcpy(&sData[Len], CUData->Data[i], sizeof(LaserTracingType_t));
					Len += sizeof(LaserTracingType_t);
					break;
				case WATER_LEVEL:
					break;					
				case _0x000B:
					break;	
				case _0x000C:
					break;
				case MULTI_PARAMETER_FUSION:				
					break;
				case  CRACK_DETECTION:
					break;
				case _0x000F:
					break;
				case ATTITUDE_MONITOR:
					break;
				case LASER_DISPLACE:
					break;
				case REBAR_STRESS:
					break;
				case ANCHOR_ROD_STRESS:
					break;
				case SURFACE_STRESS:
					break;
				case PRESSURE:
					break;
				case MICROWAVE_DISPLACE:
					break;
			}
			SensorN++;
		}
		if(SensorN >= CUPara->SensorN)
			break;
	}
	sData[0] = (Len - 3) & 0x00ff;
	sData[1] = ((Len - 3) >> 8) & 0x00ff;
	sData[2] = NET_COMM_CMD_UPDATE;
	return Len;
}

void DebugDisplaySensorData(int SensorIdx, uint16_t SensorType, uint8_t *SensorData)
{
	switch(SensorType) {
		case SENSOR_TYPE_NULL: {
			break;
		}
		case FORCE_6D: {
			Force6D_T Sensor;
			memcpy((uint8_t *)&Sensor, SensorData, sizeof(Force6D_T));
			MAIN_DBG_LOG("Sensor%d Type %04x: Accx=%d, Accy=%d, Accz=%d, Strain1=%d, Strain2=%d, Strain3=%d, Strain4=%d, Strain5=%d, Strain6=%d\r\n", 
										SensorIdx, SensorType, Sensor.AccX, Sensor.AccY, Sensor.AccZ,
										Sensor.Strain1, Sensor.Strain2, Sensor.Strain3, Sensor.Strain4, Sensor.Strain5, Sensor.Strain6);
			break;
		}
		case OSMOTIC_PRESSURE: {
			break;
		}
		case ELASTIC_WAVEGUIDE:{
			break;
		}
		case DIELECTRIC_MASS:{
			break;
		}
		case VIBRATE_SENSOR:{
			break;
		}
		case CONT_DEFOR_3D:{
			break;}
		case COMM_UNIT:{
			break;
		}
		case FORCE_3D: {
			break;
		}
		case LASER_TRACING: {
			LaserTracingType_t Sensor;
			memcpy((uint8_t *)&Sensor, SensorData, sizeof(LaserTracingType_t));
			MAIN_DBG_LOG("Sensor%d Type %04x: PitchAngle=%04d, RollAngle=%04d, YawAngle=%04d\r\n", 
										SensorIdx, SensorType, Sensor.PitchAngle, Sensor.RollAngle, Sensor.YawAngle);
			break;
		}
		case WATER_LEVEL: {
			break;
		}
		case _0x000B: {
			break;
		}
		case _0x000C: {
			break;
		}
		case MULTI_PARAMETER_FUSION: {
			break;
		}
		case CRACK_DETECTION: {
			break;
		}
		case _0x000F: {
			break;
		}
		case ATTITUDE_MONITOR: {
			break;
		}
		case LASER_DISPLACE: {
			break;
		}
		case REBAR_STRESS: {
			break;
		}
		case ANCHOR_ROD_STRESS: {
			break;
		}
		case SURFACE_STRESS: {
			break;
		}
		case PRESSURE: {
			break;
		}
		case MICROWAVE_DISPLACE: {
			break;
		}
		default:
			break;
	}
}

/*****************************************************************************************
* 函数名称: CommUnitAnalyze
* 功能描述: 通讯单元数据解析，使用于LORA和RS485通讯
* 参    数: rData,输入数据
            rLen, 输入数据长度
* 返 回 值: 返回接收到的通讯单元序号，错误返回-1
*****************************************************************************************/
int CommUnitAnalyze(GateWayPara GateWay, uint8_t *rData, uint16_t rLen, SendData Response)
{
	uint16_t check, crc16;
	int CommUnitIdx;
	uint16_t PayLoadLen;
	uint8_t *PayLoad;
	uint8_t *MegData;
	uint16_t len;
	//uint8_t *Data;
	uint16_t CommUintLen;
	
	CommUnitFrameHeader CUHeader = (CommUnitFrameHeader)rData;
	PayLoad = &rData[sizeof(CommUnitFrameHeader_t)];
	
	if(CUHeader->Header != 0x7B)
		return -1;
	
	check = CRC_Modbus(0xA001, rData, rLen - 2);
	crc16 = rData[rLen - 2] | (rData[rLen - 1] << 8);
	
	if(check != crc16)
		return -1;
	
	if((CUHeader->Cmd != COMM_UNIT_CMD_REG) && (memcmp(GateWay->ConfigPara.GwMac, CUHeader->GWMac, 6) != 0))
		return -1;
	
	CommUnitIdx = CheckCommUnitReg(GateWay, CUHeader->DevMac);
	if(CommUnitIdx < 0) {
		if(CUHeader->Cmd != COMM_UNIT_CMD_REG)
			return -1;
	}
	
	switch(CUHeader->Cmd) {
		case COMM_UNIT_CMD_REG:{
			if(PayLoad[0] > SENSOR_NUM_MAX) {
				return -1;
			}
			
//			if(CUHeader->PayloadLen < 2)
//				return -1;
			
			if(CommUnitIdx >= 0) {		//设备存在
				MAIN_DBG_LOG("\r\nCommUnit has already been registered! Mac:%02X-%02X-%02X-%02X-%02X-%02X\r\n",
									CUHeader->DevMac[0], CUHeader->DevMac[1], CUHeader->DevMac[2], CUHeader->DevMac[3], CUHeader->DevMac[4], CUHeader->DevMac[5]);
				uint8_t ret = 1;
				GateWay->ConfigPara.CommUnitArray[CommUnitIdx].CommErrCnt = 0;
				GateWay->ConfigPara.CommUnitArray[CommUnitIdx].ConfigFlag = true;
				GateWay->ConfigPara.CommUnitArray[CommUnitIdx].CailFlag = false;
				GateWay->ConfigPara.CommUnitArray[CommUnitIdx].TimeSyncFlag = false;
				GateWay->ConfigPara.CommUnitArray[CommUnitIdx].ContLaser = false;
				GateWay->ConfigPara.CommUnitArray[CommUnitIdx].LaserOnOff = false;
				CommUnitCmdSend(GateWay, CUHeader->DevMac, COMM_UNIT_CMD_REG, &ret, 1, Response);
				WritePara((uint8_t *)&GateWay->ConfigPara, sizeof(GWConfigPara_t));
				return CommUnitIdx;
			}
			for(int i = 0; i < COMMUNIT_NUM_MAX; i++) {
				if(GateWay->ConfigPara.CommUnitArray[i].RegFlag == false) {
					CommUnitIdx = i;
					GateWay->ConfigPara.CommUnitArray[i].RegFlag = true;
					GateWay->ConfigPara.CommUnitArray[i].CommStatus = true;
					GateWay->ConfigPara.CommUnitArray[i].CailFlag = false;
					GateWay->ConfigPara.CommUnitArray[i].TimeSyncFlag = false;
					GateWay->ConfigPara.CommUnitArray[i].ContLaser = false;
					GateWay->ConfigPara.CommUnitArray[i].LaserOnOff = false;
					
					GateWay->ConfigPara.CommUnitArray[i].CUType = DEV_TYPE_EXT_COMMUNIT;//外置通讯单元
					MAIN_DBG_LOG("\r\nCommUnit register succeed!\r\n");
					
					memcpy(GateWay->ConfigPara.CommUnitArray[i].MasterMac, &PayLoad[1], 6);
					MAIN_DBG_LOG("Mac:%02X-%02X-%02X-%02X-%02X-%02X\r\n",CUHeader->DevMac[0], CUHeader->DevMac[1], CUHeader->DevMac[2], CUHeader->DevMac[3], CUHeader->DevMac[4], CUHeader->DevMac[5]);
					
					GateWay->ConfigPara.CommUnitArray[i].SensorN = PayLoad[0];
					MAIN_DBG_LOG("SensorN: %d ", GateWay->ConfigPara.CommUnitArray[i].SensorN);
					//memcpy(GateWay->ConfigPara.CommUnitArray[i].SensorType, &PayLoad[1], CUHeader->PayloadLen-1);
					MAIN_DBG_LOG("Sensor Type: ");
					for(int j = 0; j < GateWay->ConfigPara.CommUnitArray[i].SensorN; j++) {
						memcpy(GateWay->ConfigPara.CommUnitArray[i].Mac[j], &PayLoad[(j*6)+1], 6);
						GateWay->ConfigPara.CommUnitArray[i].SensorType[j] = PayLoad[(j*6)+1] | (PayLoad[(j*6)+2] << 8);
						MAIN_DBG_LOG("0x%04x, ", GateWay->ConfigPara.CommUnitArray[i].SensorType[j]);
					}
					MAIN_DBG_LOG("\r\n");
					GateWay->ConfigPara.CommUnitArray[i].CommErrCnt = 0;
					GateWay->ConfigPara.CommUnitArray[i].ConfigFlag = true;
					GateWay->ConfigPara.CommUnitArray[i].CollectInterval = LW_DEV_COLLECT_INTERVAL_MAX;
					GateWay->ConfigPara.CommUnitArray[i].ReportInterval = LW_DEV_REPORT_INTERVAL_MAX;
					GateWay->ConfigPara.CommUnitArray[i].ERInterval = LW_DEV_ER_INTERVAL_MAX;
					GateWay->ConfigPara.CommUnitArray[i].ERTime = LW_DEV_ER_TIME_MAX;
					WritePara((uint8_t *)&GateWay->ConfigPara, sizeof(GWConfigPara_t));
					uint8_t ret = 1;
					CommUnitCmdSend(GateWay, CUHeader->DevMac, COMM_UNIT_CMD_REG, &ret, 1, Response);
					
					if(GateWay->SvrRegFlag) {	//网关已注册，向服务发送新设备添加指令
						PayLoadLen = (GateWay->ConfigPara.CommUnitArray[i].SensorN * 6) + 2;
						MegData = rt_malloc(PayLoadLen + 3);
						MegData[0] = PayLoadLen & 0x00ff;;
						MegData[1] = (PayLoadLen >> 8) & 0x00ff;
						MegData[2] = NET_COMM_CMD_ADD_UNIT;
						for(uint8_t i = 0; i < GateWay->ConfigPara.CommUnitArray[i].SensorN; i++)
						{
							memcpy(&MegData[3], GateWay->ConfigPara.CommUnitArray[i].Mac[i], 6);
						}
						CatOneEthSendQueue(MegData, PayLoadLen+3);
						rt_free(MegData);
					}
					return 0xff;
				}
			}
			MAIN_DBG_LOG("\r\nCommUnit register failed! Mac:%02X-%02X-%02X-%02X-%02X-%02X\r\n",
									CUHeader->DevMac[0], CUHeader->DevMac[1], CUHeader->DevMac[2], CUHeader->DevMac[3], CUHeader->DevMac[4], CUHeader->DevMac[5]);
			break;}
			
		case COMM_UNIT_CMD_CAIL:{
			if(PayLoad[0] == 0) {
				GateWay->ConfigPara.CommUnitArray[CommUnitIdx].CailFlag = true;
				MAIN_DBG_LOG("CommUnit calibrate failed! Mac:%02X-%02X-%02X-%02X-%02X-%02X\r\n",
									CUHeader->DevMac[0], CUHeader->DevMac[1], CUHeader->DevMac[2], CUHeader->DevMac[3], CUHeader->DevMac[4], CUHeader->DevMac[5]);
			} 
			else if(PayLoad[0] == 1){
				GateWay->ConfigPara.CommUnitArray[CommUnitIdx].CailFlag = false;
				MAIN_DBG_LOG("CommUnit calibrate succeed! Mac:%02X-%02X-%02X-%02X-%02X-%02X\r\n",
									CUHeader->DevMac[0], CUHeader->DevMac[1], CUHeader->DevMac[2], CUHeader->DevMac[3], CUHeader->DevMac[4], CUHeader->DevMac[5]);
			}
			uint32_t ctime = TimeTs();
			if(GateWay->ConfigPara.CommUnitArray[CommUnitIdx].ConfigFlag == true) {
				GateWay->ConfigPara.CommUnitArray[CommUnitIdx].ConfigFlag = false;
				LPDevConfigPara_t Config;
				Config.CollectInterval = GateWay->ConfigPara.CommUnitArray[CommUnitIdx].CollectInterval;
				Config.ReportInterval = GateWay->ConfigPara.CommUnitArray[CommUnitIdx].ReportInterval;
				Config.ERInterval = GateWay->ConfigPara.CommUnitArray[CommUnitIdx].ERInterval;
				Config.ERTime = GateWay->ConfigPara.CommUnitArray[CommUnitIdx].ERTime;
				Config.TimeStamp = ctime;
				MAIN_DBG_LOG("CI:%d, RI:%d, EI:%d, ET:%d\r\n", Config.CollectInterval, Config.ReportInterval, Config.ERInterval, Config.ERTime);
				CommUnitCmdSend(GateWay, CUHeader->DevMac, COMM_UNIT_CMD_READ, (uint8_t *)&Config, sizeof(LPDevConfigPara_t), Response);	
			}
			else if(GateWay->ConfigPara.CommUnitArray[CommUnitIdx].ContLaser == true)
			{
				if(GateWay->ConfigPara.CommUnitArray[CommUnitIdx].LaserOnOff == true)
				{//打开激光
					CommUnitCmdSend(GateWay, CUHeader->DevMac, COMM_UNIT_CMD_CONT_LASER, (uint8_t *)&GateWay->ConfigPara.CommUnitArray[CommUnitIdx].LaserOnOff, 1, Response);	
				}
				MAIN_DBG_LOG("Issue laser control commands.\r\n");
			}
			else if(GateWay->ConfigPara.CommUnitArray[CommUnitIdx].CailFlag == true)
			{
				CommUnitCmdSend(GateWay, CUHeader->DevMac, COMM_UNIT_CMD_CAIL, 0, 0, Response);	
				MAIN_DBG_LOG("Issue calibration instructions.\r\n");
			}
			else if(GateWay->ConfigPara.CommUnitArray[CommUnitIdx].TimeSyncFlag == true)
			{
				CommUnitCmdSend(GateWay, CUHeader->DevMac, COMM_UNIT_CMD_TIME_SYNC, (uint8_t *)&ctime, 4, Response);	
				MAIN_DBG_LOG("Issue a time synchronization command.\r\n");
			}
			WritePara((uint8_t *)&GateWay->ConfigPara, sizeof(GWConfigPara_t));
			break;}
			
		case COMM_UNIT_CMD_READ:{
//			if(PayLoad[1] > SENSOR_NUM_MAX) {
//				return CommUnitIdx;
//			}
			GateWay->ConfigPara.CommUnitArray[CommUnitIdx].CommStatus = true;
			GateWay->ConfigPara.CommUnitArray[CommUnitIdx].RevNewDataFlag = true;
			GateWay->ConfigPara.CommUnitArray[CommUnitIdx].CommErrCnt = 0;
			GateWay->ConfigPara.CommUnitArray[CommUnitIdx].BatLevel = PayLoad[0];
			GateWay->ConfigPara.CommUnitArray[CommUnitIdx].RSSI = PayLoad[1];
			GateWay->ConfigPara.CommUnitArray[CommUnitIdx].Nsr = PayLoad[2];
//			memset(GateWay->ConfigPara.CommUnitArray[CommUnitIdx].SensorType, 0x00, sizeof(GateWay->ConfigPara.CommUnitArray[CommUnitIdx].SensorType));
//			memcpy(GateWay->ConfigPara.CommUnitArray[CommUnitIdx].SensorType, &PayLoad[2], GateWay->ConfigPara.CommUnitArray[CommUnitIdx].SensorN * 2);
//			len = 0;
//			Data = &PayLoad[GateWay->ConfigPara.CommUnitArray[CommUnitIdx].SensorN * 2 + 2];
//			int16_t Rssi;
//			int8_t Snr;
//			SX1276LoCalcRssiSnr(&Rssi, &Snr);
			MAIN_DBG_LOG("\r\nCUMac:%02X-%02X-%02X-%02X-%02X-%02X, Bat: %d%, SN: %d，Rssi:%d, Snr:%d\r\n", 
										CUHeader->DevMac[0], CUHeader->DevMac[1], CUHeader->DevMac[2], CUHeader->DevMac[3], CUHeader->DevMac[4], CUHeader->DevMac[5], 
										GateWay->ConfigPara.CommUnitArray[CommUnitIdx].BatLevel, 
										GateWay->ConfigPara.CommUnitArray[CommUnitIdx].SensorN, 
										GateWay->ConfigPara.CommUnitArray[CommUnitIdx].RSSI, 
										GateWay->ConfigPara.CommUnitArray[CommUnitIdx].Nsr);
			for(int i = 0; i < GateWay->ConfigPara.CommUnitArray[CommUnitIdx].SensorN; i++) {
				memcpy(GateWay->CUDataArray[CommUnitIdx].Data[i], &PayLoad[0], SensorTypeDataLen[GateWay->ConfigPara.CommUnitArray[CommUnitIdx].SensorType[i]]);
				//显示传感器数据
				DebugDisplaySensorData(i, GateWay->ConfigPara.CommUnitArray[CommUnitIdx].SensorType[i], GateWay->CUDataArray[CommUnitIdx].Data[i]);
				len += SensorTypeDataLen[GateWay->ConfigPara.CommUnitArray[CommUnitIdx].SensorType[i]];
			}
#ifdef LORA_LOWPOWER
			uint32_t ctime = TimeTs();
			LPDevConfigPara_t Config;
			if(GateWay->ConfigPara.CommUnitArray[CommUnitIdx].CollectInterval > 7200 || GateWay->ConfigPara.CommUnitArray[CommUnitIdx].CollectInterval < 30)
			{
				GateWay->ConfigPara.CommUnitArray[CommUnitIdx].CollectInterval = 300;
				GateWay->ConfigPara.CommUnitArray[CommUnitIdx].ConfigFlag = true;
			}
			if(GateWay->ConfigPara.CommUnitArray[CommUnitIdx].ReportInterval > 720 || GateWay->ConfigPara.CommUnitArray[CommUnitIdx].ReportInterval < 5)
			{	
				GateWay->ConfigPara.CommUnitArray[CommUnitIdx].ReportInterval = 20;
				GateWay->ConfigPara.CommUnitArray[CommUnitIdx].ConfigFlag = true;
			}
			if(GateWay->ConfigPara.CommUnitArray[CommUnitIdx].ERInterval > 5 || GateWay->ConfigPara.CommUnitArray[CommUnitIdx].ERInterval < 1)
			{
				GateWay->ConfigPara.CommUnitArray[CommUnitIdx].ERInterval = 2;
				GateWay->ConfigPara.CommUnitArray[CommUnitIdx].ConfigFlag = true;
			}
			if(GateWay->ConfigPara.CommUnitArray[CommUnitIdx].ERTime > 120 || GateWay->ConfigPara.CommUnitArray[CommUnitIdx].ERTime < 10)
			{
				GateWay->ConfigPara.CommUnitArray[CommUnitIdx].ERTime = 20;
				GateWay->ConfigPara.CommUnitArray[CommUnitIdx].ConfigFlag = true;
			}
			if(GateWay->ConfigPara.CommUnitArray[CommUnitIdx].ConfigFlag == true) {
				GateWay->ConfigPara.CommUnitArray[CommUnitIdx].ConfigFlag = false;
				Config.CollectInterval = GateWay->ConfigPara.CommUnitArray[CommUnitIdx].CollectInterval;
				Config.ReportInterval = GateWay->ConfigPara.CommUnitArray[CommUnitIdx].ReportInterval;
				Config.ERInterval = GateWay->ConfigPara.CommUnitArray[CommUnitIdx].ERInterval;
				Config.ERTime = GateWay->ConfigPara.CommUnitArray[CommUnitIdx].ERTime;
				Config.TimeStamp = ctime;
				MAIN_DBG_LOG("CI:%d, RI:%d, EI:%d, ET:%d\r\n", Config.CollectInterval, Config.ReportInterval, Config.ERInterval, Config.ERTime);
				CommUnitCmdSend(GateWay, CUHeader->DevMac, COMM_UNIT_CMD_READ, (uint8_t *)&Config, sizeof(LPDevConfigPara_t), Response);	
			}
			else if(GateWay->ConfigPara.CommUnitArray[CommUnitIdx].ContLaser == true)
			{
				if(GateWay->ConfigPara.CommUnitArray[CommUnitIdx].LaserOnOff == true)
				{//打开激光
					CommUnitCmdSend(GateWay, CUHeader->DevMac, COMM_UNIT_CMD_CONT_LASER, (uint8_t *)&GateWay->ConfigPara.CommUnitArray[CommUnitIdx].LaserOnOff, 1, Response);	
				}
				MAIN_DBG_LOG("Issue laser control commands.\r\n");
			}
			else if(GateWay->ConfigPara.CommUnitArray[CommUnitIdx].CailFlag == true)
			{
				CommUnitCmdSend(GateWay, CUHeader->DevMac, COMM_UNIT_CMD_CAIL, 0, 0, Response);	
				MAIN_DBG_LOG("Issue calibration instructions.\r\n");
			}
			else if(GateWay->ConfigPara.CommUnitArray[CommUnitIdx].TimeSyncFlag == true)
			{
				CommUnitCmdSend(GateWay, CUHeader->DevMac, COMM_UNIT_CMD_TIME_SYNC, (uint8_t *)&ctime, 4, Response);	
				MAIN_DBG_LOG("Issue a time synchronization command.\r\n");
			}
			else 
				CommUnitCmdSend(GateWay, CUHeader->DevMac, COMM_UNIT_CMD_READ, (uint8_t *)&ctime, 4, Response);	
#endif
			MegData = rt_malloc(512);
			CommUintLen = CommUintOrgData(GateWay, &GateWay->ConfigPara.CommUnitArray[CommUnitIdx], &GateWay->CUDataArray[CommUnitIdx], MegData);
			//AddLog(&MegData[2], CommUintLen);
			CatOneEthSendQueue(MegData, CommUintLen);
			rt_free(MegData);
			WritePara((uint8_t *)&GateWay->ConfigPara, sizeof(GWConfigPara_t));
			break;}

		case COMM_UNIT_CMD_TIME_SYNC:{
			if(PayLoad[0] == 0) {
				GateWay->ConfigPara.CommUnitArray[CommUnitIdx].TimeSyncFlag = true;
				MAIN_DBG_LOG("CommUnit time synchronization failed! Mac:%02X-%02X-%02X-%02X-%02X-%02X\r\n",
									CUHeader->DevMac[0], CUHeader->DevMac[1], CUHeader->DevMac[2], CUHeader->DevMac[3], CUHeader->DevMac[4], CUHeader->DevMac[5]);
			} 
			else if(PayLoad[0] == 1){
				GateWay->ConfigPara.CommUnitArray[CommUnitIdx].TimeSyncFlag = false;
				MAIN_DBG_LOG("CommUnit time synchronization succeed! Mac:%02X-%02X-%02X-%02X-%02X-%02X\r\n",
									CUHeader->DevMac[0], CUHeader->DevMac[1], CUHeader->DevMac[2], CUHeader->DevMac[3], CUHeader->DevMac[4], CUHeader->DevMac[5]);
			}
			uint32_t ctime = TimeTs();
			if(GateWay->ConfigPara.CommUnitArray[CommUnitIdx].ConfigFlag == true) {
				GateWay->ConfigPara.CommUnitArray[CommUnitIdx].ConfigFlag = false;
				LPDevConfigPara_t Config;
				Config.CollectInterval = GateWay->ConfigPara.CommUnitArray[CommUnitIdx].CollectInterval;
				Config.ReportInterval = GateWay->ConfigPara.CommUnitArray[CommUnitIdx].ReportInterval;
				Config.ERInterval = GateWay->ConfigPara.CommUnitArray[CommUnitIdx].ERInterval;
				Config.ERTime = GateWay->ConfigPara.CommUnitArray[CommUnitIdx].ERTime;
				Config.TimeStamp = ctime;
				MAIN_DBG_LOG("CI:%d, RI:%d, EI:%d, ET:%d\r\n", Config.CollectInterval, Config.ReportInterval, Config.ERInterval, Config.ERTime);
				CommUnitCmdSend(GateWay, CUHeader->DevMac, COMM_UNIT_CMD_READ, (uint8_t *)&Config, sizeof(LPDevConfigPara_t), Response);	
			}
			else if(GateWay->ConfigPara.CommUnitArray[CommUnitIdx].ContLaser == true)
			{
				if(GateWay->ConfigPara.CommUnitArray[CommUnitIdx].LaserOnOff == true)
				{//打开激光
					CommUnitCmdSend(GateWay, CUHeader->DevMac, COMM_UNIT_CMD_CONT_LASER, (uint8_t *)&GateWay->ConfigPara.CommUnitArray[CommUnitIdx].LaserOnOff, 1, Response);	
				}
				MAIN_DBG_LOG("Issue laser control commands.\r\n");
			}
			else if(GateWay->ConfigPara.CommUnitArray[CommUnitIdx].CailFlag == true)
			{
				CommUnitCmdSend(GateWay, CUHeader->DevMac, COMM_UNIT_CMD_CAIL, 0, 0, Response);	
				MAIN_DBG_LOG("Issue calibration instructions.\r\n");
			}
			else if(GateWay->ConfigPara.CommUnitArray[CommUnitIdx].TimeSyncFlag == true)
			{
				CommUnitCmdSend(GateWay, CUHeader->DevMac, COMM_UNIT_CMD_TIME_SYNC, (uint8_t *)&ctime, 4, Response);	
				MAIN_DBG_LOG("Issue a time synchronization command.\r\n");
			}
			WritePara((uint8_t *)&GateWay->ConfigPara, sizeof(GWConfigPara_t));
			break;}

		case COMM_UNIT_CMD_CONT_LASER:{
			if(PayLoad[0] == 0) {
				//应答服务器
				MegData = rt_malloc(10);
				MegData[0] = 7;
				MegData[1] = 0;
				MegData[2] = NET_COMM_CMD_CONT_LASER;
				MegData[3] = CUHeader->DevMac[0];
				MegData[4] = CUHeader->DevMac[1];
				MegData[5] = CUHeader->DevMac[2];
				MegData[6] = CUHeader->DevMac[3];
				MegData[7] = CUHeader->DevMac[4];
				MegData[8] = CUHeader->DevMac[5];
				MegData[9] = PayLoad[0];
				CatOneEthSendQueue(MegData, 10);
				rt_free(MegData);
				GateWay->ConfigPara.CommUnitArray[CommUnitIdx].ContLaser = false;
				MAIN_DBG_LOG("CommUnit The laser has been turned off! Mac:%02X-%02X-%02X-%02X-%02X-%02X\r\n",
									CUHeader->DevMac[0], CUHeader->DevMac[1], CUHeader->DevMac[2], CUHeader->DevMac[3], CUHeader->DevMac[4], CUHeader->DevMac[5]);
			}
			else if(PayLoad[0] == 1){
				//应答服务器
				MegData = rt_malloc(10);
				MegData[0] = 7;
				MegData[1] = 0;
				MegData[2] = NET_COMM_CMD_CONT_LASER;
				MegData[3] = CUHeader->DevMac[0];
				MegData[4] = CUHeader->DevMac[1];
				MegData[5] = CUHeader->DevMac[2];
				MegData[6] = CUHeader->DevMac[3];
				MegData[7] = CUHeader->DevMac[4];
				MegData[8] = CUHeader->DevMac[5];
				MegData[9] = PayLoad[0];
				CatOneEthSendQueue(MegData, 10);
				rt_free(MegData);
				GateWay->ConfigPara.CommUnitArray[CommUnitIdx].ContLaser = false;
				MAIN_DBG_LOG("CommUnit The laser has been activated! Mac:%02X-%02X-%02X-%02X-%02X-%02X\r\n",
									CUHeader->DevMac[0], CUHeader->DevMac[1], CUHeader->DevMac[2], CUHeader->DevMac[3], CUHeader->DevMac[4], CUHeader->DevMac[5]);
			}
			uint32_t ctime = TimeTs();
			if(GateWay->ConfigPara.CommUnitArray[CommUnitIdx].ConfigFlag == true) {
				GateWay->ConfigPara.CommUnitArray[CommUnitIdx].ConfigFlag = false;
				LPDevConfigPara_t Config;
				Config.CollectInterval = GateWay->ConfigPara.CommUnitArray[CommUnitIdx].CollectInterval;
				Config.ReportInterval = GateWay->ConfigPara.CommUnitArray[CommUnitIdx].ReportInterval;
				Config.ERInterval = GateWay->ConfigPara.CommUnitArray[CommUnitIdx].ERInterval;
				Config.ERTime = GateWay->ConfigPara.CommUnitArray[CommUnitIdx].ERTime;
				Config.TimeStamp = ctime;
				MAIN_DBG_LOG("CI:%d, RI:%d, EI:%d, ET:%d\r\n", Config.CollectInterval, Config.ReportInterval, Config.ERInterval, Config.ERTime);
				CommUnitCmdSend(GateWay, CUHeader->DevMac, COMM_UNIT_CMD_READ, (uint8_t *)&Config, sizeof(LPDevConfigPara_t), Response);	
			}
			else if(GateWay->ConfigPara.CommUnitArray[CommUnitIdx].ContLaser == true)
			{
				if(GateWay->ConfigPara.CommUnitArray[CommUnitIdx].LaserOnOff == true)
				{//打开激光
					CommUnitCmdSend(GateWay, CUHeader->DevMac, COMM_UNIT_CMD_CONT_LASER, (uint8_t *)&GateWay->ConfigPara.CommUnitArray[CommUnitIdx].LaserOnOff, 1, Response);	
				}
				MAIN_DBG_LOG("Issue laser control commands.\r\n");
			}
			else if(GateWay->ConfigPara.CommUnitArray[CommUnitIdx].CailFlag == true)
			{
				CommUnitCmdSend(GateWay, CUHeader->DevMac, COMM_UNIT_CMD_CAIL, 0, 0, Response);	
				MAIN_DBG_LOG("Issue calibration instructions.\r\n");
			}
			else if(GateWay->ConfigPara.CommUnitArray[CommUnitIdx].TimeSyncFlag == true)
			{
				CommUnitCmdSend(GateWay, CUHeader->DevMac, COMM_UNIT_CMD_TIME_SYNC, (uint8_t *)&ctime, 4, Response);	
				MAIN_DBG_LOG("Issue a time synchronization command.\r\n");
			}
			WritePara((uint8_t *)&GateWay->ConfigPara, sizeof(GWConfigPara_t));
			break;}			
		
		default:
			break;
	}
	return CommUnitIdx;
}

/*****************************************************************************************
* 函数名称: Cat1RevCallBack
* 功能描述: 4G接收回调函数
* 参    数: rData，数据输入接口
            rLen,  数据长度输入接口
* 返 回 值: 无
*****************************************************************************************/
int Cat1EthRevCallBack(GateWayPara GateWay, uint8_t *rData, uint16_t rLen)
{
	uint16_t check,crc16;
	uint8_t *Data;
	uint8_t *MegData;
	uint8_t sLen;
	
	uint8_t CommUintMac[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
	
	NetCommFrameHeader NCHeader = (NetCommFrameHeader)rData;
	
	uint16_t FrameLen = sizeof(NetCommFrameHeader_t) + NCHeader->PayloadLen;
	if(FrameLen > CAT_ONE_REV_LEN_MAX)
		return -1;
	if(NCHeader->Header != 0x7A)
		return -1;
	if(memcmp(NCHeader->GWMac, GateWay->ConfigPara.GwMac, 6) != 0x00)
		return -1;

	
	check = CRC_Modbus(0xA001, rData, FrameLen);
	crc16 = rData[FrameLen] | (rData[FrameLen + 1] << 8);
	Data = &rData[sizeof(NetCommFrameHeader_t)];
	
	if(check != crc16)
		return -1;
	
	uint32_t cTime = TimeTs();
	if(abs((int)(NCHeader->Timestamp - cTime)) > 2) {
		TimeSync(NCHeader->Timestamp);
		GateWay->TimeSyncFlag = true;
		SensorCommPara_t SCPara;
		SCPara.Cmd = RS485_SENSOR_CMD_TIME_SYNC;
		SCPara.SensorAddr = 0x00;
		SCPara.SensorType = 0x00;
		SCPara.CmdParaLen = 4;
		SCPara.CmdPara = (uint8_t *)&NCHeader->Timestamp;
		
		memcpy(&CommUintMac[0], Data, 6);
		
		if(GateWay->ConfigPara.Rs485Ch1.Enable == true) {	//内部通讯单元处理
			if(GateWay->ConfigPara.Rs485Ch1.CommUnitEnable == true)
				CommUnitCmdSend(GateWay, CommUintMac, COMM_UNIT_CMD_TIME_SYNC, &rData[14], 4, GateWay->ConfigPara.Rs485Ch1.RS485Send);			
			else 
				RS485CmdSend(GateWay, 1, &SCPara);
		}
		if(GateWay->ConfigPara.Rs485Ch2.Enable == true) {
			if(GateWay->ConfigPara.Rs485Ch2.CommUnitEnable == true)
				CommUnitCmdSend(GateWay, CommUintMac, COMM_UNIT_CMD_TIME_SYNC, &rData[14], 4, GateWay->ConfigPara.Rs485Ch2.RS485Send);
			else 
				RS485CmdSend(GateWay, 2, &SCPara);
		}
		for(int i = 0; i < COMMUNIT_NUM_MAX; i++)//参数遍历
		{
			if(GateWay->ConfigPara.CommUnitArray[i].RegFlag == true)
				GateWay->ConfigPara.CommUnitArray[i].TimeSyncFlag = true;//校时置位，等待下次此MAC主设备上传数据时下发校准指令（低功耗）
		}
		//校准其他通讯网关
		//CommUnitCmdSend(GateWay, CommUintMac, COMM_UNIT_CMD_TIME_SYNC, &rData[14], 4, Sx1276LoRaSendBuffer);
	}

	switch(NCHeader->Cmd) {
		case NET_COMM_CMD_REG:{
			if(*Data == 1) {	//注册成功
				GateWay->SvrRegFlag = true;
				//memcpy(GateWay->SvrMac, NCHeader->SvrMac, 6);
				memset(GateWay->SvrMac, 0x00, 6);
				WritePara((uint8_t *)&GateWay->ConfigPara, sizeof(GWConfigPara_t));
				MAIN_DBG_LOG("Gateway Registered...\r\n");
			}
			else {
				GateWay->SvrRegFlag = false;
				memset(GateWay->SvrMac, 0x00, 6);
				MAIN_DBG_LOG("Gateway Register Failed....\r\n");
			}
			break;}
			
		case NET_COMM_CMD_CAIL:{
			//应答服务器
			MegData = rt_malloc(4);
			MegData[0] = 1;
			MegData[1] = 0;
			MegData[2] = NET_COMM_CMD_CAIL;
			MegData[3] = 1;
			sLen = 4;
			CatOneEthSendQueue(MegData, sLen);
			rt_free(MegData);
			//开始校准
			memcpy(&CommUintMac[0], Data, 6);
			if(memcmp(CommUintMac, Data, 6) == 0) {	//校准所有传感器
				SensorCommPara_t SCPara;
				SCPara.Cmd = RS485_SENSOR_CMD_CAIL;
				SCPara.SensorAddr = 0x00;
				//SCPara.SensorType = 0x00;
				SCPara.CmdParaLen = 0;
				SCPara.CmdPara = NULL;
				if(GateWay->ConfigPara.Rs485Ch1.Enable == true) {	//内部通讯单元处理
					if(GateWay->ConfigPara.Rs485Ch1.CommUnitEnable == true)
						RS485CmdSend(GateWay, 1, &SCPara);
					else 
					  CommUnitCmdSend(GateWay, CommUintMac, COMM_UNIT_CMD_CAIL, NULL, 0, GateWay->ConfigPara.Rs485Ch1.RS485Send);
				}
				if(GateWay->ConfigPara.Rs485Ch2.Enable == true) {
					if(GateWay->ConfigPara.Rs485Ch1.CommUnitEnable == true)
						RS485CmdSend(GateWay, 2, &SCPara);
					else 
					  CommUnitCmdSend(GateWay, CommUintMac, COMM_UNIT_CMD_CAIL, NULL, 0, GateWay->ConfigPara.Rs485Ch2.RS485Send);
				}
				
				for(int i = 0; i < COMMUNIT_NUM_MAX; i++)//参数遍历
				{
					if(GateWay->ConfigPara.CommUnitArray[i].RegFlag == true)
						GateWay->ConfigPara.CommUnitArray[i].CailFlag = true;//校准置位，等待下次此MAC主设备上传数据时下发校准指令（低功耗）
				}
				//校准其他通讯网关
				//CommUnitCmdSend(GateWay, CommUintMac, COMM_UNIT_CMD_CAIL, NULL, 0, Sx1276LoRaSendBuffer);
				MAIN_DBG_LOG("Calibrate all device.\r\n");
			}
			else {
				int ret = CheckCommUnitReg(GateWay, CommUintMac);
				if(ret < 0)
					return -1;
				if(GateWay->ConfigPara.CommUnitArray[ret].CUType !=  DEV_TYPE_EXT_COMMUNIT)
					return -1;
				if((GateWay->ConfigPara.CommUnitArray[ret].Mac[0][3] / 0x80) != 1) {//判断是否为通讯单元（主设备）
					if(GateWay->ConfigPara.CommUnitArray[ret].Mac[0][2] == 1)//判断通讯类型
					{
						GateWay->ConfigPara.CommUnitArray[ret].CailFlag = true;//校准置位，等待下次此MAC主设备上传数据时下发校准指令（低功耗）
						//CommUnitCmdSend(GateWay, CommUintMac, COMM_UNIT_CMD_CAIL, NULL, 0, Sx1276LoRaSendBuffer);//查询模式
						MAIN_DBG_LOG("Calibrate Mac:%02X-%02X-%02X-%02X-%02X-%02X\r\n",
							CommUintMac[0], CommUintMac[1], CommUintMac[2], CommUintMac[3], CommUintMac[4], CommUintMac[5]);
					}
					else if(GateWay->ConfigPara.CommUnitArray[ret].Mac[0][2] == 2)//判断通讯类型
					{
						if(GateWay->ConfigPara.Rs485Ch1.Enable == true && !GateWay->ConfigPara.Rs485Ch1.CommUnitEnable) 
						{
							CommUnitCmdSend(GateWay, CommUintMac, COMM_UNIT_CMD_CAIL, NULL, 0, GateWay->ConfigPara.Rs485Ch1.RS485Send);
						}
						else if(GateWay->ConfigPara.Rs485Ch2.Enable == true && !GateWay->ConfigPara.Rs485Ch2.CommUnitEnable)
						{
							CommUnitCmdSend(GateWay, CommUintMac, COMM_UNIT_CMD_CAIL, NULL, 0, GateWay->ConfigPara.Rs485Ch2.RS485Send);
						}
					}
				}
			}
			break;}
		
		case NET_COMM_CMD_UPDATE:{
			MAIN_DBG_LOG("Received server response.....\r\n");
			break;}
		
		case NET_COMM_CMD_READ_GW_INFO: {
			MegData = rt_malloc(512);
			uint16_t SensorCnt = 0;
			sLen = 5;
			if(GateWay->ConfigPara.Rs485Ch1.Enable == true) {	//内部通讯单元处理
				if(GateWay->ConfigPara.Rs485Ch1.CommUnitEnable == true) {
					SensorCnt++;
					memcpy(&MegData[sLen], GateWay->ConfigPara.Rs485Ch1.CUData.Para.Mac[0], 6);
					sLen += 6;
				}
			}
			if(GateWay->ConfigPara.Rs485Ch2.Enable == true) {
				if(GateWay->ConfigPara.Rs485Ch2.CommUnitEnable == true) {
					SensorCnt++;
					memcpy(&MegData[sLen], GateWay->ConfigPara.Rs485Ch2.CUData.Para.Mac[0], 6);
					sLen += 6;
				}
			}
			for(int i = 0; i < COMMUNIT_NUM_MAX; i++) {
				if(GateWay->ConfigPara.CommUnitArray[i].RegFlag) {
					for(int j = 0; j < GateWay->ConfigPara.CommUnitArray[i].SensorN; j++)
					{
						SensorCnt++;
						memcpy(&MegData[sLen], GateWay->ConfigPara.CommUnitArray[i].Mac[j], 6);
						sLen += 6;
					}
				}
			}
			MegData[sLen++] = GateWay->Battery;
			MegData[sLen++] = GateWay->UploadInterval & 0x00ff;
			MegData[sLen++] = (GateWay->UploadInterval >> 8) & 0x00ff;
			MegData[sLen++] = GateWay->HistoryNum & 0x00ff;
			MegData[sLen++] = (GateWay->HistoryNum >> 8) & 0x00ff;
			MegData[sLen++] = (GateWay->HistoryNum >> 16) & 0x00ff;
			MegData[sLen++] = (GateWay->HistoryNum >> 24) & 0x00ff;
			MegData[0] = (sLen - 3) & 0x00ff;//数据体长度
			MegData[1] = ((sLen - 3) >> 8) & 0x00ff;//数据体长度
			MegData[2] = NET_COMM_CMD_READ_GW_INFO;//指令
			MegData[3] = SensorCnt&0xFF;
			MegData[4] = (SensorCnt >> 8)&0xFF;
			CatOneEthSendQueue(MegData, sLen);
			rt_free(MegData);
			break;
		}
		
		case NET_COMM_CMD_GW_PARA_CONFIG:{
			//应答服务器
			MegData = rt_malloc(4);
			MegData[0] = 1;
			MegData[1] = 0;
			MegData[2] = NET_COMM_CMD_GW_PARA_CONFIG;
			MegData[3] = 1;
			sLen = 4;
			CatOneEthSendQueue(MegData, sLen);
			rt_free(MegData);
			MAIN_DBG_LOG("AThe server sends down the gateway parameter configuration...\r\n");
		break;}
		
		case NET_COMM_CMD_HIS_DATA: {
			uint32_t *StartIdx, *EndIdx;
			StartIdx = (uint32_t *)Data;
			EndIdx = (uint32_t *)&Data[4];
			if(*StartIdx > GateWay->HistoryNum)
				return -1;
			
			if(*EndIdx == 0) {
				*EndIdx = GateWay->HistoryNum;
			}
			LogHeader_t LogH;
			LogH.LogEndAddr = 0;
			for(int i = *StartIdx; i < *EndIdx; i++) {
				uint8_t *HisData;
				int ret = ReadHistoryData(&LogH, &HisData, i);
				if(HisData != NULL) {
					MegData = rt_malloc(ret + 15);
					MegData[0] = ret - 1 + 4;
					MegData[1] = NET_COMM_CMD_HIS_DATA;
					memcpy(&MegData[2], (uint8_t *)&LogH.LogIdx, 4);
					sLen = 6;
					memcpy(&MegData[sLen], HisData, 6);
					sLen += 6;
					memcpy(&MegData[sLen], &HisData[7], ret - 7);
					sLen += ret - 7;
					CatOneEthSendQueue(MegData, sLen);
					rt_free(MegData);
					rt_free(HisData);
					rt_thread_delay(10);
				}
				else {
					continue;
				}
			}
		}
			
		case NET_COMM_CMD_ADD_UNIT:{
			if(*Data == 1) {	//录入成功
				MAIN_DBG_LOG("Adding CommUnit succeeded...\r\n");
			}
			else {
				MAIN_DBG_LOG("Adding CommUnit Failed...\r\n");
			}
		break;}
		
		case NET_COMM_CMD_LP_DEV_CONFIG: {
			//开始配置
			SvrDownLPDevConfigPara_t *LPDevConfig;
			LPDevConfig = (SvrDownLPDevConfigPara_t *)Data;
			int ret = memcmp(CommUintMac, LPDevConfig->CommDevAddr, 6);
			if(ret == 0) {
				for(int i = 0; i < COMMUNIT_NUM_MAX; i++) {
					if(GateWay->ConfigPara.CommUnitArray[i].RegFlag) {
						GateWay->ConfigPara.CommUnitArray[i].CollectInterval = LPDevConfig->CollectInterval;
						GateWay->ConfigPara.CommUnitArray[i].ReportInterval = LPDevConfig->ReportInterval;
						GateWay->ConfigPara.CommUnitArray[i].ERInterval = LPDevConfig->ERInterval;
						GateWay->ConfigPara.CommUnitArray[i].ERTime = LPDevConfig->ERTime;
						GateWay->ConfigPara.CommUnitArray[i].ConfigFlag = true;
					}
				}
				MAIN_DBG_LOG("Configure all the parameters of the main devices.\r\n");
				WritePara((uint8_t *)&GateWay->ConfigPara, sizeof(GWConfigPara_t));
			}
			else {
				memcpy(&CommUintMac[0], Data, 6);
				int ret = CheckCommUnitReg(GateWay, CommUintMac);
				if(ret < 0)
					return -1;
				GateWay->ConfigPara.CommUnitArray[ret].CollectInterval = LPDevConfig->CollectInterval;
				GateWay->ConfigPara.CommUnitArray[ret].ReportInterval = LPDevConfig->ReportInterval;
				GateWay->ConfigPara.CommUnitArray[ret].ERInterval = LPDevConfig->ERInterval;
				GateWay->ConfigPara.CommUnitArray[ret].ERTime = LPDevConfig->ERTime;
				GateWay->ConfigPara.CommUnitArray[ret].ConfigFlag = true;
				WritePara((uint8_t *)&GateWay->ConfigPara, sizeof(GWConfigPara_t));
				MAIN_DBG_LOG("Main equipment parameter configuration. Mac:%02X-%02X-%02X-%02X-%02X-%02X\r\n",
							CommUintMac[0], CommUintMac[1], CommUintMac[2], CommUintMac[3], CommUintMac[4], CommUintMac[5]);
			}
			//应答服务器
			MegData = rt_malloc(4);
			MegData[0] = 1;
			MegData[1] = 0;
			MegData[2] = NET_COMM_CMD_LP_DEV_CONFIG;
			MegData[3] = 1;
			sLen = 4;
			CatOneEthSendQueue(MegData, sLen);
			rt_free(MegData);
			break;}
		
		case NET_COMM_CMD_CONT_LASER:{
			memcpy(&CommUintMac[0], Data, 6);
			int ret = CheckCommUnitReg(GateWay, CommUintMac);
			if(ret < 0)
				return -1;
			if(GateWay->ConfigPara.CommUnitArray[ret].CUType !=  DEV_TYPE_EXT_COMMUNIT)
				return -1;
			if((GateWay->ConfigPara.CommUnitArray[ret].Mac[0][3] / 0x80) != 1) {//判断是否为通讯单元（主设备）
				if(GateWay->ConfigPara.CommUnitArray[ret].Mac[0][2] == 1)//判断通讯类型
				{
					GateWay->ConfigPara.CommUnitArray[ret].LaserOnOff = Data[6];//服务器下发打开或者关闭激光
					if(GateWay->ConfigPara.CommUnitArray[ret].LaserOnOff == true)
					{
						GateWay->ConfigPara.CommUnitArray[ret].ContLaser = true;//控制激光，等待下次此MAC主设备上传数据时下发打开激光指令（低功耗）
						MAIN_DBG_LOG("Waiting for the laser response. Mac:%02X-%02X-%02X-%02X-%02X-%02X\r\n",
							CommUintMac[0], CommUintMac[1], CommUintMac[2], CommUintMac[3], CommUintMac[4], CommUintMac[5]);
					}
					else if(GateWay->ConfigPara.CommUnitArray[ret].LaserOnOff == false)
					{//直接发送
						MAIN_DBG_LOG("Waiting for the laser response. Mac:%02X-%02X-%02X-%02X-%02X-%02X\r\n",
							CommUintMac[0], CommUintMac[1], CommUintMac[2], CommUintMac[3], CommUintMac[4], CommUintMac[5]);
						GateWay->ConfigPara.CommUnitArray[ret].ContLaser = false;
						CommUnitCmdSend(GateWay, CommUintMac, COMM_UNIT_CMD_CONT_LASER, (uint8_t *)&GateWay->ConfigPara.CommUnitArray[ret].LaserOnOff, 1, Sx1276LoRaSendBuffer);//查询模式
					}
				}
				else if(GateWay->ConfigPara.CommUnitArray[ret].Mac[0][2] == 2)//判断通讯类型
				{
					if(GateWay->ConfigPara.Rs485Ch1.Enable == true && !GateWay->ConfigPara.Rs485Ch1.CommUnitEnable) 
					{
						GateWay->ConfigPara.CommUnitArray[ret].LaserOnOff = Data[6];//服务器下发打开或者关闭激光
						if(GateWay->ConfigPara.CommUnitArray[ret].LaserOnOff == true)
						{
							GateWay->ConfigPara.CommUnitArray[ret].ContLaser = true;//控制激光，等待下次此MAC主设备上传数据时下发打开激光指令（低功耗）
						}
						else if(GateWay->ConfigPara.CommUnitArray[ret].LaserOnOff == false)
						{
							CommUnitCmdSend(GateWay, CommUintMac, COMM_UNIT_CMD_CONT_LASER, &Data[6], 1, GateWay->ConfigPara.Rs485Ch1.RS485Send);
						}
					}
					else if(GateWay->ConfigPara.Rs485Ch2.Enable == true && !GateWay->ConfigPara.Rs485Ch2.CommUnitEnable)
					{
						GateWay->ConfigPara.CommUnitArray[ret].LaserOnOff = Data[6];//服务器下发打开或者关闭激光
						if(GateWay->ConfigPara.CommUnitArray[ret].LaserOnOff == true)
						{
							GateWay->ConfigPara.CommUnitArray[ret].ContLaser = true;//控制激光，等待下次此MAC主设备上传数据时下发打开激光指令（低功耗）
						}
						else if(GateWay->ConfigPara.CommUnitArray[ret].LaserOnOff == false)
						{
							CommUnitCmdSend(GateWay, CommUintMac, COMM_UNIT_CMD_CONT_LASER, &Data[6], 1, GateWay->ConfigPara.Rs485Ch2.RS485Send);
						}	
					}
				}
			}
		break;}
		 
		 default:
		break;
	}
	return 0;
}
