Files
2026-06-22 09:19:00 +08:00

906 lines
31 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#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-保留
26, //0x0001-应力场检测单元
10, //0x0002-渗透压检测单元
14, //0x0003-弹性波导检测单元
10, //0x0004-介电质普检测单元
6, //0x0005-微振动
6, //0x0006-三维连续变形检测单元
0, //0x0007-保留
36, //0x0008-应力场(地磁)检测单元
16, //0x0009-渗透压(地磁)检测单元
20, //0x000A-弹性波导(地磁)检测单元
16, //0x000B-介电质普(地磁)检测单元
12, //0x000C-三维连续变形(地磁)检测单元
14, //0x000D-二维应力场检测单元
24, //0x000E-裂缝检测单元
0, //0x000F-6维力敏
8, //0x0010-姿态检测单元
4, //0x0011-激光位移检测单元
24, //0x0012-裂缝检测单元别名
};
/*****************************************************************************************
* 函数名称: 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
* 功能描述: 上报数据组织
* 参 数: SvrMac,服务器MAC地址
MegData, 消息队列数据
OutData, 输出数据出口
* 返 回 值: 数据长度
*****************************************************************************************/
int NetCommOrgData(GateWayPara GateWay, uint8_t *MegData, uint8_t *OutData)
{
uint8_t PayloadLen, Cmd, *Meg;
uint16_t check;
uint8_t Len;
PayloadLen = MegData[0];
Cmd = MegData[1];
Meg = &MegData[2];
NetCommFrameHeader NCHeader = (NetCommFrameHeader)OutData;
NCHeader->Header = 0x7A;
memcpy(NCHeader->GWMac, GateWay->ConfigPara.GwMac, 6);
memcpy(NCHeader->SvrMac, GateWay->SvrMac, 6);
NCHeader->Cmd = Cmd;
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_MUM_MAX; i++) {
if(memcmp(GateWay->ConfigPara.CommUnitArray[i].Mac, CommUnitMac, 6) == 0)
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);
}
}
/*****************************************************************************************
* 函数名称: RS485OrgData
* 功能描述: 下发传感器指令函数
* 参 数: GWMac,网关mac地址
CUPara, 通讯单元参数
sData, 数据入口
* 返 回 值: 数据长度
*****************************************************************************************/
int CommUintOrgData(GateWayPara GateWay, CommUnitPara CUPara, CommUnitData CUData, uint8_t *sData)
{
uint8_t Len = 0;
uint8_t SensorN = 0;
Len = 2;
memcpy(&sData[2], CUPara->Mac, 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 STRAIN_SENSOR:
memcpy(&sData[Len], CUData->Data[i], sizeof(StrainSensorType_t));
Len += sizeof(StrainSensorType_t);
break;
case PRESSURE_SENSOR:
memcpy(&sData[Len], CUData->Data[i], sizeof(PressureSensorType_t));
Len += sizeof(PressureSensorType_t);
break;
case SONAR_SENSOR:
memcpy(&sData[Len], CUData->Data[i], sizeof(SonarSensorType_t));
Len += sizeof(SonarSensorType_t);
break;
case CAP_SENSOR:
memcpy(&sData[Len], CUData->Data[i], sizeof(CapSensorType_t));
Len += sizeof(CapSensorType_t);
break;
case VIBRATE_SENSOR:
break;
case DEFM_3D_SENSOR:
memcpy(&sData[Len], CUData->Data[i], sizeof(Defm3DSensorType_t));
Len += sizeof(Defm3DSensorType_t);
break;
case STRAIN_SENSOR_MAG:
memcpy(&sData[Len], CUData->Data[i], sizeof(StrainMagSensorType_t));
Len += sizeof(StrainMagSensorType_t);
break;
case PRESSURE_SENSOR_MAG:
memcpy(&sData[Len], CUData->Data[i], sizeof(PressureMagSensorType_t));
Len += sizeof(PressureMagSensorType_t);
break;
case SONAR_SENSOR_MAG:
memcpy(&sData[Len], CUData->Data[i], sizeof(SonarMagSensorType_t));
Len += sizeof(SonarMagSensorType_t);
break;
case CAP_SENSOR_MAG:
memcpy(&sData[Len], CUData->Data[i], sizeof(CapMagSensorType_t));
Len += sizeof(CapMagSensorType_t);
break;
case DEFM_3D_SENSOR_MAG:
memcpy(&sData[Len], CUData->Data[i], sizeof(Defm3DMagSensorType_t));
Len += sizeof(Defm3DMagSensorType_t);
break;
case STRAIN_2_SENSOR:
memcpy(&sData[Len], CUData->Data[i], sizeof(Strain2SensorType_t));
Len += sizeof(Strain2SensorType_t);
break;
case CRACK_2_SENSOR:
case CRACK_SENSOR:
memcpy(&sData[Len], CUData->Data[i], sizeof(CrackSensorType_t));
Len += sizeof(CrackSensorType_t);
break;
case SIX_DIM_SENSOR:
break;
case POSTURE_SENSOR:
memcpy(&sData[Len], CUData->Data[i], sizeof(PostureSensorType_t));
Len += sizeof(PostureSensorType_t);
break;
case LASER_DISTANCE_SENSOR:
memcpy(&sData[Len], CUData->Data[i], sizeof(LaserDistanceSensorType_t));
Len += sizeof(LaserDistanceSensorType_t);
break;
}
SensorN++;
}
if(SensorN >= CUPara->SensorN)
break;
}
sData[0] = Len - 2;
sData[1] = NET_COMM_CMD_UPDATE;
return Len;
}
void DebugDisplaySensorData(int SensorIdx, uint16_t SensorType, uint8_t *SensorData)
{
switch(SensorType) {
case STRAIN_SENSOR: {
StrainSensorType_t Sensor;
memcpy((uint8_t *)&Sensor, SensorData, sizeof(StrainSensorType_t));
MAIN_DBG_LOG("Sensor%d Type %04x: Accx=%d, Accy=%d, Accz=%d, Strain1=%d, Strain2=%d, Strain3=%d, Strain4=%d, Strain5=%d\r\n",
SensorIdx, SensorType, Sensor.AccX, Sensor.AccY, Sensor.AccZ,
Sensor.Strain1, Sensor.Strain2, Sensor.Strain3, Sensor.Strain4, Sensor.Strain5);
break;
}
case STRAIN_SENSOR_MAG: {
StrainMegSensorType_t Sensor;
memcpy((uint8_t *)&Sensor, SensorData, sizeof(StrainMegSensorType_t));
MAIN_DBG_LOG("Sensor%d Type %04x: Accx=%04d, Accy=%04d, Accz=%04d, Megx=%04d, Megy=%04d, Megz=%04d\r\n",
SensorIdx, SensorType, Sensor.AccX, Sensor.AccY, Sensor.AccZ, Sensor.MegX, Sensor.MegY, Sensor.MegZ);
MAIN_DBG_LOG(" Strain1=%05d, Strain2=%05d, Strain3=%05d, Strain4=%05d, Strain5=%05d, Strain6=%05d\r\n",
Sensor.Strain1, Sensor.Strain2, Sensor.Strain3, Sensor.Strain4, Sensor.Strain5, Sensor.Strain6);
break;
}
case PRESSURE_SENSOR:{
PressureSensorType_t Sensor;
memcpy((uint8_t *)&Sensor, SensorData, sizeof(PressureSensorType_t));
MAIN_DBG_LOG("Sensor%d Type %04x: Accx=%d, Accy=%d, Accz=%d, Press=%d\r\n",
SensorIdx, SensorType, Sensor.AccX, Sensor.AccY, Sensor.AccZ, Sensor.Pressure);
break;
}
case SONAR_SENSOR:{
SonarSensorType_t Sensor;
memcpy((uint8_t *)&Sensor, SensorData, sizeof(SonarSensorType_t));
MAIN_DBG_LOG("Sensor%d Type %04x: Accx=%04d, Accy=%04d, Accz=%04d, Sonar1=%04d, Sonar2=%04d, Sonar3=%04d, Sonar4=%04d\r\n",
SensorIdx, SensorType, Sensor.AccX, Sensor.AccY, Sensor.AccZ,
Sensor.Sonar1, Sensor.Sonar2, Sensor.Sonar3, Sensor.Sonar4);
break;
}
case CAP_SENSOR:{
CapSensorType_t Sensor;
memcpy((uint8_t *)&Sensor, SensorData, sizeof(CapSensorType_t));
MAIN_DBG_LOG("Sensor%d Type %04x: Accx=%04d, Accy=%04d, Accz=%04d, Cap1=%04d, Cap2=%04d\r\n",
SensorIdx, SensorType, Sensor.AccX, Sensor.AccY, Sensor.AccZ,
Sensor.Capacitance1, Sensor.Capacitance2);
break;
}
case VIBRATE_SENSOR:
break;
case DEFM_3D_SENSOR:{
Defm3DSensorType_t Sensor;
memcpy((uint8_t *)&Sensor, SensorData, sizeof(Defm3DSensorType_t));
MAIN_DBG_LOG("Sensor%d Type %04x: Accx=%04d, Accy=%04d, Accz=%04d\r\n",
SensorIdx, SensorType, Sensor.AccX, Sensor.AccY, Sensor.AccZ);
break;
}
case STRAIN_2_SENSOR: {
Strain2SensorType_t Sensor;
memcpy((uint8_t *)&Sensor, SensorData, sizeof(Strain2SensorType_t));
MAIN_DBG_LOG("Sensor%d Type %04x: Accx=%d, Accy=%d, Accz=%d, Strain1=%d, Strain2=%d\r\n",
SensorIdx, SensorType, Sensor.AccX, Sensor.AccY, Sensor.AccZ, Sensor.Strain1, Sensor.Strain2);
break;
}
case CRACK_2_SENSOR:
case CRACK_SENSOR: {
CrackSensorType_t Sensor;
memcpy((uint8_t *)&Sensor, SensorData, sizeof(CrackSensorType_t));
MAIN_DBG_LOG("Sensor%d Type %04x: AccxL=%04d, AccyL=%04d, AcczL=%04d, MegxL=%04d, MegyL=%04d, MegzL=%04d\r\n",
SensorIdx, SensorType, Sensor.AccX_L, Sensor.AccY_L, Sensor.AccZ_L, Sensor.MagX_L, Sensor.MagY_L, Sensor.MagZ_L);
MAIN_DBG_LOG(" AccxR=%04d, AccyR=%04d, AcczR=%04d, MegxR=%04d, MegyR=%04d, MegzR=%04d\r\n",
Sensor.AccX_R, Sensor.AccY_R, Sensor.AccZ_R, Sensor.MagX_R, Sensor.MagY_R, Sensor.MagZ_R);
break;
}
case POSTURE_SENSOR: {
PostureSensorType_t Sensor;
memcpy((uint8_t *)&Sensor, SensorData, sizeof(PostureSensorType_t));
MAIN_DBG_LOG("Sensor%d Type %04x: Pitch=%04d, Roll=%04d, VibStr=%04d, Temper=%04d\r\n",
SensorIdx, SensorType, Sensor.PitchAngle, Sensor.RollAngle, Sensor.VibrationStrength, Sensor.Temperature);
break;
}
case LASER_DISTANCE_SENSOR: {
LaserDistanceSensorType_t Sensor;
memcpy((uint8_t *)&Sensor, SensorData, sizeof(LaserDistanceSensorType_t));
MAIN_DBG_LOG("Sensor%d Type %04x: Distance=%d\r\n", SensorIdx, SensorType, Sensor.Distance);
break;
}
case DEFM_3D_SENSOR_MAG: {
Defm3DMegSensorType_t Sensor;
memcpy((uint8_t *)&Sensor, SensorData, sizeof(Defm3DMegSensorType_t));
MAIN_DBG_LOG("Sensor%d Type %04x: Accx=%04d, Accy=%04d, Accz=%04d, Megx=%04d, Megy=%04d, Megz=%04d\r\n",
SensorIdx, SensorType, Sensor.AccX, Sensor.AccY, Sensor.AccZ, Sensor.MegX, Sensor.MegY, Sensor.MegZ);
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;
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(CommUnitIdx >= 0) { //设备存在
MAIN_DBG_LOG("CommUnit 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;
CommUnitCmdSend(GateWay, CUHeader->DevMac, COMM_UNIT_CMD_REG, &ret, 1, Response);
return CommUnitIdx;
}
for(int i = 0; i < COMMUNIT_MUM_MAX; i++) {
if(GateWay->ConfigPara.CommUnitArray[i].RegFlag == false) {
CommUnitIdx = i;
memcpy(GateWay->ConfigPara.CommUnitArray[i].Mac, CUHeader->DevMac, 6);
GateWay->ConfigPara.CommUnitArray[i].CUType = CUHeader->DevMac[0] | (CUHeader->DevMac[1] << 8);
GateWay->ConfigPara.CommUnitArray[i].RegFlag = true;
MAIN_DBG_LOG("CommUnit register succeed!\r\n");
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++) {
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 * 2 + 7;
len = PayLoadLen + 6;
MegData = rt_malloc(len);
MegData[0] = len;
MegData[1] = NET_COMM_CMD_ADD_UNIT;
memcpy(&MegData[2], CUHeader->DevMac, 6);
memcpy(&MegData[8], PayLoad, CUHeader->PayloadLen);
CatOneEthSendQueue(MegData, len + 2);
rt_free(MegData);
}
return 0xff;
}
}
MAIN_DBG_LOG("CommUnit 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) {
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 {
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]);
}
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].SensorN = PayLoad[1];
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("Rssi:%d, Snr:%d\r\n", Rssi, Snr);
MAIN_DBG_LOG("CommUnit Mac:%02X-%02X-%02X-%02X-%02X-%02XBatLevel: %d%, SensorN: %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);
for(int i = 0; i < GateWay->ConfigPara.CommUnitArray[CommUnitIdx].SensorN; i++) {
memcpy(GateWay->CUDataArray[CommUnitIdx].Data[i], &Data[len], 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();
// if(GateWay->ConfigPara.CommUnitArray[CommUnitIdx].ConfigFlag == true) {
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
// 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);
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;
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;
if(GateWay->ConfigPara.Rs485Ch1.Enable) { //内部通讯单元处理
if(GateWay->ConfigPara.Rs485Ch1.CommUnitEnable)
RS485CmdSend(GateWay, 1, &SCPara);
else
CommUnitCmdSend(GateWay, CommUintMac, COMM_UNIT_CMD_TIME_SYNC, &rData[14], 4, GateWay->ConfigPara.Rs485Ch1.RS485Send);
}
if(GateWay->ConfigPara.Rs485Ch2.Enable) {
if(GateWay->ConfigPara.Rs485Ch2.CommUnitEnable)
RS485CmdSend(GateWay, 2, &SCPara);
else
CommUnitCmdSend(GateWay, CommUintMac, COMM_UNIT_CMD_TIME_SYNC, &rData[14], 4, GateWay->ConfigPara.Rs485Ch2.RS485Send);
}
//校准其他通讯网关
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);
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(3);
MegData[0] = 1;
MegData[1] = NET_COMM_CMD_CAIL;
MegData[2] = 1;
sLen = 3;
CatOneEthSendQueue(MegData, sLen);
rt_free(MegData);
//开始校准
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) { //内部通讯单元处理
if(GateWay->ConfigPara.Rs485Ch1.CommUnitEnable)
RS485CmdSend(GateWay, 1, &SCPara);
else
CommUnitCmdSend(GateWay, CommUintMac, COMM_UNIT_CMD_CAIL, NULL, 0, GateWay->ConfigPara.Rs485Ch1.RS485Send);
}
if(GateWay->ConfigPara.Rs485Ch2.Enable) {
if(GateWay->ConfigPara.Rs485Ch1.CommUnitEnable)
RS485CmdSend(GateWay, 2, &SCPara);
else
CommUnitCmdSend(GateWay, CommUintMac, COMM_UNIT_CMD_CAIL, NULL, 0, GateWay->ConfigPara.Rs485Ch2.RS485Send);
}
//校准其他通讯网关
CommUnitCmdSend(GateWay, CommUintMac, COMM_UNIT_CMD_CAIL, NULL, 0, Sx1276LoRaSendBuffer);
}
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[1] == 1) {
CommUnitCmdSend(GateWay, CommUintMac, COMM_UNIT_CMD_CAIL, NULL, 0, Sx1276LoRaSendBuffer);
}
else if(GateWay->ConfigPara.CommUnitArray[ret].Mac[1] == 2) {
if(GateWay->ConfigPara.Rs485Ch1.Enable && !GateWay->ConfigPara.Rs485Ch1.CommUnitEnable) {
CommUnitCmdSend(GateWay, CommUintMac, COMM_UNIT_CMD_CAIL, NULL, 0, GateWay->ConfigPara.Rs485Ch1.RS485Send);
}
else if(GateWay->ConfigPara.Rs485Ch2.Enable && !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(255);
int SensorCnt = 0;
sLen = 3;
if(GateWay->ConfigPara.Rs485Ch1.Enable) { //内部通讯单元处理
if(GateWay->ConfigPara.Rs485Ch1.CommUnitEnable) {
SensorCnt++;
memcpy(&MegData[sLen], GateWay->ConfigPara.Rs485Ch1.CUData.Para.Mac, 6);
sLen += 6;
}
}
if(GateWay->ConfigPara.Rs485Ch2.Enable) {
if(GateWay->ConfigPara.Rs485Ch2.CommUnitEnable) {
SensorCnt++;
memcpy(&MegData[sLen], GateWay->ConfigPara.Rs485Ch2.CUData.Para.Mac, 6);
sLen += 6;
}
}
for(int i = 0; i < COMMUNIT_MUM_MAX; i++) {
if(GateWay->ConfigPara.CommUnitArray[i].RegFlag) {
SensorCnt++;
memcpy(&MegData[sLen], GateWay->ConfigPara.CommUnitArray[i].Mac, 6);
sLen += 6;
}
}
MegData[sLen++] = GateWay->Battery;
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 - 2;
MegData[1] = NET_COMM_CMD_READ_GW_INFO;
MegData[2] = SensorCnt;
CatOneEthSendQueue(MegData, sLen);
rt_free(MegData);
break;
}
case NET_COMM_CMD_READ_UNIT_INFO: {
MegData = rt_malloc(40);
sLen = 2;
CommUnitPara CUnit;
if(GateWay->ConfigPara.Rs485Ch1.Enable) { //内部通讯单元处理
if(GateWay->ConfigPara.Rs485Ch1.CommUnitEnable) {
if(memcmp(GateWay->ConfigPara.Rs485Ch1.CUData.Para.Mac, Data, 6) == 0)
CUnit = &GateWay->ConfigPara.Rs485Ch1.CUData.Para;
}
}
else if(GateWay->ConfigPara.Rs485Ch2.Enable) {
if(GateWay->ConfigPara.Rs485Ch2.CommUnitEnable) {
if(memcmp(GateWay->ConfigPara.Rs485Ch2.CUData.Para.Mac, Data, 6) == 0)
CUnit = &GateWay->ConfigPara.Rs485Ch2.CUData.Para;
}
}
else {
int ret = CheckCommUnitReg(GateWay, Data);
if(ret < 0)
return -1;
CUnit = &GateWay->ConfigPara.CommUnitArray[ret];
}
if(CUnit->SensorN > 16)
return -1;
memcpy(&MegData[sLen], CUnit->Mac, 6);
sLen += 6;
MegData[sLen++] = CUnit->SensorN;
//memcpy(&MegData[sLen], CUnit->SensorType, CUnit->SensorN * 2);
//sLen += CUnit->SensorN * 2;
uint8_t Sensor = 0;
for(int i = 0; i < SENSOR_NUM_MAX; i++) {
if(CUnit->SensorType[i] != 0x0000) {
MegData[sLen++] = CUnit->SensorType[i] & 0x00ff;
MegData[sLen++] = (CUnit->SensorType[i] >> 8) & 0x00ff;
Sensor++;
}
if(Sensor >= CUnit->SensorN)
break;
}
MegData[0] = sLen - 2;
MegData[1] = NET_COMM_CMD_READ_UNIT_INFO;
CatOneEthSendQueue(MegData, sLen);
rt_free(MegData);
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 + 10);
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_MUM_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;
}
}
WritePara((uint8_t *)&GateWay->ConfigPara, sizeof(GWConfigPara_t));
}
else {
int CommUnitIdx = CheckCommUnitReg(GateWay, LPDevConfig->CommDevAddr);
if(CommUnitIdx >= 0) {
GateWay->ConfigPara.CommUnitArray[CommUnitIdx].CollectInterval = LPDevConfig->CollectInterval;
GateWay->ConfigPara.CommUnitArray[CommUnitIdx].ReportInterval = LPDevConfig->ReportInterval;
GateWay->ConfigPara.CommUnitArray[CommUnitIdx].ERInterval = LPDevConfig->ERInterval;
GateWay->ConfigPara.CommUnitArray[CommUnitIdx].ERTime = LPDevConfig->ERTime;
GateWay->ConfigPara.CommUnitArray[CommUnitIdx].ConfigFlag = true;
WritePara((uint8_t *)&GateWay->ConfigPara, sizeof(GWConfigPara_t));
}
}
break;
}
default:
break;
}
return 0;
}