// // Created by hyz on 2024/6/5. // #ifndef WEATHERCOMM_H #define WEATHERCOMM_H #include #include "GPIOControl.h" #ifndef DWORD typedef unsigned int DWORD; #endif #ifndef WORD typedef unsigned short WORD; #endif #ifndef BYTE typedef unsigned char BYTE; #endif #ifndef FALSE #define FALSE 0 #endif #ifndef TRUE #define TRUE 1 #endif #define LOBYTE(w) ((unsigned char)(w)) #define HIBYTE(w) ((unsigned char)(((unsigned short)(w) >> 8) & 0xFF)) #define LOWORD(l) ((WORD)(l)) #define HIWORD(l) ((WORD)((DWORD)(l) >> 16)) #define MAX_STRING_LEN 32 #define IOT_PARAM_WRITE 0xAE #define IOT_PARAM_READ 0xAF #define MAX_SERIAL_DEV_NUM 25 /* 最大接串口传感器数量*/ #define MAX_SERIAL_PORT_NUM 3 #define MAX_DEV_VALUE_NUM 12 /* 一台装置最大的采样值数量*/ #define WEATHER_PROTOCOL 1 /* 温湿度协议序号*/ #define WIND_PROTOCOL 2 /* 风速风向协议序号*/ #define SLANT_PROTOCOL 3 /* 倾斜角协议序号*/ #define RALLY_PROTOCOL 4 /* 拉力协议序号*/ #define PELCO_P_PROTOCOL 5 /* 摄像机Pelco_P协议序号*/ #define PELCO_D_PROTOCOL 6 /* 摄像机Pelco_D协议序号*/ #define SERIALCAMERA_PROTOCOL 8 /* 串口摄像机协议序号*/ #define RESERVE2_PROTOCOL 17 /* 备用2协议序号*/ #define RESERVE4_PROTOCOL 19 /* 备用4协议序号*/ #define RESERVE5_PROTOCOL 20 /* 备用5协议序号*/ #define INVALID_PROTOCOL 21 /* 无效协议序号*/ #define WEATHER_DATA_NUM 8 /* 气象数据最大数量(一般最多是6要素)*/ #define RALLY_DATA_NUM 2 /* 拉力数据最大数量(一般是1个)*/ #define SLANTANGLE_DATA_NUM 3 /* 倾角数据最大数量(一般只有X轴和Y轴值)*/ #define PTZ_MOVETIME 1 // 云台移动等待时间为1秒 #define MAX_CHANNEL_NUM 2 /* 视频通道最大通道*/ #define MAX_PHOTO_FRAME_LEN 256 /* 图片数据一包最大长度*/ #define RECVDATA_MAXLENTH 2048 /* 接收数据缓冲区最大值*/ #define TIMER_CNT 50 // Poll命令定时器时间 5 ms #define SENDDATA_MAXLENTH RECVDATA_MAXLENTH /* 正常发送数据缓冲区最大值*/ // 摄像机控制命令宏定义 #define Cmd_Cancel 0x00000000 // 关闭功能 #define SET_PRESETNO 0x00030000 // 设置预置点 #define MOVE_TO_PRESETNO 0x00070000 // 调用预置点 /* 摄像机PELCO-P控制命令宏定义*/ #define P_Auto_Scan 0x20000000 /* 自动扫描功能控制(1/0 打开/关闭该功能)*/ #define P_IRIS_CLOSE 0x08000000 /* 光圈缩小(1 有效)*/ #define P_IRIS_OPEN 0x04000000 /* 光圈放大(1 有效)*/ #define P_FOCUS_NEAR 0x02000000 /* 近距离聚焦(1 有效)*/ #define P_FOCUS_FAR 0x01000000 /* 远距离聚焦(1 有效)*/ #define P_ZOOM_WIDE 0x00400000 /* 远离物体(1 有效)*/ #define P_ZOOM_TELE 0x00200000 /* 接近物体(1 有效)*/ #define P_MOVE_DOWN 0x0010001f /* 向下移动镜头(1 有效)*/ #define P_MOVE_UP 0x0008001f /* 向上移动镜头(1 有效)*/ #define P_MOVE_LEFT 0x00041f00 /* 向左移动镜头(1 有效)*/ #define P_MOVE_RIGHT 0x00021f00 /* 向右移动镜头(1 有效)*/ // 摄像机PELCO-D控制命令宏定义 #define D_Auto_Scan 0x10000000 /* 自动扫描功能控制(1/0 打开/关闭该功能)*/ #define D_IRIS_CLOSE 0x04000000 /* 光圈缩小(1 有效)*/ #define D_IRIS_OPEN 0x02000000 /* 光圈放大(1 有效)*/ #define D_FOCUS_NEAR 0x01000000 /* 近距离聚焦(1 有效)*/ #define D_FOCUS_FAR 0x00800000 /* 远距离聚焦(1 有效)*/ #define D_ZOOM_WIDE 0x00400000 /* 远离物体(1 有效)*/ #define D_ZOOM_TELE 0x00200000 /* 接近物体(1 有效)*/ #define D_MOVE_DOWN 0x0010002d /* 向下移动镜头(1 有效)*/ #define D_MOVE_UP 0x0008002d /* 向上移动镜头(1 有效)*/ #define D_MOVE_LEFT 0x00042d00 /* 向左移动镜头(1 有效)*/ #define D_MOVE_RIGHT 0x00022d00 /* 向右移动镜头(1 有效)*/ #define SPEED_DOME_CAMERA 0 /* 球机摄像机*/ #define SERIAL_CAMERA 2 /* 串口摄像机a*/ #define LOGE(fmt, args...) __android_log_print(ANDROID_LOG_ERROR, "serial_port_comm", fmt, ##args) /* 红色*/ #define LOGI(fmt, args...) __android_log_print(ANDROID_LOG_INFO, "Sensors_Protocol", fmt, ##args) /* 草绿色*/ #define LOGV(fmt, args...) __android_log_print(ANDROID_LOG_VERBOSE, "serial_port_comm", fmt, ##args)/* 白色*/ #define LOGW(fmt, args...) __android_log_print(ANDROID_LOG_WARN, "Sensors_Protocol", fmt, ##args) /* 黄色*/ #define LOGD(fmt, args...) __android_log_print(ANDROID_LOG_DEBUG, "Sensors_Protocol", fmt, ##args) /* 蓝色*/ #define HexCharToInt( c ) (((c) >= '0') && ((c) <= '9') ? (c) - '0' : ((c) >= 'a') && ((c) <= 'f') ? (c) - 'a' + 10 :((c) >= 'A') && ((c) <= 'F') ? (c) - 'A' + 10 : 0 ) typedef struct { int cmd; int value; int result; long value2; char str[MAX_STRING_LEN]; }IOT_PARAM; //SDS包类型结构 typedef struct { BYTE PortIdx; // 信息类型 WORD MsgType; // 信息类型 int MsgLen; // 信息长度 u_char MsgData[RECVDATA_MAXLENTH]; } RTUMSG; typedef struct { //float fAiDead; // 数据变化死区(百分系数值,如:设置死区为5%,只需赋值5即可) float fFactor; // 数据系数 float EuValueDelta; // 数据工程值偏移 //BYTE Polar; // 数据极性(有无符号位) } AI_PARAM; typedef struct { AI_PARAM AiParam; // 数据点配置参数 BYTE AiState; // 遥测是否有效标识 float EuValue; // 遥测工程值 } AI_DEF; // 需要配置的串口装置参数 typedef struct { unsigned int baudrate; /* 波特率*/ int databit; /* 数据位*/ char stopbit[8]; /* 停止位*/ char parity; /* 校验位*/ char pathname[64]; /* 串口文件名及路径*/ int commid; /* 串口序号 注意:从0开始*/ u_char ProtocolIdx; /* 规约索引,大于 0*/ int devaddr; /* 装置使用的地址*/ u_char IsNoInsta; /* 装置没有安装或者已经坏了(1:正常, 0:无效,坏了或没有安装)*/ u_char CameraChannel; /* 像机的通道号*/ //u_char PowerPort; /* 传感器所接航空头编号*/ } SERIAL_PARAM; typedef struct { int m_iRevStatus; /* */ int m_iRecvLen; /* */ int m_iNeedRevLength; /* */ int iRecvTime; /* */ u_char m_au8RecvBuf[RECVDATA_MAXLENTH];/* */ int fd; /* 串口打开的文件句柄*/ u_char PollCmd[SENDDATA_MAXLENTH]; int cmdlen; // 发送缓冲区命令长度 //******************** Poll Cmd **************************** u_char Retry; /* 重试命令次数 */ u_char RetryCnt; /* 重试命令计数*/ u_long RetryTime; /* 重试命令时间 */ u_long RetryTimeCnt; /* 重试命令时间计数*/ u_long WaitTime; /* 命令间隔时间 */ u_long WaitTimeCnt; /* 命令间隔时间计数*/ u_char ForceWaitFlag; /* 强制等待标志*/ u_short ForceWaitCnt; /* 强制等待计数*/ u_char ReSendCmdFlag; /* 重发命令标志 */ u_char SendCmdFlag; /* 命令发送标志 */ u_char RevCmdFlag; /* 命令正常接收标志*/ //********************************************************** } SIO_PARAM_SERIAL_DEF; //串口相关装置所有参数集中定义 typedef struct { //******************** 端口基本信息 ************************ u_char IsNeedSerial; /* 是否需要使用串口通讯*/ int CmdWaitTime; /* 没有使用*/ u_char UseSerialidx; /* 使用的串口序号*/ int SerialCmdidx; /* 正在使用的串口发送命令的命令序号(-1:表示没有命令发送) 加密使用 0x00,生成初始向量IV(即生成随机数) 0x01,导入初始向量; 0x02,用对端SM2公钥加密随机数; 0x03,使用SM3 Hash报文数据; 0x04,使用SM2私钥签名; 0x05,使用SM2私钥解密对端随机数; 0x06,对安全因子进行认证; 0x0a,使用对端SM2公钥验签; 0x09,导入密钥DK(即导入对称密钥); 0x08,使用SM1加密; 0x0b,使用SM1解密; 0x0c,导出SM2公钥; 密钥协商过程: 1、请求0->2->c->3->3->4 2、对端应答5->a 3、确认6->3->9 数据加解密过程: 1、加密0->1->8 2、解密1->b*/ int enrecvtime; /* 发送加密命令后接收到应答计时*/ long FirstCmdTimeCnt; /* 串口读取数据起始时间*/ u_char nextcmd; /* 第二次发送读取气象雨量命令 加密使用: 0x00,无加密动作; 0x1X,密钥协商请求过程; 0x2X,密钥协商对端应答过程; 0x3X,密钥协商确认过程; 0x4X,数据加密过程; 0x5X,数据解密过程;*/ int m_iRevStatus; /* 接收数据缓冲区状态*/ int m_iRecvLen; /* 接收数据长度*/ int m_iNeedRevLength; /* 还需要接收的数据长度*/ int recvdatacnt; /* 接收到有效数据*/ u_char SameTypeDevIdx; /* 相同类型装置顺序排列序号(从0开始)*/ int iRecvTime; /* 最近一次收到数据的绝对时间*/ u_char uOpenPowerFlag; /* 传感器上电标志(0:不需要打开; 1:需要打开)*/ AI_DEF aiValue[MAX_DEV_VALUE_NUM]; /* 传感器采样值*/ } SERIAL_DEV_DEF; //串口相关装置所有参数集中定义 typedef struct { u_char uRunMode; /* 程序运行模式(0:正常运行模式;1:测试运行模式;)*/ u_char IsGprs; /* GPRS网络是否注册*/ u_char IsHexToAt; /* 串口1是否使用At指令(0:使用At指令;1:使用16进制数据传输)*/ u_char sampling[5]; /* 正在进行采样(0:没有进行采样;1:正在进行采样;)*/ u_char clcyesampling; /* 正在进行采样(0:没有进行采样;1:正在进行采样;)*/ u_char camerauseserial; /* 云台指令正在使用那个串口*/ DWORD PtzCmdType; /* 云台指令类型*/ int usecameradevidx; /* 有像机指令需要执行*/ /* 执行指令的装置序号(-1:表示没有需要执行的指令;)*/ int SendStopPtzCmdTimeCnt; /* 发送云台停止指令*/ u_char serialstatus[MAX_SERIAL_PORT_NUM]; /* 串口是否可以使用状态分别对应串口1、2、3*/ SERIAL_DEV_DEF ms_dev[MAX_SERIAL_DEV_NUM]; /* 装置所接传感器数量*/ int UseingSerialdev[MAX_SERIAL_PORT_NUM]; /* 正在使用串口通讯的装置序号(-1,表示串口空闲)*/ int curdevidx[MAX_SERIAL_PORT_NUM]; /* 当前正在通讯的装置序号(-1表示没有装置需要通讯)*/ u_char IsReadWireTem; /* 是否在开始读取测温数据(0:表示没有;1:是)*/ //int proruntime; /* 程序运行时间*/ int IsSleep; /* 是否使程序休眠(1:不休眠;2:休眠)*/ int tempsamplingstartime; /* 测温启动距离采样启动时间间隔*/ int tempsamplingsucctime; /* 测温启动距离采样成功时间间隔*/ int samplingtimeSec; /* 高速采样数据秒级时间控制*/ int SectimesamplingCnt[3]; /* 高速采样数据秒级采样数*/ int SunshineSensorsFault; /* 控制日照传感器故障发送*/ int TempSensorsFault; /* 控制测温传感器故障发送*/ int FirstSensorsFault; /* 第一次检测传感器故障发送*/ int SensorsIsUse; /* 传感器是否启用与自检位置匹配*/ int sequsampling; /* 顺序采样控制序号-1:无采样;其他对应相应装置序号*/ #if !SOUTHERN_POWER_GRID_V1 int SensorsFault; /*字节位从低到高温度、湿度、风速、风向、 气压、导线测温、日照、雨量、摄像头、拉力、倾角*/ int FlagSensorsFault; /*标志字节位从低到高温度、湿度、风速、风向、 气压、导线测温、日照、雨量、摄像头、拉力、倾角*/ #endif int imagepacketnum; /* 串口摄像机拍照图片总包数*/ int historyimagenum[MAX_CHANNEL_NUM]; /* 球机保存的历史图片数量*/ #if 1 //int sendflag; /* 临时上送泄露电流值标志*/ int sendphototime; /* 临时上送图片数据统计*/ int sendphotocmdcnt; /* 一次拍照过程中发送拍照指令计数*/ int photographtime; /* 图片拍摄的时间*/ int iLastGetPhotoNo; /* 设置串口摄像机参数时暂存拍照命令序号*/ #endif u_char errorPhotoNoCnt; /* 串口摄像机拍照时回应错误包号计数(如:召第6包回应第3包)*/ u_char RephotographCnt; /* 串口摄像机重拍计数(只在读照片数据应答出错时才重拍)*/ int restartflag; /* 升级重启标识*/ int selfflag; /* 是否检测传感器故障和关闭485电源标志*/ BYTE bEncryptstate; /* 加密状态 0:加密协商过程;1:加密协商完成; 2:明文协商过程;3:明文协商完成*/ #if ENCRYPTION_CHIP CERTIFICATE cert; /* 本端证书*/ BYTE Randomnumber[18]; /* 临时存储加密芯片产生的随机数据*/ BYTE KeyRandonum[18]; /* 临时存储对端的随机数据及会话密钥DK*/ BYTE Sm2publickey[64]; /* 临时存储本端Sm2公钥*/ BYTE Sm2encrypt[128]; /* 临时存储使用本端Sm2公钥加密后的数据*/ BYTE Sm3hashdata[32]; /* 临时存储Sm3 Hash后数据*/ BYTE Safetycertification[32];/* 临时存储安全认证因子*/ char ticr[64]; /* 临时存储证书请求的主题信息*/ WORD wframeno; /* 帧序号*/ BYTE encry_chipstate; /* 加密芯片复位状态*/ int enchipstartnum; /* 加密芯片复位次数*/ #endif } SRDT_DEF; static void PortDataProcess( void ); static long get_msec(); int serial_port_comm(); static int weather_comm(SERIAL_PARAM weatherport); static void setRS485Enable(bool z); static void set485WriteMode(); static void set485ReadMode(); static void set12VEnable(bool z); static void setCam3V3Enable(bool enabled); // 串口相关的所有函数定义 /* 打开串口电源*/ void Gm_OpenSerialPower(void); // 打开传感器电源 void Gm_OpenSensorsPower(int port); // 关闭传感器电源 void Gm_CloseSensorsPower(int port); // 打开串口通讯 void Gm_OpenSerialPort(int devidx); // 关闭串口通讯 void Gm_CloseSerialPort(void); // 功能说明:串口发送数据 返回实际发送的字节数 WORD GM_SerialComSend(const unsigned char * cSendBuf, unsigned long nSendLen, int commid); // 启动串口通讯 void GM_StartSerialComm(void); // 启动使用串口拍照 void GM_StartSerialCameraPhoto(BYTE channel, int cmdidx); // 串口轮询通讯定时器 int GM_SerialTimer(void); //轮询所有串口和传感器是否需要生成下发命令 void Gm_FindAllSensorsCommand(void); //检查所有传感器是否采集完毕,采集完毕的关闭传感器电源 void GM_IsCloseSensors(void); //检查所有串口是否有数据接收,有则启动接收 void GM_AllSerialComRecv(void); //判断是否需要关闭定时器 int GM_CloseTimer(void); // 串口接收数据处理 void SerialDataProcess(int devidx, u_char *buf, int len); // 串口摄像机数据处理 void CameraPhotoPortDataProcess( int port); // 发送命令 void SendCmdFormPollCmdBuf( int port ); // 清除发送命令的所有标识 void ClearCmdAllFlag(int commid); // 下发串口拍照指令控制 int FindNextCameraPhotoCommand(int devidx); // 生成 CameraPhoto命令 void MakeCameraPhotoCommand( int portno, BYTE cmdidx, int OneParam, WORD TwoParam, BYTE Threep ); // 清除命令缓冲区 void ClearCmdFormPollCmdBuf(int port); // 准备发送云台指令 int Gm_CtrlPtzCmd(u_char channel, DWORD ptzcmd); // 发送转动摄像机云台命令定时器 int Gm_Camera_Timer(void); // 生成 PELCO_P 命令 * void Gm_SendPelco_pCommand( DWORD cmdtype); // 计算Pelco_p校验 BYTE Gm_Pelco_pXORCheck( BYTE *msg, int len ); // 生成 PELCO_D 命令 * void Gm_SendPelco_DCommand( DWORD cmdtype); // 计算Pelco_D校验 BYTE Gm_Pelco_DCheck( BYTE *msg, int len ); // 查询传感器电源状态 char Gm_GetSensorsPowerState(int port); // 通过传感器使用的航空头查找传感器使用的串口序号 void FindDevUseSerialCommNo(void); // 初始化所有串口及所接传感器的配置 void Gm_InitSerialComm(void); // 寻找并生成下一条倾角命令 int FindNextShxyProtocolCommand( int devidx ); // 倾角命令校验码计算 unsigned char CalLpc(unsigned char *msg, int len); // 读上海欣影传感器协议数据 void ShxyProtocolRecvData(int commid, u_char *buf, int len); // 检查检验和是否正确 int CheckShxyProtocolLpcError( u_char* msg, int len ); // 把16进制和10进制ASCII字符串转换成int整数 int ATOI(char *buf); //生成倾角命令 void MakeShxyProtocolPollCommand(int portno, BYTE cmdidx); // 上海欣影传感器协议数据处理 void ShxyProtocolDataProcess( int commid); // 控制关闭传感器电源 //void Gm_CtrlCloseSensorsPower(int devidx); // 检查传感器电源是否应该关闭或打开 //void Gm_CheckSensorsPower(void); int Gm_SetSerialPortBaud(int commid); // 得到串口波特率 //T_baudrate Gm_GetSerialPortBaud(UART_baudrate Baudrate); void Gm_CloseSerialCamera(void); // 生成一个随机整数 int GeneratingRandomNumber(void); #endif //WEATHERCOMM_H