Files
GateWay/Project/GateWay/source/User/Src/Public.c
T
YuanHongbin 626f33a15e fix(register): 注册payload合法性校验,拦截串台乱码注册
- 新增RegPayloadValid校验: SensorN非0/PayloadLen与条目数匹配/传感器类型白名单(SensorTypeDataLen表内且非保留)/MAC非全0全FF且非网关MAC/注册帧GWMac非空时必须与本网关匹配
- 频偏串台误解调的乱码帧几乎必然被拦截(随机类型命中合法类型概率约0.03%), 不再占用注册表槽位
- GWMac为全0/全FF视为未填放行, 兼容老固件; 已注册设备重注册路径不受影响
2026-09-08 10:14:52 +08:00

1515 lines
60 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.
#include "main.h"
#include "Public.h"
#include "RS485Task.h"
#include "LoraTask.h"
#include "spiflash.h"
#include "CatOneTask.h"
#include <stdlib.h>
#include "sx127x.h"
const char *ChannelName(Channel_m ch)
{
switch(ch) {
case CH_NULL: return "null";
case CH_DBG: return "dbg";
case CH_RS485_1: return "ch1";
case CH_RS485_2: return "ch2";
case CH_ETH: return "eth";
case CH_LORA: return "lora";
case CH_CAT1: return "cat1";
default: return "?";
}
}
//传感器对应的数据长度
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-裂缝检测单元
0, //0x000F-预留
8, //0x0010-姿态检测单元
4, //0x0011-激光位移检测单元
4, //0x0012-表面应力传感器
4, //0x0013-压力传感器
4, //0x0014-微波测距传感器
0, //0x0015-表贴式结冰传感器
0, //0x0016-埋入式结冰传感器
4, //0x0017-单通道钢筋应力传感器
4, //0x0018-单通道锚杆轴力传感器
32, //0x0019-8通道钢筋拉压力传感器
32, //0x001A-8通道锚杆轴力传感器
0, //0x001B-16通道钢筋应力传感器
0, //0x001C-16通道锚杆轴力传感器
0, //0x001D-爆炸冲击传感器
0, //0x001E-随行支架传感器
0, //0x001F-冻融循环传感器
19, //0x0020-位移计
};
/*****************************************************************************************
* 函数名称: 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(CRC16_BASE, OutData, Len);
OutData[Len++] = check & 0x00ff;
OutData[Len++] = (check >> 8) & 0x00ff;
return Len;
}
/*****************************************************************************************
* 函数名称: CheckCommUnitReg
* 功能描述: 检查设备是否注册
* 参 数: GateWay,网关句柄
CommUnitMac, 待检查的设备MAC
* 返 回 值: 已注册返回非0,没注册返回-1
*****************************************************************************************/
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;
}
/*****************************************************************************************
* 函数名称: CheckCommUnitExcl
* 功能描述: 检查设备是否排除
* 参 数: GateWay,网关句柄
CommUnitMac, 待检查的设备MAC
* 返 回 值: 已排除返回非0,没排除返回-1
*****************************************************************************************/
int CheckCommUnitExcl(GateWayPara GateWay, uint8_t *CommUnitMac)
{
for(int i = 0; i < COMMUNIT_NUM_MAX; i++) {//判断是否被排除
if(memcmp(GateWay->ConfigPara.ExclCommUnit[i].ExclMac, CommUnitMac, 6) == 0) {
if(GateWay->ConfigPara.ExclCommUnit[i].ExclFlag == true)
return i;
}
}
return -1;
}
/*****************************************************************************************
* 函数名称: RegPayloadValid
* 功能描述: 注册请求payload合法性校验,拦截频偏串台误解调的乱码帧,避免乱码设备占用注册表
* 参 数: GateWay, 网关句柄
CUHeader, 注册帧头
PayLoad, 注册负载数据
* 返 回 值: 合法返回true, 非法返回false
*****************************************************************************************/
static bool RegPayloadValid(GateWayPara GateWay, CommUnitFrameHeader CUHeader, uint8_t *PayLoad)
{
uint8_t SensorN = PayLoad[0];
int i, j;
bool MacEmpty;
/*空注册无意义*/
if(SensorN == 0) {
return false;
}
/*payload长度必须容纳N个传感器条目(每条目6字节)*/
if(CUHeader->PayloadLen < (uint16_t)(SensorN * 6 + 1)) {
return false;
}
/*通讯单元自身MAC不能为全0/全FF*/
MacEmpty = true;
for(i = 0; i < 6; i++) {
if(CUHeader->DevMac[i] != 0x00 && CUHeader->DevMac[i] != 0xFF) { MacEmpty = false; break; }
}
if(MacEmpty) {
return false;
}
/*注册帧GWMac若非空(全0/全FF视为未填)则必须与本网关匹配*/
MacEmpty = true;
for(i = 0; i < 6; i++) {
if(CUHeader->GWMac[i] != 0x00 && CUHeader->GWMac[i] != 0xFF) { MacEmpty = false; break; }
}
if(!MacEmpty && memcmp(CUHeader->GWMac, GateWay->ConfigPara.GwMac, 6) != 0) {
return false;
}
/*逐传感器: 类型必须在已知类型表内且非保留(数据长度>0), MAC非全0/全FF且不等于网关MAC*/
for(j = 0; j < SensorN; j++) {
uint16_t RegType = PayLoad[(j*6)+1] | (PayLoad[(j*6)+2] << 8);
if(RegType == 0x0000 || RegType >= sizeof(SensorTypeDataLen)/sizeof(SensorTypeDataLen[0])
|| SensorTypeDataLen[RegType] == 0) {
return false;
}
MacEmpty = true;
for(i = 0; i < 6; i++) {
uint8_t mac = PayLoad[(j*6)+1+i];
if(mac != 0x00 && mac != 0xFF) { MacEmpty = false; break; }
}
if(MacEmpty || memcmp(&PayLoad[(j*6)+1], GateWay->ConfigPara.GwMac, 6) == 0) {
return false;
}
}
return true;
}
/*****************************************************************************************
* 函数名称: 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 && Cmd != COMM_UNIT_CMD_GET_SIGNAL)
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(CRC16_BASE, SendBuff, SendLen);
SendBuff[SendLen++] = crc16 & 0x00ff;
SendBuff[SendLen++] = (crc16 >> 8) & 0x00ff;
if(Send != NULL) {
Send(SendBuff, SendLen);
}
}
/*****************************************************************************************
* 函数名称: TrySendFullPowerCmd
* 功能描述: 当传感器处于FullPower状态时,直接下发待处理配置命令,无需等待传感器上报
* 参 数: GateWay, 网关参数
CommUnitIdx, 通讯单元索引
* 返 回 值: 无
*****************************************************************************************/
void TrySendFullPowerCmd(GateWayPara GateWay, int CommUnitIdx)
{
if(CommUnitIdx < 0 || CommUnitIdx >= COMMUNIT_NUM_MAX)
return;
if(GateWay->ConfigPara.CommUnitArray[CommUnitIdx].RegFlag != true)
return;
if(GateWay->ConfigPara.CommUnitArray[CommUnitIdx].CUType != DEV_TYPE_EXT_COMMUNIT)
return;
//使用传感器当前已确认生效的FPO参数判断是否处于全功率时段
uint8_t FPOStart = GateWay->ConfigPara.CommUnitArray[CommUnitIdx].CurFPOTimeStart;
uint8_t FPODur = GateWay->ConfigPara.CommUnitArray[CommUnitIdx].CurFPOTime;
if(FPODur == 0)
return; //传感器当前未配置全功率时段,不能直接下发,需等待上报回应
struct tm cTime;
TimeGet(&cTime);
int curHour = cTime.tm_hour;
int endHour = FPOStart + FPODur;
bool inFPO = false;
if(FPODur >= 24) {
inFPO = true; //全天全功率
}
else if(endHour > 24) {
//跨天:如 Start=22, Dur=4,则 22~23 和 0~1 为全功率
inFPO = (curHour >= FPOStart || curHour < endHour - 24);
}
else {
//同天:如 Start=8, Dur=10,则 8~17 为全功率
inFPO = (curHour >= FPOStart && curHour < endHour);
}
if(!inFPO)
return;
uint8_t *Mac = GateWay->ConfigPara.CommUnitArray[CommUnitIdx].Mac[0];
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;
CommUnitCmdSend(GateWay, Mac, COMM_UNIT_CMD_READ, (uint8_t *)&Config, sizeof(LPDevConfigPara_t), Sx1276LoRaSendBuffer);
MAIN_DBG_LOG("FullPower direct send config. Mac:%02X-%02X-%02X-%02X-%02X-%02X\r\n",
Mac[0], Mac[1], Mac[2], Mac[3], Mac[4], Mac[5]);
}
else if(GateWay->ConfigPara.CommUnitArray[CommUnitIdx].ContLaser == true) {
if(GateWay->ConfigPara.CommUnitArray[CommUnitIdx].LaserOnOff == true) {
CommUnitCmdSend(GateWay, Mac, COMM_UNIT_CMD_CONT_LASER, (uint8_t *)&GateWay->ConfigPara.CommUnitArray[CommUnitIdx].LaserOnOff, 1, Sx1276LoRaSendBuffer);
}
MAIN_DBG_LOG("FullPower direct send laser cmd.\r\n");
}
else if(GateWay->ConfigPara.CommUnitArray[CommUnitIdx].CailFlag == true) {
CommUnitCmdSend(GateWay, Mac, COMM_UNIT_CMD_CAIL, 0, 0, Sx1276LoRaSendBuffer);
MAIN_DBG_LOG("FullPower direct send calibrate cmd.\r\n");
}
else if(GateWay->ConfigPara.CommUnitArray[CommUnitIdx].TimeSyncFlag == true) {
CommUnitCmdSend(GateWay, Mac, COMM_UNIT_CMD_TIME_SYNC, (uint8_t *)&ctime, 4, Sx1276LoRaSendBuffer);
MAIN_DBG_LOG("FullPower direct send time sync cmd.\r\n");
}
else if(GateWay->ConfigPara.CommUnitArray[CommUnitIdx].FPOTimeFlag == true) {
GateWay->ConfigPara.CommUnitArray[CommUnitIdx].FPOTimeFlag = false;
GateWay->ConfigPara.CommUnitArray[CommUnitIdx].FPOTimeConfirmed = false;
uint8_t FPOData[2];
FPOData[0] = GateWay->ConfigPara.CommUnitArray[CommUnitIdx].FPOTimeStart;
FPOData[1] = GateWay->ConfigPara.CommUnitArray[CommUnitIdx].FPOTime;
CommUnitCmdSend(GateWay, Mac, COMM_UNIT_CMD_SET_FPO_TIME, FPOData, 2, Sx1276LoRaSendBuffer);
MAIN_DBG_LOG("FullPower direct send FPO config. Start:%d, Duration:%d\r\n", FPOData[0], FPOData[1]);
}
WritePara((uint8_t *)&GateWay->ConfigPara, sizeof(GWConfigPara_t));
}
/*****************************************************************************************
* 函数名称: CommUintOrgData
* 功能描述: 上传传感器数据函数
* 参 数: CUPara, 通讯单元参数
CUData, 通讯单元数据
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;
case DISPLACEMENT:
memcpy(&sData[Len], CUData->Data[i], sizeof(Displacement_T));
Len += sizeof(Displacement_T);
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;
}
case DISPLACEMENT: {
Displacement_T Sensor;
memcpy((uint8_t *)&Sensor, SensorData, sizeof(Displacement_T));
MAIN_DBG_LOG("Sensor%d Type %04x: PitchAngle=%04d, RollAngle=%04d, YawAngle=%04d, Temp=%06f, Altitude=%06f, Distance=%04d\r\n",
SensorIdx, SensorType, Sensor.PitchAngle, Sensor.RollAngle, Sensor.YawAngle, Sensor.Temp, Sensor.Altitude, Sensor.Distance);
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, ExclCommUnit;
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(CRC16_BASE, rData, rLen - 2);
crc16 = rData[rLen - 2] | (rData[rLen - 1] << 8);
if(check != crc16)
return -1;
if((CUHeader->Cmd != COMM_UNIT_CMD_REG && CUHeader->Cmd != COMM_UNIT_CMD_GET_SIGNAL) && (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 && CUHeader->Cmd != COMM_UNIT_CMD_GET_SIGNAL){//判断是否是注册请求
return -1;
}
ExclCommUnit = CheckCommUnitExcl(GateWay, CUHeader->DevMac);//判断是否是被排除的设备
if(ExclCommUnit > -1) {
return -1;
}
}
switch(CUHeader->Cmd) {
case COMM_UNIT_CMD_REG:{
if(PayLoad[0] > SENSOR_NUM_MAX) {
return -1;
}
/*串台防护: 校验注册payload合法性, 拦截频偏误解调的乱码帧*/
if(!RegPayloadValid(GateWay, CUHeader, PayLoad)) {
MAIN_DBG_LOG("\r\nReg rejected: invalid payload (cross-band interference?) 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]);
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;
CommUnitPara_t *pCU = &GateWay->ConfigPara.CommUnitArray[CommUnitIdx];
bool ParaChanged = (pCU->CommErrCnt != 0 || pCU->ConfigFlag != true || pCU->CailFlag != false ||
pCU->TimeSyncFlag != false || pCU->ContLaser != false || pCU->LaserOnOff != false ||
pCU->FPOTimeFlag != false || pCU->FPOTimeConfirmed != true);
pCU->CommErrCnt = 0;
pCU->ConfigFlag = true;
pCU->CailFlag = false;
pCU->TimeSyncFlag = false;
pCU->ContLaser = false;
pCU->LaserOnOff = false;
pCU->FPOTimeFlag = false;
pCU->FPOTimeConfirmed = true;
/*先发应答再写FlashWritePara需擦除2个扇区并写入约7KB参数(耗时百毫秒级),
若先写Flash,应答延迟过大,会超出传感器注册请求后的接收窗口导致其收不到回应;
参数无变化时跳过写入,避免传感器反复重注册时频繁擦写Flash*/
CommUnitCmdSend(GateWay, CUHeader->DevMac, COMM_UNIT_CMD_REG, &ret, 1, Response);
if(ParaChanged)
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;
GateWay->ConfigPara.CommUnitArray[i].FPOTimeStart = LW_DEV_FPO_TIME_START_DEFAULT;
GateWay->ConfigPara.CommUnitArray[i].FPOTime = LW_DEV_FPO_TIME_DEFAULT;
GateWay->ConfigPara.CommUnitArray[i].CurFPOTimeStart = LW_DEV_FPO_TIME_START_DEFAULT;
GateWay->ConfigPara.CommUnitArray[i].CurFPOTime = LW_DEV_FPO_TIME_DEFAULT;
GateWay->ConfigPara.CommUnitArray[i].FPOTimeFlag = false;
GateWay->ConfigPara.CommUnitArray[i].FPOTimeConfirmed = true;
uint8_t ret = 1;
//先发应答再写Flash,避免WritePara耗时导致应答延迟过大(原因同上)
CommUnitCmdSend(GateWay, CUHeader->DevMac, COMM_UNIT_CMD_REG, &ret, 1, Response);
WritePara((uint8_t *)&GateWay->ConfigPara, sizeof(GWConfigPara_t));
if(GateWay->MuchRegFlag) { //网关已注册,向服务发送新设备添加指令
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;
MegData[3] = (GateWay->ConfigPara.CommUnitArray[i].SensorN) & 0x00ff;;
MegData[4] = (GateWay->ConfigPara.CommUnitArray[i].SensorN >> 8) & 0x00ff;
for(uint8_t k = 0; k < GateWay->ConfigPara.CommUnitArray[i].SensorN; k++)
{
memcpy(&MegData[5], GateWay->ConfigPara.CommUnitArray[i].Mac[k], 6);
}
UploadSend(MegData, PayLoadLen+5);
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");
}
else if(GateWay->ConfigPara.CommUnitArray[CommUnitIdx].FPOTimeFlag == true)
{
GateWay->ConfigPara.CommUnitArray[CommUnitIdx].FPOTimeFlag = false;
GateWay->ConfigPara.CommUnitArray[CommUnitIdx].FPOTimeConfirmed = false;
uint8_t FPOData[2];
FPOData[0] = GateWay->ConfigPara.CommUnitArray[CommUnitIdx].FPOTimeStart;
FPOData[1] = GateWay->ConfigPara.CommUnitArray[CommUnitIdx].FPOTime;
CommUnitCmdSend(GateWay, CUHeader->DevMac, COMM_UNIT_CMD_SET_FPO_TIME, FPOData, 2, Response);
MAIN_DBG_LOG("Issue FPO time config command. Start:%d, Duration:%d\r\n", FPOData[0], FPOData[1]);
}
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 if(GateWay->ConfigPara.CommUnitArray[CommUnitIdx].FPOTimeFlag == true)
{
GateWay->ConfigPara.CommUnitArray[CommUnitIdx].FPOTimeFlag = false;
GateWay->ConfigPara.CommUnitArray[CommUnitIdx].FPOTimeConfirmed = false;
uint8_t FPOData[2];
FPOData[0] = GateWay->ConfigPara.CommUnitArray[CommUnitIdx].FPOTimeStart;
FPOData[1] = GateWay->ConfigPara.CommUnitArray[CommUnitIdx].FPOTime;
CommUnitCmdSend(GateWay, CUHeader->DevMac, COMM_UNIT_CMD_SET_FPO_TIME, FPOData, 2, Response);
MAIN_DBG_LOG("Issue FPO time config command. Start:%d, Duration:%d\r\n", FPOData[0], FPOData[1]);
}
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);
UploadSend(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");
}
else if(GateWay->ConfigPara.CommUnitArray[CommUnitIdx].FPOTimeFlag == true)
{
GateWay->ConfigPara.CommUnitArray[CommUnitIdx].FPOTimeFlag = false;
GateWay->ConfigPara.CommUnitArray[CommUnitIdx].FPOTimeConfirmed = false;
uint8_t FPOData2[2];
FPOData2[0] = GateWay->ConfigPara.CommUnitArray[CommUnitIdx].FPOTimeStart;
FPOData2[1] = GateWay->ConfigPara.CommUnitArray[CommUnitIdx].FPOTime;
CommUnitCmdSend(GateWay, CUHeader->DevMac, COMM_UNIT_CMD_SET_FPO_TIME, FPOData2, 2, Response);
MAIN_DBG_LOG("Issue FPO time config command. Start:%d, Duration:%d\r\n", FPOData2[0], FPOData2[1]);
}
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];
UploadSend(MegData, 10);
rt_free(MegData);
GateWay->ConfigPara.CommUnitArray[CommUnitIdx].LaserOnOff = false;
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];
UploadSend(MegData, 10);
rt_free(MegData);
GateWay->ConfigPara.CommUnitArray[CommUnitIdx].LaserOnOff = true;
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");
}
else if(GateWay->ConfigPara.CommUnitArray[CommUnitIdx].FPOTimeFlag == true)
{
GateWay->ConfigPara.CommUnitArray[CommUnitIdx].FPOTimeFlag = false;
GateWay->ConfigPara.CommUnitArray[CommUnitIdx].FPOTimeConfirmed = false;
uint8_t FPOData3[2];
FPOData3[0] = GateWay->ConfigPara.CommUnitArray[CommUnitIdx].FPOTimeStart;
FPOData3[1] = GateWay->ConfigPara.CommUnitArray[CommUnitIdx].FPOTime;
CommUnitCmdSend(GateWay, CUHeader->DevMac, COMM_UNIT_CMD_SET_FPO_TIME, FPOData3, 2, Response);
MAIN_DBG_LOG("Issue FPO time config command. Start:%d, Duration:%d\r\n", FPOData3[0], FPOData3[1]);
}
WritePara((uint8_t *)&GateWay->ConfigPara, sizeof(GWConfigPara_t));
break;}
case COMM_UNIT_CMD_GET_SIGNAL:{
int16_t Rssi;
int8_t Snr;
uint8_t SignalPayload[2];
SX1276LoCalcRssiSnr(&Rssi, &Snr);
SignalPayload[0] = (uint8_t)Snr;
SignalPayload[1] = (uint8_t)(Rssi & 0xFF);
CommUnitCmdSend(GateWay, CUHeader->DevMac, COMM_UNIT_CMD_GET_SIGNAL, SignalPayload, 2, Response);
MAIN_DBG_LOG("\r\nCUMac:%02X-%02X-%02X-%02X-%02X-%02X, RX(Dev->GW): SNR:%d, RSSI:%d\r\n",
CUHeader->DevMac[0], CUHeader->DevMac[1], CUHeader->DevMac[2], CUHeader->DevMac[3], CUHeader->DevMac[4], CUHeader->DevMac[5],
Snr, Rssi);
break;}
case COMM_UNIT_CMD_SET_FPO_TIME:{
//传感器回应0x0A命令,携带配置参数
uint8_t FPOResponse = 0;
if(PayLoad[0] <= 23 && PayLoad[1] <= 24) {
GateWay->ConfigPara.CommUnitArray[CommUnitIdx].FPOTimeStart = PayLoad[0];
GateWay->ConfigPara.CommUnitArray[CommUnitIdx].FPOTime = PayLoad[1];
GateWay->ConfigPara.CommUnitArray[CommUnitIdx].CurFPOTimeStart = PayLoad[0];
GateWay->ConfigPara.CommUnitArray[CommUnitIdx].CurFPOTime = PayLoad[1];
GateWay->ConfigPara.CommUnitArray[CommUnitIdx].FPOTimeConfirmed = true;
FPOResponse = 1;
MAIN_DBG_LOG("FPO time confirmed. Mac:%02X-%02X-%02X-%02X-%02X-%02X, Start:%d, Duration:%d\r\n",
CUHeader->DevMac[0], CUHeader->DevMac[1], CUHeader->DevMac[2], CUHeader->DevMac[3], CUHeader->DevMac[4], CUHeader->DevMac[5],
PayLoad[0], PayLoad[1]);
WritePara((uint8_t *)&GateWay->ConfigPara, sizeof(GWConfigPara_t));
}
else {
MAIN_DBG_LOG("FPO time config invalid. Start:%d, Duration:%d\r\n", PayLoad[0], PayLoad[1]);
}
//回应服务器0x0A命令:DevAddr(6) + Response(1)
MegData = rt_malloc(10);
MegData[0] = 7;
MegData[1] = 0;
MegData[2] = NET_COMM_CMD_FPO_CONFIG;
memcpy(&MegData[3], CUHeader->DevMac, 6);
MegData[9] = FPOResponse;
UploadSend(MegData, 10);
rt_free(MegData);
break;}
default:
break;
}
return CommUnitIdx;
}
/*****************************************************************************************
* 函数名称: _NetRevCallBack
* 功能描述: much、auch接收回调函数
* 参 数: rData,数据输入接口
rLen, 数据长度输入接口
* 返 回 值: 无
*****************************************************************************************/
static int _NetRevCallBack(GateWayPara GateWay, uint8_t *rData, uint16_t rLen, bool *pRegFlag)
{
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(CRC16_BASE, 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, (uint8_t *)&NCHeader->Timestamp, 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, (uint8_t *)&NCHeader->Timestamp, 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主设备上传数据时下发校准指令(低功耗)
TrySendFullPowerCmd(GateWay, i);
}
}
//校准其他通讯网关
//CommUnitCmdSend(GateWay, CommUintMac, COMM_UNIT_CMD_TIME_SYNC, &rData[14], 4, Sx1276LoRaSendBuffer);
}
switch(NCHeader->Cmd) {
case NET_COMM_CMD_REG:{
if(*Data == 1) { //注册成功
*pRegFlag = true;
memset(GateWay->SvrMac, 0x00, 6);
WritePara((uint8_t *)&GateWay->ConfigPara, sizeof(GWConfigPara_t));
MAIN_DBG_LOG("Gateway %s Registered...\r\n",
pRegFlag == &GateWay->MuchRegFlag ? "Much" : "Auch");
}
else {
*pRegFlag = false;
memset(GateWay->SvrMac, 0x00, 6);
MAIN_DBG_LOG("Gateway %s Register Failed....\r\n",
pRegFlag == &GateWay->MuchRegFlag ? "Much" : "Auch");
}
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;
UploadSend(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.Rs485Ch2.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主设备上传数据时下发校准指令(低功耗)
TrySendFullPowerCmd(GateWay, i);
}
}
//校准其他通讯网关
//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]);
TrySendFullPowerCmd(GateWay, ret);
}
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.CUPara.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.CUPara.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;
UploadSend(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;
UploadSend(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;
UploadSend(MegData, sLen);
rt_free(MegData);
rt_free(HisData);
rt_thread_delay(10);
}
else {
continue;
}
}
break;}
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: {
//13字节:DevAddr(6) + CollectInterval(2) + ReportInterval(2) + ERInterval(1) + ERTime(1)
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;
TrySendFullPowerCmd(GateWay, i);
}
}
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]);
TrySendFullPowerCmd(GateWay, ret);
}
//应答服务器
MegData = rt_malloc(4);
MegData[0] = 1;
MegData[1] = 0;
MegData[2] = NET_COMM_CMD_LP_DEV_CONFIG;
MegData[3] = 1;
sLen = 4;
UploadSend(MegData, sLen);
rt_free(MegData);
break;}
case NET_COMM_CMD_FPO_CONFIG: {
//8字节:DevAddr(6) + FPOTimeStart(1) + FPOTime(1),全功率时间配置
SvrDownFPOConfigPara_t *FPOConfig;
FPOConfig = (SvrDownFPOConfigPara_t *)Data;
memcpy(&CommUintMac[0], Data, 6);
int ret = CheckCommUnitReg(GateWay, CommUintMac);
if(ret < 0)
return -1;
GateWay->ConfigPara.CommUnitArray[ret].FPOTimeStart = FPOConfig->FPOTimeStart;
GateWay->ConfigPara.CommUnitArray[ret].FPOTime = FPOConfig->FPOTime;
GateWay->ConfigPara.CommUnitArray[ret].FPOTimeFlag = true;
GateWay->ConfigPara.CommUnitArray[ret].FPOTimeConfirmed = false;
WritePara((uint8_t *)&GateWay->ConfigPara, sizeof(GWConfigPara_t));
MAIN_DBG_LOG("FPO time config. Mac:%02X-%02X-%02X-%02X-%02X-%02X, Start:%d, Duration:%d\r\n",
CommUintMac[0], CommUintMac[1], CommUintMac[2], CommUintMac[3], CommUintMac[4], CommUintMac[5],
FPOConfig->FPOTimeStart, FPOConfig->FPOTime);
TrySendFullPowerCmd(GateWay, ret);
break;}
case NET_COMM_CMD_ALARM:{
MAIN_DBG_LOG("Received server response.....\r\n");
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]);
TrySendFullPowerCmd(GateWay, ret);
}
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;
}
int MuchRevCallBack(GateWayPara GateWay, uint8_t *rData, uint16_t rLen)
{
return _NetRevCallBack(GateWay, rData, rLen, &GateWay->MuchRegFlag);
}
int AuchRevCallBack(GateWayPara GateWay, uint8_t *rData, uint16_t rLen)
{
return _NetRevCallBack(GateWay, rData, rLen, &GateWay->AuchRegFlag);
}