CSM315Protocol.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457
  1. #ifndef C315_PROTOCOL_H
  2. #define C315_PROTOCOL_H
  3. #pragma once
  4. #include "GlobalHead.h"
  5. #include "AlarmDefine.h"
  6. #include <set>
  7. #include <vector>
  8. #pragma pack(push, 1)
  9. #define FRAME_HEADER_315 "qknet" //帧头
  10. #define FRAME_TYPE_HEARTBEAT 0x0F //心跳帧
  11. #define FRAME_TYPE_DATA 0x8F //数据帧
  12. #define FRAME_TAIL_315 0xFFFFFFFF //帧尾
  13. //与JHD系统的通信协议
  14. #define PROTOCAL_CODE 0x02 //协议码
  15. #define PROTOCAL_DATAVERSION 0x01 //数据版本
  16. //命令帧 应答帧 主动上送帧 回执帧等
  17. enum FRAME_KIND {
  18. CMD = 0,
  19. RECV,
  20. SEND,
  21. BACK,
  22. GENERAL
  23. };
  24. //scz 2022.11.09 新增 待补全
  25. enum class E_315_PROTOCOL_TYPE : uint8_t
  26. {
  27. ACTIVE_KEEP = 0, //心跳包
  28. E_315_PROTOCOL_0x23 = 0x23, //缺口配置 道岔缺口
  29. E_315_PROTOCOL_0x26 = 0x26, //道岔缺口数值
  30. E_315_PROTOCOL_0x27 = 0x27, //道岔缺口报警、预警及图像视频信息
  31. E_315_PROTOCOL_0x29 = 0x29, //道岔缺口最新图像
  32. E_315_PROTOCOL_0x32 = 0x32, //历史图像信息列表
  33. E_315_PROTOCOL_0x2A = 0x2A, //历史图像信息
  34. E_315_PROTOCOL_0x2E = 0x2E, //视频信息列表
  35. E_315_PROTOCOL_0x2F = 0x2F, //视频文件
  36. E_315_PROTOCOL_0x22 = 0x22, //1DQJ、区段状态信息
  37. E_315_PROTOCOL_0x25 = 0x25, //油压曲线
  38. E_315_PROTOCOL_0x24 = 0x24, //油位及缺口采集设备状态信息
  39. E_315_PROTOCOL_0x30 = 0x30, //视频流信息
  40. E_315_PROTOCOL_0x31 = 0x31, //请求命令时转辙机的定反位状态
  41. //E_315_PROTOCOL_0x40 = 0x40, //全行程受力信息 全行程子系统占用
  42. //E_315_PROTOCOL_0x41 = 0x41, //全行程最新值
  43. //E_315_PROTOCOL_0x42 = 0x42, //服务端回执主动推送的全行程最新值.
  44. //E_315_PROTOCOL_0x43 = 0x43, //全行程预报警信息
  45. //E_315_PROTOCOL_0x44 = 0x44, //服务端回执主动推送预报警信息
  46. //E_315_PROTOCOL_0x45 = 0x45, //测试历史数据
  47. //E_315_PROTOCOL_0x46 = 0x46, //查询曲线时间信息
  48. //E_315_PROTOCOL_0x47 = 0x47, //查询曲线数据
  49. //E_315_PROTOCOL_0x48 = 0x48, //服务端回执主动推送曲线数据
  50. E_315_PROTOCOL_0x50 = 0x50, //受力配置信息 受力监测子系统
  51. E_315_PROTOCOL_0x51 = 0x51, //受力最新值
  52. E_315_PROTOCOL_0x52 = 0x52, //服务端回执主动推送的受力最新值
  53. E_315_PROTOCOL_0x53 = 0x53, //受力预报警信息
  54. E_315_PROTOCOL_0x54 = 0x54, //服务端回执主动推送预报警信息
  55. E_315_PROTOCOL_0x55 = 0x55, //测试历史数据
  56. E_315_PROTOCOL_0x56 = 0x56, //查询曲线时间信息
  57. E_315_PROTOCOL_0x57 = 0x57, //查询曲线数据
  58. E_315_PROTOCOL_0x58 = 0x58, //服务端回执主动推送曲线数据
  59. //E_315_PROTOCOL_0x60 = 0x60, //框架配置信息 道岔框架系统
  60. //E_315_PROTOCOL_0x61 = 0x61, //框架最新值
  61. //E_315_PROTOCOL_0x62 = 0x62, //服务端回执主动推送的框架最新值
  62. //E_315_PROTOCOL_0x63 = 0x63, //框架预报警信息
  63. //E_315_PROTOCOL_0x64 = 0x64, //服务端回执主动推送预报警信息
  64. //E_315_PROTOCOL_0x65 = 0x65, //测试历史数据
  65. //E_315_PROTOCOL_0x66 = 0x66, //查询曲线时间信息
  66. //E_315_PROTOCOL_0x67 = 0x67, //查询曲线数据
  67. //E_315_PROTOCOL_0x68 = 0x68, //服务端回执主动推送曲线数据
  68. };
  69. //协议头
  70. typedef struct CPTL_Head
  71. {
  72. BYTE sHead[5]; //帧头5B
  73. BYTE byProtocolCode; //协议码1B
  74. BYTE byDataVersion; //数据版本1B
  75. BYTE byFrameType; //帧类型1B
  76. DWORD dwFrameLen; //帧内容长度4B
  77. }CPTL_HEAD, * PCPTL_HEAD;
  78. enum class TIEDA_VAL_STATE : uint8_t
  79. {
  80. TVS_POLL = 0x00,//为轮询值,日常采集
  81. TVS_MOVEING = 0x01,//扳动过程采集值
  82. TVS_AFTER_MOVE = 0x02, //为扳动后采集值
  83. TVS_PASSING = 0x03, //过车过程中采集值
  84. TVS_AFTER_PASS = 0x04, //过车后采集值
  85. };
  86. enum class TIEDA_VAL_SYMBOL : uint8_t
  87. {
  88. TVS_POSITIVE_NUMBER = 0x00,
  89. TVS_MINUS_NUMBER = 0x01,
  90. };
  91. //铁大采集值
  92. /*
  93. 采用3字节定义一个采集值,D0~D15:采集数值,D16~D19:采集精度,D20~D22:值状态,D23:值正负。
  94. 采集精度:1=表示精度为1,即采集数值为实际的采集值.
  95. 2=表示精度为10,表示采集数值为实际采集值*10.
  96. 3=表示精度为100,表示表示采集数值为实际采集值*100.
  97. 4=表示精度为1000,表示表示采集数值为实际采集值*1000.
  98. 5=表示精度为0.1,表示表示采集数值为实际采集值/10.
  99. 6=表示精度为0.01,表示表示采集数值为实际采集值/100.
  100. 7=表示精度为0.001,表示表示采集数值为实际采集值/1000.
  101. 值状态:0=表示为轮询值,日常采集
  102. 1=表示扳动过程采集值
  103. 2=表示为扳动后采集值
  104. 3=表示过车过程中采集值
  105. 4=表示过车后采集值
  106. 值正负:0=正值
  107. 1=负值.
  108. 0xFFFFFF表示无效值,采集传感器故障、超量程异常、通讯丢失等;
  109. 当处于某状态时(例如扳动中,此时缺口值无效),状态值为1,精度不变,采集值填0xFFFF,表示在该状态下,采集值无意义;
  110. 例如: 采集值 byte val[3]={ 0x81,0x00,0x23}; 表示采集值为0x0081, 精度为3(100),状态为2(扳动后),正负为0(正值),实际值为(1.29f);
  111. 采集值 byte val[3]={ 0x81,0x00,0xA5}; 表示值为0x0081, 精度为5(0.1),状态为2(扳动后),正负为1(负值),实际值为-1290;*/
  112. union TIEDA_ACQ_VALUE
  113. {
  114. //uint8_t value[3];
  115. struct {
  116. uint16_t v; //值 默认 实际采集值/10
  117. uint8_t precision : 4; //精度 默认5
  118. TIEDA_VAL_STATE state : 3; //状态
  119. TIEDA_VAL_SYMBOL symbol : 1; //符号
  120. };
  121. TIEDA_ACQ_VALUE(int32_t a, TIEDA_VAL_STATE b, uint8_t d = 5)
  122. {
  123. symbol = TIEDA_VAL_SYMBOL::TVS_POSITIVE_NUMBER;
  124. if (a <= -INVLID_VAL || a >= INVLID_VAL)
  125. {
  126. v = USHORT_MAX;
  127. }
  128. else if (a < 0)
  129. {
  130. a = -a;
  131. symbol = TIEDA_VAL_SYMBOL::TVS_MINUS_NUMBER;
  132. }
  133. precision = d;
  134. if (d == 5)
  135. v = a / 10;
  136. else
  137. v = a;
  138. state = b;
  139. }
  140. TIEDA_ACQ_VALUE(int a)
  141. {
  142. if (a == INT_MIN)
  143. memset(this, 0xff, 3);
  144. }
  145. TIEDA_ACQ_VALUE()
  146. {
  147. v = 0;
  148. precision = 5;
  149. state = TIEDA_VAL_STATE::TVS_POLL;
  150. symbol = TIEDA_VAL_SYMBOL::TVS_POSITIVE_NUMBER;
  151. }
  152. float tovalue()
  153. {
  154. BYTE* val = (BYTE*)this;
  155. if (val[0] == 0xFF && val[1] == 0xFF && val[2] == 0xFF)
  156. return INT_MIN;
  157. float n = v;
  158. if (symbol == TIEDA_VAL_SYMBOL::TVS_MINUS_NUMBER) n *= -1;
  159. switch (precision)
  160. {
  161. case 2:
  162. n /= 10.0;
  163. break;
  164. case 3:
  165. n /= 100.0;
  166. break;
  167. case 4:
  168. n /= 1000.0;
  169. break;
  170. case 5:
  171. n *= 10.0;
  172. break;
  173. case 6:
  174. n *= 100.0;
  175. break;
  176. case 7:
  177. n *= 1000.0;
  178. break;
  179. default:
  180. break;
  181. }
  182. return n;
  183. }
  184. string tostring()
  185. {
  186. float n = tovalue();
  187. if (n == INT_MIN)
  188. return "无效值";
  189. string msg;
  190. switch (state)
  191. {
  192. case TIEDA_VAL_STATE::TVS_POLL:
  193. msg = "日常采集:";
  194. break;
  195. case TIEDA_VAL_STATE::TVS_MOVEING:
  196. msg = "扳动过程采集:";
  197. break;
  198. case TIEDA_VAL_STATE::TVS_AFTER_MOVE:
  199. msg = "扳动后采集:";
  200. break;
  201. case TIEDA_VAL_STATE::TVS_PASSING:
  202. msg = "过车中采集:";
  203. break;
  204. case TIEDA_VAL_STATE::TVS_AFTER_PASS:
  205. msg = "过车后采集:";
  206. break;
  207. default:
  208. break;
  209. }
  210. msg += to_string(n);
  211. return msg;
  212. }
  213. };
  214. //道岔缺口配置信息(315) 命令码:0x23
  215. typedef struct
  216. {
  217. BYTE cmdid; //命令码:0x23
  218. WORD cfgcnt; //配置数
  219. LPVOID lpcfg; //转辙机配置i
  220. }StGapCfgRes;
  221. //转辙机配置
  222. typedef struct
  223. {
  224. BYTE nlen; //转辙机名称长度
  225. LPSTR lpname; //转辙机名称
  226. BYTE stype; //转辙机类型
  227. WORD sid; //转辙机ID
  228. WORD cnt; //采集信息个数
  229. LPWORD lpinfo; //采集信息类型
  230. }StSwitchCfg;
  231. //道岔缺口配置信息 end
  232. //曲线信息
  233. typedef struct
  234. {
  235. BYTE cmdid; //命令码:0x46/0x56/0x66
  236. DWORD starttime; //开始时间
  237. DWORD endtime; //结束时间
  238. WORD cnt; //牵引点数目
  239. LPVOID lpcfg; //牵引点配置
  240. }StCurveCfgRes;
  241. //配置
  242. typedef struct
  243. {
  244. WORD sid; //转辙机ID
  245. }StTractionCfg;
  246. //配置
  247. typedef struct
  248. {
  249. WORD sid; //转辙机ID
  250. WORD cnt; //记录数目
  251. LPVOID lpcrecord;//记录
  252. }StTractionCfg1;
  253. //配置
  254. typedef struct
  255. {
  256. DWORD time; //结束时间
  257. }StTractionCfg11;
  258. //配置信息 end
  259. //配置信息
  260. typedef struct
  261. {
  262. BYTE cmdid; //命令码:0x40/0x50/0x60
  263. WORD cnt; //配置个数
  264. LPVOID lpcfg; //配置信息
  265. }StNodeCfgRes;
  266. typedef struct
  267. {
  268. BYTE namelen; //牵引点名称长度
  269. LPSTR lpname; //牵引点名称
  270. WORD sid; //牵引点ID
  271. BYTE cnt; //采集信息个数
  272. WORD lpinfo[0]; //采集信息类型
  273. }StNodeInfo;
  274. //配置
  275. typedef struct
  276. {
  277. WORD acqTypeID; //采集信息类型码
  278. }StNodeAcqCfg;
  279. struct NodeConfig
  280. {
  281. CString strNodeName;
  282. WORD wNodeID;
  283. std::vector<WORD> vecAcqTypeID;
  284. };
  285. struct NodeRealData
  286. {
  287. DWORD dwAcqTime;
  288. WORD wNodeID;
  289. BYTE byFixInvert; //定反位
  290. std::vector<WORD> vecAcqTypeID;
  291. std::vector<BYTE> vecStatus;
  292. std::vector<int> vecAcqData;
  293. };
  294. struct stQueryAlarm
  295. {
  296. BYTE cmdid; //命令码:0x43/0x53/0x63
  297. DWORD starttime; //开始时间
  298. DWORD endtime; //结束时间
  299. WORD wNodeID; //牵引点ID =0xffff时表示查询所有设备
  300. WORD wAlarmType; //报警类型 =0xffff时表示查询所有报警
  301. };
  302. struct stAlarmItem
  303. {
  304. WORD wNodeID;
  305. BYTE byAlarmType; //报警状态
  306. DWORD time; //报警时间
  307. DWORD dwRestoreTime; //恢复时间
  308. WORD wAlarmType; //报警类型
  309. //BYTE cbAlarmValue[3];//报警值
  310. TIEDA_ACQ_VALUE sAlarmValue; //报警值
  311. //BYTE cbRefValue[3]; //参考值
  312. TIEDA_ACQ_VALUE sRefValue; //参考值
  313. WORD wSuggestID; //维护建议ID
  314. };
  315. //配置
  316. struct stQueryHisDataItem
  317. {
  318. WORD wNodeID; //牵引点ID
  319. WORD acqTypeID; //采集信息类型码
  320. };
  321. struct stQueryHisData
  322. {
  323. BYTE cmdid; //命令码:0x45/0x55/0x65
  324. DWORD starttime; //开始时间
  325. DWORD endtime; //结束时间
  326. WORD cnt; //数量
  327. WORD lpinfo[0]; //采集信息类型
  328. };
  329. struct stQueryHisCurveList
  330. {
  331. BYTE cmdid; //命令码:0x46/0x56/0x66
  332. DWORD starttime; //开始时间
  333. DWORD endtime; //结束时间
  334. WORD cnt; //数量
  335. WORD lpinfo[0]; //采集信息类型
  336. };
  337. struct stQueryHisCurve
  338. {
  339. BYTE cmdid; //命令码:0x46/0x56/0x66
  340. WORD wNodeID; //牵引点ID
  341. DWORD time; //时间
  342. };
  343. struct stHisStaticValue
  344. {
  345. DWORD dwStartTime; //起始时间
  346. std::vector<std::pair<WORD, int>> vctAcqData;
  347. };
  348. //心跳数据
  349. typedef struct
  350. {
  351. DWORD hbtime; //时间: 4B的unix时间用于时钟同步
  352. BYTE filldata[3]; //填充3个字节的0xFF
  353. }StHeartBeat315;
  354. #pragma pack(pop)
  355. typedef std::map<time_t, int> MapTimeInt;
  356. typedef MapTimeInt::iterator MapTimeIntItor;
  357. class CCSM315Protocol
  358. {
  359. public:
  360. CCSM315Protocol(int nDataVersion/*CLinkAdmin* pLinkAdmin, const char* strLogName*/);
  361. virtual ~CCSM315Protocol();
  362. static void InitFrmHead12B(BYTE* pBuf, BYTE frmtype, BYTE datVer);
  363. static void InitFrmHead12B(CPTL_HEAD* pHead, BYTE frmtype, BYTE datVer);
  364. static void InitFrmHead12B(C315CommData& CommData, BYTE frmtype, BYTE datVer);
  365. //buf:缓冲区 size:缓冲区大小 len:取出的数据长度
  366. static BOOL GetFrameData(LPBYTE& buf, int& size, int& len);
  367. static std::string GetStrFromData(const BYTE* buf, int dwLen);
  368. public:
  369. static E_315_PROTOCOL_TYPE GetProtocolType(BYTE* pBuf, WORD wDataSize);
  370. static BOOL IsReceiptProtocol(E_315_PROTOCOL_TYPE e);
  371. static BOOL GetResendProtocol(E_315_PROTOCOL_TYPE e, int& nReSendCount, int& nReSendInterval);
  372. public:
  373. static BOOL Parse(StHeartBeat315&, LPVOID, int);
  374. //接收解析
  375. public:
  376. static BOOL RecvParse(StGapCfgRes& data, LPVOID buf, int len);
  377. static BOOL RecvParse(StCurveCfgRes& data, LPVOID buf, int len, FRAME_KIND&e);
  378. //组装数据
  379. public:
  380. static BOOL DataSerialize(BYTE byProtocalCMD, const std::vector<NodeConfig>& vecConfig, C315CommData& CommData);
  381. static BOOL DataSerialize(BYTE byProtocalCMD, const std::vector<NodeRealData>& vecConfig, C315CommData& CommData);
  382. static BOOL DataSerialize(BYTE byProtocalCMD, bool bPush,
  383. WORD wEqpNO, BYTE byFixOrNot, const std::vector<WORD>& vctAcqType,
  384. const std::vector<TIEDA_ACQ_VALUE>& vctData, const std::vector<BYTE>& vctStatus,
  385. const CTime& atime, C315CommData& CommData);
  386. //static BOOL DataSerialize(BYTE byProtocalCMD, bool bPush, int no,
  387. // WORD wIdx, int num, const std::vector<int>& vctData0,
  388. // const std::vector<int>& vctData1, const std::vector<int>& vctData2,
  389. // DWORD atime, C315CommData& CommData);
  390. //static BOOL DataSerialize(BYTE byProtocalCMD, BYTE byFixOrNot, bool bPush, int no, WORD wEqpNO, int num,
  391. // const MapTimeIntItor& map00, const MapTimeIntItor& map01,
  392. // const MapTimeIntItor& map10, const MapTimeIntItor& map11,
  393. // const MapTimeIntItor& map20, const MapTimeIntItor& map21,
  394. // time_t time, C315CommData& CommData);
  395. static BOOL DataSerialize(BYTE byProtocalCMD, BYTE byFixOrNot, bool bPush, int no, WORD wEqpNO, int num,
  396. std::map<time_t, int>* mapData[], time_t tmStartSecond, time_t tmEndSecond, C315CommData& CommData);
  397. static BOOL DataSerialize(BYTE byProtocalCMD, bool bPush, int no, const std::vector<stAlarmItem>& vctAlarm, C315CommData& CommData);
  398. static BOOL DataSerialize(BYTE byProtocalCMD, const std::map<WORD, std::vector<DWORD>>& mapData, C315CommData& CommData);
  399. ////first:makelong(牵引点, 采集码) second.first:采集时间 vector:采集数据列表 pair:偏移时间和采集值
  400. static BOOL DataSerialize(BYTE byProtocalCMD, const std::map<DWORD, stHisStaticValue>& mapData, C315CommData& CommData);
  401. public:
  402. static BOOL Release(StGapCfgRes&);
  403. static BOOL Release(StCurveCfgRes&, FRAME_KIND& e);
  404. private:
  405. static int m_CSMCmdRegion_DataVersion;
  406. };
  407. #endif // !C315_PROTOCOL_H