6444 lines
220 KiB
C
6444 lines
220 KiB
C
/*
|
||
*********************************************************************************************************
|
||
* IAR Development Kits
|
||
* on the
|
||
*
|
||
* M451
|
||
*
|
||
* Filename : uart_dtu.c
|
||
* Version : V1.00
|
||
* Programmer(s) : Qian Xianghong
|
||
*********************************************************************************************************
|
||
*/
|
||
|
||
#include "includes.h"
|
||
#include "cJSON.h"
|
||
// 初始唤醒次数(快速发送)
|
||
#define INITIAL_TRAN_COUNT 6
|
||
|
||
// 绝对值
|
||
#define abs(x) ((x) < 0 ? -(x) : (x))
|
||
|
||
// GPS上报数据的时间戳,年基数为2010
|
||
#define GPS_BASE_YEAR 2010
|
||
|
||
// Boot-loader地址(在线升级以后重启运行)
|
||
#define LDROM_BASE 0x100000ul // 1M
|
||
|
||
// GPRS串口接收的循环缓冲
|
||
#define DTU_TASKM_DATA_COUNT 200
|
||
loopbuff_t DTU_TaskM;
|
||
uint8_t DTU_TaskM_Data[sizeof(uint8_t) * (DTU_TASKM_DATA_COUNT + 1)] = {0};
|
||
|
||
// GPS开启计时
|
||
volatile uint32_t DTU_gpsTime = 0;
|
||
|
||
// 强制上传数据
|
||
volatile uint8_t DTU_dataConn = 0;
|
||
// 强制连接维护平台
|
||
volatile uint8_t DTU_ldmsConn = 0;
|
||
// 维护平台连接计时
|
||
volatile uint32_t DTU_ldmsTime = 0;
|
||
// 最近一条上传数据的采集时间
|
||
volatile uint32_t DTU_dataTime = 0;
|
||
|
||
// 串口超时定时器
|
||
const uint16_t DTU_tmrQPendLong = 120; // 120s
|
||
const uint16_t DTU_tmrQPendShort = 5; // 5s
|
||
const uint16_t DTU_tmrQPendSpec = 40; // 40s
|
||
|
||
// 发送成功时间
|
||
volatile uint32_t DTU_succTime = 0;
|
||
|
||
// DTU上电标志
|
||
uint8_t DTU_hasPowered = 0;
|
||
uint8_t DTU_imeiRead = 0;
|
||
uint8_t DTU_simCard = 0;
|
||
uint8_t DTU_simReg = 0;
|
||
uint8_t DTU_gprsReg = 0;
|
||
uint8_t DTU_isATMode = 0;
|
||
uint8_t DTU_gprsAttached = 0;
|
||
uint8_t DTU_linkEstablished = 0;
|
||
uint8_t DTU_sslConfig = 0;
|
||
uint8_t DTU_mqttConfig = 0;
|
||
uint8_t DTU_ipFetched = 0;
|
||
char DTU_APN[20] = "";
|
||
uint8_t DTU_isRMCFormat = 0;
|
||
uint8_t DTU_fail_count = 0;
|
||
uint8_t DTU_shutdown_count = 0;
|
||
|
||
// 是否需要检查并重启GPS
|
||
uint8_t DTU_needCheckGPS = 0;
|
||
void DTU_CheckGPS();
|
||
// GPRS拨号
|
||
uint32_t Sim808_GPRSDial();
|
||
// 从服务器获取当前时间
|
||
void DTU_setOffsetSecondsFromServer();
|
||
|
||
// 这个缓冲区比较大,不放在stack里面
|
||
#define DTU_GPSDATA_SIZE 120
|
||
char DTU_gpsData[2][DTU_GPSDATA_SIZE] = {0}; // 扩展内存
|
||
#define DTU_RECVBUFF_SIZE 200
|
||
char DTU_recvBuff[DTU_RECVBUFF_SIZE] = {0}; // 扩展内存
|
||
|
||
// 一次请求升级包数据大小
|
||
#define UPGRADE_DATA_LEN 1024
|
||
|
||
// DTU_Task任务和服务器之间的收发缓冲
|
||
#define TASK_SENDBUFF_SIZE 800
|
||
uint8_t Task_sendBuff[TASK_SENDBUFF_SIZE] = {0}; // 扩展内存
|
||
|
||
#if UPGRADE_DATA_LEN >= SFLASH_ERASE_SIZE
|
||
#define TASK_RECVBUFF_SIZE (UPGRADE_DATA_LEN + 32)
|
||
#else
|
||
#define TASK_RECVBUFF_SIZE (SFLASH_ERASE_SIZE)
|
||
#endif
|
||
uint8_t Task_recvBuff[TASK_RECVBUFF_SIZE] = {0}; // 扩展内存
|
||
|
||
// 信号量,用于通知执行任务
|
||
volatile uint8_t DTU_semGPS = 0;
|
||
volatile uint8_t DTU_semGPRS = 0;
|
||
volatile uint8_t DTU_semSync = 0;
|
||
|
||
// **************** 上传GPS调试信息 ********************
|
||
// GPS闪断次数:取值为0~599循环计数
|
||
uint16_t GPS_BOD_COUNT = 0;
|
||
// *****************************************************
|
||
|
||
// 用于发送到服务器的数据结构
|
||
// 和蓝牙的相应命令一致
|
||
#pragma pack(push, 1)
|
||
|
||
typedef struct
|
||
{
|
||
uint16_t mark;
|
||
unsigned ver : 7;
|
||
unsigned trans : 1;
|
||
unsigned reserved: 8;
|
||
uint16_t len;
|
||
union
|
||
{
|
||
uint16_t cmd;
|
||
struct
|
||
{
|
||
uint8_t err;
|
||
uint8_t cmd_L;
|
||
};
|
||
};
|
||
} bluetooth_recv_t;
|
||
|
||
typedef bluetooth_recv_t bluetooth_send_t;
|
||
|
||
typedef struct
|
||
{
|
||
unsigned staEPress3 : 2;
|
||
unsigned staETempr1 : 2;
|
||
unsigned staETempr2 : 2;
|
||
unsigned staETempr3 : 2;
|
||
|
||
unsigned staDiff : 2;
|
||
unsigned staPress : 2;
|
||
unsigned staEPress1 : 2;
|
||
unsigned staEPress2 : 2;
|
||
|
||
} bluetooth_sensor_t;
|
||
|
||
typedef struct
|
||
{
|
||
unsigned maskStamp : 1;
|
||
unsigned maskEPress1 : 1;
|
||
unsigned maskEPress2 : 1;
|
||
unsigned maskEPress3 : 1;
|
||
unsigned : 1;
|
||
unsigned maskLowPower : 1;
|
||
unsigned maskAbnormal : 1;
|
||
unsigned maskCharging : 1;
|
||
|
||
unsigned maskRssi : 1;
|
||
unsigned maskGPS : 1;
|
||
unsigned maskETempr1 : 1;
|
||
unsigned maskETempr2 : 1;
|
||
unsigned maskETempr3 : 1;
|
||
unsigned maskBattery : 1;
|
||
unsigned maskFlow : 1;
|
||
unsigned maskLeak : 1;
|
||
} bluetooth_mask_t;
|
||
|
||
typedef union
|
||
{
|
||
struct
|
||
{
|
||
unsigned sec : 6;
|
||
unsigned min : 6;
|
||
unsigned hour_L : 4;
|
||
unsigned hour_H : 1;
|
||
unsigned day : 5;
|
||
unsigned mon : 4;
|
||
unsigned year : 6;
|
||
};
|
||
uint32_t tm;
|
||
} bluetooth_timestamp_t;
|
||
|
||
typedef union
|
||
{
|
||
unsigned long long ll;
|
||
struct
|
||
{
|
||
unsigned long l;
|
||
unsigned long h;
|
||
};
|
||
} longlong_mask_t;
|
||
|
||
typedef struct
|
||
{
|
||
union
|
||
{
|
||
struct
|
||
{
|
||
unsigned sateCount : 5; // gps可见卫星数量
|
||
unsigned posState : 1; // gps定位状态 (0-GPS未定位,1-GPS已定位)
|
||
unsigned carState : 1; // 车辆是否启动 (0-车辆未启动,1-车辆已启动)
|
||
unsigned carEvent : 1; // 车辆启动或停止事件(0-启动状态未改变,1-启动状态已改变)
|
||
};
|
||
uint8_t state;
|
||
};
|
||
bluetooth_timestamp_t time; // 时间戳
|
||
int32_t latitude;
|
||
int32_t longitude;
|
||
uint16_t speed;
|
||
} gps_data_t;
|
||
|
||
typedef struct // size = 158
|
||
{
|
||
uint32_t sample_time; // 采集时间:自启动以来经过的秒数
|
||
data_dtu_t dtuData; // size = 36
|
||
data_sample_t sampleData; // size = 118
|
||
} gprs_data_t;
|
||
|
||
// 双向通讯的数据结构
|
||
typedef struct // size = 120
|
||
{
|
||
uint16_t serverVer; // 服务器参数版本号
|
||
uint8_t type; // 储罐类型
|
||
uint32_t diameter; // 内径
|
||
uint32_t len; // 圆柱体长度
|
||
uint32_t lenExtra; // 直边封头长度
|
||
uint32_t reserved_1[3];
|
||
uint8_t source; // 液源
|
||
uint32_t density; // 各液源的比重(kg/m3)
|
||
uint16_t fullPct; // 满液位百分比
|
||
uint16_t priPct; // 关键液位百分比
|
||
uint16_t orderPct; // 订货液位百分比
|
||
uint16_t emptyPct; // 空液位百分比
|
||
uint32_t planMount; // 每日计划用量
|
||
uint32_t predictMount; // 每日预测用量
|
||
uint16_t warnVolt; // 电压报警低点: 10mV
|
||
uint16_t warnVoltH; // 电压报警高点: 10mV
|
||
uint16_t warnPress; // 压力报警低点: KPa
|
||
uint16_t warnPressH; // 压力报警高点: KPa
|
||
uint32_t intervalTrans; // 数据上报周期
|
||
uint32_t intervalSample; // 数据采集周期
|
||
uint32_t intervalGPSTrans; // 位置上报周期
|
||
uint32_t intervalGPS; // 位置采集周期
|
||
union
|
||
{
|
||
struct
|
||
{
|
||
char gpsServer[20]; // 远传服务器 (只上传,不修改)
|
||
int16_t gpsPort; // 远传端口 (只上传,不修改)
|
||
char pwd1[6]; // 储罐参数修改密码
|
||
};
|
||
struct
|
||
{
|
||
char gprsServer[26]; // praxair:修改数据服务器地址
|
||
int16_t gprsPort; // praxair: 修改数据服务器端口
|
||
};
|
||
};
|
||
uint32_t options; // 参数开关
|
||
union
|
||
{
|
||
uint8_t reserved_2[12];
|
||
struct
|
||
{
|
||
uint16_t floorLevel; // praxair: 液量报警下限
|
||
uint16_t span; // praxair: 液量变化报警门限
|
||
uint16_t spanPeriod; // praxair: 液量变化报警时间
|
||
unsigned floorLevelAssigned : 1; // praxair: 参数中floorLevel是否有效
|
||
unsigned spanAssigned : 1; // praxair: 参数中span是否有效
|
||
unsigned spanPeriodAssigned : 1; // praxair: 参数中spanPeriod是否有效
|
||
unsigned intervalTransAssigned : 1; // praxair: 参数中intervalTrans是否有效
|
||
unsigned gprsServerAssigned : 1; // praxair: 参数中数据服务器地址是否有效
|
||
unsigned gprsPortAssigned : 1; // praxair: 参数中数据服务器端口是否有效
|
||
unsigned : 2;
|
||
};
|
||
};
|
||
uint32_t ts; // 参数时间戳
|
||
} param_data_t;
|
||
|
||
// 升级进度信息(存放在FRAM中,可断点续传)
|
||
typedef struct
|
||
{
|
||
uint16_t check; // 标志,固定为0x55AA
|
||
uint32_t ver; // 固件版本
|
||
int32_t fileSize; // 固件总字节数
|
||
uint16_t fileCrc; // 固件总的crc
|
||
int32_t offset; // 本次固件偏移量
|
||
int32_t len; // 本次数据长度
|
||
uint16_t crc; // 本记录的crc
|
||
} upgrade_info_t;
|
||
|
||
// 升级包接收记录
|
||
typedef struct
|
||
{
|
||
uint32_t ver; // 固件版本
|
||
int32_t fileSize; // 固件总字节数
|
||
uint16_t fileCrc; // 固件总的crc
|
||
int32_t offset; // 本次固件偏移量
|
||
int32_t len; // 本次数据长度
|
||
uint8_t data[UPGRADE_DATA_LEN]; // 本次数据
|
||
uint16_t crc; // 本次数据的crc
|
||
} upgrade_frame_t;
|
||
|
||
// 升级文件头
|
||
typedef struct // size=12
|
||
{
|
||
unsigned short check; // 数据有效标志, 0x55AA表示有效
|
||
unsigned upgrade_request : 1; // 升级请求标志,0-无升级,1-有升级
|
||
unsigned upgrade_result : 3; // 升级失败标志,0-成功,1-失败,其余保留
|
||
unsigned encrypt_flag : 2; // 加密标志, 0-无加密,其余保留
|
||
unsigned compress_flag : 2; // 压缩标志, 0-无压缩,1-有压缩,其余保留
|
||
unsigned rerseved1 : 8; // 保留,必须为0xFF
|
||
|
||
unsigned long upgrade_length; // 升级文件长度
|
||
|
||
unsigned rerseved2 : 8; // 保留,必须为0xFF
|
||
unsigned rerseved3 : 8; // 保留,必须为0xFF
|
||
unsigned short crc; // 对前面内容的crc校验
|
||
} TUpgradeHeader;
|
||
|
||
// 阿里云密钥记录
|
||
typedef struct // size=76
|
||
{
|
||
unsigned short check; // 数据有效标志, 0x55AA表示有效
|
||
uint8_t PSN[6]; // 获取密钥所用的PSN(如果PSN改变需重新获取)
|
||
char product[12]; // 产品代码
|
||
char device[21]; // 默认为cPSN
|
||
char secret[33]; // 设备密钥
|
||
unsigned short crc; // 对前面内容的crc校验
|
||
} TAliyunSecret;
|
||
|
||
#define ALIYUN_SECRET_SIZE (66)
|
||
|
||
#pragma pack(pop)
|
||
|
||
// 阿里云密钥
|
||
TAliyunSecret aliyunSecret = {0};
|
||
|
||
// 升级包记录
|
||
upgrade_info_t upInfo = {0};
|
||
|
||
// GPS循环缓冲记录
|
||
loopbuff_t gpsBuff = {0};
|
||
|
||
// 存放GPRS记录的循环缓冲
|
||
loopbuff_t gprsBuff = {0};
|
||
loopbuff_t bd_gprsBuff = {0};
|
||
// GPRS记录读写缓冲
|
||
gprs_data_t gprsRWBuf;
|
||
|
||
void pack_param_DO23_data(param_data_t *param)
|
||
{
|
||
memset(param, 0, sizeof(param_data_t));
|
||
param->serverVer = htons(dcBuff.configBottle.serverVer);
|
||
param->type = dcBuff.configBottle.type;
|
||
param->diameter = htonl(dcBuff.configBottle.diameter);
|
||
param->len = htonl(dcBuff.configBottle.len);
|
||
param->lenExtra = htonl(dcBuff.configBottle.lenExtra);
|
||
param->source = dcBuff.configBottle.source;
|
||
param->density = htonl(Config_GetDensity(dcBuff.configBottle.source) * 1000);
|
||
param->fullPct = htons(dcBuff.configBottle.fullPct);
|
||
param->priPct = htons(dcBuff.configBottle.priPct);
|
||
param->orderPct = htons(dcBuff.configBottle.orderPct);
|
||
param->emptyPct = htons(dcBuff.configBottle.emptyPct);
|
||
param->planMount = htonl(dcBuff.configBottle.planMount);
|
||
param->predictMount = htonl(dcBuff.configBottle.predictMount);
|
||
param->warnVolt = htons(dcBuff.configBottle.warnVolt);
|
||
param->warnVoltH = htons(dcBuff.configBottle.warnVoltH);
|
||
param->warnPress = htons(dcBuff.configBottle.warnPress);
|
||
param->warnPressH = htons(dcBuff.configBottle.warnPressH);
|
||
param->intervalTrans = htonl(dcBuff.configData.intervalTrans);
|
||
param->intervalSample = htonl(dcBuff.configData.intervalSample);
|
||
param->intervalGPSTrans = htonl(dcBuff.configData.intervalGPSTrans);
|
||
param->intervalGPS = htonl(dcBuff.configData.intervalGPS);
|
||
if(dcBuff.configBottle.serverVer != 3)
|
||
{
|
||
strcpy(param->gpsServer, dcBuff.configData.gpsServer);
|
||
param->gpsPort = htons(dcBuff.configData.gpsPort);
|
||
strcpy(param->pwd1, dcBuff.configDisplay.pwd1);
|
||
}
|
||
param->options = dcBuff.configBottle.options;
|
||
if(dcBuff.configBottle.dispMode == DISP_MODE_ALL)
|
||
param->options |= 0x0003ul;
|
||
else
|
||
param->options &= ~0x0003ul;
|
||
param->options = htonl(param->options);
|
||
param->ts = htonl(dcBuff.configBottle.ts);
|
||
|
||
// praxair
|
||
memset(param->reserved_2, 0, sizeof(param->reserved_2));
|
||
if(dcBuff.configBottle.serverVer == 3)
|
||
{
|
||
param->floorLevel = htons(dcBuff.configBottle.floorLevel);
|
||
param->floorLevelAssigned = 1;
|
||
param->span = htons(dcBuff.configBottle.span);
|
||
param->spanAssigned = 1;
|
||
param->spanPeriod = htons(dcBuff.configBottle.spanPeriod);
|
||
param->spanPeriodAssigned = 1;
|
||
param->intervalTransAssigned = 1;
|
||
strcpy(param->gprsServer, dcBuff.configData.server);
|
||
param->gprsServerAssigned = 1;
|
||
param->gprsPort = htons(dcBuff.configData.port);
|
||
param->gprsPortAssigned = 1;
|
||
}
|
||
}
|
||
|
||
void parse_param_D021_data(param_data_t *param)
|
||
{
|
||
int serverVer = ntohs(param->serverVer);
|
||
dcBuff.configBottle.serverVer = serverVer;
|
||
|
||
if(serverVer == 3) // praxair
|
||
{
|
||
if(param->floorLevelAssigned)
|
||
dcBuff.configBottle.floorLevel = ntohs(param->floorLevel);
|
||
if(param->spanAssigned)
|
||
dcBuff.configBottle.span = ntohs(param->span);
|
||
if(param->spanPeriodAssigned)
|
||
dcBuff.configBottle.spanPeriod = ntohs(param->spanPeriod);
|
||
if(param->intervalTransAssigned)
|
||
dcBuff.configData.intervalTrans = ntohl(param->intervalTrans);
|
||
if(param->gprsServerAssigned)
|
||
{
|
||
strcpy(dcBuff.configData.server, param->gprsServer);
|
||
strcpy(dcBuff.configData.upgServer, param->gprsServer);
|
||
strcpy(dcBuff.configData.gpsServer, param->gprsServer);
|
||
}
|
||
if(param->gprsPortAssigned)
|
||
{
|
||
dcBuff.configData.port = ntohs(param->gprsPort);
|
||
dcBuff.configData.upgPort = dcBuff.configData.port + 1;
|
||
dcBuff.configData.gpsPort = dcBuff.configData.port + 2;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
dcBuff.configBottle.type = param->type;
|
||
dcBuff.configBottle.diameter = ntohl(param->diameter);
|
||
dcBuff.configBottle.len = ntohl(param->len);
|
||
dcBuff.configBottle.lenExtra = ntohl(param->lenExtra);
|
||
dcBuff.configBottle.source = param->source;
|
||
Config_SetDensity(dcBuff.configBottle.source, ntohl(param->density) / 1000.0);
|
||
dcBuff.configBottle.fullPct = ntohs(param->fullPct);
|
||
dcBuff.configBottle.priPct = ntohs(param->priPct);
|
||
dcBuff.configBottle.orderPct = ntohs(param->orderPct);
|
||
dcBuff.configBottle.emptyPct = ntohs(param->emptyPct);
|
||
dcBuff.configBottle.planMount = ntohl(param->planMount);
|
||
dcBuff.configBottle.predictMount = ntohl(param->predictMount);
|
||
dcBuff.configBottle.warnVolt = ntohs(param->warnVolt);
|
||
dcBuff.configBottle.warnVoltH = ntohs(param->warnVoltH);
|
||
dcBuff.configBottle.warnPress = ntohs(param->warnPress);
|
||
dcBuff.configBottle.warnPressH = ntohs(param->warnPressH);
|
||
dcBuff.configData.intervalTrans = ntohl(param->intervalTrans);
|
||
dcBuff.configData.intervalSample = ntohl(param->intervalSample);
|
||
|
||
// 以下参数只做上传,不做修改
|
||
// dcBuff.configData.intervalGPSTrans = ntohl(param->intervalGPSTrans);
|
||
// dcBuff.configData.intervalGPS = ntohl(param->intervalGPS);
|
||
// strcpy(dcBuff.configData.gpsServer, param->gpsServer);
|
||
// dcBuff.configData.gpsPort = ntohs(param->gpsPort);
|
||
// strcpy(dcBuff.configDisplay.pwd1, param->pwd1);
|
||
|
||
dcBuff.configBottle.options = ntohl(param->options);
|
||
if(dcBuff.configBottle.options & 0x0003ul)
|
||
dcBuff.configBottle.dispMode = DISP_MODE_ALL;
|
||
else
|
||
dcBuff.configBottle.dispMode = DISP_MODE_DPRESS;
|
||
dcBuff.configBottle.ts = ntohl(param->ts);
|
||
}
|
||
}
|
||
|
||
// 是否GPS定位
|
||
volatile uint8_t GPS_Locate = 1;
|
||
volatile uint8_t GPS_Located = 0;
|
||
volatile uint32_t GPS_waitTick = 0;
|
||
volatile uint8_t GPS_Waiting = 0;
|
||
// GPS定位超时
|
||
const uint8_t DTU_tmrLocate = 90;
|
||
|
||
// GPS发送数据
|
||
volatile uint32_t GPS_tranTick = 0;
|
||
|
||
// 保存上次数据的时间
|
||
bluetooth_timestamp_t GPS_LastTime = {0};
|
||
|
||
// 是否发送GPRS数据
|
||
uint8_t GPRS_Send_Task = 0;
|
||
uint32_t GPRS_Send_Time = 0;
|
||
// 是否保存GPRS数据
|
||
uint8_t GPRS_Save_Task = 0;
|
||
uint32_t GPRS_Save_Time = 0;
|
||
|
||
// 计算两个经纬度之间的距离
|
||
const double EARTH_RADIUS = 6378.137;
|
||
double rad(double d)
|
||
{
|
||
return d * PI / 180.0;
|
||
}
|
||
|
||
double GetDistance(int32_t lat1, int32_t lng1, int32_t lat2, int32_t lng2)
|
||
{
|
||
double radLat1 = rad(lat1 * 0.000001);
|
||
double radLat2 = rad(lat2 * 0.000001);
|
||
double a = radLat1 - radLat2;
|
||
double b = rad(lng1 * 0.000001) - rad(lng2 * 0.000001);
|
||
double s = 2 * asin(sqrt(pow(sin(a / 2), 2) +
|
||
cos(radLat1) * cos(radLat2) * pow(sin(b / 2), 2)));
|
||
s = s * EARTH_RADIUS;
|
||
return s;
|
||
}
|
||
|
||
// 比较新数据的时间,是否晚于老数据的时间
|
||
int32_t GPS_IsLateThan(bluetooth_timestamp_t *pNewTime, bluetooth_timestamp_t *pOldTime)
|
||
{
|
||
uint8_t newHour = (pNewTime->hour_H << 4) | pNewTime->hour_L;
|
||
uint8_t oldHour = (pOldTime->hour_H << 4) | pOldTime->hour_L;
|
||
|
||
if(pNewTime->year > pOldTime->year)
|
||
return TRUE;
|
||
if(pNewTime->year < pOldTime->year)
|
||
return FALSE;
|
||
if(pNewTime->mon > pOldTime->mon)
|
||
return TRUE;
|
||
if(pNewTime->mon < pOldTime->mon)
|
||
return FALSE;
|
||
if(pNewTime->day > pOldTime->day)
|
||
return TRUE;
|
||
if(pNewTime->day < pOldTime->day)
|
||
return FALSE;
|
||
if(newHour > oldHour)
|
||
return TRUE;
|
||
if(newHour < oldHour)
|
||
return FALSE;
|
||
if(pNewTime->min > pOldTime->min)
|
||
return TRUE;
|
||
if(pNewTime->min < pOldTime->min)
|
||
return FALSE;
|
||
|
||
return pNewTime->sec > pOldTime->sec;
|
||
}
|
||
|
||
// 计算两个时间间隔的秒数
|
||
uint32_t GPS_CalcInterval(bluetooth_timestamp_t *pNewTime, bluetooth_timestamp_t *pOldTime)
|
||
{
|
||
// 计算从OldYear以来的秒数
|
||
uint32_t newSeconds = Calc_SecondsFromYear(GPS_BASE_YEAR + pOldTime->year, pNewTime->year + GPS_BASE_YEAR, pNewTime->mon,
|
||
pNewTime->day, (pNewTime->hour_H << 4) | pNewTime->hour_L, pNewTime->min, pNewTime->sec);
|
||
uint32_t oldSeconds = Calc_SecondsFromYear(GPS_BASE_YEAR + pOldTime->year, pOldTime->year + GPS_BASE_YEAR, pOldTime->mon,
|
||
pOldTime->day, (pOldTime->hour_H << 4) | pOldTime->hour_L, pOldTime->min, pOldTime->sec);
|
||
|
||
return newSeconds - oldSeconds;
|
||
}
|
||
|
||
// 将一个数据加入队列
|
||
void GPS_PutToQueue(gps_data_t *gps)
|
||
{
|
||
uint16_t nextPtr;
|
||
|
||
// 如果要添加数据的时间大于上一条数据的时间
|
||
if(GPS_LastTime.year == 0 || GPS_IsLateThan(&gps->time, &GPS_LastTime))
|
||
{
|
||
// 移动写指针
|
||
nextPtr = LoopBuff_GetNextPtr(&gpsBuff, gpsBuff.info.wtPtr);
|
||
|
||
// 如果队列已满
|
||
if(nextPtr == gpsBuff.info.rdPtr)
|
||
{
|
||
// 移动读指针(丢弃第一条数据)
|
||
gpsBuff.info.rdPtr = LoopBuff_GetNextPtr(&gpsBuff, gpsBuff.info.rdPtr);
|
||
}
|
||
|
||
// 将新数据加到最后
|
||
FRAM_BufferWrite(LoopBuff_GetDataPos(&gpsBuff, gpsBuff.info.wtPtr), (uint8_t *) gps, sizeof(gps_data_t));
|
||
gpsBuff.info.wtPtr = nextPtr;
|
||
// 保存到铁电
|
||
FRAM_SaveInfo(gpsBuff.info_base, (uint8_t *) &gpsBuff.info, sizeof(gpsBuff.info));
|
||
|
||
GPS_LastTime = gps->time;
|
||
}
|
||
}
|
||
|
||
// 将一个数据加入队列
|
||
void GPRS_PutToQueue(loopbuff_t *lpBuff, data_dtu_t *dtuData, data_sample_t *sampleData)
|
||
{
|
||
uint16_t nextPtr;
|
||
S_RTC_TIME_DATA_T sRTC;
|
||
gprs_data_t *gprs;
|
||
|
||
// 移动写指针
|
||
nextPtr = LoopBuff_GetNextPtr(lpBuff, lpBuff->info.wtPtr);
|
||
|
||
// 如果队列已满
|
||
if(nextPtr == lpBuff->info.rdPtr)
|
||
{
|
||
// 移动读指针(丢弃第一条数据)
|
||
lpBuff->info.rdPtr = LoopBuff_GetNextPtr(lpBuff, lpBuff->info.rdPtr);
|
||
}
|
||
|
||
// 将新数据加到最后
|
||
gprs = &gprsRWBuf;
|
||
// 获取当前时间
|
||
RTC_GetDateAndTime(&sRTC);
|
||
// 计算自上次gps定位以来的时间
|
||
gprs->sample_time = Calc_SecondsFromYear(INITIAL_YEAR, sRTC.u32Year, sRTC.u32Month, sRTC.u32Day,
|
||
sRTC.u32Hour, sRTC.u32Minute, sRTC.u32Second);
|
||
gprs->dtuData = *dtuData;
|
||
gprs->sampleData = *sampleData;
|
||
FRAM_BufferWrite(LoopBuff_GetDataPos(lpBuff, lpBuff->info.wtPtr), (uint8_t *) gprs, sizeof(gprs_data_t));
|
||
|
||
lpBuff->info.wtPtr = nextPtr;
|
||
}
|
||
|
||
// 将前面几条数据移出队列
|
||
void GPS_MoveFromQueue(uint8_t count)
|
||
{
|
||
LoopBuff_RemoveItems(&gpsBuff, count);
|
||
// 保存到铁电
|
||
FRAM_SaveInfo(gpsBuff.info_base, (uint8_t *) &gpsBuff.info, sizeof(gpsBuff.info));
|
||
}
|
||
|
||
// 查找队列前面的数据, 找出时间间隔相同的一组,最多max_count条
|
||
// 本函数在调用的地方加锁,因为这个函数返回以后接着要取数据
|
||
uint8_t GPS_LookData(uint8_t max_count, uint16_t *interval, uint8_t *done)
|
||
{
|
||
uint8_t count = 0;
|
||
uint8_t i;
|
||
uint16_t gps_count = 0, nextPtr;
|
||
gps_data_t gps0, gps1;
|
||
|
||
*interval = 0;
|
||
*done = 1;
|
||
|
||
if(max_count < 1)
|
||
return 0;
|
||
|
||
// 获取未发送记录条数
|
||
gps_count = LoopBuff_GetCount(&gpsBuff);
|
||
if(gps_count < 2)
|
||
return gps_count;
|
||
|
||
count = 2;
|
||
FRAM_BufferRead(LoopBuff_GetDataPos(&gpsBuff, gpsBuff.info.rdPtr), (uint8_t *) &gps0, sizeof(gps_data_t));
|
||
nextPtr = LoopBuff_GetNextPtr(&gpsBuff, gpsBuff.info.rdPtr);
|
||
FRAM_BufferRead(LoopBuff_GetDataPos(&gpsBuff, nextPtr), (uint8_t *) &gps1, sizeof(gps_data_t));
|
||
*interval = GPS_CalcInterval(&gps1.time, &gps0.time);
|
||
for(i = 2; count < max_count && i < gps_count; i++)
|
||
{
|
||
// 如果后面的时间间隔不一样
|
||
gps0 = gps1;
|
||
nextPtr = LoopBuff_GetNextPtr(&gpsBuff, nextPtr);
|
||
FRAM_BufferRead(LoopBuff_GetDataPos(&gpsBuff, nextPtr), (uint8_t *) &gps1, sizeof(gps_data_t));
|
||
if(GPS_CalcInterval(&gps1.time, &gps0.time) != *interval)
|
||
break;
|
||
count++;
|
||
}
|
||
if(i < gps_count)
|
||
*done = 0;
|
||
return count;
|
||
}
|
||
|
||
// 将采集数据中的传感器状态转换为蓝牙协议中的状态
|
||
static uint8_t Bluetooth_ConvertStat(sensor_status_t *pStat)
|
||
{
|
||
if(pStat->notConnect)
|
||
return 3;
|
||
if(pStat->overFlow)
|
||
return 1;
|
||
if(pStat->underFlow)
|
||
return 2;
|
||
return 0;
|
||
}
|
||
|
||
// GPS uart
|
||
void UART1_IRQHandler(void)
|
||
{
|
||
uint8_t u8DTU;
|
||
|
||
if(UART_GET_INT_FLAG(UART1, UART_ISR_RDA_IS_Msk) || UART_GET_INT_FLAG(UART1, UART_ISR_RTO_IS_Msk)) /* Rx Ready or Time-out INT*/
|
||
{
|
||
// do
|
||
{
|
||
u8DTU = UART1->RBR;
|
||
// printf("%c", u8DTU);
|
||
// 直接处理
|
||
DTU_Task0(u8DTU);
|
||
} //while(UART_IS_RX_READY(UART1));
|
||
}
|
||
|
||
if(UART_GET_INT_FLAG(UART1, UART_ISR_BUF_ERR_IS_Msk)) /* Buffer Error INT */
|
||
{
|
||
UART_ClearIntFlag(UART1, UART_ISR_BUF_ERR_IS_Msk);
|
||
}
|
||
if(UART_GET_INT_FLAG(UART1, UART_ISR_RLS_IS_Msk)) /* RLS INT */
|
||
{
|
||
UART_ClearIntFlag(UART1, UART_ISR_RLS_IS_Msk);
|
||
}
|
||
}
|
||
|
||
// GSM uart
|
||
void SC1_IRQHandler(void)
|
||
{
|
||
uint8_t u8DTU;
|
||
|
||
if(SCUART_GET_INT_FLAG(SC1, SC_ISR_RDA_IS_Msk) || SCUART_GET_INT_FLAG(SC1, SC_ISR_RTMR_IS_Msk)) /* Rx Ready or Time-out INT*/
|
||
{
|
||
SCUART_CLR_INT_FLAG(SC1, SC_ISR_RDA_IS_Msk | SC_ISR_RTMR_IS_Msk);
|
||
//do
|
||
{
|
||
u8DTU = SC1->RBR;
|
||
// if(u8DTU == '\n')
|
||
// printf("\\n\n");
|
||
// else if(u8DTU == '\r')
|
||
// printf("\\r");
|
||
// else
|
||
// printf("%c", u8DTU);
|
||
// 加入缓冲
|
||
LoopBuff_PutItem(&DTU_TaskM, &u8DTU);
|
||
}// while(SCUART_IS_RX_READY(SC1));
|
||
}
|
||
if(SCUART_GET_INT_FLAG(SC1, SC_ISR_TERR_IS_Msk))
|
||
{
|
||
SCUART_CLR_INT_FLAG(SC1, SC_ISR_TERR_IS_Msk);
|
||
}
|
||
}
|
||
|
||
void DTU_Init()
|
||
{
|
||
/* 配置GSM端口 */
|
||
/* Select SC UART module clock source as HXT and UART module clock divider as 1 */
|
||
CLK_SetModuleClock(SC1_MODULE, CLK_CLKSEL2_SC_S_HXT, CLK_SC1_CLK_DIVIDER(1));
|
||
|
||
/*---------------------------------------------------------------------------------------------------------*/
|
||
/* Init I/O Multi-function */
|
||
/*---------------------------------------------------------------------------------------------------------*/
|
||
|
||
/* Set PC.0 and PC.1 pin for SC UART mode */
|
||
SYS->PC_L_MFP &= ~(SYS_PC_L_MFP_PC0_MFP_Msk | SYS_PC_L_MFP_PC1_MFP_Msk);
|
||
SYS->PC_L_MFP |= (SYS_PC_L_MFP_PC0_MFP_SC1_CLK | SYS_PC_L_MFP_PC1_MFP_SC1_DAT);
|
||
|
||
/* Enable SC UART module clock */
|
||
CLK_EnableModuleClock(SC1_MODULE);
|
||
|
||
/* 配置GPS端口: GPS和Debug共用一个串口,GPS用到输入,DEBUG用到输出 */
|
||
}
|
||
|
||
void DTU_Open()
|
||
{
|
||
// 分配扩展内存
|
||
// DTU_gpsData[0] = (char *) SRAM_Alloc(DTU_GPSDATA_SIZE);
|
||
// DTU_gpsData[1] = (char *) SRAM_Alloc(DTU_GPSDATA_SIZE);
|
||
// DTU_recvBuff = (char *) SRAM_Alloc(DTU_RECVBUFF_SIZE);
|
||
// Task_sendBuff = (uint8_t *) SRAM_Alloc(TASK_SENDBUFF_SIZE);
|
||
// Task_recvBuff = (uint8_t *) SRAM_Alloc(TASK_RECVBUFF_SIZE);
|
||
LoopBuff_Create(&gpsBuff, sizeof(gps_data_t), FRAM_GPS_DATA_COUNT, FRAM_GPS_INFO_BASE, FRAM_GPS_DATA_BASE);
|
||
LoopBuff_Create(&gprsBuff, sizeof(gprs_data_t), FRAM_GPRS_DATA_COUNT, FRAM_GPRS_INFO_BASE, FRAM_GPRS_DATA_BASE);
|
||
LoopBuff_Create(&bd_gprsBuff, sizeof(gprs_data_t), FRAM_BD_GPRS_DATA_COUNT, FRAM_GPRS_BD_INFO_BASE, FRAM_GPRS_BD_DATA_BASE);
|
||
LoopBuff_Create(&DTU_TaskM, sizeof(uint8_t), DTU_TASKM_DATA_COUNT, 0, (uint32_t) DTU_TaskM_Data);
|
||
|
||
/*---------------------------------------------------------------------------------------------------------*/
|
||
/* Init UART */
|
||
/*---------------------------------------------------------------------------------------------------------*/
|
||
|
||
/* 打开GSM端口 */
|
||
SYS_ResetModule(SC1_RST);
|
||
|
||
/* Configure UART0 and set UART0 baud rate */
|
||
SCUART_Open(SC1, 115200);
|
||
|
||
/* 打开GPS端口: GPS和Debug共用一个串口,GPS用到输入,DEBUG用到输出 */
|
||
|
||
/* Enable RDA\RLS\Time-out Interrupt */
|
||
SCUART_ENABLE_INT(SC1, (SC_IER_RDA_IE_Msk)); // | SC_IER_RTMR_IE_Msk));// | SC_IER_TERR_IE_Msk));
|
||
UART_ENABLE_INT(UART1, (UART_IER_RDA_IE_Msk | UART_IER_BUF_ERR_IE_Msk | UART_IER_RLS_IE_Msk)); // | UART_IER_RTO_IE_Msk));
|
||
/* Enable SC1 interrupt */
|
||
NVIC_SetPriority(SC1_IRQn, 1);
|
||
NVIC_EnableIRQ(SC1_IRQn);
|
||
NVIC_SetPriority(UART1_IRQn, 1);
|
||
NVIC_EnableIRQ(UART1_IRQn);
|
||
}
|
||
|
||
// 清空无效数据
|
||
static void DTU_ClearQueue()
|
||
{
|
||
uint8_t timeOut;
|
||
uint32_t timeOutTick;
|
||
|
||
do
|
||
{
|
||
timeOut = 1;
|
||
timeOutTick = GetDelayTick(500);
|
||
while(!IsTickOut(timeOutTick))
|
||
{
|
||
if(LoopBuff_GetCount(&DTU_TaskM))
|
||
{
|
||
timeOut = 0;
|
||
break;
|
||
}
|
||
}
|
||
LoopBuff_Clear(&DTU_TaskM);
|
||
} while(!timeOut);
|
||
}
|
||
|
||
// 等待DTU命令的返回,检查期待的结果字符串
|
||
uint32_t DTU_ParseResult(char *checkPattern, char *checkErrPattern, char *resultBuff, uint16_t waitSeconds)
|
||
{
|
||
uint8_t done = 0, timeOut;
|
||
uint32_t timeOutTick;
|
||
uint8_t u8DTU;
|
||
uint16_t count, idx = 0;
|
||
uint32_t ret = FALSE;
|
||
uint8_t strLen = strlen(checkPattern);
|
||
uint8_t errLen = strlen(checkErrPattern);
|
||
|
||
memset(DTU_recvBuff, 0, DTU_RECVBUFF_SIZE);
|
||
// 检测返回信息
|
||
do
|
||
{
|
||
timeOut = 1;
|
||
timeOutTick = GetDelayTick(waitSeconds * 1000);
|
||
while(!IsTickOut(timeOutTick))
|
||
{
|
||
// 喂狗
|
||
if(!Wakeup_Sleeping)
|
||
WDT_RESET_COUNTER();
|
||
|
||
if(LoopBuff_GetCount(&DTU_TaskM))
|
||
{
|
||
timeOut = 0;
|
||
break;
|
||
}
|
||
}
|
||
|
||
if(!timeOut)
|
||
{
|
||
count = LoopBuff_GetCount(&DTU_TaskM);
|
||
while(count--)
|
||
{
|
||
// 取数据
|
||
memmove(&u8DTU, LoopBuff_GetDataPtr(&DTU_TaskM, DTU_TaskM.info.rdPtr), 1);
|
||
LoopBuff_RemoveItems(&DTU_TaskM, 1);
|
||
|
||
// if(u8DTU == '\n')
|
||
// printf("\\n");
|
||
// else if(u8DTU == '\r')
|
||
// printf("\\r");
|
||
// else
|
||
// printf("%c", u8DTU);
|
||
|
||
// 如果是检测发送的提示符(>),直接返回成功
|
||
if(strcmp(checkPattern, ">") == 0 && u8DTU == '>')
|
||
{
|
||
strcpy(resultBuff, ">");
|
||
ret = TRUE;
|
||
|
||
done = 1;
|
||
break;
|
||
}
|
||
// 换行符
|
||
if(u8DTU == '\n')
|
||
{
|
||
// 丢掉\n前面的\r
|
||
if(idx > 0 && DTU_recvBuff[idx - 1] == '\r')
|
||
DTU_recvBuff[--idx] = 0;
|
||
|
||
// 先检查字符串(电话号码没有特征字符串)
|
||
if((strLen > 0 && strstr(DTU_recvBuff, checkPattern)) || (strLen == 0 && idx > 0))
|
||
{
|
||
DTU_recvBuff[idx] = 0;
|
||
strcpy(resultBuff, DTU_recvBuff);
|
||
ret = TRUE;
|
||
|
||
done = 1;
|
||
break;
|
||
}
|
||
// 检查返回错误的字符串
|
||
if(errLen > 0 && strstr(DTU_recvBuff, checkErrPattern))
|
||
{
|
||
DTU_recvBuff[idx] = 0;
|
||
strcpy(resultBuff, DTU_recvBuff);
|
||
ret = FALSE;
|
||
|
||
done = 1;
|
||
break;
|
||
}
|
||
// 没有所要的字符串,清空
|
||
memset(DTU_recvBuff, 0, DTU_RECVBUFF_SIZE);
|
||
idx = 0;
|
||
continue;
|
||
}
|
||
if(idx < DTU_RECVBUFF_SIZE)
|
||
DTU_recvBuff[idx++] = u8DTU;
|
||
}
|
||
}
|
||
} while(!done && !timeOut);
|
||
|
||
return ret;
|
||
}
|
||
|
||
// 执行命令,等待结果
|
||
uint32_t DTU_ExecuteCmd(char *cmd, char *checkPattern, char *checkErrPattern, char *resultBuff, uint16_t waitSeconds)
|
||
{
|
||
uint32_t ret = FALSE;
|
||
|
||
// 检查并及时打开GPS电源
|
||
if(DTU_needCheckGPS)
|
||
DTU_CheckGPS();
|
||
|
||
if(DTU_hasPowered)
|
||
{
|
||
// 唤醒
|
||
// SCUART_Write(SC1, (uint8_t *) "AT\r", 3);
|
||
// delay_ms(5);
|
||
|
||
printf("\n=> %s\n", cmd);
|
||
|
||
// 清空数据
|
||
DTU_ClearQueue();
|
||
// 发送命令, 并附加回车换行符
|
||
SCUART_Write(SC1, (uint8_t *) cmd, strlen(cmd));
|
||
SCUART_Write(SC1, (uint8_t *) "\r", 1);
|
||
// 等待结果
|
||
ret = DTU_ParseResult(checkPattern, checkErrPattern, resultBuff, waitSeconds);
|
||
}
|
||
|
||
return ret;
|
||
}
|
||
|
||
// 等待服务器端返回(至少len个字节,最多size个字节),直到收完或超时
|
||
// 返回值为实际收到的数据长度
|
||
uint16_t DTU_WaitResponse(uint8_t ssl, uint16_t len, uint8_t *buff, uint16_t size, uint16_t waitSeconds)
|
||
{
|
||
uint8_t timeOut;
|
||
uint32_t timeOutTick;
|
||
uint8_t u8DTU, phase;
|
||
uint16_t i, count, data_count;
|
||
uint16_t preidx, idx;
|
||
char cntbuff[40], prebuff[40], *p, *p1;
|
||
|
||
// 等待返回数据
|
||
idx = 0;
|
||
|
||
memset(prebuff, 0, sizeof(prebuff));
|
||
preidx = 0;
|
||
phase = 0;
|
||
do
|
||
{
|
||
timeOut = 1;
|
||
timeOutTick = GetDelayTick(idx == 0 ? waitSeconds * 1000 : 1000);
|
||
while(!IsTickOut(timeOutTick))
|
||
{
|
||
// 喂狗
|
||
if(!Wakeup_Sleeping)
|
||
WDT_RESET_COUNTER();
|
||
|
||
if(LoopBuff_GetCount(&DTU_TaskM))
|
||
{
|
||
timeOut = 0;
|
||
break;
|
||
}
|
||
}
|
||
|
||
if(!timeOut)
|
||
{
|
||
count = LoopBuff_GetCount(&DTU_TaskM);
|
||
while(count--)
|
||
{
|
||
// 取数据
|
||
memmove(&u8DTU, LoopBuff_GetDataPtr(&DTU_TaskM, DTU_TaskM.info.rdPtr), 1);
|
||
LoopBuff_RemoveItems(&DTU_TaskM, 1);
|
||
|
||
// if(u8DTU == '\n')
|
||
// printf("\\n");
|
||
// else if(u8DTU == '\r')
|
||
// printf("\\r");
|
||
// else if(isprint(u8DTU))
|
||
// printf("%c", u8DTU);
|
||
// else
|
||
// printf("[%02X]", u8DTU);
|
||
|
||
if(phase == 0)
|
||
{
|
||
// 接收URC消息错误
|
||
if(preidx >= sizeof(prebuff) - 1)
|
||
return 0;
|
||
|
||
prebuff[preidx++] = u8DTU;
|
||
if(u8DTU == '\n')
|
||
{
|
||
if(!ssl)
|
||
p = strstr(prebuff, "+QIURC: \"recv\",0,");
|
||
else
|
||
p = strstr(prebuff, "+QSSLURC: \"recv\",1,");
|
||
if(p) // 获取数据长度
|
||
{
|
||
p += (ssl ? 19 : 17);
|
||
p1 = strstr(p, "\r\n");
|
||
|
||
// 接收URC消息错误
|
||
if(!p1 || p1 >= p + sizeof(cntbuff))
|
||
return 0;
|
||
|
||
memset(cntbuff, 0, sizeof(cntbuff));
|
||
strncpy(cntbuff, p, p1 - p);
|
||
data_count = atoi(cntbuff);
|
||
phase = 1;
|
||
}
|
||
else
|
||
{
|
||
memset(prebuff, 0, sizeof(prebuff));
|
||
preidx = 0;
|
||
}
|
||
}
|
||
}
|
||
else if(idx < size)
|
||
{
|
||
if(data_count--)
|
||
buff[idx++] = u8DTU;
|
||
if(data_count == 0)
|
||
{
|
||
memset(prebuff, 0, sizeof(prebuff));
|
||
preidx = 0;
|
||
phase = 0;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
} while(idx < size && !timeOut);
|
||
|
||
if(!ssl)
|
||
{
|
||
printf("\nresponse from server (%d bytes):\n", idx);
|
||
for(i = 0; i < idx && i < 128; i++)
|
||
printf("%02X ", buff[i]);
|
||
if(idx > 128)
|
||
printf("...");
|
||
printf("\n");
|
||
}
|
||
if(idx < len)
|
||
strcpy(dcBuff.powerInfo.gprsFailCode, "RECV");
|
||
else
|
||
{
|
||
// 不清除错误代码(始终保留最近一次的错误代码)
|
||
// strcpy(dcBuff.powerInfo.gprsFailCode, "");
|
||
}
|
||
return idx;
|
||
}
|
||
|
||
// 模块DEACT
|
||
uint8_t DTU_Shutdown()
|
||
{
|
||
uint8_t ret = 0;
|
||
char buff[40];
|
||
|
||
// 设置标志
|
||
DTU_imeiRead = 0;
|
||
DTU_simCard = 0;
|
||
DTU_simReg = 0;
|
||
DTU_gprsReg = 0;
|
||
DTU_gprsAttached = 0;
|
||
DTU_linkEstablished = 0;
|
||
DTU_sslConfig = 0;
|
||
DTU_mqttConfig = 0;
|
||
DTU_ipFetched = 0;
|
||
DTU_fail_count = 0;
|
||
dcBuff.dtuData.connected = 0;
|
||
DTU_shutdown_count++;
|
||
|
||
if(DTU_ExecuteCmd("AT+QIDEACT=1", "OK", "ERROR", buff, DTU_tmrQPendSpec))
|
||
{
|
||
strcpy(DTU_APN, "");
|
||
printf("\nDTU shutdown.\n");
|
||
ret = 1;
|
||
}
|
||
else
|
||
printf("\nDTU shutdown failed.\n");
|
||
|
||
return ret;
|
||
}
|
||
|
||
// 发送数据, 等待服务器返回
|
||
uint32_t DTU_SendAndRecv(uint8_t ssl, uint8_t *data, uint16_t len, uint16_t *recvLen, uint8_t *recvBuff, uint16_t recvSize)
|
||
{
|
||
char cmd[40], buff[40];
|
||
int8_t try_count = 2;
|
||
uint32_t ret = TRUE;
|
||
uint16_t rlen = *recvLen;
|
||
uint16_t totalLen = 0, rslen;
|
||
S_RTC_TIME_DATA_T sRTC;
|
||
|
||
// 唤醒
|
||
// SCUART_Write(SC1, (uint8_t *) "AT\r", 3);
|
||
// delay_ms(5);
|
||
|
||
// 清空数据
|
||
DTU_ClearQueue();
|
||
// EC20一次最多只能发送1460字节
|
||
while(totalLen < len)
|
||
{
|
||
if(len - totalLen > 1460)
|
||
rslen = 1460;
|
||
else
|
||
rslen = len - totalLen;
|
||
// 发送命令, 并附加回车换行符
|
||
if(!ssl)
|
||
sprintf(cmd, "AT+QISEND=0,%d", rslen);
|
||
else
|
||
sprintf(cmd, "AT+QSSLSEND=1,%d", rslen);
|
||
|
||
do
|
||
{
|
||
ret = FALSE;
|
||
|
||
SCUART_Write(SC1, (uint8_t *) cmd, strlen(cmd));
|
||
SCUART_Write(SC1, (uint8_t *) "\r", 1);
|
||
if(DTU_ParseResult(">", "", buff, DTU_tmrQPendShort))
|
||
{
|
||
delay_ms(10);
|
||
SCUART_Write(SC1, data + totalLen, rslen);
|
||
ret = DTU_ParseResult("SEND OK", "SEND FAIL", buff, DTU_tmrQPendSpec);
|
||
}
|
||
if(ret)
|
||
{
|
||
totalLen += rslen;
|
||
break;
|
||
}
|
||
delay_ms(200);
|
||
} while(--try_count > 0);
|
||
|
||
if(!ret)
|
||
{
|
||
strcpy(dcBuff.powerInfo.gprsFailCode, "SEND");
|
||
break;
|
||
}
|
||
}
|
||
|
||
if(ret && rlen > 0)
|
||
{
|
||
do
|
||
{
|
||
rslen = DTU_WaitResponse(ssl, rlen, recvBuff, recvSize, DTU_tmrQPendSpec);
|
||
memmove(recvLen, &rslen, 2);
|
||
ret = (rslen >= rlen);
|
||
if(ret)
|
||
break;
|
||
delay_ms(200);
|
||
} while(--try_count > 0);
|
||
}
|
||
|
||
if(ret)
|
||
{
|
||
DTU_fail_count = 0;
|
||
DTU_shutdown_count = 0;
|
||
printf("\nSend %d bytes ok\n", len);
|
||
// 记录发送成功的时间
|
||
RTC_GetDateAndTime(&sRTC);
|
||
DTU_succTime = Calc_SecondsFromYear(INITIAL_YEAR, sRTC.u32Year, sRTC.u32Month, sRTC.u32Day,
|
||
sRTC.u32Hour, sRTC.u32Minute, sRTC.u32Second);
|
||
return TRUE;
|
||
}
|
||
|
||
printf("\nSend failed\n");
|
||
|
||
// 如果2次失败,模块关机/关电
|
||
if(++DTU_fail_count >= 2)
|
||
{
|
||
if(DTU_shutdown_count >= 1 || !DTU_Shutdown())
|
||
DTU_PowerOff();
|
||
}
|
||
|
||
return FALSE;
|
||
}
|
||
|
||
// 打开GPS功能
|
||
uint32_t DTU_EnableGPS()
|
||
{
|
||
char cmd[50], buff[50];
|
||
uint8_t try_count = 2;
|
||
static uint8_t first = 1;
|
||
|
||
// 禁止重启GPS
|
||
DTU_needCheckGPS = 0;
|
||
|
||
if(!IS_VCC_GPS_ON())
|
||
{
|
||
VCC_GPS_ON();
|
||
delay_ms(2500);
|
||
}
|
||
|
||
// DTU_ExecuteCmd("AT+QGPSDEL=3", "OK", "ERROR", buff, DTU_tmrQPendShort);
|
||
// DTU_ExecuteCmd("AT+QGPSXTRA=0", "OK", "ERROR", buff, DTU_tmrQPendShort);
|
||
// return FALSE;
|
||
|
||
#if 0
|
||
// 检查QGPSXTRA
|
||
if(!DTU_ExecuteCmd("AT+QGPSXTRA?", "+QGPSXTRA: 1", "+QGPSXTRA: 0", buff, DTU_tmrQPendShort))
|
||
{
|
||
// 如果没有, 则设置并重启
|
||
if(DTU_ExecuteCmd("AT+QGPSXTRA=1", "OK", "ERROR", buff, DTU_tmrQPendShort))
|
||
{
|
||
DTU_PowerOff();
|
||
delay_ms(200);
|
||
NVIC_SystemReset();
|
||
}
|
||
}
|
||
|
||
// 检查QGPSXTRADATA
|
||
if(DTU_ExecuteCmd("AT+QGPSXTRADATA?", "+QGPSXTRADATA: ", "ERROR", buff, DTU_tmrQPendShort)
|
||
&& strstr(buff, "+QGPSXTRADATA: 0,"))
|
||
{
|
||
// 先删除内存文件
|
||
DTU_ExecuteCmd("AT+QFDEL=\"RAM:xtra2.bin\"", "OK", "ERROR", buff, DTU_tmrQPendShort);
|
||
// 下载XTRADATA
|
||
if(Sim808_GPRSDial()
|
||
&& DTU_ExecuteCmd("AT+QHTTPCFG=\"contextid\",1", "OK", "ERROR", buff, DTU_tmrQPendShort)
|
||
&& DTU_ExecuteCmd("AT+QHTTPCFG=\"responseheader\",0", "OK", "ERROR", buff, DTU_tmrQPendShort)
|
||
&& DTU_ExecuteCmd("AT+QHTTPURL=40,10", "CONNECT", "ERROR", buff, DTU_tmrQPendShort)
|
||
)
|
||
{
|
||
strcpy(cmd, "http://xtrapath1.izatcloud.net/xtra2.bin");
|
||
SCUART_Write(SC1, (uint8_t *) cmd, strlen(cmd));
|
||
if(DTU_ParseResult("OK", "ERROR", buff, DTU_tmrQPendShort)
|
||
&& DTU_ExecuteCmd("AT+QHTTPGET=80", "+QHTTPGET: 0,", "ERROR", buff, DTU_tmrQPendSpec)
|
||
&& DTU_ExecuteCmd("AT+QHTTPREADFILE=\"RAM:xtra2.bin\",80", "+QHTTPREADFILE: 0", "ERROR", buff, DTU_tmrQPendSpec)
|
||
&& DTU_ExecuteCmd("AT+QLTS=2", "+QLTS: ", "ERROR", buff, DTU_tmrQPendShort) // Get UTC time
|
||
)
|
||
{
|
||
// 获取时间
|
||
memset(cmd, 0, sizeof(cmd));
|
||
strncpy(cmd, strstr(buff, "+QLTS: \"") + 8, 19);
|
||
// 注入时间、XTRADATA
|
||
sprintf(buff, "AT+QGPSXTRATIME=0,\"%s\",1,1,3500", cmd); // Inject UTC time
|
||
strcpy(cmd, buff);
|
||
if(DTU_ExecuteCmd(cmd, "OK", "ERROR", buff, DTU_tmrQPendShort)
|
||
&& DTU_ExecuteCmd("AT+QGPSXTRADATA=\"RAM:xtra2.bin\"", "OK", "ERROR", buff, DTU_tmrQPendShort)
|
||
)
|
||
{
|
||
printf("\nGPS XTRADATA Injected.\n");
|
||
}
|
||
}
|
||
}
|
||
}
|
||
#endif
|
||
|
||
while(try_count--)
|
||
{
|
||
delay_ms(200);
|
||
|
||
// 先停止GPS定位
|
||
if(DTU_ExecuteCmd("AT+QGPSEND", "OK", "ERROR", buff, DTU_tmrQPendShort))
|
||
{
|
||
printf("\nGPS disabled.\n");
|
||
delay_ms(200);
|
||
}
|
||
|
||
// 查询当前输出端口是否为uartdebug
|
||
if(first || !DTU_ExecuteCmd("AT+QGPSCFG=\"outport\"", "+QGPSCFG:", "ERROR", buff, DTU_tmrQPendShort)
|
||
|| strstr(buff, "uartdebug") == 0)
|
||
{
|
||
// 设置当前输出端口为uartdebug
|
||
if(!DTU_ExecuteCmd("AT+QGPSCFG=\"outport\",\"uartdebug\"", "OK", "ERROR", buff, DTU_tmrQPendShort))
|
||
{
|
||
printf("\nSet GPS outport failed.\n");
|
||
continue;
|
||
}
|
||
first = 0;
|
||
}
|
||
if(DTU_ExecuteCmd("AT+QGPS=1,255,50,0,4", "OK", "ERROR", buff, DTU_tmrQPendShort))
|
||
{
|
||
printf("\nGPS enabled.\n");
|
||
// 允许重启GPS
|
||
DTU_needCheckGPS = 1;
|
||
return TRUE;
|
||
}
|
||
}
|
||
|
||
printf("\nGPS enable failed.\n");
|
||
// 允许重启GPS
|
||
DTU_needCheckGPS = 1;
|
||
return FALSE;
|
||
}
|
||
|
||
// 模块上电,等1秒钟才能发送命令
|
||
void DTU_PowerOn()
|
||
{
|
||
char buff[40];
|
||
S_RTC_TIME_DATA_T sRTC;
|
||
uint8_t try_count = 2;
|
||
|
||
if(!DTU_hasPowered)
|
||
{
|
||
printf("\nDTU power on ...\n");
|
||
|
||
delay_ms(200);
|
||
VCC_GSM_ON();
|
||
// delay_ms(10000);
|
||
DTU_ParseResult("RDY", "", buff, DTU_tmrQPendShort * 3);
|
||
|
||
// 获取当前时间
|
||
RTC_GetDateAndTime(&sRTC);
|
||
// 重设自上次gps定位以来的时间
|
||
DTU_gpsTime = Calc_SecondsFromYear(INITIAL_YEAR, sRTC.u32Year, sRTC.u32Month, sRTC.u32Day,
|
||
sRTC.u32Hour, sRTC.u32Minute, sRTC.u32Second);
|
||
|
||
// 设置标志
|
||
DTU_hasPowered = 1;
|
||
|
||
// 关闭命令回显
|
||
while(try_count--)
|
||
{
|
||
if(DTU_ExecuteCmd("ATE0", "OK", "", buff, DTU_tmrQPendShort))
|
||
{
|
||
printf("\nDTU echo off.\n");
|
||
break;
|
||
}
|
||
printf("\nDTU echo off failed.\n");
|
||
delay_ms(2000);
|
||
}
|
||
|
||
// 版本
|
||
if(DTU_ExecuteCmd("ATI", "Revision: ", "", buff, DTU_tmrQPendShort))
|
||
printf("\n%s\n", buff);
|
||
|
||
if(GPS_Waiting || dcBuff.configDisplay.op_SEND_GPS_DATA)
|
||
{
|
||
if(try_count > 0)
|
||
delay_ms(2000);
|
||
// 在这里主动打开GPS
|
||
DTU_EnableGPS();
|
||
}
|
||
}
|
||
}
|
||
|
||
// 关闭GPS功能
|
||
void DTU_DisableGPS()
|
||
{
|
||
char buff[50];
|
||
|
||
if(IS_VCC_GPS_ON())
|
||
{
|
||
VCC_GPS_OFF();
|
||
if(DTU_ExecuteCmd("AT+QGPSEND", "OK", "ERROR", buff, DTU_tmrQPendShort))
|
||
printf("\nGPS disabled.\n");
|
||
else
|
||
printf("\nGPS disable failed.\n");
|
||
}
|
||
}
|
||
|
||
// 模块关电
|
||
void DTU_PowerOff()
|
||
{
|
||
char buff[40];
|
||
|
||
// 禁止重启GPS
|
||
DTU_needCheckGPS = 0;
|
||
|
||
if(DTU_hasPowered)
|
||
{
|
||
// 关闭GPS
|
||
DTU_DisableGPS();
|
||
|
||
if(DTU_ExecuteCmd("AT+QPOWD=1", "POWERED DOWN", "", buff, DTU_tmrQPendShort * 2))
|
||
printf("\nGPRS disconnected.\n");
|
||
else
|
||
printf("\nGPRS disconnect failed.\n");
|
||
|
||
// 设置标志
|
||
DTU_hasPowered = 0;
|
||
DTU_imeiRead = 0;
|
||
DTU_simCard = 0;
|
||
DTU_simReg = 0;
|
||
DTU_gprsReg = 0;
|
||
DTU_isATMode = 0;
|
||
DTU_gprsAttached = 0;
|
||
DTU_linkEstablished = 0;
|
||
DTU_sslConfig = 0;
|
||
DTU_mqttConfig = 0;
|
||
DTU_ipFetched = 0;
|
||
strcpy(DTU_APN, "");
|
||
DTU_isRMCFormat = 0;
|
||
DTU_fail_count = 0;
|
||
dcBuff.dtuData.connected = 0;
|
||
DTU_shutdown_count = 0;
|
||
|
||
printf("\nDTU power off ...\n");
|
||
VCC_GSM_OFF();
|
||
}
|
||
}
|
||
|
||
// 读取IMEI号码(测试4G模块是否正常)
|
||
uint32_t DTU_ReadIMEI()
|
||
{
|
||
char buff[40];
|
||
uint8_t try_count = 2;
|
||
|
||
if(DTU_imeiRead)
|
||
return TRUE;
|
||
|
||
while(try_count--)
|
||
{
|
||
if(DTU_ExecuteCmd("AT+GSN", "", "ERROR", buff, DTU_tmrQPendShort))
|
||
{
|
||
if(strlen(buff) == 15)
|
||
{
|
||
DTU_imeiRead = 1;
|
||
printf("\nThe IMEI is: %s\n", buff);
|
||
return TRUE;
|
||
}
|
||
}
|
||
delay_ms(200);
|
||
}
|
||
|
||
printf("\nRead IMEI failed.\n");
|
||
return FALSE;
|
||
}
|
||
|
||
// 检查sim card
|
||
uint32_t DTU_CheckSimCard()
|
||
{
|
||
char buff[40];
|
||
uint8_t try_count = 4;
|
||
|
||
if(DTU_simCard)
|
||
return TRUE;
|
||
|
||
while(try_count--)
|
||
{
|
||
if(DTU_ExecuteCmd("AT+CPIN?","+CPIN:", "", buff, DTU_tmrQPendShort) && strstr(buff, "+CPIN: READY"))
|
||
{
|
||
DTU_simCard = 1;
|
||
printf("\nSim card ready.\n");
|
||
return TRUE;
|
||
}
|
||
delay_ms(200);
|
||
}
|
||
|
||
DTU_simReg = 0;
|
||
DTU_gprsReg = 0;
|
||
DTU_gprsAttached = 0;
|
||
DTU_linkEstablished = 0;
|
||
DTU_sslConfig = 0;
|
||
DTU_mqttConfig = 0;
|
||
DTU_ipFetched = 0;
|
||
printf("\nSim card not ready.\n");
|
||
return FALSE;
|
||
}
|
||
|
||
// 检查GPRS附着情况:最多等40秒
|
||
uint32_t DTU_CheckGprs()
|
||
{
|
||
char buff[40];
|
||
uint32_t check_time;
|
||
S_RTC_TIME_DATA_T sRTC;
|
||
|
||
if(DTU_gprsAttached)
|
||
return TRUE;
|
||
|
||
// 获取当前时间
|
||
RTC_GetDateAndTime(&sRTC);
|
||
check_time = Calc_SecondsFromYear(INITIAL_YEAR, sRTC.u32Year, sRTC.u32Month, sRTC.u32Day,
|
||
sRTC.u32Hour, sRTC.u32Minute, sRTC.u32Second);
|
||
|
||
DTU_ExecuteCmd("AT+CGATT=1", "OK", "ERROR", buff, DTU_tmrQPendLong);
|
||
|
||
do
|
||
{
|
||
if(DTU_ExecuteCmd("AT+CGATT?", "+CGATT: 1", "+CGATT: 0", buff, DTU_tmrQPendShort))
|
||
{
|
||
DTU_gprsAttached = 1;
|
||
printf("\nGprs attached.\n");
|
||
return TRUE;
|
||
}
|
||
|
||
delay_ms(1000);
|
||
RTC_GetDateAndTime(&sRTC);
|
||
} while(Calc_SecondsFromYear(INITIAL_YEAR, sRTC.u32Year, sRTC.u32Month, sRTC.u32Day,
|
||
sRTC.u32Hour, sRTC.u32Minute, sRTC.u32Second) < check_time + 120);
|
||
|
||
DTU_gprsAttached = 0;
|
||
DTU_linkEstablished = 0;
|
||
DTU_sslConfig = 0;
|
||
DTU_mqttConfig = 0;
|
||
DTU_ipFetched = 0;
|
||
printf("\nGprs not attached.\n");
|
||
|
||
// 如果1次失败,模块关机/关电
|
||
if(++DTU_fail_count >= 1)
|
||
{
|
||
if(DTU_shutdown_count >= 1 || !DTU_Shutdown())
|
||
DTU_PowerOff();
|
||
}
|
||
|
||
return FALSE;
|
||
}
|
||
|
||
char *DTU_DecideAPN()
|
||
{
|
||
if(strncmp(dcBuff.powerInfo.simNumber, "898604", 6) == 0)
|
||
return "CMIOT";
|
||
if(strncmp(dcBuff.powerInfo.simNumber, "898607", 6) == 0)
|
||
return "CMIOT";
|
||
if(strncmp(dcBuff.powerInfo.simNumber, "898602", 6) == 0)
|
||
return "CMIOT";
|
||
if(strncmp(dcBuff.powerInfo.simNumber, "898600", 6) == 0)
|
||
return "CMIOT";
|
||
if(strncmp(dcBuff.powerInfo.simNumber, "898608", 6) == 0)
|
||
return "CMIOT";
|
||
if(strcmp(dcBuff.configDisplay.APN, "CMNET") == 0)
|
||
return "CMIOT";
|
||
return dcBuff.configDisplay.APN;
|
||
}
|
||
|
||
// 设置APN
|
||
uint32_t DTU_SetAPN(char *APN)
|
||
{
|
||
char cmd[50], buff[40];
|
||
uint8_t try_count = 2;
|
||
|
||
if(strcmp(DTU_APN, APN) == 0)
|
||
return TRUE;
|
||
|
||
while(try_count--)
|
||
{
|
||
sprintf(cmd, "AT+QICSGP=1,1,\"%s\",\"\",\"\"", APN);
|
||
if(DTU_ExecuteCmd(cmd, "OK", "ERROR", buff, DTU_tmrQPendShort))
|
||
{
|
||
strcpy(DTU_APN, APN);
|
||
printf("\nSet APN to \"%s\".\n", APN);
|
||
return TRUE;
|
||
}
|
||
delay_ms(200);
|
||
}
|
||
|
||
printf("\nSet APN failed.\n");
|
||
|
||
return FALSE;
|
||
}
|
||
|
||
// 建立无线链路
|
||
uint32_t DTU_EstablishLink()
|
||
{
|
||
char buff[40];
|
||
uint8_t try_count = 2;
|
||
|
||
if(DTU_linkEstablished)
|
||
return TRUE;
|
||
|
||
while(try_count--)
|
||
{
|
||
if(DTU_ExecuteCmd("AT+QIACT=1", "OK", "ERROR", buff, DTU_tmrQPendLong))
|
||
{
|
||
DTU_linkEstablished = 1;
|
||
printf("\nGprs link established\n");
|
||
|
||
// DTU_ExecuteCmd("AT+QIDNSCFG=1", "OK", "ERROR", buff, DTU_tmrQPendShort);
|
||
|
||
return TRUE;
|
||
}
|
||
delay_ms(200);
|
||
}
|
||
|
||
DTU_ipFetched = 0;
|
||
printf("\nGprs link not established.\n");
|
||
|
||
// 如果2次失败,模块关机/关电
|
||
if(++DTU_fail_count >= 1)
|
||
{
|
||
if(DTU_shutdown_count >= 1 || !DTU_Shutdown())
|
||
DTU_PowerOff();
|
||
}
|
||
|
||
return FALSE;
|
||
}
|
||
|
||
uint32_t DTU_ConfigSSL()
|
||
{
|
||
char cmd[40], buff[40];
|
||
|
||
if(DTU_sslConfig)
|
||
return TRUE;
|
||
|
||
// 检查、上传CA证书
|
||
while(!DTU_ExecuteCmd("AT+QFLST=\"RAM:ca_cert.pem\"", "+QFLST: \"RAM:ca_cert.pem\"", "ERROR", buff, DTU_tmrQPendShort))
|
||
{
|
||
sprintf(cmd, "AT+QFUPL=\"RAM:ca_cert.pem\",%d", strlen(ca_cert));
|
||
if(DTU_ExecuteCmd(cmd, "CONNECT", "ERROR", buff, DTU_tmrQPendShort))
|
||
{
|
||
SCUART_Write(SC1, (uint8_t *) ca_cert, strlen(ca_cert));
|
||
if(DTU_ParseResult("+QFUPL:", "ERROR", buff, DTU_tmrQPendShort))
|
||
{
|
||
printf("\nca_cert.pem uploaded\n");
|
||
break;
|
||
}
|
||
}
|
||
printf("\nca_cert.pem upload failed\n");
|
||
return FALSE;
|
||
}
|
||
|
||
// 检查、上传CLIENT证书
|
||
while(!DTU_ExecuteCmd("AT+QFLST=\"RAM:client_cert.pem\"", "+QFLST: \"RAM:client_cert.pem\"", "ERROR", buff, DTU_tmrQPendShort))
|
||
{
|
||
sprintf(cmd, "AT+QFUPL=\"RAM:client_cert.pem\",%d", strlen(client_cert));
|
||
if(DTU_ExecuteCmd(cmd, "CONNECT", "ERROR", buff, DTU_tmrQPendShort))
|
||
{
|
||
SCUART_Write(SC1, (uint8_t *) client_cert, strlen(client_cert));
|
||
if(DTU_ParseResult("+QFUPL:", "ERROR", buff, DTU_tmrQPendShort))
|
||
{
|
||
printf("\nclient_cert.pem uploaded\n");
|
||
break;
|
||
}
|
||
}
|
||
printf("\nclient_cert.pem upload failed\n");
|
||
return FALSE;
|
||
}
|
||
|
||
// 检查、上传CLIENT密钥
|
||
while(!DTU_ExecuteCmd("AT+QFLST=\"RAM:client_key.pem\"", "+QFLST: \"RAM:client_key.pem\"", "ERROR", buff, DTU_tmrQPendShort))
|
||
{
|
||
sprintf(cmd, "AT+QFUPL=\"RAM:client_key.pem\",%d", strlen(client_key));
|
||
if(DTU_ExecuteCmd(cmd, "CONNECT", "ERROR", buff, DTU_tmrQPendShort))
|
||
{
|
||
SCUART_Write(SC1, (uint8_t *) client_key, strlen(client_key));
|
||
if(DTU_ParseResult("+QFUPL:", "ERROR", buff, DTU_tmrQPendShort))
|
||
{
|
||
printf("\nclient_key.pem uploaded\n");
|
||
break;
|
||
}
|
||
}
|
||
printf("\nclient_key.pem upload failed\n");
|
||
return FALSE;
|
||
}
|
||
|
||
if(!DTU_ExecuteCmd("AT+QSSLCFG=\"ignorelocaltime\",1,1", "OK", "ERROR", buff, DTU_tmrQPendShort))
|
||
return FALSE;
|
||
if(!DTU_ExecuteCmd("AT+QSSLCFG=\"sslversion\",1,4", "OK", "ERROR", buff, DTU_tmrQPendShort))
|
||
return FALSE;
|
||
if(!DTU_ExecuteCmd("AT+QSSLCFG=\"ciphersuite\",1,0xFFFF", "OK", "ERROR", buff, DTU_tmrQPendShort))
|
||
return FALSE;
|
||
if(!DTU_ExecuteCmd("AT+QSSLCFG=\"seclevel\",1,2", "OK", "ERROR", buff, DTU_tmrQPendShort))
|
||
return FALSE;
|
||
if(!DTU_ExecuteCmd("AT+QSSLCFG=\"cacert\",1,\"RAM:ca_cert.pem\"", "OK", "ERROR", buff, DTU_tmrQPendShort))
|
||
return FALSE;
|
||
if(!DTU_ExecuteCmd("AT+QSSLCFG=\"clientcert\",1,\"RAM:client_cert.pem\"", "OK", "ERROR", buff, DTU_tmrQPendShort))
|
||
return FALSE;
|
||
if(!DTU_ExecuteCmd("AT+QSSLCFG=\"clientkey\",1,\"RAM:client_key.pem\"", "OK", "ERROR", buff, DTU_tmrQPendShort))
|
||
return FALSE;
|
||
|
||
DTU_sslConfig = 1;
|
||
return TRUE;
|
||
}
|
||
|
||
uint32_t DTU_ConfigMQTT()
|
||
{
|
||
char cmd[100], buff[40], psn[14];
|
||
|
||
if(DTU_mqttConfig)
|
||
return TRUE;
|
||
|
||
sprintf(psn, "20%02d%02d%02d%02d%03d", dcBuff.configBottle.PSN[0], dcBuff.configBottle.PSN[1],
|
||
dcBuff.configBottle.PSN[2], dcBuff.configBottle.PSN[3],
|
||
(dcBuff.configBottle.PSN[4] << 8) | dcBuff.configBottle.PSN[5]);
|
||
|
||
// 每次重连服务器,需要重新订阅topic
|
||
if(!DTU_ExecuteCmd("AT+QMTCFG=\"session\",0,1", "OK", "ERROR", buff, DTU_tmrQPendShort))
|
||
return FALSE;
|
||
// URC只报长度,不报内容
|
||
if(!DTU_ExecuteCmd("AT+QMTCFG=\"recv/mode\",0,1,1", "OK", "ERROR", buff, DTU_tmrQPendShort))
|
||
return FALSE;
|
||
// 阿里云授权码
|
||
// sprintf(cmd, "AT+QMTCFG=\"aliauth\",0,\"%s\",\"%s\",\"%s\"",
|
||
// aliyunSecret.product, aliyunSecret.device, aliyunSecret.secret);
|
||
|
||
// if(!DTU_ExecuteCmd(cmd, "OK", "ERROR", buff, DTU_tmrQPendShort))
|
||
// return FALSE;
|
||
|
||
DTU_mqttConfig = 1;
|
||
return TRUE;
|
||
}
|
||
|
||
// 获取基站定位经纬度
|
||
uint32_t DTU_GetCellLocPosition()
|
||
{
|
||
char buff[40];
|
||
uint8_t try_count = 2;
|
||
char *p, *p1 = NULL;
|
||
|
||
// 查询当前multi PDNs是否enabled(默认enabled)
|
||
// if(!DTU_ExecuteCmd("AT+QCFG=\"PDP/DuplicateChk\"", "+QCFG: \"pdp/duplicatechk\"", "ERROR", buff, DTU_tmrQPendShort)
|
||
// || strstr(buff, ",1") == 0)
|
||
// {
|
||
// // 设置当前multi PDNs为enabled
|
||
// if(!DTU_ExecuteCmd("AT+QCFG=\"PDP/DuplicateChk\",1", "OK", "ERROR", buff, DTU_tmrQPendShort))
|
||
// {
|
||
// printf("\nSet multi PDNs failed.\n");
|
||
// return FALSE;
|
||
// }
|
||
// }
|
||
// // 查询当前contextid是否为1(默认为1)
|
||
// if(!DTU_ExecuteCmd("AT+QLOCCFG=\"contextid\"", "+QLOCCFG: \"contextid\"", "ERROR", buff, DTU_tmrQPendShort)
|
||
// || strstr(buff, ",1") == 0)
|
||
// {
|
||
// // 设置当前contextid为1
|
||
// if(!DTU_ExecuteCmd("AT+QLOCCFG=\"contextid\",1", "OK", "ERROR", buff, DTU_tmrQPendShort))
|
||
// {
|
||
// printf("\nSet Cell-Loc contextid failed.\n");
|
||
// return FALSE;
|
||
// }
|
||
// }
|
||
// 设置token(默认为空)
|
||
if(!DTU_ExecuteCmd("AT+QLOCCFG=\"token\"", "+QLOCCFG: \"token\"", "ERROR", buff, DTU_tmrQPendShort)
|
||
|| strstr(buff, "exist") == 0)
|
||
{
|
||
if(!DTU_ExecuteCmd("AT+QLOCCFG=\"token\",\"u3S224CX18r4O045\"", "OK", "ERROR", buff, DTU_tmrQPendShort))
|
||
{
|
||
printf("\nSet Cell-Loc token failed.\n");
|
||
return FALSE;
|
||
}
|
||
}
|
||
// 查询当前基站定位服务器是否为www.queclocator.com:80
|
||
if(!DTU_ExecuteCmd("AT+QLOCCFG=\"server\"", "+QLOCCFG: \"server\"", "ERROR", buff, DTU_tmrQPendShort)
|
||
|| strstr(buff, "www.queclocator.com:80") == 0)
|
||
{
|
||
// 设置当前基站定位服务器为www.queclocator.com:80
|
||
if(!DTU_ExecuteCmd("AT+QLOCCFG=\"server\",\"www.queclocator.com:80\"", "OK", "ERROR", buff, DTU_tmrQPendShort))
|
||
{
|
||
printf("\nSet Cell-Loc server failed.\n");
|
||
return FALSE;
|
||
}
|
||
}
|
||
while(try_count--)
|
||
{
|
||
if(DTU_ExecuteCmd("AT+QCELLLOC", "+QCELLLOC: ", "ERROR", buff, DTU_tmrQPendSpec))
|
||
{
|
||
p = strstr(buff, "+QCELLLOC: ");
|
||
if(p)
|
||
{
|
||
p += 11;
|
||
p1 = strstr(p, ",");
|
||
if(p1)
|
||
{
|
||
dcBuff.dtuData.posState = 1; // 基站定位成功
|
||
|
||
*p1 = 0;
|
||
dcBuff.dtuData.longitude = atof(p) * 1000000;
|
||
p = p1 + 1;
|
||
dcBuff.dtuData.latitude = atof(p) * 1000000;
|
||
|
||
printf("\nLatitude:\t%10.6f\n", dcBuff.dtuData.latitude * 0.000001);
|
||
printf("Longitude:\t%10.6f\n", dcBuff.dtuData.longitude * 0.000001);
|
||
|
||
return TRUE;
|
||
}
|
||
}
|
||
}
|
||
|
||
// 有可能是原来的token不对,重新设一次
|
||
if(!DTU_ExecuteCmd("AT+QLOCCFG=\"token\",\"u3S224CX18r4O045\"", "OK", "ERROR", buff, DTU_tmrQPendShort))
|
||
{
|
||
printf("\nSet Cell-Loc token failed.\n");
|
||
return FALSE;
|
||
}
|
||
delay_ms(200);
|
||
}
|
||
|
||
printf("\nGet Cell-Loc position failed.\n");
|
||
|
||
return FALSE;
|
||
}
|
||
|
||
// 设置普通(AT命令,非透传)模式
|
||
// !!! 此命令在4G模块无效 !!!
|
||
uint32_t DTU_SetATMode()
|
||
{
|
||
char buff[40];
|
||
uint8_t try_count = 2;
|
||
|
||
if(DTU_isATMode)
|
||
return TRUE;
|
||
|
||
while(try_count--)
|
||
{
|
||
if(DTU_ExecuteCmd("AT+QIMODE=0","OK", "ERROR", buff, DTU_tmrQPendShort))
|
||
{
|
||
DTU_isATMode = 1;
|
||
printf("\nSet to AT cmd mode.\n");
|
||
return TRUE;
|
||
}
|
||
delay_ms(200);
|
||
}
|
||
|
||
printf("\nSet AT mode failed.\n");
|
||
|
||
return FALSE;
|
||
}
|
||
|
||
// 获得本机IP地址
|
||
uint32_t DTU_FetchIP()
|
||
{
|
||
char buff[40];
|
||
uint8_t try_count = 2;
|
||
|
||
if(DTU_ipFetched)
|
||
return TRUE;
|
||
|
||
while(try_count--)
|
||
{
|
||
if(DTU_ExecuteCmd("AT+QIACT?", "+QIACT: 1,1", "+QIACT: 1,0", buff, DTU_tmrQPendShort))
|
||
{
|
||
DTU_ipFetched = 1;
|
||
printf("\nLocal ip is: %s\n", buff + 14);
|
||
return TRUE;
|
||
}
|
||
delay_ms(200);
|
||
}
|
||
|
||
printf("\nFetch ip failed.\n");
|
||
|
||
return FALSE;
|
||
}
|
||
|
||
// 设置服务器格式为DNS
|
||
// !!! 此命令在4G模块无效 !!!
|
||
uint32_t DTU_SetDNSIP()
|
||
{
|
||
char buff[40];
|
||
uint8_t try_count = 2;
|
||
|
||
while(try_count--)
|
||
{
|
||
if(DTU_ExecuteCmd("AT+QIDNSIP=1", "OK", "ERROR", buff, DTU_tmrQPendShort))
|
||
{
|
||
printf("\nSet remote server to domain name.\n");
|
||
return TRUE;
|
||
}
|
||
delay_ms(200);
|
||
}
|
||
|
||
printf("\nSet remote server to domain name failed.\n");
|
||
|
||
return FALSE;
|
||
}
|
||
|
||
// 连接服务器:Direct push mode
|
||
uint32_t DTU_Connect(uint8_t ssl, char *server, short port)
|
||
{
|
||
char cmd[80], buff[40];
|
||
uint32_t ret = FALSE;
|
||
uint8_t try_count = 1;
|
||
|
||
while(try_count--)
|
||
{
|
||
if(!ssl)
|
||
{
|
||
sprintf(cmd, "AT+QIOPEN=1,0,\"TCP\",\"%s\",%d,0,1", server, port);
|
||
if(!DTU_ExecuteCmd(cmd, "+QIOPEN: 0,", "ERROR", buff, DTU_tmrQPendSpec))
|
||
break;
|
||
if(strstr(buff, "+QIOPEN: 0,0"))
|
||
{
|
||
ret = TRUE;
|
||
break;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
sprintf(cmd, "AT+QSSLOPEN=1,1,1,\"%s\",%d,1", server, port);
|
||
if(!DTU_ExecuteCmd(cmd, "+QSSLOPEN: 1,", "ERROR", buff, DTU_tmrQPendSpec))
|
||
break;
|
||
if(strstr(buff, "+QSSLOPEN: 1,0"))
|
||
{
|
||
ret = TRUE;
|
||
break;
|
||
}
|
||
}
|
||
delay_ms(200);
|
||
}
|
||
|
||
if(ret)
|
||
{
|
||
dcBuff.dtuData.connected = 1;
|
||
printf("\nConnect to %s: %d\n", server, port);
|
||
return TRUE;
|
||
}
|
||
|
||
dcBuff.dtuData.connected = 0;
|
||
printf("\nCan not connect to %s: %d\n", server, port);
|
||
|
||
// 如果2次失败,模块关机/关电
|
||
if(++DTU_fail_count >= 2)
|
||
{
|
||
if(DTU_shutdown_count >= 1 || !DTU_Shutdown())
|
||
DTU_PowerOff();
|
||
}
|
||
|
||
return FALSE;
|
||
}
|
||
|
||
// 关闭连接
|
||
uint32_t DTU_Close(uint8_t ssl)
|
||
{
|
||
char buff[40];
|
||
uint8_t try_count = 2;
|
||
uint8_t ret;
|
||
|
||
if(!dcBuff.dtuData.connected)
|
||
return TRUE;
|
||
dcBuff.dtuData.connected = 0;
|
||
|
||
while(try_count--)
|
||
{
|
||
// 可能返回OK,也可能返回错误(如连接已关闭,或被服务器主动关闭),都视为关闭成功
|
||
if(!ssl)
|
||
ret = DTU_ExecuteCmd("AT+QICLOSE=0", "OK", "ERROR", buff, DTU_tmrQPendSpec);
|
||
else
|
||
ret = DTU_ExecuteCmd("AT+QSSLCLOSE=1", "OK", "ERROR", buff, DTU_tmrQPendSpec);
|
||
if(ret)
|
||
{
|
||
printf("\nConnection closed.\n");
|
||
return TRUE;
|
||
}
|
||
delay_ms(200);
|
||
}
|
||
|
||
printf("\nConnection close failed.\n");
|
||
return FALSE;
|
||
}
|
||
|
||
// 读取sim卡电话号码
|
||
uint32_t DTU_ReadPhoneNo()
|
||
{
|
||
char buff[40];
|
||
uint8_t try_count = 2;
|
||
|
||
if(strlen(dcBuff.powerInfo.simNumber))
|
||
return TRUE;
|
||
|
||
while(try_count--)
|
||
{
|
||
if(DTU_ExecuteCmd("AT+QCCID", "+QCCID: ", "ERROR", buff, DTU_tmrQPendShort))
|
||
{
|
||
strcpy(dcBuff.powerInfo.simNumber, buff + 8);
|
||
printf("\nThe phone no is: %s\n", dcBuff.powerInfo.simNumber);
|
||
return TRUE;
|
||
}
|
||
delay_ms(200);
|
||
}
|
||
|
||
printf("\nRead phone no failed.\n");
|
||
return FALSE;
|
||
}
|
||
|
||
// 读取信号强度
|
||
uint32_t DTU_ReadRssi(uint8_t *rssi)
|
||
{
|
||
char buff[40];
|
||
uint8_t try_count = 6;
|
||
char *pCSQ, *pCommon;
|
||
uint8_t csq;
|
||
|
||
*rssi = 0;
|
||
while(try_count--)
|
||
{
|
||
if(DTU_ExecuteCmd("AT+CSQ", "+CSQ:", "ERROR", buff, DTU_tmrQPendShort))
|
||
{
|
||
pCSQ = strstr(buff, "+CSQ: ");
|
||
pCommon = strstr(buff, ",");
|
||
if(pCommon)
|
||
*pCommon = 0;
|
||
// 将0~31的强度值转换为百分比
|
||
csq = atoi(pCSQ + 6);
|
||
printf("\nThe CSQ is: %d\n", csq);
|
||
if(csq != 99 && csq != 199)
|
||
{
|
||
if(csq < 100)
|
||
{
|
||
if(csq <= 31)
|
||
*rssi = csq * 100 / 31;
|
||
}
|
||
else
|
||
{
|
||
if(csq <= 191)
|
||
*rssi = csq - 100 + 9;
|
||
}
|
||
if(*rssi > 100)
|
||
*rssi = 100;
|
||
printf("\nThe rssi is: %d\n", *rssi);
|
||
return TRUE;
|
||
}
|
||
}
|
||
delay_ms(500);
|
||
}
|
||
|
||
printf("\nRead rssi failed.\n");
|
||
return FALSE;
|
||
}
|
||
|
||
// 读取入网标志
|
||
uint32_t DTU_ReadRegistry(uint8_t *reg)
|
||
{
|
||
char buff[40];
|
||
char *pReg;
|
||
uint32_t check_time;
|
||
uint16_t DTU_regTime = 60;
|
||
uint8_t rssi = 0;
|
||
S_RTC_TIME_DATA_T sRTC;
|
||
|
||
if(DTU_simReg)
|
||
{
|
||
*reg = 1;
|
||
return TRUE;
|
||
}
|
||
|
||
DTU_ReadRssi(&rssi);
|
||
if(rssi >= 50)
|
||
DTU_regTime = 150;
|
||
|
||
// 获取当前时间
|
||
RTC_GetDateAndTime(&sRTC);
|
||
check_time = Calc_SecondsFromYear(INITIAL_YEAR, sRTC.u32Year, sRTC.u32Month, sRTC.u32Day,
|
||
sRTC.u32Hour, sRTC.u32Minute, sRTC.u32Second);
|
||
|
||
*reg = 0;
|
||
do
|
||
{
|
||
if(DTU_ExecuteCmd("AT+CREG?", "+CREG:", "ERROR", buff, DTU_tmrQPendShort))
|
||
{
|
||
|
||
pReg = strstr(buff, ",");
|
||
if(pReg)
|
||
{
|
||
*reg = *(pReg + 1) - '0';
|
||
if(*reg == 0)
|
||
break;
|
||
}
|
||
//printf("\n%s\n", buff);
|
||
if(*reg == 1 || *reg == 5)
|
||
{
|
||
printf("\nRegistry status: %d.\n", *reg);
|
||
*reg = 1;
|
||
DTU_simReg = 1;
|
||
return TRUE;
|
||
}
|
||
}
|
||
|
||
delay_ms(1000);
|
||
RTC_GetDateAndTime(&sRTC);
|
||
} while(Calc_SecondsFromYear(INITIAL_YEAR, sRTC.u32Year, sRTC.u32Month, sRTC.u32Day,
|
||
sRTC.u32Hour, sRTC.u32Minute, sRTC.u32Second) < check_time + DTU_regTime);
|
||
|
||
printf("\nRegistry status: %d.\n", *reg);
|
||
|
||
// 如果2次失败,模块关机/关电
|
||
if(++DTU_fail_count >= 2)
|
||
{
|
||
if(DTU_shutdown_count >= 1 || !DTU_Shutdown())
|
||
DTU_PowerOff();
|
||
}
|
||
else
|
||
{
|
||
DTU_gprsReg = 0;
|
||
DTU_gprsAttached = 0;
|
||
DTU_linkEstablished = 0;
|
||
DTU_sslConfig = 0;
|
||
DTU_mqttConfig = 0;
|
||
DTU_ipFetched = 0;
|
||
}
|
||
|
||
return FALSE;
|
||
}
|
||
|
||
// 读取GPRS入网标志
|
||
uint32_t DTU_ReadGPRSRegistry(uint8_t *reg)
|
||
{
|
||
char buff[40];
|
||
char *pReg;
|
||
uint32_t check_time;
|
||
S_RTC_TIME_DATA_T sRTC;
|
||
|
||
if(DTU_gprsReg)
|
||
{
|
||
*reg = 1;
|
||
return TRUE;
|
||
}
|
||
|
||
// 获取当前时间
|
||
RTC_GetDateAndTime(&sRTC);
|
||
check_time = Calc_SecondsFromYear(INITIAL_YEAR, sRTC.u32Year, sRTC.u32Month, sRTC.u32Day,
|
||
sRTC.u32Hour, sRTC.u32Minute, sRTC.u32Second);
|
||
|
||
*reg = 0;
|
||
do
|
||
{
|
||
if(DTU_ExecuteCmd("AT+CGREG?", "+CGREG:", "", buff, DTU_tmrQPendShort))
|
||
{
|
||
pReg = strstr(buff, ",");
|
||
if(pReg)
|
||
{
|
||
*reg = *(pReg + 1) - '0';
|
||
if(*reg == 0)
|
||
break;
|
||
}
|
||
if(*reg == 1 || *reg == 5)
|
||
{
|
||
printf("\nGPRS registry status: %d.\n", *reg);
|
||
*reg = 1;
|
||
DTU_gprsReg = 1;
|
||
return TRUE;
|
||
}
|
||
}
|
||
|
||
delay_ms(1000);
|
||
RTC_GetDateAndTime(&sRTC);
|
||
} while(Calc_SecondsFromYear(INITIAL_YEAR, sRTC.u32Year, sRTC.u32Month, sRTC.u32Day,
|
||
sRTC.u32Hour, sRTC.u32Minute, sRTC.u32Second) < check_time + 60);
|
||
|
||
printf("\nGPRS registry status: %d.\n", *reg);
|
||
|
||
return FALSE;
|
||
}
|
||
|
||
// 处理时差函数
|
||
void GPS_ProcessTimeLag(date_time_t *sysTime, int8_t timeLag)
|
||
{
|
||
// 处理时差:正时差
|
||
if(timeLag > 0)
|
||
{
|
||
sysTime->hour += timeLag;
|
||
if(sysTime->hour >= 24)
|
||
{
|
||
sysTime->hour %= 24;
|
||
if(sysTime->day < get_month_days(sysTime->year + 2000, sysTime->month))
|
||
sysTime->day++;
|
||
else
|
||
{
|
||
sysTime->day = 1;
|
||
if(sysTime->month < 12)
|
||
sysTime->month++;
|
||
else
|
||
{
|
||
sysTime->month = 1;
|
||
sysTime->year++;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
// 处理时差:负时差
|
||
else if(timeLag < 0)
|
||
{
|
||
// hour是无符号数
|
||
if(sysTime->hour >= (-timeLag))
|
||
sysTime->hour += timeLag;
|
||
else
|
||
{
|
||
sysTime->hour += (24 + timeLag);
|
||
if(sysTime->day > 1)
|
||
sysTime->day--;
|
||
else
|
||
{
|
||
if(sysTime->month > 1)
|
||
{
|
||
sysTime->month--;
|
||
sysTime->day = get_month_days(sysTime->year + 2000, sysTime->month);
|
||
}
|
||
else
|
||
{
|
||
sysTime->month = 12;
|
||
sysTime->day = 31;
|
||
sysTime->year--;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// 读取GPRS网络信息信息
|
||
uint32_t Sim808_ReadGPRS()
|
||
{
|
||
uint8_t val;
|
||
|
||
printf("\nRead RSSI data ....\n");
|
||
DTU_PowerOn();
|
||
if(!DTU_ReadIMEI())
|
||
{
|
||
strcpy(dcBuff.powerInfo.gprsFailCode, "EC20");
|
||
return FALSE;
|
||
}
|
||
if(!DTU_CheckSimCard())
|
||
{
|
||
strcpy(dcBuff.powerInfo.gprsFailCode, "SIM");
|
||
return FALSE;
|
||
}
|
||
DTU_ReadPhoneNo();
|
||
if(!DTU_SetAPN(DTU_DecideAPN()))
|
||
{
|
||
strcpy(dcBuff.powerInfo.gprsFailCode, "APN");
|
||
return FALSE;
|
||
}
|
||
if(!DTU_ReadRegistry(&val))
|
||
{
|
||
strcpy(dcBuff.powerInfo.gprsFailCode, "REG");
|
||
return FALSE;
|
||
}
|
||
dcBuff.dtuData.networked = (val == 1 ? 1 : 0);
|
||
if(DTU_ReadRssi(&val))
|
||
dcBuff.dtuData.rssi = val;
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
void DTU_setOffsetSeconds()
|
||
{
|
||
char buff[40], *p;
|
||
S_RTC_TIME_DATA_T sRTC;
|
||
uint32_t totalSeconds1, totalSeconds2;
|
||
int8_t zz;
|
||
|
||
if(DTU_ExecuteCmd("AT+QLTS=2", "+QLTS: ", "ERROR", buff, DTU_tmrQPendShort)) // Get UTC time
|
||
{
|
||
// 获取当前时间
|
||
RTC_GetDateAndTime(&sRTC);
|
||
totalSeconds1 = Calc_SecondsFromYear(INITIAL_YEAR, sRTC.u32Year, sRTC.u32Month, sRTC.u32Day,
|
||
sRTC.u32Hour, sRTC.u32Minute, sRTC.u32Second);
|
||
|
||
// UTC日期
|
||
p = strstr(buff, "+QLTS: \"") + 8;
|
||
printf("\n%s\n", p);
|
||
// 4位年份
|
||
p[4] = 0;
|
||
sRTC.u32Year = atoi(p);
|
||
p += 5;
|
||
// 2位月份
|
||
p[2] = 0;
|
||
sRTC.u32Month = atoi(p);
|
||
p += 3;
|
||
// 2位日期
|
||
p[2] = 0;
|
||
sRTC.u32Day = atoi(p);
|
||
p += 3;
|
||
// 2位小时
|
||
p[2] = 0;
|
||
sRTC.u32Hour = atoi(p);
|
||
p += 3;
|
||
// 2位分钟
|
||
p[2] = 0;
|
||
sRTC.u32Minute = atoi(p);
|
||
p += 3;
|
||
// 2位秒
|
||
sRTC.u32Second = (*p - '0') * 10 + (*(p + 1) - '0');
|
||
p += 2;
|
||
// 3位时差(按1/4小时, 带符号)
|
||
p[3] = 0;
|
||
zz = atoi(p);
|
||
|
||
totalSeconds2 = Calc_SecondsFromYear(INITIAL_YEAR, sRTC.u32Year, sRTC.u32Month, sRTC.u32Day,
|
||
sRTC.u32Hour, sRTC.u32Minute, sRTC.u32Second);
|
||
|
||
// 将UTC时间转换为GMT时间(时差为0)
|
||
totalSeconds2 -= zz * 900;
|
||
// 将GMT时间转换为UTC时间(按配置的时差)
|
||
totalSeconds2 += dcBuff.configData.timeLag * 3600;
|
||
|
||
if(RTC_offsetSeconds == 0)
|
||
RTC_offsetSeconds = totalSeconds2 - totalSeconds1;
|
||
}
|
||
}
|
||
|
||
// GPRS拨号
|
||
uint32_t Sim808_GPRSDial()
|
||
{
|
||
uint8_t reg;
|
||
|
||
printf("\nGPRS Dialing ....\n");
|
||
DTU_PowerOn();
|
||
if(!DTU_ReadIMEI())
|
||
{
|
||
strcpy(dcBuff.powerInfo.gprsFailCode, "EC20");
|
||
return FALSE;
|
||
}
|
||
if(!DTU_CheckSimCard())
|
||
{
|
||
strcpy(dcBuff.powerInfo.gprsFailCode, "SIM");
|
||
return FALSE;
|
||
}
|
||
if(!DTU_SetAPN(DTU_DecideAPN()))
|
||
{
|
||
strcpy(dcBuff.powerInfo.gprsFailCode, "APN");
|
||
return FALSE;
|
||
}
|
||
if(!DTU_ReadRegistry(®))
|
||
{
|
||
strcpy(dcBuff.powerInfo.gprsFailCode, "REG");
|
||
return FALSE;
|
||
}
|
||
DTU_ReadGPRSRegistry(®);
|
||
// if(!DTU_CheckGprs())
|
||
// {
|
||
// strcpy(dcBuff.powerInfo.gprsFailCode, "GPRS");
|
||
// return FALSE;
|
||
// }
|
||
// if(!DTU_SetATMode())
|
||
// {
|
||
// strcpy(dcBuff.powerInfo.gprsFailCode, "AT");
|
||
// return FALSE;
|
||
// }
|
||
if(!DTU_EstablishLink())
|
||
{
|
||
strcpy(dcBuff.powerInfo.gprsFailCode, "ACT");
|
||
return FALSE;
|
||
}
|
||
|
||
// 修正时间基准(可显示绝对时间)
|
||
if(RTC_offsetSeconds == 0)
|
||
DTU_setOffsetSeconds();
|
||
if(RTC_offsetSeconds == 0)
|
||
DTU_setOffsetSecondsFromServer();
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
uint32_t Sim808_Connect(uint8_t ssl, char *server, int port)
|
||
{
|
||
if(!Sim808_GPRSDial())
|
||
return FALSE;
|
||
|
||
// if(!DTU_FetchIP())
|
||
// {
|
||
// strcpy(dcBuff.powerInfo.gprsFailCode, "IP");
|
||
// return FALSE;
|
||
// }
|
||
// if(!DTU_SetDNSIP())
|
||
// {
|
||
// strcpy(dcBuff.powerInfo.gprsFailCode, "DNS");
|
||
// return FALSE;
|
||
// }
|
||
|
||
if(ssl && !DTU_ConfigSSL())
|
||
{
|
||
strcpy(dcBuff.powerInfo.gprsFailCode, "SSL");
|
||
return FALSE;
|
||
}
|
||
|
||
printf("\nConnect to server....\n");
|
||
|
||
if(!DTU_Connect(ssl, server, port))
|
||
{
|
||
strcpy(dcBuff.powerInfo.gprsFailCode, "CONN");
|
||
return FALSE;
|
||
}
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
// 获取基站定位经纬度
|
||
uint32_t Sim808_GetCellLocPosition()
|
||
{
|
||
if(!Sim808_GPRSDial())
|
||
return FALSE;
|
||
|
||
printf("\nGet Cell-Loc position....\n");
|
||
|
||
// 获取基站定位经纬度
|
||
return DTU_GetCellLocPosition();
|
||
}
|
||
|
||
uint32_t Sim808_SendAndRecv(uint8_t ssl, uint8_t *data, uint16_t len, uint16_t *recvLen, uint8_t *recvBuff, uint16_t recvSize)
|
||
{
|
||
return DTU_SendAndRecv(ssl, data, len, recvLen, recvBuff, recvSize);
|
||
}
|
||
|
||
// EC20一次最多只能发送1500字节
|
||
uint32_t DTU_MqttPublish(uint8_t *data, uint16_t len)
|
||
{
|
||
static uint16_t msgid = 1;
|
||
char cmd[100], buff[40], psn[14];
|
||
int8_t try_count = 2;
|
||
S_RTC_TIME_DATA_T sRTC;
|
||
|
||
sprintf(psn, "20%02d%02d%02d%02d%03d", dcBuff.configBottle.PSN[0], dcBuff.configBottle.PSN[1],
|
||
dcBuff.configBottle.PSN[2], dcBuff.configBottle.PSN[3],
|
||
(dcBuff.configBottle.PSN[4] << 8) | dcBuff.configBottle.PSN[5]);
|
||
|
||
while(try_count--)
|
||
{
|
||
// 唤醒
|
||
// SCUART_Write(SC1, (uint8_t *) "AT\r", 3);
|
||
// delay_ms(5);
|
||
|
||
// 清空数据
|
||
DTU_ClearQueue();
|
||
// 发送命令, 并附加回车换行符
|
||
// sprintf(cmd, "AT+QMTPUBEX=0,%d,1,0,\"/sys/%s/%s/thing/model/up_raw\",%d",
|
||
// msgid, aliyunSecret.product, aliyunSecret.device, len);
|
||
sprintf(cmd, "AT+QMTPUBEX=0,%d,1,0,\"rockcar/guanshuche02\",%d",
|
||
msgid, len);
|
||
printf("\n%s\n", cmd);
|
||
SCUART_Write(SC1, (uint8_t *) cmd, strlen(cmd));
|
||
SCUART_Write(SC1, (uint8_t *) "\r", 1);
|
||
if(DTU_ParseResult(">", "ERROR", buff, DTU_tmrQPendShort))
|
||
{
|
||
delay_ms(10);
|
||
SCUART_Write(SC1, data, len);
|
||
if(DTU_ParseResult("+QMTPUBEX: ", "ERROR", buff, DTU_tmrQPendSpec))
|
||
{
|
||
sprintf(cmd, "+QMTPUBEX: 0,%d,0", msgid);
|
||
if(strstr(buff, cmd))
|
||
{
|
||
DTU_fail_count = 0;
|
||
DTU_shutdown_count = 0;
|
||
printf("\nSend %d bytes ok\n", len);
|
||
msgid++;
|
||
if(msgid == 0)
|
||
msgid++;
|
||
// 记录发送成功的时间
|
||
RTC_GetDateAndTime(&sRTC);
|
||
DTU_succTime = Calc_SecondsFromYear(INITIAL_YEAR, sRTC.u32Year, sRTC.u32Month, sRTC.u32Day,
|
||
sRTC.u32Hour, sRTC.u32Minute, sRTC.u32Second);
|
||
return TRUE;
|
||
}
|
||
}
|
||
}
|
||
|
||
strcpy(dcBuff.powerInfo.gprsFailCode, "SEND");
|
||
delay_ms(200);
|
||
}
|
||
|
||
printf("\nSend failed\n");
|
||
|
||
// 如果2次失败,模块关机/关电
|
||
if(++DTU_fail_count >= 2)
|
||
{
|
||
if(DTU_shutdown_count >= 1 || !DTU_Shutdown())
|
||
DTU_PowerOff();
|
||
}
|
||
|
||
return FALSE;
|
||
}
|
||
|
||
uint32_t Sim808_MqttPublish(uint8_t *data, uint16_t len)
|
||
{
|
||
return DTU_MqttPublish(data, len);
|
||
}
|
||
|
||
// 关闭连接
|
||
uint32_t MQTT_Close()
|
||
{
|
||
char buff[40];
|
||
uint8_t try_count = 2;
|
||
|
||
if(!dcBuff.dtuData.connected)
|
||
return TRUE;
|
||
dcBuff.dtuData.connected = 0;
|
||
|
||
while(try_count--)
|
||
{
|
||
// 可能返回OK,也可能返回错误(如连接已关闭,或被服务器主动关闭),都视为关闭成功
|
||
if(DTU_ExecuteCmd("AT+QMTDISC=0","+QMTDISC: 0,0", "ERROR", buff, DTU_tmrQPendShort))
|
||
{
|
||
printf("\nConnection closed.\n");
|
||
return TRUE;
|
||
}
|
||
delay_ms(200);
|
||
}
|
||
|
||
printf("\nConnection close failed.\n");
|
||
return FALSE;
|
||
}
|
||
|
||
// 连接服务器:MQTT
|
||
uint32_t DTU_MqttConnect(const char *server, int port)
|
||
{
|
||
char cmd[80], buff[40];
|
||
uint8_t try_count = 1;
|
||
|
||
while(try_count--)
|
||
{
|
||
sprintf(cmd, "AT+QMTOPEN=0,\"%s\",%d", server, port);
|
||
if(DTU_ExecuteCmd(cmd, "+QMTOPEN: 0,0", "ERROR", buff, DTU_tmrQPendSpec)
|
||
&& DTU_ExecuteCmd("AT+QMTCONN=0,\"oilH2\",\"agfTc766c\"","+QMTCONN: 0,0,0", "ERROR", buff, DTU_tmrQPendShort))
|
||
{
|
||
dcBuff.dtuData.connected = 1;
|
||
printf("\nConnect to %s:%d\n", server, port);
|
||
return TRUE;
|
||
}
|
||
delay_ms(200);
|
||
}
|
||
|
||
dcBuff.dtuData.connected = 0;
|
||
printf("\nCan not connect to %s:%d\n", server, port);
|
||
|
||
// 如果2次失败,模块关机/关电
|
||
if(++DTU_fail_count >= 2)
|
||
{
|
||
if(DTU_shutdown_count >= 1 || !DTU_Shutdown())
|
||
DTU_PowerOff();
|
||
}
|
||
|
||
return FALSE;
|
||
}
|
||
|
||
uint32_t Sim808_MqttConnect(const char *server, int port)
|
||
{
|
||
if(!Sim808_GPRSDial())
|
||
return FALSE;
|
||
|
||
// if(!DTU_FetchIP())
|
||
// {
|
||
// strcpy(dcBuff.powerInfo.gprsFailCode, "IP");
|
||
// return FALSE;
|
||
// }
|
||
// if(!DTU_SetDNSIP())
|
||
// {
|
||
// strcpy(dcBuff.powerInfo.gprsFailCode, "DNS");
|
||
// return FALSE;
|
||
// }
|
||
|
||
if(!DTU_ConfigMQTT())
|
||
{
|
||
strcpy(dcBuff.powerInfo.gprsFailCode, "MQTT");
|
||
return FALSE;
|
||
}
|
||
|
||
printf("\nConnect to MQTT-Server....\n");
|
||
|
||
if(!DTU_MqttConnect(server, port))
|
||
{
|
||
strcpy(dcBuff.powerInfo.gprsFailCode, "CONN");
|
||
return FALSE;
|
||
}
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
// ASCII重组
|
||
void ASCII2Hex(char hchar, char lchar, uint8_t* hex)
|
||
{
|
||
uint8_t h = 0, l = 0;
|
||
|
||
if(hchar >= '0' && hchar <= '9')
|
||
{
|
||
h = hchar - '0';
|
||
}
|
||
else if(hchar >= 'A' && hchar <= 'F')
|
||
{
|
||
h = hchar - 'A' + 10;
|
||
}
|
||
else if(hchar >= 'a' && hchar <= 'f')
|
||
{
|
||
h = hchar - 'a' + 10;
|
||
}
|
||
|
||
if(lchar >= '0' && lchar <= '9')
|
||
{
|
||
l = lchar - '0';
|
||
}
|
||
else if(lchar >= 'A' && lchar <= 'F')
|
||
{
|
||
l = lchar - 'A' + 10;
|
||
}
|
||
else if(lchar >= 'a' && lchar <= 'f')
|
||
{
|
||
l = lchar - 'a' + 10;
|
||
}
|
||
|
||
*hex = (h << 4) | l;
|
||
}
|
||
|
||
uint8_t check_sum(char *message)
|
||
{
|
||
int16_t i, len = strlen(message);
|
||
uint8_t cs0, cs1 = 0;
|
||
|
||
if(len < 4 || message[0] != '$' || message[len - 3] != '*')
|
||
return 0;
|
||
|
||
for(i = 1; i < len - 3; i++)
|
||
{
|
||
cs1 ^= message[i];
|
||
}
|
||
|
||
ASCII2Hex(message[len - 2], message[len - 1], &cs0);
|
||
|
||
if(cs1 == cs0)
|
||
return 1;
|
||
|
||
printf("\nCheck sum error: %s<>%02X", message, cs1);
|
||
return 0;
|
||
}
|
||
|
||
uint32_t parse_vtg(char *message, data_dtu_t *sample)
|
||
{
|
||
char *p = message, *pe = p + strlen(message), *p1 = NULL;
|
||
char buff[20];
|
||
|
||
// $GNVTG,293.56,T,,M,1.13,N,2.10,K,A*28
|
||
|
||
// 运动角度
|
||
p = strstr(p, ",");
|
||
if(!p || ++p >= pe)
|
||
return 0;
|
||
|
||
// T=真北参照系
|
||
p = strstr(p, ",");
|
||
if(!p || ++p >= pe)
|
||
return 0;
|
||
|
||
// 运动角度
|
||
p = strstr(p, ",");
|
||
if(!p || ++p >= pe)
|
||
return 0;
|
||
|
||
// M=磁北参照系
|
||
p = strstr(p, ",");
|
||
if(!p || ++p >= pe)
|
||
return 0;
|
||
|
||
// 水平运动速度(节)
|
||
p = strstr(p, ",");
|
||
if(!p || ++p >= pe)
|
||
return 0;
|
||
|
||
// N=节
|
||
p = strstr(p, ",");
|
||
if(!p || ++p >= pe)
|
||
return 0;
|
||
|
||
// 水平运动速度(千米)
|
||
p = strstr(p, ",");
|
||
if(!p || ++p >= pe)
|
||
return 0;
|
||
p1 = strstr(p, ",");
|
||
if(!p1)
|
||
return 0;
|
||
memset(buff, 0, sizeof(buff));
|
||
strncpy(buff, p, p1 - p);
|
||
sample->speed = atof(buff);
|
||
|
||
return 1;
|
||
}
|
||
|
||
uint32_t parse_gga(char *message, data_dtu_t *sample)
|
||
{
|
||
char *p = message, *pe = p + strlen(message), *p1 = NULL;
|
||
char buff[20];
|
||
|
||
// $GNGGA,014600.000,3029.3359,N,10357.9168,E,1,4,4.16,200.1,M,-32.0,M,,*6B
|
||
|
||
if(!check_sum(message))
|
||
return 0;
|
||
|
||
// UTC 时间
|
||
p = strstr(p, ",");
|
||
if(!p || ++p >= pe)
|
||
return 0;
|
||
|
||
// 纬度
|
||
p = strstr(p, ",");
|
||
if(!p || ++p >= pe)
|
||
return 0;
|
||
|
||
// N/S
|
||
p = strstr(p, ",");
|
||
if(!p || ++p >= pe)
|
||
return 0;
|
||
|
||
// 经度
|
||
p = strstr(p, ",");
|
||
if(!p || ++p >= pe)
|
||
return 0;
|
||
|
||
// E/W
|
||
p = strstr(p, ",");
|
||
if(!p || ++p >= pe)
|
||
return 0;
|
||
|
||
// GPS状态
|
||
p = strstr(p, ",");
|
||
if(!p || ++p >= pe)
|
||
return 0;
|
||
|
||
// 正在使用的卫星数
|
||
p = strstr(p, ",");
|
||
if(!p || ++p >= pe)
|
||
return 0;
|
||
p1 = strstr(p, ",");
|
||
if(!p1)
|
||
return 0;
|
||
memset(buff, 0, sizeof(buff));
|
||
strncpy(buff, p, p1 - p);
|
||
sample->sateCount = atoi(buff);
|
||
|
||
return 1;
|
||
}
|
||
|
||
uint32_t parse_rmc(char *message, data_dtu_t *sample)
|
||
{
|
||
char *p = message, *pe = p + strlen(message), *p1 = NULL;
|
||
char buff[20];
|
||
uint16_t deg;
|
||
float fen;
|
||
|
||
// $GNRMC,014600.000,A,3029.3359,N,10357.9168,E,1.13,293.56,070417,,,A*7C
|
||
|
||
if(!check_sum(message))
|
||
return 0;
|
||
|
||
// UTC时间
|
||
p = strstr(p, ",");
|
||
if(!p || ++p >= pe)
|
||
return 0;
|
||
p1 = strstr(p, ",");
|
||
if(!p1 || p1 < p + 6)
|
||
return 0;
|
||
// 2位小时
|
||
memset(buff, 0, sizeof(buff));
|
||
strncpy(buff, p, 2);
|
||
p += 2;
|
||
sample->sysTime.hour = atoi(buff);
|
||
// 2位分钟
|
||
memset(buff, 0, sizeof(buff));
|
||
strncpy(buff, p, 2);
|
||
p += 2;
|
||
sample->sysTime.minute = atoi(buff);
|
||
// 2位秒
|
||
memset(buff, 0, sizeof(buff));
|
||
strncpy(buff, p, 2);
|
||
p += 2;
|
||
sample->sysTime.second = atoi(buff);
|
||
if(sample->sysTime.hour > 23 || sample->sysTime.minute > 59 || sample->sysTime.second > 59)
|
||
return 0;
|
||
|
||
// 定位状态
|
||
p = strstr(p, ",");
|
||
if(!p || ++p >= pe)
|
||
return 0;
|
||
sample->posState = (*p == 'A');
|
||
|
||
// 纬度
|
||
p = strstr(p, ",");
|
||
if(!p || ++p >= pe)
|
||
return 0;
|
||
p1 = strstr(p, ",");
|
||
if(!p1 || p1 < p + 11)
|
||
return 0;
|
||
memset(buff, 0, sizeof(buff));
|
||
strncpy(buff, p, 2);
|
||
deg = atoi(buff);
|
||
p += 2;
|
||
strncpy(buff, p, 9);
|
||
fen = atof(buff);
|
||
if(deg > 90 || fen >= 60 || (deg == 90 && fen > 0))
|
||
return 0;
|
||
sample->latitude = (deg + fen / 60) * 1000000ul;
|
||
|
||
// N/S
|
||
p = strstr(p, ",");
|
||
if(!p || ++p >= pe)
|
||
return 0;
|
||
if(*p == 'S')
|
||
sample->latitude = -sample->latitude;
|
||
|
||
// 经度
|
||
p = strstr(p, ",");
|
||
if(!p || ++p >= pe)
|
||
return 0;
|
||
p1 = strstr(p, ",");
|
||
if(!p1 || p1 < p + 12)
|
||
return 0;
|
||
memset(buff, 0, sizeof(buff));
|
||
strncpy(buff, p, 3);
|
||
deg = atoi(buff);
|
||
p += 3;
|
||
strncpy(buff, p, 9);
|
||
fen = atof(buff);
|
||
if(deg > 180 || fen >= 60 || (deg == 180 && fen > 0))
|
||
return 0;
|
||
sample->longitude = (deg + fen / 60) * 1000000ul;
|
||
|
||
// E/W
|
||
p = strstr(p, ",");
|
||
if(!p || ++p >= pe)
|
||
return 0;
|
||
if(*p == 'W')
|
||
sample->longitude = -sample->longitude;
|
||
|
||
// 速度(节)
|
||
p = strstr(p, ",");
|
||
if(!p || ++p >= pe)
|
||
return 0;
|
||
p1 = strstr(p, ",");
|
||
if(!p1)
|
||
return 0;
|
||
memset(buff, 0, sizeof(buff));
|
||
strncpy(buff, p, p1 - p);
|
||
sample->speed = atof(buff) * 1.852;
|
||
|
||
// 方位角
|
||
p = strstr(p, ",");
|
||
if(!p || ++p >= pe)
|
||
return 0;
|
||
|
||
// UTC日期
|
||
p = strstr(p, ",");
|
||
if(!p || ++p >= pe)
|
||
return 0;
|
||
p1 = strstr(p, ",");
|
||
if(!p1 || p1 < p + 6)
|
||
return 0;
|
||
// 2位日期
|
||
memset(buff, 0, sizeof(buff));
|
||
strncpy(buff, p, 2);
|
||
p += 2;
|
||
sample->sysTime.day = atoi(buff);
|
||
// 2位月份
|
||
memset(buff, 0, sizeof(buff));
|
||
strncpy(buff, p, 2);
|
||
p += 2;
|
||
sample->sysTime.month = atoi(buff);
|
||
// 2位年份
|
||
memset(buff, 0, sizeof(buff));
|
||
strncpy(buff, p, 2);
|
||
p += 2;
|
||
sample->sysTime.year = atoi(buff);
|
||
if(sample->sysTime.month < 1 || sample->sysTime.month > 12 || sample->sysTime.day < 1 || sample->sysTime.day > 31)
|
||
return 0;
|
||
|
||
// 处理时差
|
||
GPS_ProcessTimeLag(&sample->sysTime, dcBuff.configData.timeLag);
|
||
|
||
return 1;
|
||
}
|
||
|
||
uint8_t parse_frame(uint8_t *bufIdx, char *message, data_dtu_t *sample)
|
||
{
|
||
uint8_t ret = 0;
|
||
S_RTC_TIME_DATA_T sRTC;
|
||
|
||
if(strncmp(message, "$GPGGA", 6) == 0)
|
||
{
|
||
// printf("\n%s\n", message);
|
||
*bufIdx = 1 - *bufIdx;
|
||
}
|
||
else if(strncmp(message, "$GPRMC", 6) == 0)
|
||
{
|
||
printf("\n%s\n", message);
|
||
|
||
// 获取当前时间
|
||
RTC_GetDateAndTime(&sRTC);
|
||
// 记录GPS上次数据时间
|
||
DTU_gpsTime = Calc_SecondsFromYear(INITIAL_YEAR, sRTC.u32Year, sRTC.u32Month, sRTC.u32Day,
|
||
sRTC.u32Hour, sRTC.u32Minute, sRTC.u32Second);
|
||
|
||
parse_gga(DTU_gpsData[1 - *bufIdx], sample);
|
||
ret = parse_rmc(message, sample);
|
||
if(!ret)
|
||
sample->posState = 0;
|
||
}
|
||
|
||
return ret;
|
||
}
|
||
|
||
// 任务主体:采集GPS数据
|
||
void DTU_Task0(uint8_t c)
|
||
{
|
||
static uint16_t RdIdx = 0;
|
||
static uint8_t bufIdx = 0;
|
||
static data_dtu_t sample = {0};
|
||
static int32_t last_latitude, last_longitude;
|
||
static uint8_t gps_flag = 0, motion_count = 0, motionless_count = 0;
|
||
static uint32_t last_time = 0;
|
||
gps_data_t gpsData;
|
||
uint32_t time;
|
||
|
||
if(c == '$' || RdIdx >= DTU_GPSDATA_SIZE)
|
||
RdIdx = 0;
|
||
|
||
if(RdIdx == 0 && c != '$')
|
||
return;
|
||
|
||
if(c != '\r' && c != '\n')
|
||
DTU_gpsData[bufIdx][RdIdx++] = c;
|
||
else
|
||
{
|
||
// 收到完整的一行
|
||
DTU_gpsData[bufIdx][RdIdx] = 0;
|
||
RdIdx = 0;
|
||
|
||
// 解析一行数据
|
||
if(parse_frame(&bufIdx, DTU_gpsData[bufIdx], &sample))
|
||
{
|
||
if(sample.sateCount > 0)
|
||
printf("sateCount:\t%d\n", sample.sateCount);
|
||
|
||
if(sample.posState)
|
||
{
|
||
time = Calc_SecondsFromYear(INITIAL_YEAR, sample.sysTime.year + 2000, sample.sysTime.month,
|
||
sample.sysTime.day, sample.sysTime.hour, sample.sysTime.minute, sample.sysTime.second);
|
||
|
||
// 修正时间基准(可显示绝对时间)
|
||
//if(RTC_offsetSeconds == 0 && time >= DTU_gpsTime)
|
||
if(time >= DTU_gpsTime) // 每次成功定位都修正时间
|
||
RTC_offsetSeconds = time - DTU_gpsTime;
|
||
|
||
if(!dcBuff.configDisplay.op_CELL_LOCATION || sample.sateCount >= 4)
|
||
{
|
||
if(time >= last_time + dcBuff.configData.intervalGPS)
|
||
{
|
||
last_time = time;
|
||
|
||
// 如果没有硬件加速度计,则用软件方式判断
|
||
if(dcBuff.configDisplay.op_SEND_GPS_DATA && Accelero_ID != ACCELERO_ID)
|
||
{
|
||
if(sample.speed <= 3)
|
||
{
|
||
motion_count = 0;
|
||
if(Motion_Status == 1 && ++motionless_count >= 3)
|
||
{
|
||
Motion_Status = 0;
|
||
printf("\nSoft Motion status = 0\n");
|
||
}
|
||
}
|
||
else
|
||
{
|
||
motionless_count = 0;
|
||
if(Motion_Status == 0 && ++motion_count >= 3)
|
||
{
|
||
Motion_Status = 1;
|
||
printf("\nSoft Motion status = 1\n");
|
||
}
|
||
}
|
||
}
|
||
|
||
printf("Latitude:\t%10.6f\n", sample.latitude * 0.000001);
|
||
printf("Longitude:\t%10.6f\n", sample.longitude * 0.000001);
|
||
printf("Speed:\t\t%d km/h\n", sample.speed);
|
||
printf("GPS time:\t%d-%02d-%02d %02d:%02d:%02d\n",
|
||
sample.sysTime.year + 2000, sample.sysTime.month, sample.sysTime.day,
|
||
sample.sysTime.hour, sample.sysTime.minute, sample.sysTime.second);
|
||
|
||
// 计算和上次定位之间的距离,或者判断运动状态
|
||
if(dcBuff.configDisplay.op_SEND_GPS_DATA && gps_flag == 1 && (
|
||
!Motion_Status
|
||
// || (sample.speed < 5 && GetDistance(last_latitude, last_longitude, sample.latitude, sample.longitude) < 10)
|
||
))
|
||
{
|
||
printf("\nCalibrate to last position\n");
|
||
sample.latitude = last_latitude;
|
||
sample.longitude = last_longitude;
|
||
}
|
||
else
|
||
{
|
||
gps_flag = 1;
|
||
last_latitude = sample.latitude;
|
||
last_longitude = sample.longitude;
|
||
}
|
||
|
||
// 写入全局缓冲
|
||
dcBuff.dtuData.posState = sample.posState;
|
||
dcBuff.dtuData.sateCount = sample.sateCount;
|
||
dcBuff.dtuData.latitude = sample.latitude;
|
||
dcBuff.dtuData.longitude = sample.longitude;
|
||
dcBuff.dtuData.speed = sample.speed;
|
||
dcBuff.dtuData.sysTime = sample.sysTime;
|
||
|
||
if(dcBuff.configDisplay.op_SEND_GPS_DATA)
|
||
{
|
||
// 加入GPS数据队列,待发送
|
||
if(sample.sateCount > 31)
|
||
gpsData.sateCount = 31;
|
||
else
|
||
gpsData.sateCount = sample.sateCount;
|
||
gpsData.posState = sample.posState;
|
||
gpsData.carState = VCC_POWER_STATUS() ? 1: 0;
|
||
gpsData.carEvent = bat_CurrentEvent;
|
||
bat_CurrentEvent = 0;
|
||
|
||
gpsData.time.year = sample.sysTime.year + 2000 - GPS_BASE_YEAR;
|
||
gpsData.time.mon = sample.sysTime.month;
|
||
gpsData.time.day = sample.sysTime.day;
|
||
gpsData.time.hour_H = sample.sysTime.hour >> 4;
|
||
gpsData.time.hour_L = sample.sysTime.hour & 0x0F;
|
||
gpsData.time.min = sample.sysTime.minute;
|
||
gpsData.time.sec = sample.sysTime.second;
|
||
gpsData.latitude = sample.latitude;
|
||
gpsData.longitude = sample.longitude;
|
||
gpsData.speed = sample.speed;
|
||
|
||
GPS_PutToQueue(&gpsData);
|
||
}
|
||
else
|
||
{
|
||
GPS_Located = 1;
|
||
// 停止超时定时器
|
||
GPS_Waiting = 0;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
// 清除数据
|
||
memset(&sample, 0, sizeof(sample));
|
||
}
|
||
}
|
||
}
|
||
|
||
uint8_t pack_gprs_send_data(gprs_data_t *pGprs, uint32_t totalSeconds)
|
||
{
|
||
uint8_t i, j;
|
||
bluetooth_sensor_t *pSensor;
|
||
bluetooth_mask_t *pMask;
|
||
uint32_t relativeTime;
|
||
S_RTC_TIME_DATA_T sRTC;
|
||
uint16_t crc;
|
||
|
||
// 打包上报数据(按modbus从机响应的格式)
|
||
memset(Task_sendBuff, 0, TASK_SENDBUFF_SIZE);
|
||
|
||
i = 0;
|
||
// PSN
|
||
memmove(Task_sendBuff + i, dcBuff.configBottle.PSN, 6);
|
||
printf("\nSend PSN: 20%02d%02d%02d%02d%03d\n", Task_sendBuff[i], Task_sendBuff[i + 1], Task_sendBuff[i + 2],
|
||
Task_sendBuff[i+3], (Task_sendBuff[i + 4] << 8) | Task_sendBuff[i + 5]);
|
||
|
||
i += 6;
|
||
// 功能码
|
||
Task_sendBuff[i++] = 0x10;
|
||
// 数据长度:先预设为0,最后再修改,位置为Task_sendBuff[7]
|
||
Task_sendBuff[i++] = 0;
|
||
|
||
// 当前差压值
|
||
i +=2 ;
|
||
// 容积百分比
|
||
i += 2;
|
||
// 当前容积
|
||
i += 4;
|
||
// 重量
|
||
i += 4;
|
||
// 高度:mmWC
|
||
i += 2;
|
||
// 压力
|
||
Int2ByteS(Task_sendBuff, i, htons(pGprs->sampleData.pressure));
|
||
i += 2;
|
||
#if 0
|
||
// 温度
|
||
Int2ByteS(Task_sendBuff, i, htons(pGprs->dtuData.batTempr);
|
||
#else
|
||
// 用温度表示自启动以来的时间分钟数,32767分钟
|
||
Int2ByteS(Task_sendBuff, i, htons((totalSeconds % 1966080ul) / 60));
|
||
#endif
|
||
i += 2;
|
||
// 液源
|
||
if(dcBuff.configBottle.source >= SOURCE_LNG && dcBuff.configBottle.source <= SOURCE_POPO)
|
||
Task_sendBuff[i] = dcBuff.configBottle.source;
|
||
i++;
|
||
// 储罐类型
|
||
if(dcBuff.configBottle.type == BOTTLE_TYPE_STAND)
|
||
Task_sendBuff[i] = 0;
|
||
else if(dcBuff.configBottle.type == BOTTLE_TYPE_LYING)
|
||
Task_sendBuff[i] = 1;
|
||
else if(dcBuff.configBottle.type == BOTTLE_TYPE_SPHERICAL)
|
||
Task_sendBuff[i] = 2;
|
||
i++;
|
||
// 故障码
|
||
pSensor = (bluetooth_sensor_t *) (Task_sendBuff + i);
|
||
|
||
pSensor->staDiff = Bluetooth_ConvertStat(&pGprs->sampleData.staDPress);
|
||
pSensor->staPress = Bluetooth_ConvertStat(&pGprs->sampleData.staPress);
|
||
pSensor->staEPress1 = Bluetooth_ConvertStat(&pGprs->sampleData.staExtPress[0]);
|
||
pSensor->staEPress2 = Bluetooth_ConvertStat(&pGprs->sampleData.staExtPress[1]);
|
||
pSensor->staEPress3 = Bluetooth_ConvertStat(&pGprs->sampleData.staExtPress[2]);
|
||
pSensor->staETempr1 = Bluetooth_ConvertStat(&pGprs->sampleData.staExtTempr[0]);
|
||
pSensor->staETempr2 = Bluetooth_ConvertStat(&pGprs->sampleData.staExtTempr[1]);
|
||
pSensor->staETempr3 = Bluetooth_ConvertStat(&pGprs->sampleData.staExtTempr[2]);
|
||
i += 2;
|
||
// 传感器状态
|
||
pMask = (bluetooth_mask_t *) (Task_sendBuff + i);
|
||
memset(pMask, 0xFF, 2);
|
||
pMask->maskFlow = 0;
|
||
pMask->maskLowPower = pGprs->dtuData.batLow;
|
||
pMask->maskAbnormal = 0;
|
||
pMask->maskCharging = pGprs->sampleData.charging;
|
||
i += 2;
|
||
|
||
// 版本号
|
||
Task_sendBuff[i++] = dcBuff.powerInfo.protocolVer.minor;
|
||
// rssi
|
||
Task_sendBuff[i++] = pGprs->dtuData.rssi;
|
||
if(pMask->maskGPS)
|
||
{
|
||
// 经度
|
||
Int2ByteL(Task_sendBuff, i, htonl(pGprs->dtuData.longitude));
|
||
|
||
i += 4;
|
||
// 纬度
|
||
Int2ByteL(Task_sendBuff, i, htonl(pGprs->dtuData.latitude));
|
||
i += 4;
|
||
}
|
||
// 扩展温度
|
||
if(pMask->maskETempr1)
|
||
{
|
||
Int2ByteS(Task_sendBuff, i, htons(pGprs->sampleData.extTempr[0]));
|
||
i += 2;
|
||
}
|
||
if(pMask->maskETempr2)
|
||
{
|
||
Int2ByteS(Task_sendBuff, i, htons(pGprs->sampleData.extTempr[1]));
|
||
i += 2;
|
||
}
|
||
if(pMask->maskETempr3)
|
||
{
|
||
#if 0
|
||
// 扩展温度3
|
||
Int2ByteS(Task_sendBuff, i, htons(pGprs->sampleData.extTempr[2]));
|
||
#else
|
||
// 用扩展温度3表示硬件配置
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.powerInfo.hardVer.major));
|
||
#endif
|
||
i += 2;
|
||
}
|
||
|
||
// 电池信息
|
||
if(pMask->maskBattery)
|
||
{
|
||
// 电量百分比
|
||
Int2ByteS(Task_sendBuff, i, htons(pGprs->dtuData.batPct));
|
||
i += 2;
|
||
// 电池内部温度
|
||
Int2ByteS(Task_sendBuff, i, htons(pGprs->dtuData.batTempr));
|
||
i += 2;
|
||
// 电池当前电压
|
||
Int2ByteS(Task_sendBuff, i, htons(pGprs->dtuData.batVoltage / 10));
|
||
i += 2;
|
||
// 电池容量
|
||
Int2ByteS(Task_sendBuff, i, htons(pGprs->dtuData.batMaxCapa));
|
||
i += 2;
|
||
// 电池当前容量
|
||
Int2ByteS(Task_sendBuff, i, htons(pGprs->dtuData.batCapa));
|
||
i += 2;
|
||
#if 0
|
||
// 充电电流,电流的符号表示充放电状态
|
||
Int2ByteS(Task_sendBuff, i, htons(pGprs->dtuData.batCurrent));
|
||
#else
|
||
// 用电流的绝对值表示复位原因
|
||
// 1-POR, 2-PIN, 4-WDT, 8-LVR, 16-BOD, 32-SYS, 128-CPU, 256-CPULK
|
||
Int2ByteS(Task_sendBuff, i, htons(pGprs->dtuData.batCurrent > 0 ? SYS_RSTSTS : -SYS_RSTSTS));
|
||
#endif
|
||
i += 2;
|
||
// 光照强度
|
||
Int2ByteS(Task_sendBuff, i, htons(pGprs->dtuData.sunLevel));
|
||
i += 2;
|
||
}
|
||
|
||
// 流量计
|
||
if(pMask->maskFlow)
|
||
{
|
||
// 天信MODBUS /A1 通信协议 (BCD码)
|
||
// 标况体积总量
|
||
i += 6;
|
||
// 标况流量
|
||
i += 4;
|
||
// 工况流量
|
||
i += 4;
|
||
// 温度
|
||
i += 4;
|
||
// 压力
|
||
i += 4;
|
||
}
|
||
|
||
// 泄露报警
|
||
if(pMask->maskLeak)
|
||
{
|
||
// 类型
|
||
Task_sendBuff[i++] = pGprs->sampleData.leak.typeLeak;
|
||
// 状态、报警浓度
|
||
if(pGprs->sampleData.leak.staLeak == LEAK_STATUS_FAULT || pGprs->sampleData.leak.staLeak == LEAK_STATUS_COMM_FAULT)
|
||
Task_sendBuff[i] = 0x80;
|
||
else
|
||
Task_sendBuff[i] = (pGprs->sampleData.leak.concentrations & 0x7F);
|
||
i++;
|
||
}
|
||
|
||
if(pMask->maskStamp)
|
||
{
|
||
if(dcBuff.powerInfo.protocolVer.minor == 107)
|
||
{
|
||
// 获取当前时间
|
||
RTC_GetDateAndTime(&sRTC);
|
||
// 计算自上次gps定位以来的时间
|
||
relativeTime = Calc_SecondsFromYear(INITIAL_YEAR, sRTC.u32Year, sRTC.u32Month, sRTC.u32Day,
|
||
sRTC.u32Hour, sRTC.u32Minute, sRTC.u32Second) - pGprs->sample_time;
|
||
Int2ByteL(Task_sendBuff, i, htonl(relativeTime));
|
||
}
|
||
// 时间
|
||
i += 4;
|
||
// 年月日
|
||
i += 4;
|
||
}
|
||
|
||
// 扩展压力
|
||
if(pMask->maskEPress1)
|
||
{
|
||
Int2ByteS(Task_sendBuff, i, htons(pGprs->sampleData.extPressure[0]));
|
||
i += 2;
|
||
}
|
||
if(pMask->maskEPress2)
|
||
{
|
||
Int2ByteS(Task_sendBuff, i, htons(pGprs->sampleData.extPressure[1]));
|
||
i += 2;
|
||
}
|
||
if(pMask->maskEPress3)
|
||
{
|
||
#if 0
|
||
// 扩展压力3
|
||
Int2ByteS(Task_sendBuff, i, htons(pGprs->sampleData.extPressure[2]));
|
||
#else
|
||
// 上传GPS调试信息: 闪断次数*100+卫星数
|
||
// 如2105表示闪断21次,卫星数5颗
|
||
Int2ByteS(Task_sendBuff, i, htons(GPS_BOD_COUNT * 100 + pGprs->dtuData.sateCount));
|
||
printf("\nGPS_DEBUG_VAL: %d\n", ntohs(Byte2IntS(Task_sendBuff, i)));
|
||
#endif
|
||
i += 2;
|
||
}
|
||
|
||
printf("\ndcBuff.powerInfo.hardVer.major = %d, dcBuff.powerInfo.softVer.minor = %d\n",
|
||
dcBuff.powerInfo.hardVer.major, dcBuff.powerInfo.softVer.minor);
|
||
// 硬件版本
|
||
//Task_sendBuff[i++] = ((dcBuff.powerInfo.hardVer.minor / 10) << 4) + dcBuff.powerInfo.hardVer.minor % 10;
|
||
Task_sendBuff[i++] = dcBuff.powerInfo.hardVer.minor;
|
||
// 软件版本
|
||
//Task_sendBuff[i++] = ((dcBuff.powerInfo.softVer.minor / 10) << 4) + dcBuff.powerInfo.softVer.minor % 10;;
|
||
Task_sendBuff[i++] = dcBuff.powerInfo.softVer.minor;
|
||
|
||
// 真空传感器1
|
||
if(pGprs->sampleData.vacuum[0].staVacuum == VACUUM_STATUS_FAULT || pGprs->sampleData.vacuum[0].staVacuum == VACUUM_STATUS_COMM_FAULT)
|
||
Int2ByteS(Task_sendBuff, i, htons(0));
|
||
else
|
||
Int2ByteS(Task_sendBuff, i, htons(1));
|
||
i += 2;
|
||
// 使用年限
|
||
Int2ByteS(Task_sendBuff, i, htons(pGprs->sampleData.vacuum[0].lifeVacuum));
|
||
i += 2;
|
||
// 真空度
|
||
Int2ByteL(Task_sendBuff, i, htonl(pGprs->sampleData.vacuum[0].vacuum * 100));
|
||
i += 4;
|
||
// 漏放气速率
|
||
Int2ByteL(Task_sendBuff, i, htonl(pGprs->sampleData.vacuum[0].rateVacuum * 100));
|
||
i += 4;
|
||
// 真空传感器2
|
||
Int2ByteS(Task_sendBuff, i, htons(0));
|
||
i += 2;
|
||
// 使用年限
|
||
i += 2;
|
||
// 真空度
|
||
i += 4;
|
||
// 漏放气速率
|
||
i += 4;
|
||
|
||
// 气瓶容量
|
||
Int2ByteL(Task_sendBuff, i, htonl(pGprs->sampleData.volumeTotal));
|
||
i += 4;
|
||
// 储罐封头直边长
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configBottle.lenExtra));
|
||
i += 2;
|
||
// 储罐筒长度
|
||
Int2ByteL(Task_sendBuff, i, htonl(dcBuff.configBottle.len));
|
||
i += 4;
|
||
// 储罐直径
|
||
Int2ByteL(Task_sendBuff, i, htonl(dcBuff.configBottle.diameter));
|
||
i += 4;
|
||
// 自动发送频率
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configData.intervalTrans / 60));
|
||
i += 2;
|
||
// 自动发送短信频率(实际发送采集频率)
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configData.intervalSample / 60));
|
||
i += 2;
|
||
|
||
// 修改数据长度
|
||
Task_sendBuff[7] = i - 8;
|
||
|
||
// 校验码
|
||
crc = MODBUS_RTU_CRC16((uint8_t *) Task_sendBuff, i);
|
||
Int2ByteS(Task_sendBuff, i, htons(crc));
|
||
i += 2;
|
||
// 结束符
|
||
Task_sendBuff[i++] = 0x0d;
|
||
Task_sendBuff[i++] = 0x0a;
|
||
|
||
return i;
|
||
}
|
||
|
||
uint8_t pack_furui_send_data(gprs_data_t *pGprs, uint32_t *relativeTime)
|
||
{
|
||
uint8_t i;
|
||
uint32_t uVal32;
|
||
S_RTC_TIME_DATA_T sRTC;
|
||
uint16_t crc;
|
||
|
||
// 打包上报数据(按modbus从机响应的格式)
|
||
memset(Task_sendBuff, 0, TASK_SENDBUFF_SIZE);
|
||
|
||
i = 0;
|
||
|
||
// 起始符
|
||
Task_sendBuff[i++] = 0x4C;
|
||
|
||
// 总长度:先预设为0,最后再修改,位置为Task_sendBuff[1]
|
||
Task_sendBuff[i++] = 0;
|
||
// 协议版本
|
||
Task_sendBuff[i++] = 1;
|
||
// 硬件版本
|
||
Task_sendBuff[i++] = dcBuff.powerInfo.hardVer.minor;
|
||
// 软件版本
|
||
Task_sendBuff[i++] = dcBuff.powerInfo.softVer.minor;
|
||
|
||
// PSN
|
||
memmove(Task_sendBuff + i, dcBuff.configBottle.PSN, 6);
|
||
printf("\nSend PSN: 20%02d%02d%02d%02d%03d\n", Task_sendBuff[i], Task_sendBuff[i + 1], Task_sendBuff[i + 2],
|
||
Task_sendBuff[i+3], (Task_sendBuff[i + 4] << 8) | Task_sendBuff[i + 5]);
|
||
i += 6;
|
||
|
||
// 时间戳
|
||
RTC_GetDateAndTime(&sRTC);
|
||
*relativeTime = Calc_SecondsFromYear(INITIAL_YEAR, sRTC.u32Year, sRTC.u32Month, sRTC.u32Day,
|
||
sRTC.u32Hour, sRTC.u32Minute, sRTC.u32Second) - pGprs->sample_time;
|
||
Int2ByteL(Task_sendBuff, i, htonl(*relativeTime));
|
||
i += 4;
|
||
|
||
// 传感器状态
|
||
uVal32 = 0xFFFFFFFFul;
|
||
// 连接状态
|
||
// if(!pGprs->sampleData.staDPress.notConnect)
|
||
// uVal32 &= ~(1ul << 0);
|
||
if(!pGprs->sampleData.staPress.notConnect)
|
||
uVal32 &= ~(1ul << 1);
|
||
if(!pGprs->sampleData.staExtPress[0].notConnect)
|
||
uVal32 &= ~(1ul << 2);
|
||
if(!pGprs->sampleData.staExtTempr[0].notConnect)
|
||
uVal32 &= ~(1ul << 3);
|
||
if(!pGprs->sampleData.staExtTempr[1].notConnect)
|
||
uVal32 &= ~(1ul << 4);
|
||
if(!(pGprs->sampleData.vacuum[0].staVacuum == VACUUM_STATUS_COMM_FAULT))
|
||
uVal32 &= ~(1ul << 5);
|
||
if(1) // 流量计
|
||
uVal32 &= ~(1ul << 6);
|
||
if(!(pGprs->sampleData.leak.staLeak == LEAK_STATUS_COMM_FAULT))
|
||
uVal32 &= ~(1ul << 7);
|
||
// 故障状态
|
||
if(!(pGprs->sampleData.staDPress.overFlow || pGprs->sampleData.staDPress.underFlow))
|
||
uVal32 &= ~(1ul << 8);
|
||
if(!(pGprs->sampleData.staPress.overFlow || pGprs->sampleData.staPress.underFlow))
|
||
uVal32 &= ~(1ul << 9);
|
||
if(!(pGprs->sampleData.staExtPress[0].overFlow || pGprs->sampleData.staExtPress[0].underFlow))
|
||
uVal32 &= ~(1ul << 10);
|
||
if(!(pGprs->sampleData.staExtTempr[0].overFlow || pGprs->sampleData.staExtTempr[0].underFlow))
|
||
uVal32 &= ~(1ul << 11);
|
||
if(!(pGprs->sampleData.staExtTempr[1].overFlow || pGprs->sampleData.staExtTempr[1].underFlow))
|
||
uVal32 &= ~(1ul << 12);
|
||
if(!(pGprs->sampleData.vacuum[0].staVacuum == VACUUM_STATUS_FAULT))
|
||
uVal32 &= ~(1ul << 13);
|
||
if(1) // 流量计
|
||
uVal32 &= ~(1ul << 14);
|
||
if(!(pGprs->sampleData.leak.staLeak == LEAK_STATUS_FAULT))
|
||
uVal32 &= ~(1ul << 15);
|
||
Int2ByteL(Task_sendBuff, i, htonl(uVal32));
|
||
i += 4;
|
||
|
||
// 当前差压值:mmWC
|
||
i +=2 ;
|
||
// 容积百分比
|
||
i += 2;
|
||
// 当前容积
|
||
i += 4;
|
||
// 重量
|
||
i += 4;
|
||
// 气瓶容量
|
||
Int2ByteL(Task_sendBuff, i, htonl(pGprs->sampleData.volumeTotal));
|
||
i += 4;
|
||
// 压力1
|
||
Int2ByteS(Task_sendBuff, i, htons(pGprs->sampleData.pressure));
|
||
i += 2;
|
||
// 压力2
|
||
Int2ByteS(Task_sendBuff, i, htons(pGprs->sampleData.extPressure[0]));
|
||
i += 2;
|
||
// 温度1
|
||
Int2ByteS(Task_sendBuff, i, htons(pGprs->sampleData.extTempr[0]));
|
||
i += 2;
|
||
// 温度2
|
||
Int2ByteS(Task_sendBuff, i, htons(pGprs->sampleData.extTempr[1]));
|
||
i += 2;
|
||
|
||
// 真空度
|
||
Int2ByteS(Task_sendBuff, i, htons((uint16_t) (pGprs->sampleData.vacuum[0].vacuum * 100)));
|
||
i += 2;
|
||
// 真空计温度
|
||
Int2ByteS(Task_sendBuff, i, htons((int16_t) pGprs->sampleData.vacuum[0].tempr));
|
||
i += 2;
|
||
|
||
// 天信MODBUS /A1 通信协议 (BCD码)
|
||
// 标况体积总量
|
||
memmove(Task_sendBuff + i, pGprs->sampleData.flow.nM3, 6);
|
||
i += 6;
|
||
// 标况流量
|
||
memmove(Task_sendBuff + i, pGprs->sampleData.flow.nM3_h, 4);
|
||
i += 4;
|
||
// 工况流量
|
||
memmove(Task_sendBuff + i, pGprs->sampleData.flow.M3_h, 4);
|
||
i += 4;
|
||
// 流量计温度
|
||
memmove(Task_sendBuff + i, pGprs->sampleData.flow.tempr, 4);
|
||
i += 4;
|
||
// 流量计压力
|
||
memmove(Task_sendBuff + i, pGprs->sampleData.flow.pressure, 4);
|
||
i += 4;
|
||
|
||
// 泄露状态
|
||
Task_sendBuff[i++] = (pGprs->sampleData.leak.staLeak == LEAK_STATUS_A2_ALARM ? 1 : 0);
|
||
|
||
// 经度
|
||
Int2ByteL(Task_sendBuff, i, htonl(pGprs->dtuData.longitude));
|
||
i += 4;
|
||
// 纬度
|
||
Int2ByteL(Task_sendBuff, i, htonl(pGprs->dtuData.latitude));
|
||
i += 4;
|
||
|
||
// rssi
|
||
Task_sendBuff[i++] = pGprs->dtuData.rssi;
|
||
|
||
// 电量百分比
|
||
Task_sendBuff[i++] = pGprs->dtuData.batPct;
|
||
// 电池当前电压
|
||
Int2ByteS(Task_sendBuff, i, htons(pGprs->dtuData.batVoltage / 10));
|
||
i += 2;
|
||
// 供电状态
|
||
Task_sendBuff[i++] = (pGprs->dtuData.batCurrent < 0 ? -1 : 1);
|
||
|
||
// 液源
|
||
if(dcBuff.configBottle.source >= SOURCE_LNG && dcBuff.configBottle.source <= SOURCE_POPO)
|
||
Task_sendBuff[i] = dcBuff.configBottle.source;
|
||
i++;
|
||
// 密度
|
||
Int2ByteS(Task_sendBuff, i, htons(Config_GetDensity(dcBuff.configBottle.source) * 1000));
|
||
i += 2;
|
||
|
||
// 储罐类型
|
||
if(dcBuff.configBottle.type == BOTTLE_TYPE_STAND)
|
||
Task_sendBuff[i] = 0;
|
||
else if(dcBuff.configBottle.type == BOTTLE_TYPE_LYING)
|
||
Task_sendBuff[i] = 1;
|
||
else if(dcBuff.configBottle.type == BOTTLE_TYPE_SPHERICAL)
|
||
Task_sendBuff[i] = 2;
|
||
i++;
|
||
// 储罐直径
|
||
Int2ByteL(Task_sendBuff, i, htonl(dcBuff.configBottle.diameter));
|
||
i += 4;
|
||
// 储罐筒长度
|
||
Int2ByteL(Task_sendBuff, i, htonl(dcBuff.configBottle.len + dcBuff.configBottle.lenExtra * 2));
|
||
i += 4;
|
||
|
||
// 采集周期
|
||
Int2ByteL(Task_sendBuff, i, htonl(dcBuff.configData.intervalSample));
|
||
i += 4;
|
||
// 发送周期
|
||
Int2ByteL(Task_sendBuff, i, htonl(dcBuff.configData.intervalTrans));
|
||
i += 4;
|
||
|
||
// 满液位百分比
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configBottle.fullPct));
|
||
i += 2;
|
||
// 关键液位百分比
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configBottle.priPct));
|
||
i += 2;
|
||
// 订货位百分比
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configBottle.orderPct));
|
||
i += 2;
|
||
// 空液位百分比
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configBottle.emptyPct));
|
||
i += 2;
|
||
// 压力报警上限
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configBottle.warnPressH));
|
||
i += 2;
|
||
// 压力报警下限
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configBottle.warnPress));
|
||
i += 2;
|
||
// 温度报警上限
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configBottle.warnTemprH));
|
||
i += 2;
|
||
// 温度报警下限
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configBottle.warnTempr));
|
||
i += 2;
|
||
// 真空度报警上限
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configBottle.warnVacuumH));
|
||
i += 2;
|
||
// 显示控制
|
||
Task_sendBuff[i++] = dcBuff.configBottle.dispMode;
|
||
|
||
// 修改数据长度
|
||
Task_sendBuff[1] = i - 1 + 2;
|
||
|
||
// 校验码
|
||
crc = MODBUS_RTU_CRC16(Task_sendBuff + 1, i - 1);
|
||
Int2ByteS(Task_sendBuff, i, htons(crc));
|
||
i += 2;
|
||
// 结束符
|
||
Task_sendBuff[i++] = 0x53;
|
||
|
||
return i;
|
||
}
|
||
|
||
uint8_t parse_furui_recv_data(uint8_t PSN[6], uint32_t relativeTime, uint16_t recvLen)
|
||
{
|
||
uint8_t i, j, len, protocol;
|
||
uint32_t mask, uVal32;
|
||
uint16_t uVal16;
|
||
int16_t val16;
|
||
uint8_t saveConfig = 0;
|
||
|
||
i = 0;
|
||
// 检查起始符、结束符
|
||
if(Task_recvBuff[i++] != 0x4C || Task_recvBuff[recvLen - 1] != 0x53)
|
||
return 0;
|
||
// 检查数据长度和CRC
|
||
len = Task_recvBuff[i++];
|
||
if(len != recvLen - 2 || MODBUS_RTU_CRC16(Task_recvBuff + 1, len) != 0)
|
||
return 0;
|
||
// 检查协议版本
|
||
protocol = Task_recvBuff[i++];
|
||
if(protocol != 1)
|
||
return 0;
|
||
// 检查PSN
|
||
if(memcmp(Task_recvBuff + i, PSN, 6) != 0)
|
||
return 0;
|
||
i += 6;
|
||
// 检查时间戳
|
||
if(ntohl(Byte2IntL(Task_recvBuff, i)) != relativeTime)
|
||
return 0;
|
||
i += 4;
|
||
// 参数更新标志
|
||
mask = ntohl(Byte2IntL(Task_recvBuff, i));
|
||
i += 4;
|
||
|
||
j = 0;
|
||
// 介质
|
||
if(mask & (1ul << (j++)))
|
||
{
|
||
printf("modify source\r\n");
|
||
if(dcBuff.configBottle.source != Task_recvBuff[i])
|
||
{
|
||
dcBuff.configBottle.source = Task_recvBuff[i];
|
||
saveConfig = 1;
|
||
}
|
||
}
|
||
i++;
|
||
|
||
// 密度
|
||
if(mask & (1ul << (j++)))
|
||
{
|
||
printf("modify density\r\n");
|
||
uVal16 = ntohs(Byte2IntS(Task_recvBuff, i));
|
||
if(Config_GetDensity(dcBuff.configBottle.source) * 1000 != uVal16)
|
||
{
|
||
Config_SetDensity(dcBuff.configBottle.source, uVal16 / 1000.0);
|
||
saveConfig = 1;
|
||
}
|
||
}
|
||
i += 2;
|
||
|
||
// 储罐类型
|
||
if(mask & (1ul << (j++)))
|
||
{
|
||
printf("modify type\r\n");
|
||
if(dcBuff.configBottle.type != Task_recvBuff[i])
|
||
{
|
||
dcBuff.configBottle.type = Task_recvBuff[i];
|
||
saveConfig = 1;
|
||
}
|
||
}
|
||
i++;
|
||
// 储罐直径
|
||
if(mask & (1ul << (j++)))
|
||
{
|
||
printf("modify diameter\r\n");
|
||
uVal32 = ntohl(Byte2IntL(Task_recvBuff, i));
|
||
if(dcBuff.configBottle.diameter != uVal32)
|
||
{
|
||
dcBuff.configBottle.diameter = uVal32;
|
||
saveConfig = 1;
|
||
}
|
||
}
|
||
i += 4;
|
||
// 储罐筒长度
|
||
if(mask & (1ul << (j++)))
|
||
{
|
||
printf("modify len\r\n");
|
||
uVal32 = ntohl(Byte2IntL(Task_recvBuff, i));
|
||
if(dcBuff.configBottle.lenExtra != 0 || dcBuff.configBottle.len != uVal32)
|
||
{
|
||
dcBuff.configBottle.lenExtra = 0;
|
||
dcBuff.configBottle.len = uVal32;
|
||
saveConfig = 1;
|
||
}
|
||
}
|
||
i += 4;
|
||
|
||
// 采集周期
|
||
if(mask & (1ul << (j++)))
|
||
{
|
||
printf("modify intervalSample\r\n");
|
||
uVal32 = ntohl(Byte2IntL(Task_recvBuff, i));
|
||
if(dcBuff.configData.intervalSample != uVal32)
|
||
{
|
||
dcBuff.configData.intervalSample = uVal32;
|
||
saveConfig = 1;
|
||
}
|
||
}
|
||
i += 4;
|
||
// 发送周期
|
||
if(mask & (1ul << (j++)))
|
||
{
|
||
printf("modify intervalTrans\r\n");
|
||
uVal32 = ntohl(Byte2IntL(Task_recvBuff, i));
|
||
if(dcBuff.configData.intervalTrans != uVal32)
|
||
{
|
||
dcBuff.configData.intervalTrans = uVal32;
|
||
saveConfig = 1;
|
||
}
|
||
}
|
||
i += 4;
|
||
|
||
// 满液位百分比
|
||
if(mask & (1ul << (j++)))
|
||
{
|
||
printf("modify fullPct\r\n");
|
||
uVal16= ntohs(Byte2IntS(Task_recvBuff, i));
|
||
if(dcBuff.configBottle.fullPct != uVal16)
|
||
{
|
||
dcBuff.configBottle.fullPct = uVal16;
|
||
saveConfig = 1;
|
||
}
|
||
}
|
||
i += 2;
|
||
// 关键液位百分比
|
||
if(mask & (1ul << (j++)))
|
||
{
|
||
printf("modify priPct\r\n");
|
||
uVal16= ntohs(Byte2IntS(Task_recvBuff, i));
|
||
if(dcBuff.configBottle.priPct != uVal16)
|
||
{
|
||
dcBuff.configBottle.priPct = uVal16;
|
||
saveConfig = 1;
|
||
}
|
||
}
|
||
i += 2;
|
||
// 订货位百分比
|
||
if(mask & (1ul << (j++)))
|
||
{
|
||
printf("modify orderPct\r\n");
|
||
uVal16= ntohs(Byte2IntS(Task_recvBuff, i));
|
||
if(dcBuff.configBottle.orderPct != uVal16)
|
||
{
|
||
dcBuff.configBottle.orderPct = uVal16;
|
||
saveConfig = 1;
|
||
}
|
||
}
|
||
i += 2;
|
||
// 空液位百分比
|
||
if(mask & (1ul << (j++)))
|
||
{
|
||
printf("modify emptyPct\r\n");
|
||
uVal16= ntohs(Byte2IntS(Task_recvBuff, i));
|
||
if(dcBuff.configBottle.emptyPct != uVal16)
|
||
{
|
||
dcBuff.configBottle.emptyPct = uVal16;
|
||
saveConfig = 1;
|
||
}
|
||
}
|
||
i += 2;
|
||
// 压力报警上限
|
||
if(mask & (1ul << (j++)))
|
||
{
|
||
printf("modify warnPressH\r\n");
|
||
uVal16= ntohs(Byte2IntS(Task_recvBuff, i));
|
||
if(dcBuff.configBottle.warnPressH != uVal16)
|
||
{
|
||
dcBuff.configBottle.warnPressH = uVal16;
|
||
saveConfig = 1;
|
||
}
|
||
}
|
||
i += 2;
|
||
// 压力报警下限
|
||
if(mask & (1ul << (j++)))
|
||
{
|
||
printf("modify warnPress\r\n");
|
||
uVal16= ntohs(Byte2IntS(Task_recvBuff, i));
|
||
if(dcBuff.configBottle.warnPress != uVal16)
|
||
{
|
||
dcBuff.configBottle.warnPress = uVal16;
|
||
saveConfig = 1;
|
||
}
|
||
}
|
||
i += 2;
|
||
// 温度报警上限
|
||
if(mask & (1ul << (j++)))
|
||
{
|
||
printf("modify warnTemprH\r\n");
|
||
uVal16= ntohs(Byte2IntS(Task_recvBuff, i));
|
||
memmove(&val16, &uVal16, 2);
|
||
if(dcBuff.configBottle.warnTemprH != val16)
|
||
{
|
||
dcBuff.configBottle.warnTemprH = val16;
|
||
saveConfig = 1;
|
||
}
|
||
}
|
||
i += 2;
|
||
// 温度报警下限
|
||
if(mask & (1ul << (j++)))
|
||
{
|
||
printf("modify warnTempr\r\n");
|
||
uVal16= ntohs(Byte2IntS(Task_recvBuff, i));
|
||
memmove(&val16, &uVal16, 2);
|
||
if(dcBuff.configBottle.warnTempr != val16)
|
||
{
|
||
dcBuff.configBottle.warnTempr = val16;
|
||
saveConfig = 1;
|
||
}
|
||
}
|
||
i += 2;
|
||
// 真空度报警上限
|
||
if(mask & (1ul << (j++)))
|
||
{
|
||
printf("modify warnVacuumH\r\n");
|
||
uVal16= ntohs(Byte2IntS(Task_recvBuff, i));
|
||
if(dcBuff.configBottle.warnVacuumH != uVal16)
|
||
{
|
||
dcBuff.configBottle.warnVacuumH = uVal16;
|
||
saveConfig = 1;
|
||
}
|
||
}
|
||
i += 2;
|
||
// 显示控制
|
||
if(mask & (1ul << (j++)))
|
||
{
|
||
printf("modify dispMode\r\n");
|
||
if(dcBuff.configBottle.dispMode != Task_recvBuff[i])
|
||
{
|
||
dcBuff.configBottle.dispMode = Task_recvBuff[i];
|
||
saveConfig = 1;
|
||
}
|
||
}
|
||
i++;
|
||
|
||
// 保存参数
|
||
if(saveConfig)
|
||
Config_SaveConfig();
|
||
|
||
return 1;
|
||
}
|
||
////////////////////////////////////////////////////////////////////////////////////////
|
||
uint8_t pack_rf_send_data(gprs_data_t *pGprs, uint32_t totalSeconds)
|
||
{
|
||
uint8_t i;
|
||
rf_sensor_t *pSensor;
|
||
S_RTC_TIME_DATA_T sRTC;
|
||
|
||
// 打包上报数据(按modbus从机响应的格式)
|
||
memset(Task_sendBuff, 0, TASK_SENDBUFF_SIZE);
|
||
|
||
i = 0;
|
||
|
||
// PSN
|
||
printf("\nRf PSN: 20%02d%02d%02d%02d%03d\n", dcBuff.configBottle.PSN[0], dcBuff.configBottle.PSN[1],
|
||
dcBuff.configBottle.PSN[2], dcBuff.configBottle.PSN[3],
|
||
(dcBuff.configBottle.PSN[4] << 8) | dcBuff.configBottle.PSN[5]);
|
||
|
||
// 差压测量:差压值 *100(KPa),称重测量:容积百分比*100,电容测量:液位高度(mm)
|
||
i += 2;
|
||
|
||
// 压力
|
||
Int2ByteS(Task_sendBuff, i, pGprs->sampleData.pressure);
|
||
i += 2;
|
||
|
||
// 温度
|
||
Int2ByteS(Task_sendBuff, i, pGprs->sampleData.extTempr[0]);
|
||
i += 2;
|
||
|
||
// 液源/贮罐类型/故障码/测量方式
|
||
pSensor = (rf_sensor_t *) (Task_sendBuff + i);
|
||
|
||
pSensor->staDiff = Bluetooth_ConvertStat(&pGprs->sampleData.staDPress);
|
||
pSensor->staPress = Bluetooth_ConvertStat(&pGprs->sampleData.staPress);
|
||
pSensor->staETempr1 = Bluetooth_ConvertStat(&pGprs->sampleData.staExtTempr[0]);
|
||
pSensor->charging = pGprs->sampleData.charging;
|
||
pSensor->bat_low = pGprs->dtuData.batLow;
|
||
pSensor->measure_type = MEASURE_DPRESS;
|
||
pSensor->bottle_type = dcBuff.configBottle.type;
|
||
pSensor->L_source = dcBuff.configBottle.source;
|
||
i += 2;
|
||
|
||
// 密度
|
||
Int2ByteS(Task_sendBuff, i, Config_GetDensity(dcBuff.configBottle.source) * 1000);
|
||
i += 2;
|
||
// 经度
|
||
Int2ByteL(Task_sendBuff, i, pGprs->dtuData.longitude);
|
||
i += 4;
|
||
// 纬度
|
||
Int2ByteL(Task_sendBuff, i, pGprs->dtuData.latitude);
|
||
i += 4;
|
||
|
||
// 电池当前电压
|
||
Int2ByteS(Task_sendBuff, i, pGprs->dtuData.batVoltage / 10);
|
||
i += 2;
|
||
|
||
// 电量百分比
|
||
Task_sendBuff[i++] = pGprs->dtuData.batPct;
|
||
#if 0
|
||
// 充电电流,电流的符号表示充放电状态
|
||
if(pGprs->dtuData.batCurrent < -128)
|
||
Task_sendBuff[i] = -128;
|
||
else if(pGprs->dtuData.batCurrent > 127)
|
||
Task_sendBuff[i] = 127;
|
||
else
|
||
Task_sendBuff[i] = pGprs->dtuData.batCurrent;
|
||
#else
|
||
// 用电流的绝对值表示复位原因
|
||
// 1-POR, 2-PIN, 4-WDT, 8-LVR, 16-BOD, 32-SYS
|
||
Task_sendBuff[i] = SYS_RSTSTS & 0x7F;
|
||
if(pGprs->dtuData.batCurrent < 0)
|
||
Task_sendBuff[i] = -Task_sendBuff[i];
|
||
#endif
|
||
i++;
|
||
|
||
// 获取当前时间
|
||
RTC_GetDateAndTime(&sRTC);
|
||
Int2ByteL(Task_sendBuff, i, Calc_SecondsFromYear(INITIAL_YEAR, sRTC.u32Year, sRTC.u32Month, sRTC.u32Day,
|
||
sRTC.u32Hour, sRTC.u32Minute, sRTC.u32Second) - pGprs->sample_time);
|
||
i += 4;
|
||
|
||
printf("\ndcBuff.powerInfo.hardVer.major = %d, dcBuff.powerInfo.softVer.minor = %d\n",
|
||
dcBuff.powerInfo.hardVer.major, dcBuff.powerInfo.softVer.minor);
|
||
// 硬件版本
|
||
Task_sendBuff[i++] = dcBuff.powerInfo.hardVer.minor;
|
||
// 软件版本
|
||
Task_sendBuff[i++] = dcBuff.powerInfo.softVer.minor;
|
||
|
||
// 储罐筒长度
|
||
Int2ByteL(Task_sendBuff, i, dcBuff.configBottle.len + dcBuff.configBottle.lenExtra * 2);
|
||
i += 4;
|
||
// 储罐直径
|
||
Int2ByteL(Task_sendBuff, i, dcBuff.configBottle.diameter);
|
||
i += 4;
|
||
// 充装比
|
||
Task_sendBuff[i++] = dcBuff.configBottle.chargePct;
|
||
|
||
return i;
|
||
}
|
||
////////////////////////////////////////////////////////////////////////////////////////
|
||
uint8_t pack_bd_send_data(gprs_data_t *pGprs, uint32_t totalSeconds)
|
||
{
|
||
uint8_t i;
|
||
rf_sensor_t *pSensor;
|
||
S_RTC_TIME_DATA_T sRTC;
|
||
|
||
// 打包上报数据(按modbus从机响应的格式)
|
||
memset(Task_sendBuff, 0, TASK_SENDBUFF_SIZE);
|
||
|
||
i = 0;
|
||
|
||
// PSN
|
||
printf("\nBD PSN: 20%02d%02d%02d%02d%03d\n", dcBuff.configBottle.PSN[0], dcBuff.configBottle.PSN[1],
|
||
dcBuff.configBottle.PSN[2], dcBuff.configBottle.PSN[3],
|
||
(dcBuff.configBottle.PSN[4] << 8) | dcBuff.configBottle.PSN[5]);
|
||
|
||
// 差压
|
||
i += 2;
|
||
|
||
// 容积百分比
|
||
i += 2;
|
||
|
||
// 当前容积
|
||
i += 4;
|
||
|
||
// 重量
|
||
i += 4;
|
||
|
||
// 压力
|
||
Int2ByteS(Task_sendBuff, i, pGprs->sampleData.pressure);
|
||
i += 2;
|
||
|
||
// 温度-扩展温度1
|
||
Int2ByteS(Task_sendBuff, i, pGprs->sampleData.extTempr[0]);
|
||
i += 2;
|
||
|
||
// 温度-调试信息:标识北斗短信
|
||
Int2ByteS(Task_sendBuff, i, 2);
|
||
i += 2;
|
||
|
||
// 液源/贮罐类型/故障码/测量方式
|
||
pSensor = (rf_sensor_t *) (Task_sendBuff + i);
|
||
|
||
pSensor->staDiff = Bluetooth_ConvertStat(&pGprs->sampleData.staDPress);
|
||
pSensor->staPress = Bluetooth_ConvertStat(&pGprs->sampleData.staPress);
|
||
pSensor->staETempr1 = Bluetooth_ConvertStat(&pGprs->sampleData.staExtTempr[0]);
|
||
pSensor->charging = pGprs->sampleData.charging;
|
||
pSensor->bat_low = pGprs->dtuData.batLow;
|
||
pSensor->measure_type = MEASURE_DPRESS;
|
||
pSensor->bottle_type = dcBuff.configBottle.type;
|
||
pSensor->L_source = dcBuff.configBottle.source;
|
||
i += 2;
|
||
|
||
// 经度
|
||
Int2ByteL(Task_sendBuff, i, pGprs->dtuData.longitude);
|
||
i += 4;
|
||
|
||
// 纬度
|
||
Int2ByteL(Task_sendBuff, i, pGprs->dtuData.latitude);
|
||
i += 4;
|
||
|
||
// 电池当前电压
|
||
Int2ByteS(Task_sendBuff, i, pGprs->dtuData.batVoltage / 10);
|
||
i += 2;
|
||
|
||
// 电量百分比
|
||
Task_sendBuff[i++] = pGprs->dtuData.batPct;
|
||
|
||
#if 0
|
||
// 充电电流,电流的符号表示充放电状态
|
||
if(pGprs->dtuData.batCurrent < -128)
|
||
Task_sendBuff[i] = -128;
|
||
else if(pGprs->dtuData.batCurrent > 127)
|
||
Task_sendBuff[i] = 127;
|
||
else
|
||
Task_sendBuff[i] = pGprs->dtuData.batCurrent;
|
||
#else
|
||
// 用电流的绝对值表示复位原因
|
||
// 1-POR, 2-PIN, 4-WDT, 8-LVR, 16-BOD, 32-SYS
|
||
Task_sendBuff[i] = SYS_RSTSTS & 0x7F;
|
||
if(pGprs->dtuData.batCurrent < 0)
|
||
Task_sendBuff[i] = -Task_sendBuff[i];
|
||
#endif
|
||
i++;
|
||
|
||
// 获取当前时间
|
||
RTC_GetDateAndTime(&sRTC);
|
||
Int2ByteL(Task_sendBuff, i, Calc_SecondsFromYear(INITIAL_YEAR, sRTC.u32Year, sRTC.u32Month, sRTC.u32Day,
|
||
sRTC.u32Hour, sRTC.u32Minute, sRTC.u32Second) - pGprs->sample_time);
|
||
i += 4;
|
||
|
||
printf("\ndcBuff.powerInfo.hardVer.major = %d, dcBuff.powerInfo.softVer.minor = %d\n",
|
||
dcBuff.powerInfo.hardVer.major, dcBuff.powerInfo.softVer.minor);
|
||
|
||
// 硬件版本
|
||
Task_sendBuff[i++] = dcBuff.powerInfo.hardVer.minor;
|
||
|
||
// 软件版本
|
||
Task_sendBuff[i++] = dcBuff.powerInfo.softVer.minor;
|
||
|
||
// 气瓶容量
|
||
Int2ByteL(Task_sendBuff, i, pGprs->sampleData.volumeTotal);
|
||
i += 4;
|
||
|
||
// 储罐筒长度
|
||
Int2ByteL(Task_sendBuff, i, dcBuff.configBottle.len + dcBuff.configBottle.lenExtra * 2);
|
||
i += 4;
|
||
|
||
// 储罐直径
|
||
Int2ByteL(Task_sendBuff, i, dcBuff.configBottle.diameter);
|
||
i += 4;
|
||
|
||
return i;
|
||
}
|
||
|
||
/// ?????????
|
||
static void *my_malloc(size_t size) {
|
||
void *ptr = malloc(200 * 5); // ???????
|
||
if (ptr == NULL) {
|
||
fprintf(stderr, "Memory allocation failed\n");
|
||
}
|
||
return ptr;
|
||
}
|
||
|
||
// ?????????
|
||
static void my_free(void *ptr) {
|
||
free(ptr);
|
||
}
|
||
|
||
|
||
|
||
|
||
uint16_t pack_json_send_data(gprs_data_t *pGprs, uint32_t totalSeconds)
|
||
{
|
||
uint16_t len = 0;
|
||
char Json_data[500],utc[21];
|
||
S_RTC_TIME_DATA_T sRTC;
|
||
Wakeup_CalcUTCTime(pGprs->sample_time + RTC_offsetSeconds, &sRTC);
|
||
sprintf(utc, "%04d-%02d-%02dT%02d:%02d:%02d", sRTC.u32Year, sRTC.u32Month, sRTC.u32Day,
|
||
sRTC.u32Hour, sRTC.u32Minute, sRTC.u32Second);
|
||
// len = sprintf(Json_data,"{\
|
||
// \"PSN\":20%02d%02d%02d%02d%03d,\
|
||
// \"RTC\":%s,\
|
||
// \"hardVer\":%d,\
|
||
// \"softVer\":%d,\
|
||
// \"batVoltage\":%d,\
|
||
// \"batPct\":%d,\
|
||
// \"latitude\":%d,\
|
||
// \"longitude\":%d,\
|
||
// \"rssi\":%d,\
|
||
// \"simNumber\":%s,\
|
||
// \"type\":%d,\
|
||
// \"diameter\":%d,\
|
||
// \"len\":%d,\
|
||
// \"source\":%d,\
|
||
// \"Theoretical_v\":%d,\
|
||
// \"Pressure\":%.2f,\
|
||
// \"volume\":%d,\
|
||
// \"warnPressH\":%.2f,\
|
||
// \"warnPressL\":%.2f,\
|
||
// \"fullPct\":%.2f,\
|
||
// \"emptyPct\":%.2f,\
|
||
// \"adExtTempr0\":%d,\
|
||
// \"adExtTempr1\":%d,\
|
||
// \"intervalSample\":%d,\
|
||
// \"intervalTrans\":%d}",
|
||
// dcBuff.configBottle.PSN[0], dcBuff.configBottle.PSN[1],
|
||
// dcBuff.configBottle.PSN[2], dcBuff.configBottle.PSN[3],
|
||
// (dcBuff.configBottle.PSN[4] << 8) | dcBuff.configBottle.PSN[5],
|
||
// utc,
|
||
// dcBuff.powerInfo.hardVer.minor,
|
||
// dcBuff.powerInfo.softVer.minor,
|
||
// dcBuff.dtuData.batVoltage,
|
||
// dcBuff.dtuData.batPct,
|
||
// dcBuff.dtuData.latitude,
|
||
// dcBuff.dtuData.longitude,
|
||
// dcBuff.dtuData.rssi,
|
||
// dcBuff.powerInfo.simNumber,
|
||
// dcBuff.configBottle.type,
|
||
// dcBuff.configBottle.diameter,
|
||
// dcBuff.configBottle.len,
|
||
// dcBuff.configBottle.source,
|
||
// Theoretical_Param.v,
|
||
|
||
// (float)dcBuff.sampleData.pressure * 0.01f,
|
||
// dcBuff.sampleData.volume,
|
||
// dcBuff.configBottle.warnPressH * 0.01f,
|
||
// dcBuff.configBottle.warnPress * 0.01f,
|
||
// dcBuff.configBottle.fullPct * 0.01f,
|
||
// dcBuff.configBottle.emptyPct * 0.01f,
|
||
// dcBuff.sampleData.extTempr[0],
|
||
// dcBuff.sampleData.extTempr[1],
|
||
// dcBuff.configData.intervalSample,
|
||
// dcBuff.configData.intervalTrans);
|
||
len = sprintf(Json_data,"{\
|
||
\"PSN\":\"20%02d%02d%02d%02d%03d\",\
|
||
\"RTC\":\"%s\",\
|
||
\"batPct\":%d,\
|
||
\"latitude\":%d,\
|
||
\"longitude\":%d,\
|
||
\"rssi\":%d,\
|
||
\"type\":%d,\
|
||
\"source\":%d,\
|
||
\"Theoretical_v\":%d,\
|
||
\"Pressure\":%.2f,\
|
||
\"volume\":%d,\
|
||
\"warnPressH\":%.2f,\
|
||
\"warnPressL\":%.2f,\
|
||
\"adExtTempr\":%d,\
|
||
\"intervalSample\":%d,\
|
||
\"intervalTrans\":%d}",
|
||
dcBuff.configBottle.PSN[0], dcBuff.configBottle.PSN[1],
|
||
dcBuff.configBottle.PSN[2], dcBuff.configBottle.PSN[3],
|
||
(dcBuff.configBottle.PSN[4] << 8) | dcBuff.configBottle.PSN[5],
|
||
utc,
|
||
dcBuff.dtuData.batPct,
|
||
dcBuff.dtuData.latitude,
|
||
dcBuff.dtuData.longitude,
|
||
dcBuff.dtuData.rssi,
|
||
dcBuff.configBottle.type,
|
||
dcBuff.configBottle.source,
|
||
Theoretical_Param.v,
|
||
|
||
(float)dcBuff.sampleData.pressure * 0.01f,
|
||
dcBuff.sampleData.volume,
|
||
dcBuff.configBottle.warnPressH * 0.01f,
|
||
dcBuff.configBottle.warnPress * 0.01f,
|
||
|
||
dcBuff.sampleData.extTempr[0],
|
||
|
||
dcBuff.configData.intervalSample,
|
||
dcBuff.configData.intervalTrans);
|
||
//len=strlen(Json_data);
|
||
for(int i=0; i<len; i++)
|
||
Task_sendBuff[i]= Json_data[i];
|
||
|
||
return(len);
|
||
}
|
||
|
||
////////////////////////////////////////////////////////////////////////////////////////
|
||
uint16_t pack_json_send_data2(gprs_data_t *pGprs, uint32_t totalSeconds)
|
||
{
|
||
char psn[14], utc[21];
|
||
S_RTC_TIME_DATA_T sRTC;
|
||
unsigned long long ll = 0;
|
||
uint16_t len= 0;
|
||
cJSON_Hooks hooks = {my_malloc, my_free};
|
||
cJSON_InitHooks(&hooks);
|
||
sprintf(psn, "20%02d%02d%02d%02d%03d", dcBuff.configBottle.PSN[0], dcBuff.configBottle.PSN[1],
|
||
dcBuff.configBottle.PSN[2], dcBuff.configBottle.PSN[3],
|
||
(dcBuff.configBottle.PSN[4] << 8) | dcBuff.configBottle.PSN[5]);
|
||
|
||
|
||
// Wakeup_CalcUTCTime(pGprs->sample_time + RTC_offsetSeconds, &sRTC);
|
||
// sprintf(utc, "%04d-%02d-%02dT%02d:%02d:%02d", sRTC.u32Year, sRTC.u32Month, sRTC.u32Day,
|
||
// sRTC.u32Hour, sRTC.u32Minute, sRTC.u32Second);
|
||
|
||
// 1. ?????? JSON ??
|
||
cJSON *root = cJSON_CreateObject();
|
||
if (root == NULL) {
|
||
printf("Error: Failed to create JSON object.\n");
|
||
return 1;
|
||
}
|
||
printf("\n111\n");
|
||
// 2. ? JSON ???????
|
||
cJSON_AddStringToObject(root, "psn", psn);
|
||
//cJSON_AddStringToObject(root, "utc", utc);
|
||
cJSON_AddNumberToObject(root, "hardVer", dcBuff.powerInfo.hardVer.minor);
|
||
cJSON_AddNumberToObject(root, "softVer", dcBuff.powerInfo.softVer.minor);
|
||
// cJSON_AddNumberToObject(root, "totalSeconds", totalSeconds);
|
||
cJSON_AddNumberToObject(root, "batVoltage", dcBuff.dtuData.batVoltage);
|
||
cJSON_AddNumberToObject(root, "batPct", dcBuff.dtuData.batPct);
|
||
cJSON_AddNumberToObject(root, "latitude", dcBuff.dtuData.latitude);
|
||
cJSON_AddNumberToObject(root, "longitude", dcBuff.dtuData.longitude);
|
||
|
||
// sprintf(utc, "%04d-%02d-%02dT%02d:%02d:%02d", dcBuff.dtuData.sysTime.year, dcBuff.dtuData.sysTime.month, dcBuff.dtuData.sysTime.day,
|
||
// dcBuff.dtuData.sysTime.hour, dcBuff.dtuData.sysTime.minute, dcBuff.dtuData.sysTime.second);
|
||
// cJSON_AddStringToObject(root, "pos_utc", utc);
|
||
//// cJSON_AddNumberToObject(root, "sateCount", dcBuff.dtuData.sateCount);// 卫星数量
|
||
//
|
||
//
|
||
// sprintf(utc, "%04d-%02d-%02dT%02d:%02d:%02d", sRTC.u32Year, sRTC.u32Month, sRTC.u32Day,
|
||
// sRTC.u32Hour, sRTC.u32Minute, sRTC.u32Second);
|
||
// cJSON_AddStringToObject(root, "data_utc", utc);// 数据时间
|
||
// //////////////////////
|
||
// cJSON_AddNumberToObject(root, "rssi", dcBuff.dtuData.rssi);// 信号强度
|
||
// cJSON_AddStringToObject(root, "simNumber", dcBuff.powerInfo.simNumber);//
|
||
//
|
||
// //len= strlen(json_str);
|
||
|
||
// printf("\n222\n");
|
||
// cJSON_AddNumberToObject(root, "type", dcBuff.configBottle.type);// 储罐类型
|
||
|
||
// cJSON_AddNumberToObject(root, "diameter", dcBuff.configBottle.diameter);
|
||
|
||
//len= strlen(json_str);
|
||
|
||
// cJSON_AddNumberToObject(root, "len", dcBuff.configBottle.len);
|
||
//len= strlen(json_str);
|
||
//cJSON_AddNumberToObject(root, "v", Theoretical_Param.v);
|
||
|
||
//cJSON_AddNumberToObject(root, "chargePct", dcBuff.configBottle.chargePct);
|
||
printf("\n333\n");
|
||
//cJSON_AddNumberToObject(root, "source", dcBuff.configBottle.source);
|
||
//len= strlen(json_str);
|
||
//cJSON_AddStringToObject(root, "server", dcBuff.configData.server);
|
||
//cJSON_AddNumberToObject(root, "port", dcBuff.configData.port);
|
||
printf("\n444\n");
|
||
cJSON_AddNumberToObject(root, "intervalTrans", dcBuff.configData.intervalTrans);
|
||
cJSON_AddNumberToObject(root, "intervalSample", dcBuff.configData.intervalSample);
|
||
|
||
cJSON_AddNumberToObject(root, "warnPress", dcBuff.configBottle.warnPress);
|
||
cJSON_AddNumberToObject(root, "warnPressH", dcBuff.configBottle.warnPressH);
|
||
|
||
cJSON_AddNumberToObject(root, "fullPct", dcBuff.configBottle.fullPct);
|
||
//printf("\n455\n");
|
||
cJSON_AddNumberToObject(root, "priPct", dcBuff.configBottle.priPct);
|
||
|
||
cJSON_AddNumberToObject(root, "orderPct", dcBuff.configBottle.orderPct);
|
||
|
||
cJSON_AddNumberToObject(root, "emptyPct", dcBuff.configBottle.emptyPct);
|
||
|
||
cJSON_AddNumberToObject(root, "warnVolt", dcBuff.configBottle.warnVolt);
|
||
|
||
cJSON_AddNumberToObject(root, "warnVoltH", dcBuff.configBottle.warnVoltH);
|
||
|
||
cJSON_AddNumberToObject(root, "planMount", dcBuff.configBottle.planMount);
|
||
|
||
cJSON_AddNumberToObject(root, "predictMount", dcBuff.configBottle.predictMount);
|
||
|
||
cJSON_AddNumberToObject(root, "floorLevel", dcBuff.configBottle.floorLevel);
|
||
|
||
cJSON_AddNumberToObject(root, "span", dcBuff.configBottle.span);
|
||
|
||
//cJSON_AddNumberToObject(root, "spanPeriod", dcBuff.configBottle.spanPeriod);
|
||
|
||
// cJSON_AddNumberToObject(root, "adDPress", dcBuff.sampleData.adDPress);
|
||
// cJSON_AddNumberToObject(root, "adPress", dcBuff.sampleData.adPress);
|
||
|
||
// cJSON_AddNumberToObject(root, "adExtTempr", dcBuff.sampleData.adExtTempr[0]);
|
||
|
||
//
|
||
// cJSON_AddNumberToObject(root, "utc", utc);
|
||
// cJSON_AddBoolToObject(root, "is_awesome", 1); // 1=true, 0=false
|
||
|
||
// // 3. ??????? JSON ??
|
||
// cJSON *features = cJSON_CreateObject();
|
||
// cJSON_AddStringToObject(features, "language", "C/C++");
|
||
// cJSON_AddNumberToObject(features, "speed", 100);
|
||
// cJSON_AddItemToObject(root, "features", features);
|
||
|
||
// // 4. ??????
|
||
// cJSON *tags = cJSON_CreateArray();
|
||
// cJSON_AddItemToArray(tags, cJSON_CreateString("AI"));
|
||
// cJSON_AddItemToArray(tags, cJSON_CreateString("JSON"));
|
||
// cJSON_AddItemToArray(tags, cJSON_CreateString("Parser"));
|
||
// cJSON_AddItemToObject(root, "tags", tags);
|
||
|
||
// 5. ? JSON ???????(?????)
|
||
|
||
// uint16_t len = sprintf((char*)Task_sendBuff,json_str);
|
||
char *json_str = cJSON_Print(root);
|
||
len= strlen(json_str);
|
||
for(int i=0; i<len; i++)
|
||
Task_sendBuff[i]= (uint8_t) *json_str++;
|
||
|
||
if (json_str != NULL) {
|
||
|
||
printf("\n555\n");
|
||
|
||
printf("\n666\n");
|
||
|
||
printf("Generated JSON:\n%s\n", json_str);
|
||
free(json_str); // ????
|
||
}
|
||
|
||
// 6. ?? cJSON ??
|
||
cJSON_Delete(root);
|
||
|
||
|
||
|
||
// return strlen(JSON_data());
|
||
return len;
|
||
}
|
||
////////////////////////////////////////////////////////////////////////////////////////
|
||
// 填写双向通讯的固定字段
|
||
uint16_t fill_biDir_fixFields(uint16_t cmd, uint16_t len)
|
||
{
|
||
bluetooth_send_t *pSend = (bluetooth_send_t *) Task_sendBuff;
|
||
uint16_t crc;
|
||
|
||
pSend->mark = CONFIG_MARK_LS;
|
||
pSend->ver = htons(dcBuff.powerInfo.protocolVer.major);
|
||
pSend->trans = 0;
|
||
pSend->len = htons(len - sizeof(bluetooth_send_t) + 2);
|
||
pSend->cmd = htons(cmd);
|
||
crc = MODBUS_RTU_CRC16((uint8_t *) Task_sendBuff, len);
|
||
Int2ByteS(Task_sendBuff, len, htons(crc));
|
||
|
||
return len + 2;
|
||
}
|
||
|
||
uint16_t pack_ldms_info_data(uint32_t dataTime, uint32_t totalSeconds)
|
||
{
|
||
uint16_t i = 0;
|
||
S_RTC_TIME_DATA_T sRTC;
|
||
bluetooth_timestamp_t t;
|
||
|
||
memset(Task_sendBuff, 0, TASK_SENDBUFF_SIZE);
|
||
|
||
// 头信息(最后再填内容)
|
||
i += sizeof(bluetooth_send_t);
|
||
// PSN
|
||
memmove(Task_sendBuff + i, dcBuff.configBottle.PSN, 6);
|
||
i += 6;
|
||
Task_sendBuff[i++] = dcBuff.powerInfo.hardVer.major;
|
||
Task_sendBuff[i++] = dcBuff.powerInfo.hardVer.minor;
|
||
Task_sendBuff[i++] = dcBuff.powerInfo.softVer.major;
|
||
Task_sendBuff[i++] = dcBuff.powerInfo.softVer.minor;
|
||
// 软件日期:yyyymmdd
|
||
Int2ByteL(Task_sendBuff, i, htonl((2000 + dcBuff.powerInfo.softDate.year) * 10000 + dcBuff.powerInfo.softDate.month * 100 + dcBuff.powerInfo.softDate.day));
|
||
i += 4;
|
||
// Report format
|
||
Task_sendBuff[i++] = dcBuff.powerInfo.protocolVer.major;
|
||
Task_sendBuff[i++] = dcBuff.powerInfo.protocolVer.minor;
|
||
// Config format
|
||
Task_sendBuff[i++] = dcBuff.configBottle.header.ver.major;
|
||
Task_sendBuff[i++] = dcBuff.configBottle.header.ver.minor;
|
||
|
||
// 运行时间:分钟
|
||
Int2ByteL(Task_sendBuff, i, htonl(totalSeconds / 60));
|
||
i += 4;
|
||
Int2ByteS(Task_sendBuff, i, htons(SYS_RSTSTS));
|
||
i += 2;
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.dtuData.batCurrent));
|
||
i += 2;
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.dtuData.batVoltage / 10));
|
||
i += 2;
|
||
Task_sendBuff[i++] = dcBuff.dtuData.batPct;
|
||
Int2ByteL(Task_sendBuff, i, htonl(dcBuff.dtuData.batCapa));
|
||
i += 4;
|
||
if(bat_veryLow)
|
||
Task_sendBuff[i] = 2;
|
||
else if(dcBuff.dtuData.batLow)
|
||
Task_sendBuff[i] = 1;
|
||
else
|
||
Task_sendBuff[i] = 0;
|
||
i++;
|
||
if(dcBuff.dtuData.posState)
|
||
Int2ByteL(Task_sendBuff, i, htonl(dcBuff.dtuData.latitude));
|
||
i += 4;
|
||
if(dcBuff.dtuData.posState)
|
||
Int2ByteL(Task_sendBuff, i, htonl(dcBuff.dtuData.longitude));
|
||
i += 4;
|
||
|
||
// 定位时间
|
||
if(dcBuff.dtuData.posState)
|
||
{
|
||
t.year = dcBuff.dtuData.sysTime.year + 2000 - 2010;
|
||
t.mon = dcBuff.dtuData.sysTime.month;
|
||
t.day = dcBuff.dtuData.sysTime.day;
|
||
t.hour_H = dcBuff.dtuData.sysTime.hour >> 4;
|
||
t.hour_L = dcBuff.dtuData.sysTime.hour & 0x0F;
|
||
t.min = dcBuff.dtuData.sysTime.minute;
|
||
t.sec = dcBuff.dtuData.sysTime.second;
|
||
Int2ByteL(Task_sendBuff, i, htonl(t.tm));
|
||
}
|
||
i += 4;
|
||
// 卫星数量
|
||
Task_sendBuff[i++] = dcBuff.dtuData.sateCount;
|
||
// 数据时间
|
||
Wakeup_CalcUTCTime(dataTime + RTC_offsetSeconds, &sRTC);
|
||
t.year = sRTC.u32Year - 2010;
|
||
t.mon = sRTC.u32Month;
|
||
t.day = sRTC.u32Day;
|
||
t.hour_H = sRTC.u32Hour >> 4;
|
||
t.hour_L = sRTC.u32Hour & 0x0F;
|
||
t.min = sRTC.u32Minute;
|
||
t.sec = sRTC.u32Second;
|
||
Int2ByteL(Task_sendBuff, i, htonl(t.tm));
|
||
i += 4;
|
||
// 信号强度
|
||
Task_sendBuff[i++] = dcBuff.dtuData.rssi;
|
||
Int2ByteL(Task_sendBuff, i, htonl(dcBuff.powerInfo.gprsSuccCount));
|
||
i += 4;
|
||
Int2ByteL(Task_sendBuff, i, htonl(dcBuff.powerInfo.gprsSendCount - dcBuff.powerInfo.gprsSuccCount));
|
||
i += 4;
|
||
if(dcBuff.powerInfo.gprsSendCount > 0)
|
||
Task_sendBuff[i] = dcBuff.powerInfo.gprsSuccCount * 100 / dcBuff.powerInfo.gprsSendCount;
|
||
i++;
|
||
memmove(Task_sendBuff + i, dcBuff.powerInfo.gprsFailCode, strlen(dcBuff.powerInfo.gprsFailCode));
|
||
i += 6;
|
||
memmove(Task_sendBuff + i, dcBuff.powerInfo.simNumber, strlen(dcBuff.powerInfo.simNumber));
|
||
i += 24;
|
||
Int2ByteL(Task_sendBuff, i, htonl(dcBuff.powerInfo.bdNumber));
|
||
i += 4;
|
||
|
||
// 储罐类型
|
||
Task_sendBuff[i++] = dcBuff.configBottle.type;
|
||
Int2ByteL(Task_sendBuff, i, htonl(dcBuff.configBottle.diameter));
|
||
i += 4;
|
||
Int2ByteL(Task_sendBuff, i, htonl(dcBuff.configBottle.len));
|
||
i += 4;
|
||
Int2ByteL(Task_sendBuff, i, htonl(dcBuff.configBottle.lenExtra));
|
||
i += 4;
|
||
Int2ByteL(Task_sendBuff, i, htonl(Theoretical_Param.v));
|
||
i += 4;
|
||
Task_sendBuff[i++] = dcBuff.configBottle.chargePct;
|
||
Task_sendBuff[i++] = dcBuff.configBottle.source;
|
||
Int2ByteS(Task_sendBuff, i, htons(Config_GetDensity(dcBuff.configBottle.source) * 1000));
|
||
i += 2;
|
||
Task_sendBuff[i++] = dcBuff.configBottle.dispMode;
|
||
Task_sendBuff[i++] = dcBuff.configDisplay.L_Unit;
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configBottle.serverVer));
|
||
i += 2;
|
||
memmove(Task_sendBuff + i, dcBuff.configData.server, strlen(dcBuff.configData.server));
|
||
i += 26;
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configData.port));
|
||
i += 2;
|
||
memmove(Task_sendBuff + i, dcBuff.configData.gpsServer, strlen(dcBuff.configData.gpsServer));
|
||
i += 26;
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configData.gpsPort));
|
||
i += 2;
|
||
memmove(Task_sendBuff + i, dcBuff.configData.upgServer, strlen(dcBuff.configData.upgServer));
|
||
i += 26;
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configData.upgPort));
|
||
i += 2;
|
||
Int2ByteL(Task_sendBuff, i, htonl(dcBuff.configData.intervalTrans));
|
||
i += 4;
|
||
Int2ByteL(Task_sendBuff, i, htonl(dcBuff.configData.intervalSample));
|
||
i += 4;
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configData.intervalGPSTrans));
|
||
i += 2;
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configData.intervalGPS));
|
||
i += 2;
|
||
Task_sendBuff[i++] = dcBuff.configData.timeLag;
|
||
|
||
strcpy((char *) Task_sendBuff + i, DTU_DecideAPN());
|
||
i += 20;
|
||
Int2ByteL(Task_sendBuff, i, htonl(dcBuff.configDisplay.bdCommander));
|
||
i += 4;
|
||
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configBottle.warnPress));
|
||
i += 2;
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configBottle.warnPressH));
|
||
i += 2;
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configBottle.fullPct));
|
||
i += 2;
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configBottle.priPct));
|
||
i += 2;
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configBottle.orderPct));
|
||
i += 2;
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configBottle.emptyPct));
|
||
i += 2;
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configBottle.warnVolt));
|
||
i += 2;
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configBottle.warnVoltH));
|
||
i += 2;
|
||
Int2ByteL(Task_sendBuff, i, htonl(dcBuff.configBottle.planMount));
|
||
i += 4;
|
||
Int2ByteL(Task_sendBuff, i, htonl(dcBuff.configBottle.predictMount));
|
||
i += 4;
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configBottle.floorLevel));
|
||
i += 2;
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configBottle.span));
|
||
i += 2;
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configBottle.spanPeriod));
|
||
i += 2;
|
||
|
||
// 测量方式
|
||
Task_sendBuff[i++] = MEASURE_DPRESS;
|
||
Task_sendBuff[i++] = 0;
|
||
Task_sendBuff[i++] = dcBuff.configDisplay.op_USE_PT100_SENSOR ? 0 : 1;
|
||
|
||
// 差压传感器参数
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorDPress.lowRange));
|
||
i += 2;
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorDPress.highRange));
|
||
i += 2;
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorDPress.zeroValue));
|
||
i += 2;
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorDPress.fullValue));
|
||
i += 2;
|
||
// 电容传感器参数
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorCap.baseC));
|
||
i += 2;
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorCap.refC));
|
||
i += 2;
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorCap.c1ADC));
|
||
i += 2;
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorCap.c2ADC));
|
||
i += 2;
|
||
Int2ByteS(Task_sendBuff, i, htons(CAP_K_C1));
|
||
i += 2;
|
||
Int2ByteS(Task_sendBuff, i, htons(CAP_K_C2));
|
||
i += 2;
|
||
// 称重传感器参数
|
||
// Int2ByteL(Task_sendBuff, i, htonl(dcBuff.configSensor.sensorWeight.lowRange));
|
||
Int2ByteL(Task_sendBuff, i, htonl(dcBuff.sampleData.adDPress));
|
||
i += 4;
|
||
// Int2ByteL(Task_sendBuff, i, htonl(dcBuff.configSensor.sensorWeight.highRange));
|
||
Int2ByteL(Task_sendBuff, i, htonl(dcBuff.sampleData.adPress));
|
||
i += 4;
|
||
// Int2ByteL(Task_sendBuff, i, htonl(dcBuff.configSensor.sensorWeight.zeroValue));
|
||
Int2ByteL(Task_sendBuff, i, htonl(dcBuff.sampleData.adExtTempr[0]));
|
||
i += 4;
|
||
// Int2ByteL(Task_sendBuff, i, htonl(dcBuff.configSensor.sensorWeight.fullValue));
|
||
Int2ByteL(Task_sendBuff, i, htonl(dcBuff.sampleData.adExtTempr[1]));
|
||
i += 4;
|
||
// 压力传感器参数
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorPress.lowRange));
|
||
i += 2;
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorPress.highRange));
|
||
i += 2;
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorPress.zeroValue));
|
||
i += 2;
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorPress.fullValue));
|
||
i += 2;
|
||
// 扩展压力传感器1参数
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorEPress[0].lowRange));
|
||
i += 2;
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorEPress[0].highRange));
|
||
i += 2;
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorEPress[0].zeroValue));
|
||
i += 2;
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorEPress[0].fullValue));
|
||
i += 2;
|
||
if(dcBuff.configDisplay.op_USE_PT100_SENSOR)
|
||
{
|
||
// 扩展温度传感器1参数
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorPTempr[0].calibrateT));
|
||
i += 2;
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorPTempr[0].calibrateR));
|
||
i += 2;
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorPTempr[0].zeroValue));
|
||
i += 2;
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorPTempr[0].fullValue));
|
||
i += 2;
|
||
// 扩展温度传感器2参数
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorPTempr[1].calibrateT));
|
||
i += 2;
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorPTempr[1].calibrateR));
|
||
i += 2;
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorPTempr[1].zeroValue));
|
||
i += 2;
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorPTempr[1].fullValue));
|
||
i += 2;
|
||
}
|
||
else
|
||
{
|
||
// 扩展温度传感器1参数
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorMTempr[0].lowRange));
|
||
i += 2;
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorMTempr[0].highRange));
|
||
i += 2;
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorMTempr[0].zeroValue));
|
||
i += 2;
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorMTempr[0].fullValue));
|
||
i += 2;
|
||
// 扩展温度传感器2参数
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorMTempr[1].lowRange));
|
||
i += 2;
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorMTempr[1].highRange));
|
||
i += 2;
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorMTempr[1].zeroValue));
|
||
i += 2;
|
||
Int2ByteS(Task_sendBuff, i, htons(dcBuff.configSensor.sensorMTempr[1].fullValue));
|
||
i += 2;
|
||
}
|
||
|
||
// 填写固定字段
|
||
return fill_biDir_fixFields(0xD035, i);
|
||
}
|
||
|
||
#define D036_PARAM_SIZE (240)
|
||
uint8_t parse_param_D036_data(uint8_t *param, uint8_t *reset)
|
||
{
|
||
longlong_mask_t mask;
|
||
uint16_t i = 0, shift = 0;
|
||
|
||
// 参数有效标志位(用一个无符号长整数表示, 共63项可选配置(bit 0~62), 最高位(bit 63)代表复位命令)
|
||
// 网络字节序: 12 34 56 78 90 ab cd ef
|
||
// h = 0x78563412, l = 0xefcdab90 (网络字节序)
|
||
// h = 0x12345678, l = 0x90abcdef (本机字节序)
|
||
// mask = 0x1234567890abcdef
|
||
mask.h = ntohl(Byte2IntL(param, i));
|
||
i += 4;
|
||
mask.l = ntohl(Byte2IntL(param, i));
|
||
i += 4;
|
||
|
||
printf("\nmask = %016llX\n", mask.ll);
|
||
|
||
// 储罐类型
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configBottle.type = param[i];
|
||
i++;
|
||
// 直径
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configBottle.diameter = ntohl(Byte2IntL(param, i));
|
||
i += 4;
|
||
// 长度
|
||
if(mask.ll & (1ull << (shift++)))
|
||
{
|
||
dcBuff.configBottle.len = ntohl(Byte2IntL(param, i));
|
||
dcBuff.configBottle.lenExtra = 0;
|
||
}
|
||
i += 4;
|
||
// 充装比
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configBottle.chargePct = param[i];
|
||
i++;
|
||
// 介质
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configBottle.source = param[i];
|
||
i++;
|
||
// 密度
|
||
if(mask.ll & (1ull << (shift++)))
|
||
Config_SetDensity(dcBuff.configBottle.source, ntohs(Byte2IntS(param, i)) / 1000.0);
|
||
i += 2;
|
||
// 显示模式
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configBottle.dispMode = param[i];
|
||
i++;
|
||
// 显示单位
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configDisplay.L_Unit = param[i];
|
||
i++;
|
||
|
||
// 服务器版本
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configBottle.serverVer = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// 远传服务器
|
||
if(mask.ll & (1ull << (shift++)))
|
||
strcpy(dcBuff.configData.server, (char *) param + i);
|
||
i += 26;
|
||
// 远传端口
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configData.port = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// 远传服务器
|
||
if(mask.ll & (1ull << (shift++)))
|
||
strcpy(dcBuff.configData.gpsServer, (char *) param + i);
|
||
i += 26;
|
||
// 远传端口
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configData.gpsPort = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// 远传服务器
|
||
if(mask.ll & (1ull << (shift++)))
|
||
strcpy(dcBuff.configData.upgServer, (char *) param + i);
|
||
i += 26;
|
||
// 远传端口
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configData.upgPort = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// 发送频率
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configData.intervalTrans = ntohl(Byte2IntL(param, i));
|
||
i += 4;
|
||
// 采集频率
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configData.intervalSample = ntohl(Byte2IntL(param, i));
|
||
i += 4;
|
||
// 发送频率
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configData.intervalGPSTrans = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// 采集频率
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configData.intervalGPS = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// 时差
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configData.timeLag = param[i];
|
||
i++;
|
||
// APN
|
||
if(mask.ll & (1ull << (shift++)))
|
||
strcpy(dcBuff.configDisplay.APN, (char *) param + i);
|
||
i += 20;
|
||
// 北斗指挥机卡号
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configDisplay.bdCommander = ntohl(Byte2IntL(param, i));
|
||
i += 4;
|
||
|
||
// 压力报警点低: KPa
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configBottle.warnPress = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// 压力报警点高: KPa
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configBottle.warnPressH = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// 满液位报警点: 0.01%
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configBottle.fullPct = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// 关键液位报警点: 0.01%
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configBottle.priPct = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// 订货液位报警点: 0.01%
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configBottle.orderPct = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// 空液位报警点: 0.01%
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configBottle.emptyPct = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// 电压报警低点: mV
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configBottle.warnVolt = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// 电压报警高点: mV
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configBottle.warnVoltH = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// 每日计划用量: L
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configBottle.planMount = ntohl(Byte2IntL(param, i));
|
||
i += 4;
|
||
// 每日预测用量: L
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configBottle.predictMount = ntohl(Byte2IntL(param, i));
|
||
i += 4;
|
||
// TTS-空液位报警点: 0.01%
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configBottle.floorLevel = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// TTS-变化量报警点: 0.01%
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configBottle.span = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// TTS-变化量检测时间: 秒
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configBottle.spanPeriod = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
|
||
// 差压传感器量程: 低
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configSensor.sensorDPress.lowRange = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// 差压传感器量程: 高
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configSensor.sensorDPress.highRange = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// 差压传感器标定: 低
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configSensor.sensorDPress.zeroValue = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// 差压传感器标定: 高
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configSensor.sensorDPress.fullValue = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// 电容传感器量程: 底电容
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configSensor.sensorCap.baseC = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// 电容传感器量程: 增长电容
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configSensor.sensorCap.refC = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// 电容传感器标定: C1ADC
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configSensor.sensorCap.c1ADC = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// 电容传感器标定: C2ADC
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configSensor.sensorCap.c2ADC = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// 称重传感器量程: 低
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configSensor.sensorWeight.lowRange = ntohl(Byte2IntL(param, i));
|
||
i += 4;
|
||
// 称重传感器量程: 高
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configSensor.sensorWeight.highRange = ntohl(Byte2IntL(param, i));
|
||
i += 4;
|
||
// 称重传感器标定: 低
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configSensor.sensorWeight.zeroValue = ntohl(Byte2IntL(param, i));
|
||
i += 4;
|
||
// 称重传感器标定: 高
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configSensor.sensorWeight.fullValue = ntohl(Byte2IntL(param, i));
|
||
i += 4;
|
||
// 压力传感器1量程: 低
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configSensor.sensorPress.lowRange = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// 压力传感器1量程: 高
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configSensor.sensorPress.highRange = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// 压力传感器1标定: 低
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configSensor.sensorPress.zeroValue = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// 压力传感器1标定: 高
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configSensor.sensorPress.fullValue = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// 压力传感器2量程: 低
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configSensor.sensorEPress[0].lowRange = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// 压力传感器2量程: 高
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configSensor.sensorEPress[0].highRange = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// 压力传感器2标定: 低
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configSensor.sensorEPress[0].zeroValue = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// 压力传感器2标定: 高
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configSensor.sensorEPress[0].fullValue = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
if(dcBuff.configDisplay.op_USE_PT100_SENSOR)
|
||
{
|
||
// 温度传感器1量程: 低
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configSensor.sensorPTempr[0].calibrateT = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// 温度传感器1量程: 高
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configSensor.sensorPTempr[0].calibrateR = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// 温度传感器1标定: 低
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configSensor.sensorPTempr[0].zeroValue = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// 温度传感器1标定: 高
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configSensor.sensorPTempr[0].fullValue = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// 温度传感器2量程: 低
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configSensor.sensorPTempr[1].calibrateT = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// 温度传感器2量程: 高
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configSensor.sensorPTempr[1].calibrateR = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// 温度传感器2标定: 低
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configSensor.sensorPTempr[1].zeroValue = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// 温度传感器2标定: 高
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configSensor.sensorPTempr[1].fullValue = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
}
|
||
else
|
||
{
|
||
// 温度传感器1量程: 低
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configSensor.sensorMTempr[0].lowRange = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// 温度传感器1量程: 高
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configSensor.sensorMTempr[0].highRange = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// 温度传感器1标定: 低
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configSensor.sensorMTempr[0].zeroValue = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// 温度传感器1标定: 高
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configSensor.sensorMTempr[0].fullValue = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// 温度传感器2量程: 低
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configSensor.sensorMTempr[1].lowRange = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// 温度传感器2量程: 高
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configSensor.sensorMTempr[1].highRange = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// 温度传感器2标定: 低
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configSensor.sensorMTempr[1].zeroValue = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// 温度传感器2标定: 高
|
||
if(mask.ll & (1ull << (shift++)))
|
||
dcBuff.configSensor.sensorMTempr[1].fullValue = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
}
|
||
|
||
*reset = ((mask.ll & (1ull << shift)) != 0);
|
||
|
||
return ((mask.ll & ~(1ull << shift)) != 0);
|
||
}
|
||
|
||
#define D038_CONFIG_SIZE (74)
|
||
uint8_t parse_config_D038_data(uint8_t *param)
|
||
{
|
||
uint16_t i = 0;
|
||
|
||
// 服务器版本
|
||
dcBuff.configBottle.serverVer = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// 远传服务器
|
||
strcpy(dcBuff.configData.server, (char *) param + i);
|
||
i += 26;
|
||
// 远传端口
|
||
dcBuff.configData.port = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// 远传服务器
|
||
strcpy(dcBuff.configData.gpsServer, (char *) param + i);
|
||
i += 26;
|
||
// 远传端口
|
||
dcBuff.configData.gpsPort = ntohs(Byte2IntS(param, i));
|
||
i += 2;
|
||
// 发送频率
|
||
dcBuff.configData.intervalTrans = ntohl(Byte2IntL(param, i));
|
||
i += 4;
|
||
// 采集频率
|
||
dcBuff.configData.intervalSample = ntohl(Byte2IntL(param, i));
|
||
i += 4;
|
||
|
||
// 硬件版本
|
||
dcBuff.configDisplay.op_HARDWARE_VER_MAJOR = param[i++];
|
||
// 只显示毫米水柱
|
||
dcBuff.configDisplay.op_DISP_MMWC_ONLY = param[i++];
|
||
// 罐箱版本
|
||
dcBuff.configDisplay.op_BOX_VER = param[i++];
|
||
// 基站定位
|
||
dcBuff.configDisplay.op_CELL_LOCATION = param[i++];
|
||
// 发送轨迹
|
||
dcBuff.configDisplay.op_SEND_GPS_DATA = param[i++];
|
||
// 通信方式
|
||
dcBuff.configDisplay.op_SERVER_PROTOCOL = param[i++];
|
||
// URL索引
|
||
dcBuff.configDisplay.op_SERVER_INDEX = param[i++];
|
||
// 单向通信
|
||
dcBuff.configDisplay.op_UNIDIR_COMM = param[i++];
|
||
|
||
return 1;
|
||
}
|
||
|
||
// 从服务器获取时间
|
||
void DTU_setOffsetSecondsFromServer()
|
||
{
|
||
bluetooth_send_t *pRecv = (bluetooth_send_t *) Task_recvBuff;
|
||
S_RTC_TIME_DATA_T sRTC;
|
||
uint32_t totalSeconds1, totalSeconds2;
|
||
int16_t zz;
|
||
uint16_t i, recvLen;
|
||
|
||
// 从服务器获取当前时间
|
||
printf("\nGet time from server ...\n");
|
||
// 连接升级服务器
|
||
if(DTU_Connect(0, dcBuff.configData.upgServer, dcBuff.configData.upgPort))
|
||
{
|
||
memset(Task_sendBuff, 0, TASK_SENDBUFF_SIZE);
|
||
|
||
i = sizeof(bluetooth_send_t);
|
||
// 填写固定字段
|
||
i = fill_biDir_fixFields(0xD03B, i);
|
||
|
||
// 发送i个字节到服务器,至少接收10个字节
|
||
recvLen = sizeof(bluetooth_recv_t) + 2;
|
||
if(DTU_SendAndRecv(0, Task_sendBuff, i, &recvLen, Task_recvBuff, TASK_RECVBUFF_SIZE))
|
||
{
|
||
if(recvLen >= sizeof(bluetooth_recv_t) + 2
|
||
&& MODBUS_RTU_CRC16(Task_recvBuff, recvLen) == 0)
|
||
{
|
||
if(recvLen >= sizeof(bluetooth_recv_t) + 11
|
||
&& pRecv->cmd == ntohs(0x003B)
|
||
&& MODBUS_RTU_CRC16(Task_recvBuff, sizeof(bluetooth_recv_t) + 11) == 0)
|
||
{
|
||
// 获取当前时间
|
||
RTC_GetDateAndTime(&sRTC);
|
||
totalSeconds1 = Calc_SecondsFromYear(INITIAL_YEAR, sRTC.u32Year, sRTC.u32Month, sRTC.u32Day,
|
||
sRTC.u32Hour, sRTC.u32Minute, sRTC.u32Second);
|
||
|
||
// UTC日期
|
||
i = sizeof(bluetooth_recv_t);
|
||
|
||
// 年
|
||
sRTC.u32Year = ntohs(Byte2IntS(Task_recvBuff, i));
|
||
i += 2;
|
||
// 月
|
||
sRTC.u32Month = Task_recvBuff[i++];
|
||
// 日
|
||
sRTC.u32Day = Task_recvBuff[i++];
|
||
// 时
|
||
sRTC.u32Hour = Task_recvBuff[i++];
|
||
// 分
|
||
sRTC.u32Minute = Task_recvBuff[i++];
|
||
// 秒
|
||
sRTC.u32Second = Task_recvBuff[i++];
|
||
// 时差(按1/4小时, 带符号)
|
||
recvLen = ntohs(Byte2IntS(Task_recvBuff, i));
|
||
memmove(&zz, &recvLen, 2);
|
||
|
||
printf("\n%04d-%02d-%02d %02d:%02d:%02d %d\n", sRTC.u32Year, sRTC.u32Month, sRTC.u32Day,
|
||
sRTC.u32Hour, sRTC.u32Minute, sRTC.u32Second, zz);
|
||
|
||
totalSeconds2 = Calc_SecondsFromYear(INITIAL_YEAR, sRTC.u32Year, sRTC.u32Month, sRTC.u32Day,
|
||
sRTC.u32Hour, sRTC.u32Minute, sRTC.u32Second);
|
||
|
||
// 将UTC时间转换为GMT时间(时差为0)
|
||
totalSeconds2 -= zz * 900;
|
||
// 将GMT时间转换为UTC时间(按配置的时差)
|
||
totalSeconds2 += dcBuff.configData.timeLag * 3600;
|
||
|
||
if(RTC_offsetSeconds == 0)
|
||
RTC_offsetSeconds = totalSeconds2 - totalSeconds1;
|
||
}
|
||
}
|
||
}
|
||
// 关闭和服务器的连接
|
||
DTU_Close(0);
|
||
}
|
||
}
|
||
////////////////////////////////////////////////////////////////////////////////////////
|
||
|
||
void DTU_CheckGPS()
|
||
{
|
||
uint32_t time;
|
||
S_RTC_TIME_DATA_T sRTC;
|
||
|
||
if(DTU_hasPowered)
|
||
{
|
||
// 获取当前时间
|
||
RTC_GetDateAndTime(&sRTC);
|
||
// 计算自上次gps定位以来的时间
|
||
time = Calc_SecondsFromYear(INITIAL_YEAR, sRTC.u32Year, sRTC.u32Month, sRTC.u32Day,
|
||
sRTC.u32Hour, sRTC.u32Minute, sRTC.u32Second);
|
||
if(!Wakeup_Sleeping && time > DTU_gpsTime + 30 && (GPS_Waiting || dcBuff.configDisplay.op_SEND_GPS_DATA))
|
||
{
|
||
// 如果是第一次,或者曾经有输出了,则闪断计数
|
||
if(GPS_BOD_COUNT == 599)
|
||
GPS_BOD_COUNT = 0;
|
||
else
|
||
GPS_BOD_COUNT++;
|
||
printf("\nGPS_BOD_COUNT: %d\n", GPS_BOD_COUNT);
|
||
|
||
printf("\n*** Restart GPS module ***\n");
|
||
DTU_EnableGPS();
|
||
DTU_gpsTime = time;
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|
||
// 任务主体:发送运行数据和GPS数据,读取网络信号强度等
|
||
void DTU_Task(void *p_arg)
|
||
{
|
||
bluetooth_send_t *pSend = (bluetooth_send_t *) Task_sendBuff;
|
||
bluetooth_send_t *pRecv = (bluetooth_send_t *) Task_recvBuff;
|
||
uint16_t crc;
|
||
uint16_t i, j, k;
|
||
uint8_t gpsCount, gpsDone;
|
||
uint16_t gpsInterval;
|
||
uint32_t totalSeconds;
|
||
uint32_t relativeTime;
|
||
S_RTC_TIME_DATA_T sRTC;
|
||
gprs_data_t *pGprs;
|
||
uint8_t try_count;
|
||
uint16_t recvLen;
|
||
uint8_t upgrade;
|
||
uint8_t ackUpgrade;
|
||
uint8_t downloadParam;
|
||
uint8_t ackParam;
|
||
uint8_t downloadConfig;
|
||
uint8_t ackConfig;
|
||
uint8_t reset = 0;
|
||
param_data_t *pParam;
|
||
TUpgradeHeader upHeader;
|
||
upgrade_frame_t *pFrame;
|
||
gps_data_t gps;
|
||
uint16_t nextPtr;
|
||
uint8_t write_count;
|
||
uint8_t rf_fail_count = 0;
|
||
uint8_t semSync, semGPRS, semGPS;
|
||
|
||
uint32_t tick;
|
||
|
||
// 从FRAM读取阿里云密钥信息
|
||
FRAM_LoadInfo(FRAM_ALIYUN_SECRET_BASE, (uint8_t *) &aliyunSecret, sizeof(aliyunSecret));
|
||
|
||
// 从FRAM读取GPS信息
|
||
FRAM_LoadInfo(gpsBuff.info_base, (uint8_t *) &gpsBuff.info, sizeof(gpsBuff.info));
|
||
if(gpsBuff.info.rdPtr > gpsBuff.maxItemCount || gpsBuff.info.wtPtr > gpsBuff.maxItemCount)
|
||
memset(&gpsBuff.info, 0, sizeof(gpsBuff.info));
|
||
|
||
// 清除数据
|
||
memset(&dcBuff.dtuData, 0, sizeof(dcBuff.dtuData));
|
||
|
||
// 读取其它板子的配置数据
|
||
|
||
// 启动定时器
|
||
GPS_tranTick = GetDelayTick(dcBuff.configData.intervalGPSTrans * 1000);
|
||
|
||
if(dcBuff.configDisplay.op_BOX_VER)
|
||
{
|
||
// 检查是否有BD模块
|
||
BD_PowerOn();
|
||
BD_PowerOff();
|
||
// 检查是否有RF模块
|
||
RF_PowerOn();
|
||
RF_PowerOff();
|
||
}
|
||
|
||
// 上电运行一次任务
|
||
DTU_semSync = 1;
|
||
DTU_semGPRS = 1;
|
||
DTU_semGPS = 1;
|
||
|
||
while(1)
|
||
{
|
||
// 喂狗
|
||
if(!Wakeup_Sleeping)
|
||
WDT_RESET_COUNTER();
|
||
|
||
// 读取信号量
|
||
semSync = DTU_semSync;
|
||
DTU_semSync = 0;
|
||
semGPRS = DTU_semGPRS;
|
||
DTU_semGPRS = 0;
|
||
semGPS = DTU_semGPS;
|
||
DTU_semGPS = 0;
|
||
|
||
// 获取当前时间
|
||
RTC_GetDateAndTime(&sRTC);
|
||
// 计算自上次gps定位以来的时间
|
||
totalSeconds = Calc_SecondsFromYear(INITIAL_YEAR, sRTC.u32Year, sRTC.u32Month, sRTC.u32Day,
|
||
sRTC.u32Hour, sRTC.u32Minute, sRTC.u32Second);
|
||
// 刚开始运行的时候,回退到刚启动的时间(忽略系统初始化时间)
|
||
if(totalSeconds < 10)
|
||
totalSeconds = 0;
|
||
|
||
// 默认不保存、不发送
|
||
GPRS_Send_Task = 0;
|
||
GPRS_Save_Task = 0;
|
||
//pack_json_send_data(pGprs, totalSeconds);
|
||
// 是否强制上传
|
||
if(DTU_dataConn)
|
||
{
|
||
DTU_dataConn = 0;
|
||
GPRS_Send_Task = 1;
|
||
}
|
||
|
||
// 是否强制定位
|
||
if(GPS_Locate)
|
||
{
|
||
GPS_Locate = 0;
|
||
|
||
// 强制定位:保存和发送
|
||
GPRS_Send_Task = 1;
|
||
GPRS_Save_Task = 1;
|
||
|
||
// 设置超时定时器
|
||
GPS_waitTick = GetDelayTick(DTU_tmrLocate * 1000);
|
||
GPS_Waiting = 1;
|
||
}
|
||
|
||
// GPS发送周期:检查电池电量
|
||
if(semGPS || semSync)
|
||
{
|
||
delay_ms(200);
|
||
|
||
// 先清除信号量
|
||
GPRS_semSampled = 0;
|
||
// 采集数据
|
||
if(!Sample_Busy())
|
||
NVIC_SetPendingIRQ(TMR1_IRQn);
|
||
tick = GetDelayTick(3000);
|
||
while(!GPRS_semSampled && !IsTickOut(tick))
|
||
{
|
||
}
|
||
|
||
// 根据电量设置工作模式
|
||
Wakeup_SetWorkMode();
|
||
}
|
||
|
||
// 检测唤醒同步信号
|
||
if(semGPRS || semSync)
|
||
{
|
||
if(dcBuff.sampleData.warnning)
|
||
{
|
||
printf("\n*** dcBuff.sampleData.warnning = 1 ***\n");
|
||
GPRS_Send_Task = 1;
|
||
dcBuff.sampleData.warnning = 0;
|
||
}
|
||
|
||
// 判断是否发送周期
|
||
// 如果发送时间到了,或者队列中的数据够了,则发送数据(为了工程测试方便,刚开始几次按照不大于5分钟的频率发送)
|
||
if(dcBuff.configDisplay.op_SEND_GPS_DATA)
|
||
{
|
||
// 发送间隔最小值
|
||
if(totalSeconds + 3 >= GPRS_Send_Time + (dcBuff.configData.intervalTrans > 300 ? 300 : dcBuff.configData.intervalTrans))
|
||
GPRS_Send_Task = 1;
|
||
}
|
||
else
|
||
{
|
||
if(((SYS_RSTSTS & 0x13) && !(SYS_RSTSTS & 0x04) && // 上电或手动复位, 非看门狗复位
|
||
totalSeconds < INITIAL_TRAN_COUNT * (dcBuff.configData.intervalSample > 300 ? 300 : dcBuff.configData.intervalSample))
|
||
|| totalSeconds + 3 >= GPRS_Send_Time + dcBuff.configData.intervalTrans
|
||
// || LoopBuff_GetCount(&gprsBuff) >= dcBuff.configData.intervalTrans / dcBuff.configData.intervalSample - 1
|
||
)
|
||
////// if(LoopBuff_GetCount(&gprsBuff) >= 11)
|
||
{
|
||
// 发送间隔最小值
|
||
if(totalSeconds + 3 >= GPRS_Send_Time + (dcBuff.configData.intervalTrans > 300 ? 300 : dcBuff.configData.intervalTrans))
|
||
GPRS_Send_Task = 1;
|
||
}
|
||
// else if(Config_CheckUpdate(&dcBuff))
|
||
// {
|
||
// GPRS_Send_Task = 1;
|
||
// }
|
||
}
|
||
|
||
// 判断是否保存周期
|
||
if(GPRS_Send_Task || totalSeconds + 3 >= GPRS_Save_Time + dcBuff.configData.intervalSample)
|
||
GPRS_Save_Task = 1;
|
||
|
||
if(GPRS_Send_Task && ((dcBuff.configDisplay.op_BOX_VER && (Motion_Detected || Motion_Status))
|
||
|| (dcBuff.configDisplay.op_SEND_GPS_DATA && Wakeup_GetWorkMode() == WORK_MODE_NORMAL)))
|
||
{
|
||
GPS_Located = 0;
|
||
|
||
// 设置超时定时器
|
||
GPS_waitTick = GetDelayTick(DTU_tmrLocate * 1000);
|
||
GPS_Waiting = 1;
|
||
}
|
||
}
|
||
|
||
// 运行数据发送周期:检测信号强度
|
||
if(semGPRS || semSync)
|
||
{
|
||
if(Wakeup_GetWorkMode() == WORK_MODE_NORMAL && GPRS_Send_Task)
|
||
{
|
||
delay_ms(200);
|
||
|
||
// 打开DTU(开始定位)
|
||
dcBuff.dtuData.networked = 0;
|
||
|
||
if(RF_initStatus)
|
||
{
|
||
// 打开射频模块
|
||
RF_PowerOn();
|
||
// 检查中继器是否存在
|
||
rf_check_gateway();
|
||
// 关闭射频模块
|
||
RF_PowerOff();
|
||
}
|
||
|
||
if(!rf_has_gateway() || GPS_Waiting || dcBuff.configDisplay.op_SEND_GPS_DATA)
|
||
{
|
||
DTU_PowerOn();
|
||
// 重新开始定位计时,保证足够定位时间
|
||
GPS_waitTick = GetDelayTick(DTU_tmrLocate * 1000);
|
||
|
||
// 采集信号强度和注册信息
|
||
Sim808_ReadGPRS();
|
||
printf("\ndcBuff.dtuData.networked: %d\n", dcBuff.dtuData.networked);
|
||
|
||
// 如果有GPRS但是信号很弱
|
||
if(rf_has_gateway() && dcBuff.dtuData.rssi < 30)
|
||
dcBuff.dtuData.networked = 0;
|
||
if(!dcBuff.dtuData.networked)
|
||
dcBuff.dtuData.rssi = 0;
|
||
}
|
||
}
|
||
|
||
// 每小时保存1条数据
|
||
if(Wakeup_GetWorkMode() == WORK_MODE_NORMAL && GPRS_Save_Task)
|
||
{
|
||
if(GPRS_Send_Task)
|
||
{
|
||
// GPRS拨号和GPS定位同时进行,以节省时间
|
||
if(dcBuff.dtuData.networked)
|
||
Sim808_GPRSDial();
|
||
|
||
// 如果不发送轨迹数据,则等待定位完成再发送运行数据
|
||
while(!dcBuff.configDisplay.op_SEND_GPS_DATA && Wakeup_GetWorkMode() == WORK_MODE_NORMAL && GPS_Waiting)
|
||
{
|
||
// 喂狗
|
||
if(!Wakeup_Sleeping)
|
||
WDT_RESET_COUNTER();
|
||
delay_ms(200);
|
||
}
|
||
|
||
if(!dcBuff.configDisplay.op_SEND_GPS_DATA)
|
||
{
|
||
// 关闭GPS
|
||
DTU_DisableGPS();
|
||
}
|
||
|
||
// 获取基站定位数据
|
||
if(GPRS_Send_Task && !GPS_Locate && !GPS_Located)
|
||
{
|
||
if(dcBuff.configDisplay.op_CELL_LOCATION)
|
||
Sim808_GetCellLocPosition();
|
||
}
|
||
|
||
// 本次定位结束
|
||
GPS_Located = 1;
|
||
// 下次有运动才定位(罐箱)
|
||
Motion_Detected = 0;
|
||
|
||
// 先清除信号量
|
||
GPRS_semSampled = 0;
|
||
// 采集数据
|
||
if(!Sample_Busy())
|
||
NVIC_SetPendingIRQ(TMR1_IRQn);
|
||
tick = GetDelayTick(3000);
|
||
while(!GPRS_semSampled && !IsTickOut(tick))
|
||
{
|
||
}
|
||
// 记录本次发送的时间
|
||
GPRS_Send_Time = totalSeconds;
|
||
}
|
||
// 加入队列,待发送
|
||
printf("\nPut gprs data to queue...\n");
|
||
GPRS_PutToQueue(&gprsBuff, &dcBuff.dtuData, &dcBuff.sampleData);
|
||
// 每条记录,北斗发送2次
|
||
if(BD_initStatus)
|
||
{
|
||
GPRS_PutToQueue(&bd_gprsBuff, &dcBuff.dtuData, &dcBuff.sampleData);
|
||
GPRS_PutToQueue(&bd_gprsBuff, &dcBuff.dtuData, &dcBuff.sampleData);
|
||
}
|
||
// 记录本次保存的时间
|
||
GPRS_Save_Time = totalSeconds;
|
||
}
|
||
}
|
||
|
||
// 用北斗发送数据
|
||
if(BD_initStatus && (semGPRS || semSync))
|
||
{
|
||
// 每采集1条就发送1条
|
||
if(LoopBuff_GetCount(&bd_gprsBuff) > 0)
|
||
{
|
||
if(Wakeup_GetWorkMode() == WORK_MODE_NORMAL)
|
||
{
|
||
// 打开北斗模块
|
||
BD_PowerOn();
|
||
|
||
if(BD_initStatus)
|
||
{
|
||
FRAM_BufferRead(LoopBuff_GetDataPos(&bd_gprsBuff, bd_gprsBuff.info.rdPtr), (uint8_t *) &gprsRWBuf, sizeof(gprs_data_t));
|
||
pGprs = &gprsRWBuf;
|
||
|
||
// 打包上报数据(按北斗精简报文的格式)
|
||
i = pack_bd_send_data(pGprs, totalSeconds);
|
||
|
||
bd_rf_app_send_data(i, Task_sendBuff);
|
||
|
||
delay_ms(200);
|
||
}
|
||
|
||
// 关闭北斗模块
|
||
BD_PowerOff();
|
||
}
|
||
|
||
// 不管是否发送成功,都移除记录(因为1分钟发送一次,没有重发机制)
|
||
LoopBuff_RemoveItems(&bd_gprsBuff, 1);
|
||
}
|
||
}
|
||
|
||
// 优先用射频发送数据
|
||
if(rf_has_gateway() && (semGPRS || semSync))
|
||
{
|
||
if(Wakeup_GetWorkMode() == WORK_MODE_NORMAL && GPRS_Send_Task)
|
||
{
|
||
// 关闭GPRS
|
||
DTU_PowerOff();
|
||
|
||
// 打开射频模块
|
||
RF_PowerOn();
|
||
|
||
k = LoopBuff_GetCount(&gprsBuff);
|
||
while(k--)
|
||
{
|
||
FRAM_BufferRead(LoopBuff_GetDataPos(&gprsBuff, gprsBuff.info.rdPtr), (uint8_t *) &gprsRWBuf, sizeof(gprs_data_t));
|
||
pGprs = &gprsRWBuf;
|
||
|
||
// 打包上报数据(按RF精简报文的格式)
|
||
i = pack_rf_send_data(pGprs, totalSeconds);
|
||
|
||
try_count = 3;
|
||
while(try_count--)
|
||
{
|
||
j = rf_app_send_data(i, Task_sendBuff);
|
||
if(j == 1)
|
||
{
|
||
rf_fail_count = 0;
|
||
LoopBuff_RemoveItems(&gprsBuff, 1);
|
||
break;
|
||
}
|
||
}
|
||
if(j == 0)
|
||
{
|
||
rf_fail_count++;
|
||
if(rf_fail_count >= 3)
|
||
{
|
||
// 清除网关信息
|
||
rf_fail_count = 0;
|
||
rf_clear_gateway();
|
||
}
|
||
// 下次再来
|
||
break;
|
||
}
|
||
}
|
||
|
||
// 关闭射频模块
|
||
RF_PowerOff();
|
||
}
|
||
}
|
||
|
||
// 如果没有卡,或者没有注册进网络,采集以后休眠
|
||
if(!dcBuff.dtuData.networked)
|
||
{
|
||
// 检查是否进入掉电模式
|
||
Wakeup_Powerdown();
|
||
continue;
|
||
}
|
||
|
||
// 检测发送采集数据的信号
|
||
if(semGPRS || semSync)
|
||
{
|
||
if(Wakeup_GetWorkMode() == WORK_MODE_NORMAL && GPRS_Send_Task)
|
||
{
|
||
// 是否下载参数:数据服务器
|
||
downloadParam = 0;
|
||
ackParam = 0;
|
||
dcBuff.configDisplay.op_SERVER_PROTOCOL = SERVER_PROTOCOL_MQTT;
|
||
dcBuff.configDisplay.op_SERVER_INDEX = 2;
|
||
dcBuff.configData.port=1883;
|
||
if(dcBuff.configDisplay.op_SERVER_PROTOCOL == SERVER_PROTOCOL_HTTPS)
|
||
{
|
||
try_count = 2;
|
||
while((try_count--) && LoopBuff_GetCount(&gprsBuff) > 0)
|
||
{
|
||
// 第一条记录,连接就开始计数
|
||
if(LoopBuff_GetCount(&gprsBuff) > 0)
|
||
dcBuff.powerInfo.gprsSendCount++;
|
||
|
||
if(Sim808_Connect(1, dcBuff.configData.server, dcBuff.configData.port))
|
||
{
|
||
nextPtr = gprsBuff.info.rdPtr;
|
||
for(k = 0; k < LoopBuff_GetCount(&gprsBuff); k++)
|
||
{
|
||
if(k > 0) // 第一条发送计数在连接之前
|
||
dcBuff.powerInfo.gprsSendCount++;
|
||
|
||
FRAM_BufferRead(LoopBuff_GetDataPos(&gprsBuff, nextPtr), (uint8_t *) &gprsRWBuf, sizeof(gprs_data_t));
|
||
pGprs = &gprsRWBuf;
|
||
|
||
nextPtr = LoopBuff_GetNextPtr(&gprsBuff, nextPtr);
|
||
|
||
// 打包上报数据(按modbus从机响应的格式)
|
||
i = pack_json_send_data(pGprs, totalSeconds);
|
||
sprintf((char *) Task_sendBuff, http_header_fmt, SERVER_URLs[dcBuff.configDisplay.op_SERVER_INDEX], dcBuff.configData.server, i);
|
||
|
||
printf("\n\n%s%s\n", Task_sendBuff, JSON_data());
|
||
|
||
recvLen = 0; // 发送HTTP头,完了直接返回,不等结果
|
||
if(!Sim808_SendAndRecv(1, Task_sendBuff, strlen((char *) Task_sendBuff), &recvLen, Task_recvBuff, sizeof(Task_recvBuff)))
|
||
break;
|
||
recvLen = 15; // 发送数据,完了等结果
|
||
if(!Sim808_SendAndRecv(1, (uint8_t *) JSON_data(), i, &recvLen, Task_recvBuff, sizeof(Task_recvBuff)))
|
||
break;
|
||
if(!strstr((char *) Task_recvBuff, "HTTP/1.1 200 OK"))
|
||
{
|
||
strcpy(dcBuff.powerInfo.gprsFailCode, "HTTP");
|
||
break;
|
||
}
|
||
dcBuff.powerInfo.gprsSuccCount++;
|
||
|
||
// 最近一条上传数据的采集时间
|
||
DTU_dataTime = pGprs->sample_time;
|
||
}
|
||
|
||
// 移除已成功发送的数据
|
||
if(k > 0)
|
||
LoopBuff_RemoveItems(&gprsBuff, k);
|
||
|
||
// 关闭和服务器的连接
|
||
DTU_Close(1);
|
||
}
|
||
}
|
||
}
|
||
else if(dcBuff.configDisplay.op_SERVER_PROTOCOL == SERVER_PROTOCOL_MQTT)
|
||
{
|
||
// 检查阿里云密钥是否有效,如无效则下载
|
||
// try_count = 2;
|
||
// while((try_count--) &&
|
||
// (aliyunSecret.check != 0x55AA || memcmp(aliyunSecret.PSN, dcBuff.configBottle.PSN, 6) != 0))
|
||
// {
|
||
// // 连接升级服务器
|
||
// if(Sim808_Connect(0, dcBuff.configData.upgServer, dcBuff.configData.upgPort))
|
||
// {
|
||
// printf("\nDownload aliyun secret ...\n");
|
||
|
||
// memset(Task_sendBuff, 0, TASK_SENDBUFF_SIZE);
|
||
//
|
||
// i = sizeof(bluetooth_send_t);
|
||
//
|
||
// // PSN
|
||
// memmove(Task_sendBuff + i, dcBuff.configBottle.PSN, 6);
|
||
// i += 6;
|
||
//
|
||
// // 填写固定字段
|
||
// i = fill_biDir_fixFields(0xD037, i);
|
||
//
|
||
// // 发送i个字节到服务器,至少接收10个字节
|
||
// // 如果失败,下次再发送
|
||
// recvLen = sizeof(bluetooth_recv_t) + 2;
|
||
// if(Sim808_SendAndRecv(0, Task_sendBuff, i, &recvLen, Task_recvBuff, TASK_RECVBUFF_SIZE))
|
||
// {
|
||
// if(recvLen >= sizeof(bluetooth_recv_t) + 2
|
||
// && MODBUS_RTU_CRC16(Task_recvBuff, recvLen) == 0)
|
||
// {
|
||
// if(recvLen >= sizeof(bluetooth_recv_t) + ALIYUN_SECRET_SIZE + 2
|
||
// && pRecv->cmd == ntohs(0x0037)
|
||
// && MODBUS_RTU_CRC16(Task_recvBuff, sizeof(bluetooth_recv_t) + ALIYUN_SECRET_SIZE + 2) == 0)
|
||
// {
|
||
// // 保存参数
|
||
// memmove(aliyunSecret.PSN, dcBuff.configBottle.PSN, 6);
|
||
// strcpy(aliyunSecret.product, (char *) Task_recvBuff + sizeof(bluetooth_recv_t));
|
||
// strcpy(aliyunSecret.device, (char *) Task_recvBuff + sizeof(bluetooth_recv_t) + sizeof(aliyunSecret.product));
|
||
// strcpy(aliyunSecret.secret, (char *) Task_recvBuff + sizeof(bluetooth_recv_t) + sizeof(aliyunSecret.product) + sizeof(aliyunSecret.device));
|
||
// FRAM_SaveInfo(FRAM_ALIYUN_SECRET_BASE, (uint8_t *) &aliyunSecret, sizeof(aliyunSecret));
|
||
// }
|
||
// }
|
||
// }
|
||
//\
|
||
// // 关闭和服务器的连接
|
||
// DTU_Close(0);
|
||
// }
|
||
// }
|
||
|
||
try_count = 2;
|
||
while((try_count--) && /*aliyunSecret.check == 0x55AA
|
||
&& memcmp(aliyunSecret.PSN, dcBuff.configBottle.PSN, 6) == 0
|
||
&& */LoopBuff_GetCount(&gprsBuff) > 0)
|
||
{
|
||
// 第一条记录,连接就开始计数
|
||
if(LoopBuff_GetCount(&gprsBuff) > 0)
|
||
dcBuff.powerInfo.gprsSendCount++;
|
||
|
||
if(Sim808_MqttConnect(SERVER_URLs[dcBuff.configDisplay.op_SERVER_INDEX], dcBuff.configData.port))
|
||
{
|
||
nextPtr = gprsBuff.info.rdPtr;
|
||
for(k = 0; k < LoopBuff_GetCount(&gprsBuff); k++)
|
||
{
|
||
if(k > 0) // 第一条发送计数在连接之前
|
||
dcBuff.powerInfo.gprsSendCount++;
|
||
|
||
FRAM_BufferRead(LoopBuff_GetDataPos(&gprsBuff, nextPtr), (uint8_t *) &gprsRWBuf, sizeof(gprs_data_t));
|
||
pGprs = &gprsRWBuf;
|
||
|
||
nextPtr = LoopBuff_GetNextPtr(&gprsBuff, nextPtr);
|
||
|
||
// 打包上报数据(按modbus从机响应的格式)
|
||
//i = pack_gprs_send_data(pGprs, totalSeconds);
|
||
i = pack_json_send_data(pGprs, totalSeconds);
|
||
|
||
if(!Sim808_MqttPublish(Task_sendBuff, i))
|
||
break;
|
||
dcBuff.powerInfo.gprsSuccCount++;
|
||
|
||
// 最近一条上传数据的采集时间
|
||
DTU_dataTime = pGprs->sample_time;
|
||
}
|
||
|
||
// 移除已成功发送的数据
|
||
if(k > 0)
|
||
LoopBuff_RemoveItems(&gprsBuff, k);
|
||
|
||
// 关闭和服务器的连接
|
||
MQTT_Close();
|
||
}
|
||
}
|
||
}
|
||
else if(dcBuff.configDisplay.op_SERVER_PROTOCOL == SERVER_PROTOCOL_TCP)
|
||
{
|
||
try_count = 2;
|
||
while((try_count--) && (LoopBuff_GetCount(&gprsBuff) > 0 // || Config_CheckUpdate(&dcBuff)
|
||
|| downloadParam || ackParam))
|
||
{
|
||
// 第一条记录,连接就开始计数
|
||
if(LoopBuff_GetCount(&gprsBuff) > 0)
|
||
dcBuff.powerInfo.gprsSendCount++;
|
||
|
||
if(Sim808_Connect(0, dcBuff.configData.server, dcBuff.configData.port))
|
||
{
|
||
// 普莱克斯、林德、宝钢的不再上传
|
||
if(dcBuff.configBottle.serverVer != 3 && dcBuff.configBottle.serverVer != 4 &&
|
||
dcBuff.configBottle.serverVer != 5
|
||
&& !dcBuff.configDisplay.op_UNIDIR_COMM && Config_CheckUpdate(&dcBuff))
|
||
{
|
||
printf("\nUpload parameters ...\n");
|
||
|
||
memset(Task_sendBuff, 0, TASK_SENDBUFF_SIZE);
|
||
|
||
i = sizeof(bluetooth_send_t);
|
||
|
||
// PSN
|
||
memmove(Task_sendBuff + i, dcBuff.configBottle.PSN, 6);
|
||
i += 6;
|
||
// 参数时间戳
|
||
Int2ByteL(Task_sendBuff, i, htonl(dcBuff.configBottle.ts));
|
||
i += 4;
|
||
// 打包参数
|
||
pParam = (param_data_t *) (Task_sendBuff + i);
|
||
pack_param_DO23_data(pParam);
|
||
i += sizeof(param_data_t);
|
||
|
||
// 填写固定字段
|
||
i = fill_biDir_fixFields(0xD023, i);
|
||
|
||
// 发送i个字节到服务器,至少接收10个字节
|
||
// 如果失败,下次再发送
|
||
recvLen = sizeof(bluetooth_recv_t) + 2;
|
||
if(Sim808_SendAndRecv(0, Task_sendBuff, i, &recvLen, Task_recvBuff, TASK_RECVBUFF_SIZE))
|
||
{
|
||
if(recvLen >= sizeof(bluetooth_recv_t) + 2
|
||
&& pRecv->cmd == ntohs(0x0023)
|
||
&& MODBUS_RTU_CRC16(Task_recvBuff, sizeof(bluetooth_recv_t) + 2) == 0)
|
||
{
|
||
// 清除更新标志,保存参数
|
||
dcBuff.configBottle.updateFlag = 0;
|
||
Config_SaveConfig();
|
||
// Can_Write(CONFIG_BOARD_SAMPLE,CAN_DC_BOTTLE_CONFIG, &display_modifi);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// 关闭和服务器的连接
|
||
DTU_Close(0);
|
||
// 重连
|
||
continue;
|
||
}
|
||
}
|
||
|
||
nextPtr = gprsBuff.info.rdPtr;
|
||
for(k = 0; k < LoopBuff_GetCount(&gprsBuff); k++)
|
||
{
|
||
if(k > 0) // 第一条发送计数在连接之前
|
||
dcBuff.powerInfo.gprsSendCount++;
|
||
|
||
FRAM_BufferRead(LoopBuff_GetDataPos(&gprsBuff, nextPtr), (uint8_t *) &gprsRWBuf, sizeof(gprs_data_t));
|
||
pGprs = &gprsRWBuf;
|
||
|
||
nextPtr = LoopBuff_GetNextPtr(&gprsBuff, nextPtr);
|
||
|
||
// 打包上报数据(按modbus从机响应的格式)
|
||
i = pack_gprs_send_data(pGprs, totalSeconds);
|
||
|
||
recvLen = 2;
|
||
if(!Sim808_SendAndRecv(0, Task_sendBuff, i, &recvLen, Task_recvBuff, TASK_RECVBUFF_SIZE))
|
||
break;
|
||
dcBuff.powerInfo.gprsSuccCount++;
|
||
|
||
// 最近一条上传数据的采集时间
|
||
DTU_dataTime = pGprs->sample_time;
|
||
|
||
// 从GPRS切换到RF,需要重新搜索网关
|
||
rf_fail_count = 0;
|
||
rf_clear_gateway();
|
||
|
||
if(!dcBuff.configDisplay.op_UNIDIR_COMM)
|
||
{
|
||
if(recvLen >= 2 && Task_recvBuff[0] == 0xFF && Task_recvBuff[1] == 0x0F)
|
||
{
|
||
// 普莱克斯、林德的不再下载
|
||
if(dcBuff.configBottle.serverVer != 3 && dcBuff.configBottle.serverVer != 4)
|
||
downloadParam = 1;
|
||
}
|
||
}
|
||
}
|
||
|
||
// 移除已成功发送的数据
|
||
if(k > 0)
|
||
LoopBuff_RemoveItems(&gprsBuff, k);
|
||
|
||
// 下载参数
|
||
if(downloadParam)
|
||
{
|
||
printf("\nDownload parameters ...\n");
|
||
|
||
memset(Task_sendBuff, 0, TASK_SENDBUFF_SIZE);
|
||
|
||
i = sizeof(bluetooth_send_t);
|
||
|
||
// PSN
|
||
memmove(Task_sendBuff + i, dcBuff.configBottle.PSN, 6);
|
||
i += 6;
|
||
|
||
// 宝钢版本:用D036替代D021, 因为服务器端没有完整的参数信息,只能修改个别参数
|
||
if(dcBuff.configBottle.serverVer == 5)
|
||
{
|
||
// 填写固定字段
|
||
i = fill_biDir_fixFields(0xD036, i);
|
||
}
|
||
else
|
||
{
|
||
// 参数时间戳
|
||
Int2ByteL(Task_sendBuff, i, htonl(dcBuff.configBottle.ts));
|
||
i += 4;
|
||
// 填写固定字段
|
||
i = fill_biDir_fixFields(0xD021, i);
|
||
}
|
||
// 发送i个字节到服务器,至少接收10个字节
|
||
recvLen = sizeof(bluetooth_recv_t) + 2;
|
||
if(Sim808_SendAndRecv(0, Task_sendBuff, i, &recvLen, Task_recvBuff, TASK_RECVBUFF_SIZE))
|
||
{
|
||
if(recvLen >= sizeof(bluetooth_recv_t) + 2
|
||
&& MODBUS_RTU_CRC16(Task_recvBuff, recvLen) == 0)
|
||
{
|
||
downloadParam = 0;
|
||
|
||
if(recvLen >= sizeof(bluetooth_recv_t) + sizeof(param_data_t) + 2
|
||
&& pRecv->cmd == ntohs(0x0021)
|
||
&& MODBUS_RTU_CRC16(Task_recvBuff, sizeof(bluetooth_recv_t) + sizeof(param_data_t) + 2) == 0)
|
||
{
|
||
// 解析参数
|
||
pParam = (param_data_t *) (Task_recvBuff + sizeof(bluetooth_recv_t));
|
||
parse_param_D021_data(pParam);
|
||
// 清除更新标志,
|
||
dcBuff.configBottle.updateFlag = 0;
|
||
}
|
||
else if(recvLen >= sizeof(bluetooth_recv_t) + D036_PARAM_SIZE + 2
|
||
&& pRecv->cmd == ntohs(0x0036)
|
||
&& MODBUS_RTU_CRC16(Task_recvBuff, sizeof(bluetooth_recv_t) + D036_PARAM_SIZE + 2) == 0)
|
||
{
|
||
// 保存参数
|
||
parse_param_D036_data(Task_recvBuff + sizeof(bluetooth_recv_t), &reset);
|
||
}
|
||
// 保存参数
|
||
Config_SaveConfig();
|
||
// Can_Write(CONFIG_BOARD_SAMPLE,CAN_DC_BOTTLE_CONFIG, &display_modifi);
|
||
// Can_Write(CONFIG_BOARD_SAMPLE,CAN_DC_SENSOR_CONFIG, &display_modifi);
|
||
// Can_Write(CONFIG_BOARD_SAMPLE,CAN_DC_DATA_CONFIG, &display_modifi);
|
||
|
||
ackParam = 1;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// 关闭和服务器的连接
|
||
DTU_Close(0);
|
||
// 重连
|
||
continue;
|
||
}
|
||
}
|
||
|
||
// 确认参数
|
||
if(ackParam)
|
||
{
|
||
printf("\nConfirm download parameters ...\n");
|
||
|
||
// 发送确认
|
||
memset(Task_sendBuff, 0, TASK_SENDBUFF_SIZE);
|
||
|
||
i = sizeof(bluetooth_send_t);
|
||
|
||
// PSN
|
||
memmove(Task_sendBuff + i, dcBuff.configBottle.PSN, 6);
|
||
i += 6;
|
||
// 参数时间戳
|
||
Int2ByteL(Task_sendBuff, i, htonl(dcBuff.configBottle.ts));
|
||
i += 4;
|
||
|
||
// 填写固定字段
|
||
i = fill_biDir_fixFields(0xD022, i);
|
||
|
||
// 发送i个字节到服务器,至少接收10个字节
|
||
// 如果失败,下次再发送
|
||
recvLen = sizeof(bluetooth_recv_t) + 2;
|
||
if(!Sim808_SendAndRecv(0, Task_sendBuff, i, &recvLen, Task_recvBuff, TASK_RECVBUFF_SIZE))
|
||
{
|
||
// 关闭和服务器的连接
|
||
DTU_Close(0);
|
||
// 重连
|
||
continue;
|
||
}
|
||
ackParam = 0;
|
||
}
|
||
|
||
// 关闭和服务器的连接
|
||
DTU_Close(0);
|
||
}
|
||
}
|
||
}
|
||
else if(dcBuff.configDisplay.op_SERVER_PROTOCOL == SERVER_PROTOCOL_FURUI)
|
||
{
|
||
try_count = 2;
|
||
while((try_count--) && LoopBuff_GetCount(&gprsBuff) > 0)
|
||
{
|
||
// 第一条记录,连接就开始计数
|
||
if(LoopBuff_GetCount(&gprsBuff) > 0)
|
||
dcBuff.powerInfo.gprsSendCount++;
|
||
|
||
if(Sim808_Connect(0, dcBuff.configData.server, dcBuff.configData.port))
|
||
{
|
||
nextPtr = gprsBuff.info.rdPtr;
|
||
for(k = 0; k < LoopBuff_GetCount(&gprsBuff); k++)
|
||
{
|
||
if(k > 0) // 第一条发送计数在连接之前
|
||
dcBuff.powerInfo.gprsSendCount++;
|
||
|
||
FRAM_BufferRead(LoopBuff_GetDataPos(&gprsBuff, nextPtr), (uint8_t *) &gprsRWBuf, sizeof(gprs_data_t));
|
||
pGprs = &gprsRWBuf;
|
||
|
||
nextPtr = LoopBuff_GetNextPtr(&gprsBuff, nextPtr);
|
||
|
||
// 打包上报数据(按modbus从机响应的格式)
|
||
i = pack_furui_send_data(pGprs, &relativeTime);
|
||
|
||
printf("\nSend %d bytes to server:\n", i);
|
||
for(j = 0; j < i; j++)
|
||
printf("%02X ", Task_sendBuff[j]);
|
||
printf("\n");
|
||
|
||
recvLen = 6;
|
||
if(!Sim808_SendAndRecv(0, Task_sendBuff, i, &recvLen, Task_recvBuff, TASK_RECVBUFF_SIZE))
|
||
break;
|
||
if(!parse_furui_recv_data(dcBuff.configBottle.PSN, relativeTime, recvLen))
|
||
break;
|
||
dcBuff.powerInfo.gprsSuccCount++;
|
||
|
||
// 最近一条上传数据的采集时间
|
||
DTU_dataTime = pGprs->sample_time;
|
||
|
||
// 从GPRS切换到RF,需要重新搜索网关
|
||
rf_fail_count = 0;
|
||
rf_clear_gateway();
|
||
}
|
||
|
||
// 移除已成功发送的数据
|
||
if(k > 0)
|
||
LoopBuff_RemoveItems(&gprsBuff, k);
|
||
|
||
// 关闭和服务器的连接
|
||
DTU_Close(0);
|
||
}
|
||
}
|
||
}
|
||
|
||
// 是否连接维护平台:每隔12小时一次(普莱克斯、林德的每次连接)
|
||
if(dcBuff.configBottle.serverVer == 3 || dcBuff.configBottle.serverVer == 4 ||
|
||
(!dcBuff.configDisplay.op_UNIDIR_COMM &&
|
||
(totalSeconds < INITIAL_TRAN_COUNT * (dcBuff.configData.intervalSample > 300 ? 300 : dcBuff.configData.intervalSample)
|
||
|| totalSeconds + 3 >= DTU_ldmsTime + 43200 || DTU_ldmsConn)))
|
||
{
|
||
// 清除强制连接维护平台标志
|
||
DTU_ldmsConn = 0;
|
||
|
||
// 保存连接维护平台时间(刚复位时连续上传6次,但只保存第一次)
|
||
if(totalSeconds >= 3600)
|
||
DTU_ldmsTime = totalSeconds;
|
||
|
||
// 是否升级或下载参数:维护平台
|
||
upgrade = 0;
|
||
ackUpgrade = 0;
|
||
downloadParam = 0;
|
||
ackParam = 0;
|
||
downloadConfig = 0;
|
||
ackConfig = 0;
|
||
reset = 0;
|
||
k = 1; // 发送1条诊断信息
|
||
|
||
try_count = 2;
|
||
while((try_count--) && (k || upgrade || ackUpgrade || downloadParam || ackParam || downloadConfig || ackConfig))
|
||
{
|
||
// 连接升级服务器
|
||
if(Sim808_Connect(0, dcBuff.configData.upgServer, dcBuff.configData.upgPort))
|
||
{
|
||
if(k)
|
||
{
|
||
// 发送诊断信息,至少接收12个字节
|
||
i = pack_ldms_info_data(DTU_dataTime, totalSeconds);
|
||
recvLen = sizeof(bluetooth_recv_t) + 2 + 2;
|
||
if(!Sim808_SendAndRecv(0, Task_sendBuff, i, &recvLen, Task_recvBuff, TASK_RECVBUFF_SIZE))
|
||
{
|
||
// 关闭和服务器的连接
|
||
DTU_Close(0);
|
||
// 重连
|
||
continue;
|
||
}
|
||
if(recvLen >= sizeof(bluetooth_recv_t) + 2 + 2 && MODBUS_RTU_CRC16(Task_recvBuff, recvLen) == 0
|
||
&& pRecv->cmd == ntohs(0x0035))
|
||
{
|
||
upgrade = Task_recvBuff[sizeof(bluetooth_recv_t)];
|
||
downloadParam = Task_recvBuff[sizeof(bluetooth_recv_t) + 1];
|
||
downloadConfig = Task_recvBuff[sizeof(bluetooth_recv_t) + 2];
|
||
k--; // 发送成功
|
||
}
|
||
}
|
||
|
||
// 下载参数
|
||
if(downloadParam)
|
||
{
|
||
printf("\nDownload parameters ...\n");
|
||
|
||
memset(Task_sendBuff, 0, TASK_SENDBUFF_SIZE);
|
||
|
||
i = sizeof(bluetooth_send_t);
|
||
|
||
// PSN
|
||
memmove(Task_sendBuff + i, dcBuff.configBottle.PSN, 6);
|
||
i += 6;
|
||
|
||
// 填写固定字段
|
||
i = fill_biDir_fixFields(0xD036, i);
|
||
|
||
// 发送i个字节到服务器,至少接收10个字节
|
||
recvLen = sizeof(bluetooth_recv_t) + 2;
|
||
if(Sim808_SendAndRecv(0, Task_sendBuff, i, &recvLen, Task_recvBuff, TASK_RECVBUFF_SIZE))
|
||
{
|
||
if(recvLen >= sizeof(bluetooth_recv_t) + 2
|
||
&& MODBUS_RTU_CRC16(Task_recvBuff, recvLen) == 0)
|
||
{
|
||
downloadParam = 0;
|
||
|
||
if(recvLen >= sizeof(bluetooth_recv_t) + D036_PARAM_SIZE + 2
|
||
&& pRecv->cmd == ntohs(0x0036)
|
||
&& MODBUS_RTU_CRC16(Task_recvBuff, sizeof(bluetooth_recv_t) + D036_PARAM_SIZE + 2) == 0)
|
||
{
|
||
// 保存参数
|
||
if(parse_param_D036_data(Task_recvBuff + sizeof(bluetooth_recv_t), &reset))
|
||
{
|
||
// 保存参数
|
||
Config_SaveConfig();
|
||
// Can_Write(CONFIG_BOARD_SAMPLE,CAN_DC_BOTTLE_CONFIG, &display_modifi);
|
||
// Can_Write(CONFIG_BOARD_SAMPLE,CAN_DC_SENSOR_CONFIG, &display_modifi);
|
||
// Can_Write(CONFIG_BOARD_SAMPLE,CAN_DC_DATA_CONFIG, &display_modifi);
|
||
// Can_Write(CONFIG_BOARD_SAMPLE,CAN_DC_DISPLAY_CONFIG, &display_modifi);
|
||
}
|
||
ackParam = 1;
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// 关闭和服务器的连接
|
||
DTU_Close(0);
|
||
// 重连
|
||
continue;
|
||
}
|
||
}
|
||
|
||
// 确认参数
|
||
if(ackParam)
|
||
{
|
||
printf("\nConfirm download parameters ...\n");
|
||
|
||
// 发送确认
|
||
memset(Task_sendBuff, 0, TASK_SENDBUFF_SIZE);
|
||
|
||
i = sizeof(bluetooth_send_t);
|
||
|
||
// PSN
|
||
memmove(Task_sendBuff + i, dcBuff.configBottle.PSN, 6);
|
||
i += 6;
|
||
// 参数时间戳
|
||
Int2ByteL(Task_sendBuff, i, htonl(dcBuff.configBottle.ts));
|
||
i += 4;
|
||
|
||
// 填写固定字段
|
||
i = fill_biDir_fixFields(0xD022, i);
|
||
|
||
// 发送i个字节到服务器,至少接收10个字节
|
||
// 如果失败,下次再发送
|
||
recvLen = sizeof(bluetooth_recv_t) + 2;
|
||
if(!Sim808_SendAndRecv(0, Task_sendBuff, i, &recvLen, Task_recvBuff, TASK_RECVBUFF_SIZE))
|
||
{
|
||
// 关闭和服务器的连接
|
||
DTU_Close(0);
|
||
// 重连
|
||
continue;
|
||
}
|
||
ackParam = 0;
|
||
}
|
||
|
||
// 下载配置
|
||
if(downloadConfig)
|
||
{
|
||
printf("\nDownload configuration ...\n");
|
||
|
||
memset(Task_sendBuff, 0, TASK_SENDBUFF_SIZE);
|
||
|
||
i = sizeof(bluetooth_send_t);
|
||
|
||
// PSN
|
||
memmove(Task_sendBuff + i, dcBuff.configBottle.PSN, 6);
|
||
i += 6;
|
||
|
||
// 填写固定字段
|
||
i = fill_biDir_fixFields(0xD038, i);
|
||
|
||
// 发送i个字节到服务器,至少接收10个字节
|
||
recvLen = sizeof(bluetooth_recv_t) + 2;
|
||
if(Sim808_SendAndRecv(0, Task_sendBuff, i, &recvLen, Task_recvBuff, TASK_RECVBUFF_SIZE))
|
||
{
|
||
if(recvLen >= sizeof(bluetooth_recv_t) + 2
|
||
&& MODBUS_RTU_CRC16(Task_recvBuff, recvLen) == 0)
|
||
{
|
||
downloadConfig = 0;
|
||
|
||
if(recvLen >= sizeof(bluetooth_recv_t) + D038_CONFIG_SIZE + 2
|
||
&& pRecv->cmd == ntohs(0x0038)
|
||
&& MODBUS_RTU_CRC16(Task_recvBuff, sizeof(bluetooth_recv_t) + D038_CONFIG_SIZE + 2) == 0)
|
||
{
|
||
// 保存参数
|
||
if(parse_config_D038_data(Task_recvBuff + sizeof(bluetooth_recv_t)))
|
||
{
|
||
// 保存参数
|
||
Config_SaveConfig();
|
||
// Can_Write(CONFIG_BOARD_SAMPLE,CAN_DC_BOTTLE_CONFIG, &display_modifi);
|
||
// Can_Write(CONFIG_BOARD_SAMPLE,CAN_DC_SENSOR_CONFIG, &display_modifi);
|
||
// Can_Write(CONFIG_BOARD_SAMPLE,CAN_DC_DATA_CONFIG, &display_modifi);
|
||
// Can_Write(CONFIG_BOARD_SAMPLE,CAN_DC_DISPLAY_CONFIG, &display_modifi);
|
||
}
|
||
ackConfig = 1;
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// 关闭和服务器的连接
|
||
DTU_Close(0);
|
||
// 重连
|
||
continue;
|
||
}
|
||
}
|
||
|
||
// 确认配置
|
||
if(ackConfig)
|
||
{
|
||
printf("\nConfirm download configuration ...\n");
|
||
|
||
// 发送确认
|
||
memset(Task_sendBuff, 0, TASK_SENDBUFF_SIZE);
|
||
|
||
i = sizeof(bluetooth_send_t);
|
||
|
||
// PSN
|
||
memmove(Task_sendBuff + i, dcBuff.configBottle.PSN, 6);
|
||
i += 6;
|
||
|
||
// 填写固定字段
|
||
i = fill_biDir_fixFields(0xD039, i);
|
||
|
||
// 发送i个字节到服务器,至少接收10个字节
|
||
// 如果失败,下次再发送
|
||
recvLen = sizeof(bluetooth_recv_t) + 2;
|
||
if(!Sim808_SendAndRecv(0, Task_sendBuff, i, &recvLen, Task_recvBuff, TASK_RECVBUFF_SIZE))
|
||
{
|
||
// 关闭和服务器的连接
|
||
DTU_Close(0);
|
||
// 重连
|
||
continue;
|
||
}
|
||
ackConfig = 0;
|
||
// 配置改变,需要复位
|
||
reset = 1;
|
||
}
|
||
|
||
// 升级
|
||
if(upgrade)
|
||
{
|
||
printf("\nUpgrade software ...\n");
|
||
|
||
// 从FRAM读取初始进度
|
||
FRAM_LoadInfo(FRAM_UPGRADE_INFO_BASE, (uint8_t *) &upInfo, sizeof(upInfo));
|
||
|
||
if(upInfo.fileSize == 0)
|
||
{
|
||
// 从头开始升级
|
||
memset(&upInfo, 0, sizeof(upInfo));
|
||
// 保存到铁电
|
||
for(write_count = 0; write_count < 2; write_count++)
|
||
{
|
||
FRAM_SaveInfo(FRAM_UPGRADE_INFO_BASE, (uint8_t *) &upInfo, sizeof(upInfo));
|
||
if(FRAM_BufferVerify(FRAM_UPGRADE_INFO_BASE, (uint8_t *) &upInfo, sizeof(upInfo)))
|
||
break;
|
||
printf("**** Verify FRAM failed at: 0x%08X, %d bytes\n", FRAM_UPGRADE_INFO_BASE, sizeof(upInfo));
|
||
delay_ms(200);
|
||
}
|
||
}
|
||
|
||
// 下载数据
|
||
while(upInfo.fileSize == 0 || upInfo.offset < upInfo.fileSize)
|
||
{
|
||
memset(Task_sendBuff, 0, TASK_SENDBUFF_SIZE);
|
||
|
||
i = sizeof(bluetooth_send_t);
|
||
|
||
// PSN
|
||
memmove(Task_sendBuff + i, dcBuff.configBottle.PSN, 6);
|
||
i += 6;
|
||
// 当前固件号
|
||
Int2ByteL(Task_sendBuff, i, htonl(upInfo.ver));
|
||
i += 4;
|
||
// 文件偏移量
|
||
Int2ByteL(Task_sendBuff, i, htonl(upInfo.offset));
|
||
i += 4;
|
||
// 请求数据长度
|
||
Int2ByteL(Task_sendBuff, i, htonl(UPGRADE_DATA_LEN));
|
||
i += 4;
|
||
|
||
// 填写固定字段
|
||
i = fill_biDir_fixFields(0xD0E0, i);
|
||
|
||
// 发送i个字节到服务器,至少接收10个字节
|
||
// 如果失败,下次再升级
|
||
recvLen = sizeof(bluetooth_recv_t) + 2;
|
||
if(!Sim808_SendAndRecv(0, Task_sendBuff, i, &recvLen, Task_recvBuff, TASK_RECVBUFF_SIZE))
|
||
break;
|
||
|
||
if(recvLen >= sizeof(bluetooth_recv_t) + 2 && MODBUS_RTU_CRC16(Task_recvBuff, recvLen) == 0)
|
||
{
|
||
if(pRecv->cmd == ntohs(0x00E0))
|
||
{
|
||
pFrame = (upgrade_frame_t *) (Task_recvBuff + sizeof(bluetooth_recv_t));
|
||
if(MODBUS_RTU_CRC16(pFrame->data, ntohl(pFrame->len) + 2) == 0)
|
||
{
|
||
// 升级内容下载成功,允许继续升级
|
||
try_count = 2;
|
||
|
||
// 如果升级包有变化
|
||
if(upInfo.fileSize > 0 && (upInfo.fileSize != ntohl(pFrame->fileSize) || upInfo.fileCrc != pFrame->fileCrc
|
||
|| upInfo.offset > ntohl(pFrame->fileSize) || upInfo.ver != ntohl(pFrame->ver)))
|
||
{
|
||
// 从头开始升级
|
||
memset(&upInfo, 0, sizeof(upInfo));
|
||
// 保存到铁电
|
||
for(write_count = 0; write_count < 2; write_count++)
|
||
{
|
||
FRAM_SaveInfo(FRAM_UPGRADE_INFO_BASE, (uint8_t *) &upInfo, sizeof(upInfo));
|
||
if(FRAM_BufferVerify(FRAM_UPGRADE_INFO_BASE, (uint8_t *) &upInfo, sizeof(upInfo)))
|
||
break;
|
||
printf("**** Verify FRAM failed at: 0x%08X, %d bytes\n", FRAM_UPGRADE_INFO_BASE, sizeof(upInfo));
|
||
delay_ms(200);
|
||
}
|
||
continue;
|
||
}
|
||
// 保存下载信息
|
||
// 如果只是网络通信失败,会断点续传
|
||
upInfo.ver = ntohl(pFrame->ver);
|
||
upInfo.fileSize = ntohl(pFrame->fileSize);
|
||
upInfo.offset = ntohl(pFrame->offset);
|
||
upInfo.len = ntohl(pFrame->len);
|
||
upInfo.fileCrc = pFrame->fileCrc;
|
||
printf("\nfileSize = %d, offset = %d, len = %d\n",
|
||
upInfo.fileSize, upInfo.offset, upInfo.len);
|
||
|
||
// 如果是第一个包,先将升级请求改为0,以免意外重启导致boot-loader解压
|
||
// 待全部下载完以后,再改为1
|
||
if(upInfo.offset == 0)
|
||
((TUpgradeHeader *) pFrame->data)->upgrade_request = 0;
|
||
#if UPGRADE_DATA_LEN >= SFLASH_ERASE_SIZE
|
||
// 直接写入flash
|
||
for(write_count = 0; write_count < 2; write_count++)
|
||
{
|
||
SFlash_BufferWrite(SFLASH_UPGRADE_BASE + upInfo.offset, pFrame->data, upInfo.len);
|
||
if(SFlash_BufferVerify(SFLASH_UPGRADE_BASE + upInfo.offset, pFrame->data, upInfo.len))
|
||
break;
|
||
printf("**** Verify SFlash failed at: 0x%08X, %d bytes\n", SFLASH_UPGRADE_BASE + upInfo.offset, upInfo.len);
|
||
delay_ms(200);
|
||
}
|
||
upInfo.offset += upInfo.len;
|
||
#else
|
||
// 为了减少flash的多次擦写,又节约收发缓冲
|
||
// 先把数据拷到flash页缓冲
|
||
for(write_count = 0; write_count < 2; write_count++)
|
||
{
|
||
FRAM_BufferWrite(FRAM_UPGRADE_DATA_BASE + upInfo.offset % SFLASH_ERASE_SIZE, pFrame->data, upInfo.len);
|
||
if(FRAM_BufferVerify(FRAM_UPGRADE_DATA_BASE + upInfo.offset % SFLASH_ERASE_SIZE, pFrame->data, upInfo.len))
|
||
break;
|
||
printf("**** Verify FRAM failed at: 0x%08X, %d bytes\n", FRAM_UPGRADE_DATA_BASE + upInfo.offset % SFLASH_ERASE_SIZE, upInfo.len);
|
||
delay_ms(200);
|
||
}
|
||
upInfo.offset += upInfo.len;
|
||
|
||
// 够一页了,或者下载完了就从铁电写入flash
|
||
if(upInfo.offset % SFLASH_ERASE_SIZE == 0)
|
||
{
|
||
FRAM_BufferRead(FRAM_UPGRADE_DATA_BASE, Task_recvBuff, SFLASH_ERASE_SIZE);
|
||
for(write_count = 0; write_count < 2; write_count++)
|
||
{
|
||
SFlash_BufferWrite(SFLASH_UPGRADE_BASE + (upInfo.offset - SFLASH_ERASE_SIZE), Task_recvBuff, SFLASH_ERASE_SIZE);
|
||
if(SFlash_BufferVerify(SFLASH_UPGRADE_BASE + (upInfo.offset - SFLASH_ERASE_SIZE), Task_recvBuff, SFLASH_ERASE_SIZE))
|
||
break;
|
||
printf("**** Verify SFlash failed at: 0x%08X, %d bytes\n", SFLASH_UPGRADE_BASE + (upInfo.offset - SFLASH_ERASE_SIZE), SFLASH_ERASE_SIZE);
|
||
delay_ms(200);
|
||
}
|
||
|
||
}
|
||
else if(upInfo.offset == upInfo.fileSize)
|
||
{
|
||
FRAM_BufferRead(FRAM_UPGRADE_DATA_BASE, Task_recvBuff, upInfo.offset % SFLASH_ERASE_SIZE);
|
||
for(write_count = 0; write_count < 2; write_count++)
|
||
{
|
||
SFlash_BufferWrite(SFLASH_UPGRADE_BASE + (upInfo.offset - upInfo.offset % SFLASH_ERASE_SIZE), Task_recvBuff, upInfo.offset % SFLASH_ERASE_SIZE);
|
||
if(SFlash_BufferVerify(SFLASH_UPGRADE_BASE + (upInfo.offset - upInfo.offset % SFLASH_ERASE_SIZE), Task_recvBuff, upInfo.offset % SFLASH_ERASE_SIZE))
|
||
break;
|
||
printf("**** Verify SFlash failed at: 0x%08X, %d bytes\n", SFLASH_UPGRADE_BASE + (upInfo.offset - upInfo.offset % SFLASH_ERASE_SIZE), upInfo.offset % SFLASH_ERASE_SIZE);
|
||
delay_ms(200);
|
||
}
|
||
}
|
||
#endif
|
||
for(write_count = 0; write_count < 2; write_count++)
|
||
{
|
||
// 保存到铁电
|
||
FRAM_SaveInfo(FRAM_UPGRADE_INFO_BASE, (uint8_t *) &upInfo, sizeof(upInfo));
|
||
if(FRAM_BufferVerify(FRAM_UPGRADE_INFO_BASE, (uint8_t *) &upInfo, sizeof(upInfo)))
|
||
break;
|
||
printf("**** Verify FRAM failed at: 0x%08X, %d bytes\n", FRAM_UPGRADE_INFO_BASE, sizeof(upInfo));
|
||
delay_ms(200);
|
||
}
|
||
}
|
||
}
|
||
else // 命令返回错误
|
||
{
|
||
// 取消本次升级
|
||
upInfo.fileSize = 0;
|
||
// 保存到铁电
|
||
for(write_count = 0; write_count < 2; write_count++)
|
||
{
|
||
FRAM_SaveInfo(FRAM_UPGRADE_INFO_BASE, (uint8_t *) &upInfo, sizeof(upInfo));
|
||
if(FRAM_BufferVerify(FRAM_UPGRADE_INFO_BASE, (uint8_t *) &upInfo, sizeof(upInfo)))
|
||
break;
|
||
printf("**** Verify FRAM failed at: 0x%08X, %d bytes\n", FRAM_UPGRADE_INFO_BASE, sizeof(upInfo));
|
||
delay_ms(200);
|
||
}
|
||
|
||
upgrade = 0;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
if(upInfo.fileSize > 0 && upInfo.offset == upInfo.fileSize)
|
||
{
|
||
SFlash_BufferRead(SFLASH_UPGRADE_BASE, (uint8_t *) &upHeader, sizeof(upHeader));
|
||
// 将升级请求改为1
|
||
upHeader.upgrade_request = 1;
|
||
if(upHeader.check == 0x55AA
|
||
&& do_crc_16(0, (uint8_t *) &upHeader, sizeof(upHeader)) == 0
|
||
&& do_sflash_crc(SFLASH_UPGRADE_BASE + sizeof(upHeader), upHeader.upgrade_length) == 0)
|
||
{
|
||
// 校验通过
|
||
printf("\nUpgrade package confirm passed\n");
|
||
// 发送确认
|
||
ackUpgrade = 1;
|
||
}
|
||
else
|
||
{
|
||
// 校验未通过
|
||
printf("\n****** Upgrade package confirm failed\n");
|
||
// 从头开始
|
||
upInfo.fileSize = 0;
|
||
// 保存到铁电
|
||
for(write_count = 0; write_count < 2; write_count++)
|
||
{
|
||
FRAM_SaveInfo(FRAM_UPGRADE_INFO_BASE, (uint8_t *) &upInfo, sizeof(upInfo));
|
||
if(FRAM_BufferVerify(FRAM_UPGRADE_INFO_BASE, (uint8_t *) &upInfo, sizeof(upInfo)))
|
||
break;
|
||
printf("**** Verify FRAM failed at: 0x%08X, %d bytes\n", FRAM_UPGRADE_INFO_BASE, sizeof(upInfo));
|
||
delay_ms(200);
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// 关闭和服务器的连接
|
||
DTU_Close(0);
|
||
// 继续
|
||
continue;
|
||
}
|
||
}
|
||
|
||
// 确认升级成功
|
||
if(ackUpgrade)
|
||
{
|
||
printf("\nConfirm upgrade software ...\n");
|
||
|
||
|
||
// 发送确认
|
||
memset(Task_sendBuff, 0, TASK_SENDBUFF_SIZE);
|
||
|
||
i = sizeof(bluetooth_send_t);
|
||
|
||
// PSN
|
||
memmove(Task_sendBuff + i, dcBuff.configBottle.PSN, 6);
|
||
i += 6;
|
||
// 当前固件号
|
||
Int2ByteL(Task_sendBuff, i, htonl(upInfo.ver));
|
||
i += 4;
|
||
// 固件的CRC16
|
||
Int2ByteS(Task_sendBuff, i, upInfo.fileCrc);
|
||
i += 2;
|
||
|
||
// 填写固定字段
|
||
i = fill_biDir_fixFields(0xD0E1, i);
|
||
|
||
// 发送i个字节到服务器,至少接收10个字节
|
||
// 如果失败,下次再发送
|
||
recvLen = sizeof(bluetooth_recv_t) + 2;
|
||
if(!Sim808_SendAndRecv(0, Task_sendBuff, i, &recvLen, Task_recvBuff, TASK_RECVBUFF_SIZE))
|
||
{
|
||
// 关闭和服务器的连接
|
||
DTU_Close(0);
|
||
// 重连
|
||
continue;
|
||
}
|
||
if(recvLen == sizeof(bluetooth_recv_t) + 2 && pRecv->cmd == ntohs(0x00E1))
|
||
{
|
||
// 将升级请求改为1
|
||
SFlash_BufferRead(SFLASH_UPGRADE_BASE, (uint8_t *) &upHeader, sizeof(upHeader));
|
||
upHeader.upgrade_request = 1;
|
||
for(write_count = 0; write_count < 2; write_count++)
|
||
{
|
||
SFlash_BufferWrite(SFLASH_UPGRADE_BASE, (uint8_t *) &upHeader, sizeof(upHeader));
|
||
if(SFlash_BufferVerify(SFLASH_UPGRADE_BASE, (uint8_t *) &upHeader, sizeof(upHeader)))
|
||
break;
|
||
printf("**** Verify SFlash failed at: 0x%08X, %d bytes\n", SFLASH_UPGRADE_BASE, sizeof(upHeader));
|
||
delay_ms(200);
|
||
}
|
||
|
||
// 下次再升级从头开始
|
||
upInfo.fileSize = 0;
|
||
// 保存到铁电
|
||
for(write_count = 0; write_count < 2; write_count++)
|
||
{
|
||
FRAM_SaveInfo(FRAM_UPGRADE_INFO_BASE, (uint8_t *) &upInfo, sizeof(upInfo));
|
||
if(FRAM_BufferVerify(FRAM_UPGRADE_INFO_BASE, (uint8_t *) &upInfo, sizeof(upInfo)))
|
||
break;
|
||
printf("**** Verify FRAM failed at: 0x%08X, %d bytes\n", FRAM_UPGRADE_INFO_BASE, sizeof(upInfo));
|
||
delay_ms(200);
|
||
}
|
||
// 关闭和服务器的连接
|
||
DTU_Close(0);
|
||
|
||
// 关闭DTU电源
|
||
VCC_GSM_OFF();
|
||
delay_ms(200);
|
||
|
||
// 将LDROM映射到地址0x0
|
||
// FMC_Open();
|
||
// FMC_SetVectorPageAddr(LDROM_BASE);
|
||
// FMC_Close();
|
||
// 复位以后执行Bootloader,将升级包解压
|
||
WDT_Close(); // 先关看门狗,免得bootloader复位
|
||
NVIC_SystemReset();
|
||
}
|
||
}
|
||
|
||
// 关闭和服务器的连接
|
||
DTU_Close(0);
|
||
|
||
// 确认参数以后才执行复位命令(避免反复复位)
|
||
if(reset && !ackParam)
|
||
{
|
||
VCC_GSM_OFF();
|
||
delay_ms(200);
|
||
NVIC_SystemReset();
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// 刚处理完,清除等待的信号。等下一个周期再执行
|
||
DTU_semGPRS = 0;
|
||
}
|
||
|
||
// 检测发送GPS定位信号
|
||
if(semGPS || semSync)
|
||
{
|
||
if(Wakeup_GetWorkMode() == WORK_MODE_NORMAL)
|
||
{
|
||
if(dcBuff.configDisplay.op_SEND_GPS_DATA && Sim808_Connect(0, dcBuff.configData.gpsServer, dcBuff.configData.gpsPort))
|
||
{
|
||
// 如果有待发送数据
|
||
do
|
||
{
|
||
// 根据发送缓冲区的大小,决定一次最多发几条数据
|
||
// 每条记录占12个字节,另外有24个字节的固定字段,比如头信息、PSN、crc等
|
||
// 如果没有合法的记录,发送一条空记录
|
||
gpsCount = GPS_LookData((TASK_SENDBUFF_SIZE - 24) / 12, &gpsInterval, &gpsDone);
|
||
if(gpsCount > 0)
|
||
{
|
||
nextPtr = gpsBuff.info.rdPtr;
|
||
FRAM_BufferRead(LoopBuff_GetDataPos(&gpsBuff, nextPtr), (uint8_t *) &gps, sizeof(gps_data_t));
|
||
}
|
||
|
||
memset(Task_sendBuff, 0, TASK_SENDBUFF_SIZE);
|
||
|
||
i = sizeof(bluetooth_send_t);
|
||
|
||
// PSN
|
||
memmove(Task_sendBuff + i, dcBuff.configBottle.PSN, 6);
|
||
i += 6;
|
||
// 坐标个数
|
||
if(gpsCount > 0)
|
||
Int2ByteS(Task_sendBuff, i, htons(gpsCount));
|
||
else
|
||
Int2ByteS(Task_sendBuff, i, htons(1));
|
||
i += 2;
|
||
// 起始时间戳
|
||
if(gpsCount > 0)
|
||
Int2ByteL(Task_sendBuff, i, htonl(gps.time.tm));
|
||
i += 4;
|
||
// 时间戳增量
|
||
if(gpsCount > 0)
|
||
Int2ByteS(Task_sendBuff, i, htons(gpsInterval));
|
||
i += 2;
|
||
for(j = 0; j < (gpsCount ? gpsCount : 1); j++)
|
||
{
|
||
// 状态
|
||
if(gpsCount > 0)
|
||
Task_sendBuff[i] = gps.state;
|
||
else
|
||
{
|
||
// 车辆是否启动(根据充电状态决定)
|
||
if(VCC_POWER_STATUS())
|
||
Task_sendBuff[i] |= (1 << 6);
|
||
// 车辆启动状态是否改变)
|
||
Task_sendBuff[i] |= (bat_CurrentEvent << 7);
|
||
bat_CurrentEvent = 0;
|
||
}
|
||
i++;
|
||
// 保留
|
||
i++;
|
||
// 经度
|
||
if(gpsCount > 0)
|
||
Int2ByteL(Task_sendBuff, i, htonl(gps.longitude));
|
||
i += 4;
|
||
// 纬度
|
||
if(gpsCount > 0)
|
||
Int2ByteL(Task_sendBuff, i, htonl(gps.latitude));
|
||
i += 4;
|
||
// 速度
|
||
if(gpsCount > 0)
|
||
Int2ByteS(Task_sendBuff, i, htons(gps.speed * 100));
|
||
i += 2;
|
||
|
||
nextPtr = LoopBuff_GetNextPtr(&gpsBuff, nextPtr);
|
||
FRAM_BufferRead(LoopBuff_GetDataPos(&gpsBuff, nextPtr), (uint8_t *) &gps, sizeof(gps_data_t));
|
||
}
|
||
|
||
// 填写固定字段
|
||
i = fill_biDir_fixFields(0xD010, i);
|
||
|
||
// 发送i个字节到服务器,至少接收10个字节
|
||
// 如果失败,下次再发送
|
||
recvLen = sizeof(bluetooth_recv_t) + 2;
|
||
if(!Sim808_SendAndRecv(0, Task_sendBuff, i, &recvLen, Task_recvBuff, TASK_RECVBUFF_SIZE))
|
||
break;
|
||
|
||
if(gpsCount > 0)
|
||
{
|
||
// 将这几条记录移除
|
||
GPS_MoveFromQueue(gpsCount);
|
||
|
||
if(gpsDone)
|
||
{
|
||
GPS_Located = 1;
|
||
// 停止超时定时器
|
||
GPS_Waiting = 0;
|
||
}
|
||
}
|
||
} while(!gpsDone);
|
||
}
|
||
|
||
// 无论如何,关闭和服务器的连接
|
||
DTU_Close(0);
|
||
|
||
// 刚处理完,清除等待的信号。等下一个周期再执行
|
||
DTU_semGPS = 0;
|
||
}
|
||
}
|
||
|
||
if(semSync)
|
||
{
|
||
// 刚处理完,清除等待的信号。等下一个周期再执行
|
||
DTU_semSync = 0;
|
||
}
|
||
// 检查是否进入掉电模式
|
||
Wakeup_Powerdown();
|
||
}
|
||
}
|