ps.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427
  1. #include "ps.h"
  2. #include "maindlg.h"
  3. static quint16 s_crc_table[16] = {0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef};
  4. //构造函数
  5. Ps::Ps(QObject *parent)
  6. : QObject{parent}
  7. {
  8. m_pMainDlg = static_cast<MainDlg*>(parent);//保存主窗口指针
  9. memset(&m_stDataBuf, 0, sizeof(PS_DATA_BUF_T));
  10. PsInit();//模块初始化
  11. }
  12. //初始化协议栈
  13. void Ps::PsInit(){
  14. m_byPacketNo = 100;
  15. memset(m_abyPsBuf, 0, sizeof(quint8)*PS_FRAME_MAX_LEN);
  16. memset(m_abyTempData, 0, sizeof(quint8)*PS_FRAME_MAX_LEN);
  17. m_wListLen = 0;
  18. QObject::connect(this, this->PsUlRespSignalQueryOk, m_pMainDlg, &m_pMainDlg->PsUlRespSignaQueryOkSlot);
  19. QObject::connect(this, this->PsUlRespSignalQueryFail, m_pMainDlg, &m_pMainDlg->PsUlRespSignaQueryFailSlot);
  20. QObject::connect(this, this->PsUlRespSignalConfigOk, m_pMainDlg, &m_pMainDlg->PsUlRespSignalConfigOkSlot);
  21. QObject::connect(this, this->PsUlRespSignalConfigFail, m_pMainDlg, &m_pMainDlg->PsUlRespSignalConfigFailSlot);
  22. QObject::connect(this, this->PsUlRespSignalUpgradeSuccess, m_pMainDlg, &m_pMainDlg->PsUlRespSignalUpgradeOkSlot);
  23. QObject::connect(this, this->PsUlRespSignalUpgradeFail, m_pMainDlg, &m_pMainDlg->PsUlRespSignalUpgradeFailSlot);
  24. }
  25. //从串口接收数据
  26. //bydataList:数据队列
  27. //wLen:数据队列长度
  28. quint8 Ps::PsReceiveData(QByteArray bydataList, quint16 wLen){
  29. quint8 byFlag = 0;
  30. quint8 byData = 0;
  31. quint16 wListLen = 0;
  32. quint16 wConsumeIndex = 0;
  33. quint16 wCounter = 0;
  34. quint8 byHeadTailFlag = 0;
  35. //按帧缓存数据
  36. for(quint16 i = 0; i < wLen; i++){
  37. byData = bydataList.at(i);
  38. if(byData == PS_AP_HEAD_FLAG){
  39. if(!m_stDataBuf.byHeadFlag){
  40. m_stDataBuf.byHeadFlag = 1;
  41. m_stDataBuf.byTailFlag = 0;
  42. m_stDataBuf.wFrameHeadIndex = m_stDataBuf.wGenerateIndex;//保存帧头
  43. }else{
  44. m_stDataBuf.byTailFlag = 1;
  45. }
  46. m_stDataBuf.abyDataList[m_stDataBuf.wGenerateIndex] = byData;
  47. m_stDataBuf.wGenerateIndex++;
  48. m_stDataBuf.wListLen++;
  49. if(m_stDataBuf.wGenerateIndex>= PS_FRAME_MAX_LEN){
  50. m_stDataBuf.wGenerateIndex = 0;
  51. }
  52. }else{
  53. if(m_stDataBuf.byHeadFlag){
  54. m_stDataBuf.abyDataList[m_stDataBuf.wGenerateIndex] = byData;
  55. m_stDataBuf.wGenerateIndex++;
  56. m_stDataBuf.wListLen++;
  57. if(m_stDataBuf.wGenerateIndex>= PS_FRAME_MAX_LEN){
  58. m_stDataBuf.wGenerateIndex = 0;
  59. }
  60. }else{
  61. byFlag = 0;
  62. }
  63. }
  64. }
  65. //缓存中没有一帧完整的数据
  66. if(!m_stDataBuf.byHeadFlag || !m_stDataBuf.byTailFlag){
  67. return 0;
  68. }
  69. //抽取数据帧
  70. wListLen = m_stDataBuf.wListLen;
  71. wConsumeIndex = m_stDataBuf.wFrameHeadIndex;
  72. while(byHeadTailFlag<2){
  73. byData = m_stDataBuf.abyDataList[wConsumeIndex];
  74. if(byData == PS_AP_HEAD_FLAG){
  75. byHeadTailFlag++;
  76. m_abyPsMsg[wCounter] = byData;
  77. wCounter++;
  78. }else{
  79. if(byHeadTailFlag==1){
  80. m_abyPsMsg[wCounter] = byData;
  81. wCounter++;
  82. }
  83. }
  84. wConsumeIndex++;
  85. if(wConsumeIndex >= PS_FRAME_MAX_LEN){
  86. wConsumeIndex = 0;
  87. }
  88. }
  89. m_stDataBuf.wConsumeIndex = wConsumeIndex;
  90. m_stDataBuf.wListLen -= wCounter;
  91. m_stDataBuf.byHeadFlag = 0;
  92. m_stDataBuf.byTailFlag = 0;
  93. //把该帧数据发送给协议栈上行主控单元
  94. byFlag = PsUlMain(m_abyPsMsg, wCounter);
  95. if(!byFlag){
  96. memset(m_abyPsMsg, 0, PS_FRAME_MAX_LEN);
  97. return 0;
  98. }
  99. memset(m_abyPsMsg, 0, PS_FRAME_MAX_LEN);
  100. return 1;
  101. }
  102. //协议栈上行主模块
  103. quint8 Ps::PsUlMain(quint8 *pbyData, quint16 wLen){
  104. quint8 byFlag = 0;
  105. quint16 wNewLen = wLen;
  106. PS_HEAD_T *pstHead = (PS_HEAD_T*)pbyData;
  107. quint8 *pbyPayload = NULL;
  108. //AP层处理
  109. byFlag = PsUlAp(pbyData, &wNewLen);
  110. if(!byFlag){
  111. return 0;
  112. }
  113. pbyPayload = (quint8*)(pbyData + sizeof(PS_HEAD_T));
  114. //VP层解析
  115. if (MCP_A == pstHead->stVpHead.byMcpType){ // MCP-A
  116. switch (pstHead->stVpHead.byVpFlag){
  117. case (quint8)VP_RESP: //应答
  118. //判断是查询应答还是设置应答
  119. if(pstHead->stMcpHead.byComd == (quint8) MCP_A_QUERY){//查询应答
  120. if(pstHead->stMcpHead.byResp == (quint8)MCP_RESP_SUCC){//查询成功
  121. emit PsUlRespSignalQueryOk(pbyPayload, (wNewLen - PS_FRAME_MIN_LEN));
  122. }else{//查询失败
  123. emit PsUlRespSignalQueryFail();
  124. }
  125. }else if(pstHead->stMcpHead.byComd == (quint8) MCP_A_CONFIGURE){//设置应答
  126. if(pstHead->stMcpHead.byResp == (quint8)MCP_RESP_SUCC){//设置成功
  127. emit PsUlRespSignalConfigOk(pbyPayload, (wNewLen - PS_FRAME_MIN_LEN));
  128. }else{//设置失败
  129. emit PsUlRespSignalConfigFail();
  130. }
  131. }
  132. break;
  133. default:
  134. byFlag = 0;
  135. break;
  136. }
  137. }
  138. else if (MCP_B == pstHead->stVpHead.byMcpType){// MCP-B(设备在线升级)
  139. switch (pstHead->stVpHead.byVpFlag){
  140. case (quint8)VP_RESP: //应答
  141. if(pstHead->stMcpHead.byResp == (quint8)MCP_RESP_SUCC){//应答成功
  142. emit PsUlRespSignalUpgradeSuccess(pbyPayload);
  143. }else{//应答失败
  144. emit PsUlRespSignalUpgradeFail();
  145. }
  146. break;
  147. default:
  148. byFlag = 0;
  149. break;
  150. }
  151. byFlag = 1;
  152. }
  153. else{ // 监控控制层协议类型错误
  154. byFlag = 0;
  155. }
  156. return 1;
  157. }
  158. //AP层处理主函数
  159. //pbyData:数据
  160. //wLen:数据长度
  161. quint8 Ps::PsUlAp(quint8 *pbyData, quint16 *pwLen){
  162. quint8 byFlag = 0;
  163. PS_HEAD_T *pstPsHead = (PS_HEAD_T*)pbyData;//帧头
  164. PS_TAIL_T *pstPsTail = NULL;//帧尾
  165. quint16 wNewLen = *pwLen;
  166. quint16 wCrc = 0;
  167. //判断帧头
  168. if(pstPsHead->stApHead.byStartFlag != PS_AP_HEAD_FLAG){
  169. return 0;
  170. }
  171. //转义逆向处理
  172. byFlag = psApTransferReverse(pbyData, &wNewLen);
  173. if(!byFlag){
  174. return byFlag;
  175. }
  176. //判断帧头
  177. pstPsTail = (PS_TAIL_T*)(pbyData + (wNewLen - 3));//帧尾
  178. if(pstPsTail->byStopFlag != PS_AP_TAIL_FLAG){
  179. return 0;
  180. }
  181. //检查CRC校验
  182. wCrc =PsApGenCrc16((pbyData+1), (wNewLen - 4), 0);
  183. if(pstPsTail->wCRC != wCrc){
  184. return 0;
  185. }
  186. *pwLen = wNewLen;//队列长度
  187. return 1;
  188. }
  189. // 对数据进行转义处理
  190. // pbyData: 待转义数据
  191. // wLen: 数据长度
  192. quint8 Ps::psApTransfer(quint8 *pbyData, quint16 *wLen)
  193. {
  194. quint16 i = 0;
  195. quint16 wCounter = 0;
  196. // 转移处理
  197. memset(m_abyTempData, 0, PS_FRAME_MAX_LEN);
  198. for (i = 1; i < (*wLen - 1); i++)
  199. {
  200. if (0x5E == pbyData[i]) // 将0x5E转义成0x5E,0x5D
  201. {
  202. m_abyTempData[wCounter] = 0x5E;
  203. wCounter++;
  204. m_abyTempData[wCounter] = 0x5D;
  205. wCounter++;
  206. }
  207. else if (0x7E == pbyData[i]) // 将0x7E转义成0x5,E0x7D
  208. {
  209. m_abyTempData[wCounter] = 0x5E;
  210. wCounter++;
  211. m_abyTempData[wCounter] = 0x7D;
  212. wCounter++;
  213. }
  214. else // 其它字符直接拷贝,不做转义处理
  215. {
  216. m_abyTempData[wCounter] = pbyData[i];
  217. wCounter++;
  218. }
  219. // 长度超长
  220. if ((wCounter + 2) > PS_FRAME_MAX_LEN)
  221. {
  222. return 0;
  223. }
  224. }
  225. // 将数据拷贝回pbyData中
  226. for (i = 0; i < wCounter; i++)
  227. {
  228. pbyData[i + 1] = m_abyTempData[i];
  229. }
  230. pbyData[wCounter + 1] = pbyData[0]; // 保存结尾字符
  231. *wLen = wCounter + 2;
  232. return 1;
  233. }
  234. //对输入数据实施转义逆向操作
  235. //pbyData:待逆转义数据
  236. //wLen:数据长度
  237. quint8 Ps::psApTransferReverse(quint8 *pbyData, quint16 *wLen)
  238. {
  239. quint16 i = 0;
  240. quint16 wCounter = 0;
  241. // 逆向转义处理
  242. memset(m_abyTempData, 0, PS_FRAME_MAX_LEN);
  243. for (i = 1; i < (*wLen - 1); i++)
  244. {
  245. if ((0x5E == pbyData[i]) && (0x5D == pbyData[i + 1])) //处理0x5E和0x5D两个连续字符
  246. {
  247. m_abyTempData[wCounter] = 0x5E;
  248. i++;
  249. wCounter++;
  250. }
  251. else if ((0x5E == pbyData[i]) && (0x7D == pbyData[i + 1])) //处理0x5E和0x7D两个连续字符
  252. {
  253. m_abyTempData[wCounter] = 0x7E;
  254. i++;
  255. wCounter++;
  256. }
  257. else /*处理其它字符*/
  258. {
  259. m_abyTempData[wCounter] = pbyData[i];
  260. wCounter++;
  261. }
  262. //数据过长退出转移处理
  263. if ((wCounter + 2) > PS_FRAME_MAX_LEN)
  264. {
  265. return 0;
  266. }
  267. }
  268. // 将保存在abyTmp中的临时数据拷贝回pbyData指针中
  269. for (i = 0; i < wCounter; i++)
  270. {
  271. pbyData[i + 1] = m_abyTempData[i];
  272. }
  273. pbyData[wCounter + 1] = pbyData[0]; // 保存结束标识符
  274. *wLen = wCounter + 2;
  275. return 1;
  276. }
  277. //生成CRC16校验码
  278. quint16 Ps::PsApGenCrc16(quint8 *data, quint16 len, quint16 def_crc)
  279. {
  280. quint16 crc = def_crc;
  281. quint8 crc_h4;
  282. quint8 *ptr = data;
  283. while (len--)
  284. {
  285. crc_h4 = (quint8)(crc >> 12);
  286. crc <<= 4;
  287. crc ^= s_crc_table[crc_h4 ^ (*ptr >> 4)];
  288. crc_h4 = (quint8)(crc >> 12);
  289. crc <<= 4;
  290. crc ^= s_crc_table[crc_h4 ^ (*ptr & 0x0f)];
  291. ptr++;
  292. }
  293. return crc;
  294. }
  295. //产生AP层报文
  296. //byMcpType:1:MCPA,2:MCPB
  297. //byMsgType:通信报文,MCPA包括(0x01:上报,0x02:配置,0x03:查询),MCPB包括(0x80:升级控制命令,0x81:升级文件传输命令)
  298. //pbyData:载荷数据
  299. //wLen:载荷数据长度
  300. //pbyApFrame:AP层帧
  301. //pwApFrameLen:AP层帧长度
  302. quint8 Ps::PsGenApMsg(quint8 byMcpType, quint8 byMsgType, quint8 *pbyData, quint16 wLen, quint8 *pbyApFrame,quint16 *pwApFrameLen){
  303. quint8 byFlag = 0;
  304. quint16 wApFrameLen = wLen + PS_FRAME_MIN_LEN;
  305. quint8 *pbyDataHead = pbyApFrame;
  306. PS_HEAD_T stHead;
  307. PS_TAIL_T stTail;
  308. quint16 wCrc = 0;
  309. //AP头
  310. stHead.stApHead.byStartFlag = PS_AP_HEAD_FLAG;
  311. //VP头
  312. stHead.stVpHead.dwProjectId = 0;
  313. stHead.stVpHead.byPacketNo = m_byPacketNo;
  314. stHead.stVpHead.dwDeviceId = 0;
  315. stHead.stVpHead.byVpFlag = VP_CMMD;
  316. stHead.stVpHead.byMcpType = byMcpType;
  317. //MCP头
  318. stHead.stMcpHead.byComd = byMsgType;
  319. stHead.stMcpHead.byResp = MCP_CMD;
  320. //保存协议头数据
  321. memcpy(pbyDataHead, &stHead, sizeof(PS_HEAD_T));
  322. pbyDataHead += sizeof(PS_HEAD_T);
  323. //组织协议载荷
  324. memcpy(pbyDataHead, pbyData, wLen);
  325. pbyDataHead += wLen;
  326. //组织协议尾
  327. wCrc = PsApGenCrc16((pbyApFrame+1), (wApFrameLen - 4), 0);//生成CRC校验码
  328. stTail.wCRC = wCrc;
  329. stTail.byStopFlag = PS_AP_TAIL_FLAG;
  330. memcpy(pbyDataHead, &stTail, sizeof(PS_TAIL_T));
  331. //实施转义处理
  332. byFlag = psApTransfer(pbyApFrame, &wApFrameLen);
  333. if(!byFlag){
  334. return byFlag;
  335. }
  336. *pwApFrameLen = wApFrameLen;//新队列长度
  337. return m_byPacketNo;//当前通信包号
  338. }
  339. //产生升级报文
  340. //byMsgType:通信报文,0x80:升级控制命令,0x81:升级文件传输命令
  341. quint8 Ps::PsGenUpgradeMsg(quint8 byMsgType, quint8 *pbyData, quint16 wLen, quint8 *pbyOamData){
  342. quint8 *pbyAddress = pbyOamData;
  343. PS_HEAD_T stHead;
  344. PS_TAIL_T stTail;
  345. //组织协议头
  346. //m_byPacketNo++;
  347. stHead.stApHead.byStartFlag = PS_AP_HEAD_FLAG;
  348. stHead.stVpHead.byPacketNo = m_byPacketNo;
  349. stHead.stVpHead.byVpFlag = VP_CMMD;
  350. stHead.stVpHead.byMcpType = MCP_B;
  351. stHead.stMcpHead.byComd = byMsgType;
  352. stHead.stMcpHead.byResp = MCP_CMD;
  353. memcpy(pbyAddress, &stHead, sizeof(PS_HEAD_T));
  354. pbyAddress = pbyAddress + sizeof(PS_HEAD_T);
  355. //组织协议载荷
  356. memcpy(pbyAddress, pbyData, sizeof(quint8)*wLen);
  357. pbyAddress = pbyAddress + wLen;
  358. //组织协议尾
  359. stTail.wCRC = 0;
  360. stTail.byStopFlag = PS_AP_TAIL_FLAG;
  361. memcpy(pbyAddress, &stTail, sizeof(PS_TAIL_T));
  362. return m_byPacketNo;//当前通信包号
  363. }