协能can协议
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252
  1. /**
  2. * @content:ModbusRTU组件实现文件
  3. * @time:2016-8-23
  4. * @author:Mr_zhu
  5. * @version: V1.0
  6. * @describe:
  7. * 1#2016-8-23#V1.0#首次生成
  8. */
  9. #include "ProtocolImpl.h"
  10. #include <cmath>
  11. #include <cstdlib>
  12. #include <vector>
  13. #include <sstream>
  14. #include <stdexcept>
  15. #include <iostream>
  16. #include <unistd.h>
  17. #include <sys/types.h>
  18. #include <sys/stat.h>
  19. #include <fcntl.h>
  20. #include <termios.h>
  21. #include <errno.h>
  22. #include <string.h>
  23. #include "../../common/GUID.cpp"
  24. #include "../../servicemodel/Base.h"
  25. #include "../../servicemodel/Channel.h"
  26. #include "../../servicemodel/Device.h"
  27. #include "../../servicemodel/Item.h"
  28. #include "../../servicemodel/Packet.h"
  29. using namespace std;
  30. bool ProtocolImpl::hasInit = false;
  31. int ProtocolImpl::findAddrFlag = 0;
  32. int ProtocolImpl::idSuccessFlag = 0;
  33. int ProtocolImpl::currentId = 1;
  34. int ProtocolImpl::timeOut = 0;
  35. int ProtocolImpl::count = 1;
  36. int ProtocolImpl::currentState = 0;
  37. int ProtocolImpl::sendDelayCout = 0;
  38. int ProtocolImpl::flag = 0;
  39. int ProtocolImpl::deviceCounts = 0;
  40. uint8_t ProtocolImpl::retBigEndian(uint32_t value, int offset)
  41. {
  42. uint8_t ret = 0;
  43. ret = (value >> offset) & 0xFF;
  44. return ret;
  45. }
  46. int ProtocolImpl::getRegAddrMax(Packet *ppacket, Item *pitem)
  47. {
  48. std::string sParaRegAddr;
  49. int iParaRegAddr;
  50. int maxRegAddr = -1;
  51. //Base& base = pitem->getBase();
  52. std::vector<Item*> items = ppacket->getVitem();
  53. for (size_t i = 0; i < items.size(); ++i) //遍历容器中的所有元素
  54. {
  55. sParaRegAddr = items[i]->getBase().getParam("起始地址");
  56. iParaRegAddr = strtol(sParaRegAddr.c_str(), NULL, HEX);
  57. if (iParaRegAddr > maxRegAddr) //更新寄存器数量最大值
  58. {
  59. maxRegAddr = iParaRegAddr;
  60. }
  61. else
  62. {
  63. }
  64. }
  65. //log_i("最大的起始地址:0x%x", maxRegAddr);
  66. return maxRegAddr;
  67. }
  68. int ProtocolImpl::getRegAddrMin(Packet *ppacket, Item *pitem)
  69. {
  70. std::string sMinRegAddr;
  71. int iMinRegAddr = 0;
  72. std::string sParaRegAddr;
  73. int iParaRegAddr;
  74. std::vector<Item*> items = ppacket->getVitem();
  75. //log_i("Items size: %zu", items.size());
  76. sMinRegAddr = items[0]->getBase().getParam("起始地址");
  77. iMinRegAddr = strtol(sMinRegAddr.c_str(), NULL, HEX);
  78. //log_i("Initial minimum register address value: 0x%x", iMinRegAddr);
  79. for (size_t i = 0; i < items.size(); ++i)
  80. {
  81. //log_i("Processing item %zu", i);
  82. sParaRegAddr = items[i]->getBase().getParam("起始地址");
  83. iParaRegAddr = strtol(sParaRegAddr.c_str(), NULL, HEX);
  84. if (iParaRegAddr < iMinRegAddr)
  85. {
  86. iMinRegAddr = iParaRegAddr;
  87. }
  88. }
  89. //log_i("最小的寄存器起始地址:0x%x", iMinRegAddr);
  90. return iMinRegAddr;
  91. }
  92. //过滤出错误帧
  93. int ProtocolImpl::filterErrFrame(PBYTE pbuf,int len)
  94. {
  95. int validlen = len;
  96. int frameId ;
  97. int kindId;
  98. int errFrameCount = 0;
  99. for (int count = 0;
  100. ((count < validlen) && ((validlen - count) >= 12));
  101. count += 12)
  102. {
  103. frameId = getRealFrame(pbuf,count);
  104. kindId = (frameId >> 24) & 0xffff;
  105. //log_i("frameId = 0x%x,kindID = 0X%x",frameId,kindId);
  106. if(kindId != 0xff84 )
  107. {
  108. errFrameCount ++;
  109. }
  110. }
  111. return errFrameCount;
  112. }
  113. int ProtocolImpl::retStateResponse(Packet *ppacket, Item *pitem, const int len,PBYTE pbuf)
  114. {
  115. int maxRegAddr = -1;
  116. int minRegAddr = 0;
  117. int regNum = 0;
  118. int datasLen = 0;
  119. int errFrameCount = 0;
  120. int errFrameLen = 0;
  121. maxRegAddr = getRegAddrMax(ppacket, pitem);
  122. minRegAddr = getRegAddrMin(ppacket, pitem);
  123. regNum = maxRegAddr - minRegAddr + 1;
  124. //log_i("reg:%d", regNum);
  125. errFrameCount = filterErrFrame(pbuf,len);
  126. errFrameLen = errFrameCount * 10;
  127. datasLen = getRealValidLen(regNum);
  128. //log_i("datasLen:%d",datasLen);
  129. log_i("最大寄存器地址:0x%x,最小寄存器数量:0x%x,寄存器个数:0x%x,理论算出应收到合法数据长度:%d,\
  130. 实际收到数据长度=%d,错误帧个数=%d,错误帧长度:%d", maxRegAddr,
  131. minRegAddr, regNum, datasLen, len,errFrameCount,errFrameLen);
  132. if (len >= (datasLen + errFrameLen))
  133. {
  134. return S_OK;
  135. }
  136. else
  137. {
  138. return S_FALSE;
  139. }
  140. return S_FALSE;
  141. }
  142. int ProtocolImpl::getRealValidLen(int maxRegNum)
  143. {
  144. int len = 0;
  145. if (maxRegNum <= 4 && maxRegNum > 0)
  146. {
  147. len = 4 + 2 * maxRegNum;
  148. log_i("第1种情况,寄存器数量小于等于4个,计算得出合法数据长度:%d", len);
  149. }
  150. else
  151. {
  152. if (maxRegNum % 4 == 0)
  153. {
  154. len = 12 * (maxRegNum / 4);
  155. log_i("第2种情况,寄存器数量多余4且%4 == 0情况,寄存器请求数量:%d,回复帧长度:%d",maxRegNum,len);
  156. }
  157. else
  158. {
  159. len = 4*((maxRegNum / 4) +1) + (maxRegNum *2); //帧数据长度+寄存器长度
  160. log_i("第3种情况,寄存器数量多余4,寄存器请求数量:%d,回复帧长度:%d",maxRegNum,len);
  161. }
  162. }
  163. return len;
  164. }
  165. int ProtocolImpl::getRealFrame(PBYTE pbuf, int count)
  166. {
  167. PBYTE ptemp = pbuf;
  168. int id = (((ptemp[0 + count] << 24) & 0xff000000)
  169. | ((ptemp[1 + count] << 16) & 0x00ff0000)
  170. | ((ptemp[2 + count] << 8) & 0x0000ff00)
  171. | ((ptemp[3 + count]) & 0x000000ff));
  172. //log_i("帧id:0x%x", id);
  173. return id;
  174. }
  175. std::map<int, int> ProtocolImpl::handleDataLess(PBYTE pbuf,int len,int regNum,int datasLen)
  176. {
  177. int iPbufId;
  178. std::map<int, int> dataSet;
  179. iPbufId = getRealFrame(pbuf, 0);
  180. log_i("handleDataLess");
  181. for (int i = 0; i < regNum; i++)
  182. {
  183. uint16_t regValue = 0;
  184. if (i * 2 + 4 <= datasLen)
  185. {
  186. regValue = (pbuf[i * 2 + 4] << 8) | pbuf[i * 2 + 5]; // 提取寄存器值
  187. dataSet[iPbufId + i] = regValue; // 绑定到map
  188. }
  189. else
  190. {
  191. log_i(
  192. "Data insufficient for regNum %d, setting default value 0xFFFF",
  193. i);
  194. // 数据不足,处理错误或默认值
  195. regValue = 0xFFFF; // 默认值为;0xFFFF
  196. dataSet[iPbufId + i] = regValue; // 绑定到map
  197. log_i("Added to dataSet: addrFrame=0x%x, value=0x%x", iPbufId + i,
  198. regValue);
  199. }
  200. }
  201. for (const auto &entry : dataSet)
  202. {
  203. log_i("addrFrame = 0x%x, value = 0x%x", entry.first, entry.second);
  204. }
  205. return dataSet;
  206. }
  207. std::map<int,int> ProtocolImpl::handleDataGreater(PBYTE pbuf,int len,int regNum,int datasLen)
  208. {
  209. log_i("handleDataGreater:收到实际数据长度:%d,请求采集个数:%d,理想情况下收到数据长度:%d", len, regNum, datasLen);
  210. log_i("进入handDataGreater时间");
  211. std::map<int, int> dataSet;
  212. for (int count = 0; (count < len) && (len - count >= 12); count += 12)
  213. {
  214. int iPbufId = getRealFrame(pbuf, count); // 假设正确解析起始寄存器ID
  215. int kindId = (iPbufId >> 24) & 0xffff;
  216. //log_i("frameId = 0x%x,kindID = 0X%x",frameId,kindId);
  217. if(kindId == 0xff84 ) //代表合法数据
  218. {
  219. for (int i = 0; i < 4 && regNum >= 0; ++i, --regNum)
  220. {
  221. uint16_t regValue;
  222. int dataOffset = count + 4 + i * 2;
  223. // 确保当前块的数据足够(两个字节)
  224. if (dataOffset + 1 < len)
  225. {
  226. regValue = (pbuf[dataOffset] << 8) | pbuf[dataOffset + 1];
  227. }
  228. else
  229. {
  230. regValue = 0xFFFF; // 数据不足,默认值
  231. }
  232. dataSet[iPbufId + i] = regValue; // 寄存器ID连续递增
  233. }
  234. }
  235. // 每个块的数据部分为8字节(从count+4到count+11)
  236. }
  237. log_i("出去handDataGreater时间");
  238. return dataSet;
  239. }
  240. //返回IO数据集
  241. std::map<int,int> ProtocolImpl::retIoDataSet(Packet *ppacket, Item *pitem,PBYTE pbuf,int len)
  242. {
  243. std::map<int, int> dataSet;
  244. dataSet = handleIoData(pbuf);
  245. return dataSet;
  246. }
  247. std::map<int,int> ProtocolImpl::handleIoData(PBYTE pbuf)
  248. {
  249. int iPbufId;
  250. std::map<int, int> dataSet;
  251. iPbufId = getRealFrame(pbuf, 0);
  252. uint16_t regValue = 0;
  253. regValue = pbuf[7];
  254. dataSet[iPbufId] = regValue;
  255. log_i("handleIoData");
  256. for (const auto &entry : dataSet)
  257. {
  258. log_i("addrFrame = 0x%x, value = 0x%x", entry.first, entry.second);
  259. }
  260. return dataSet;
  261. }
  262. std::map<int,int>ProtocolImpl::retDataSet(Packet *ppacket, Item *pitem,PBYTE pbuf,int len)
  263. {
  264. std::map<int, int> dataSet; // 存储寄存器地址和值
  265. int maxRegAddr, minRegAddr, regNum;
  266. int datasLen = 0;
  267. maxRegAddr = getRegAddrMax(ppacket, pitem);
  268. minRegAddr = getRegAddrMin(ppacket, pitem);
  269. regNum = maxRegAddr - minRegAddr + 1;
  270. datasLen = getRealValidLen(regNum);
  271. if (datasLen <= 12)
  272. {
  273. dataSet = handleDataLess(pbuf,len,regNum,datasLen);
  274. }
  275. else
  276. {
  277. dataSet = handleDataGreater(pbuf,len,regNum,datasLen);
  278. }
  279. return dataSet;
  280. }
  281. int ProtocolImpl::iGetItemParaConfig(Item *pitem,std::string attribute)
  282. {
  283. Item *t_item = pitem;
  284. Base &t_base = t_item->getBase();
  285. string sAttribute = "";
  286. int iAttribute = 0;
  287. sAttribute = t_base.getParam(attribute);
  288. //log_i("%s: %s",attribute.c_str(), sAttribute.c_str());
  289. iAttribute = strtol(sAttribute.c_str(), NULL, HEX);
  290. //log_i("retV:0x%x",iAttribute);
  291. return iAttribute;
  292. }
  293. std::string ProtocolImpl::sGetItemParaConfig(Item *pitem, std::string attribute)
  294. {
  295. Item *t_item = pitem;
  296. Base &t_base = t_item->getBase();
  297. string sAttribute = "";
  298. sAttribute = t_base.getParam(attribute);
  299. //log_i("%s: %s",attribute.c_str(), sAttribute.c_str());
  300. return sAttribute;
  301. }
  302. void ProtocolImpl::setData(Item *pitem,int16_t pbuf,int receiveData,int paraData,std::string t_sDataType,std::string t_sByteOrder,string t_sBits)
  303. {
  304. Item* t_item = pitem;
  305. int16_t buf = pbuf;
  306. string t_str;
  307. char t[256];
  308. if(receiveData == paraData)
  309. {
  310. log_i("当前时间,比对成功,设置数据");
  311. //log_i("ID匹配,处理数据");
  312. if (t_sDataType == "I")
  313. {
  314. //log_i("数据类型为I,调用merge16函数,buf=0x%x",buf);
  315. t_item->setValue(merge16(buf, t_sByteOrder));
  316. }
  317. else if (t_sDataType == "UI")
  318. {
  319. //log_i("数据类型为UI,调用merge16函数");
  320. t_item->setValue(merge16(buf, t_sByteOrder));
  321. log_i("当前时间,设置数据成功,数据类型UI");
  322. }
  323. else if (t_sDataType == "B")
  324. {
  325. int index = t_sBits.find(".");
  326. //log_i("t_sBits =%s, index = %d",t_sBits.c_str(),index);
  327. if (index != -1)
  328. {
  329. string t_sBitnum = t_sBits.substr(0,index);
  330. int t_iBitnum =(int) (strtol(t_sBitnum.c_str(),NULL, 10)); //----位起始地址
  331. int t_Bits =(int) (strtol(t_sBits.substr(index + 1).c_str(),NULL, 10));
  332. //log_i("数据类型为B,调用merge16函数");
  333. unsigned short t_usdata =(unsigned short) (strtol(merge16_u(buf,t_sByteOrder).c_str(),NULL, 10));
  334. //log_i("位起始地址t_iBitnum = %d, t_Bits= %d, t_usdata = %d",t_iBitnum,t_Bits,t_usdata);
  335. unsigned short bits = 0;
  336. for (int i = 0; i < t_Bits; i++)
  337. {
  338. unsigned short bit = (t_usdata >> (t_iBitnum + i))& 0x0001;
  339. bits += bit * pow(2, i);
  340. }
  341. snprintf(t, 256, "%d", bits);
  342. t_str = t;
  343. t_item->setValue(t_str);
  344. }
  345. log_i("当前时间,设置数据成功,数据类型B");
  346. }
  347. }
  348. }
  349. int ProtocolImpl::set_gpio_value(const std::string& gpio_path, const std::string& value)
  350. {
  351. int fd = open(gpio_path.c_str(), O_WRONLY);
  352. if (fd < 0)
  353. {
  354. log_e("Failed to open GPIO value file: %s", gpio_path.c_str());
  355. return -1;
  356. }
  357. if (write(fd, value.c_str(), value.length()) < 0)
  358. {
  359. log_e("Failed to write to GPIO value file: %s", gpio_path.c_str());
  360. close(fd);
  361. return -1;
  362. }
  363. close(fd);
  364. return 0;
  365. }
  366. void ProtocolImpl::proceessReplyFrame(int frame,int datas)
  367. {
  368. log_i("当前状态:%d ---0-初始化,1-发送,2-接收,3-结束",currentState);
  369. if (frame == 0x7F0) // 总主分配ID回复帧的CANID
  370. {
  371. log_i("processReply datas = %d",datas);
  372. unsigned char reply_id = datas; // 回复自身的ID编号
  373. log_i("reply_id = 0x%x",reply_id);
  374. if (reply_id == currentId)
  375. {
  376. log_i("收到设备%d的回复", reply_id);
  377. if(currentId == 2)
  378. {
  379. log_i("回复帧,currentId = %d",currentId );
  380. currentState = END;
  381. idSuccessFlag =2;
  382. }
  383. else
  384. {
  385. if (orderMode == 0) // 根据分配次序修改下一个要分配的ID
  386. {
  387. currentId ++; // 正序分配
  388. currentState = SEND;
  389. }
  390. else
  391. {
  392. currentId --; // 倒序分配
  393. currentState = SEND;
  394. }
  395. // 使能下一个设备
  396. //数据发送正确,且有回复,开始发送下一帧
  397. }
  398. }
  399. else
  400. {
  401. currentId = 1;
  402. idSuccessFlag = 0;
  403. log_i("收到错误的回复帧,ID不匹配");
  404. }
  405. }
  406. else
  407. {
  408. //currentId = 1;
  409. currentState = SEND;
  410. idSuccessFlag = 0;
  411. log_i("收到未知的CAN帧");
  412. }
  413. if(idSuccessFlag == deviceCounts)
  414. {
  415. findAddrFlag = 1;
  416. currentId = 1;
  417. currentState = END;
  418. }
  419. }
  420. //发送分配帧
  421. void ProtocolImpl::sendAllocFrame(PBYTE pbuf, int id, int &len)
  422. {
  423. pbuf[0] = 0x00;
  424. pbuf[1] = 0x00;
  425. pbuf[2] = 0x07;
  426. pbuf[3] = 0xf0;
  427. pbuf[4] = static_cast<uint8_t>(id); // 转换为字节
  428. pbuf[5] = static_cast<uint8_t>(deviceCounts); // 转换为字节
  429. pbuf[6] = static_cast<uint8_t>(orderMode); // 转换为字节
  430. pbuf[7] = static_cast<uint8_t>(orderState); // 转换为字节
  431. // pbuf[8] = 0;
  432. // pbuf[9] = 0;
  433. // pbuf[10] = 0;
  434. // pbuf[11] = 0;
  435. // 打印调试信息
  436. log_i("发送分配地址帧: ");
  437. for (int i = 0; i < 8; i++) {
  438. log_i("%02X ", pbuf[i]);
  439. }
  440. currentState = RECEIVED ;
  441. len = 8;
  442. }
  443. void ProtocolImpl::initIO()
  444. {
  445. currentId = 1;
  446. if(count == 1)
  447. {
  448. if (set_gpio_value(devPath, lowLevel) == 0)
  449. {
  450. log_i("Set GPIO 436 to high");
  451. }
  452. else
  453. {
  454. log_e("Failed to set GPIO 436 to high");
  455. }
  456. }
  457. else
  458. {
  459. if(count > 4)
  460. {
  461. // 设置 GPIO 436 为低电平
  462. if (set_gpio_value(devPath, highLevel) == 0)
  463. {
  464. log_i("Set GPIO 436 to low");
  465. currentState = SEND;
  466. }
  467. else
  468. {
  469. log_e("Failed to set GPIO 436 to low");
  470. }
  471. count = 0;
  472. }
  473. }
  474. count ++;
  475. }
  476. HRESULT ProtocolImpl::queryInterface(const IID &iid, void **ppv)
  477. {
  478. if (iid == IID_IProtocol)
  479. {
  480. log_d( "成功返回Protocol-CANDEXN协议句柄");
  481. *ppv = static_cast<ProtocolI*>(this);
  482. }
  483. else if (iid == IID_IUnknown)
  484. {
  485. log_d( "成功返回Protocol-CANDEXN协议IUnknown句柄");
  486. *ppv = static_cast<IUnknown*>(this);
  487. }
  488. else
  489. {
  490. log_d( "未查询到接口");
  491. *ppv = NULL;
  492. return E_NOINTERFACE;
  493. }
  494. reinterpret_cast<IUnknown*>(*ppv)->addRef();
  495. return S_OK;
  496. }
  497. ULONG ProtocolImpl::addRef(void)
  498. {
  499. return ++m_cRef;
  500. }
  501. ULONG ProtocolImpl::release(void)
  502. {
  503. if (--m_cRef == 0)
  504. {
  505. delete this;
  506. return 0;
  507. }
  508. return m_cRef;
  509. }
  510. ULONG ProtocolImpl::getVersion()
  511. {
  512. return VERSION;
  513. }
  514. /**
  515. * @content:组织读数据报文
  516. * @time:2016-9-9
  517. * @author:Mr_zhu
  518. * @param: pdevice(设备句柄),ppacket(包句柄),pitem(点句柄),pbuf(数据缓冲区),len(返回报文长度)
  519. * @return: HRESULT(S_OK,S_FALSE)
  520. * @decribe
  521. * 1#2016-9-9#V1.0#首次生成
  522. */
  523. HRESULT ProtocolImpl::onRead(Device *pdevice, Packet *ppacket, Item *pitem,
  524. PBYTE pbuf, int &len)
  525. {
  526. log_i("onRead");
  527. Channel *pC = pdevice->getParent();
  528. if (pC == nullptr)
  529. {
  530. log_i("Channel pointer is null");
  531. return S_FALSE;
  532. }
  533. if (m_tmpItems.count(pC->getBase().getObjid().toString()) == 0)
  534. {
  535. deviceCounts = pC->getDeviceCount();
  536. maxId = deviceCounts;
  537. //maxId = 2;
  538. log_i("maxid =%d",maxId);
  539. }
  540. log_i("当前状态:%d ---0-初始化,1-发送,2-接收,3-结束",currentState);
  541. if(currentState == INIT)
  542. {
  543. initIO();
  544. }
  545. if(currentState == SEND)
  546. {
  547. log_i("currenntId = %d",currentId);
  548. if(currentId != 1)
  549. {
  550. log_i("发送延迟计数:%d",sendDelayCout);
  551. if(sendDelayCout > 2)
  552. {
  553. sendAllocFrame(pbuf,currentId , len);
  554. //sendDelayCout = 0;
  555. }
  556. sendDelayCout++;
  557. }
  558. else
  559. {
  560. sendAllocFrame(pbuf,currentId , len);
  561. timeOut = 0;
  562. }
  563. //pdevice->getBase().setRwstate(READ_WAIT);
  564. pdevice->getBase().setRwstate(WRITE_WAIT);
  565. }
  566. if(currentState == RECEIVED)
  567. {
  568. if(timeOut > 10)
  569. {
  570. currentState = INIT;
  571. sendDelayCout = 0;
  572. }
  573. timeOut ++;
  574. }
  575. if(currentState != END)
  576. {
  577. log_i("len的长度:%d",len);
  578. return S_OK;
  579. }
  580. if(currentState == END)
  581. //if(findAddrFlag == 1)
  582. {
  583. idSuccessFlag = 0;
  584. if (ppacket->getVitem().size() == 0)
  585. {
  586. return S_FALSE;
  587. }
  588. //pdevice->getBase().setRwstate(READ_WAIT); //----设置设备状态
  589. std::string sParaId;
  590. int iParaId;
  591. Base &t_base = ppacket->getVitem().at(0)->getBase();
  592. sParaId = t_base.getParam("功能码");
  593. log_i("sParaId =%s,对应的实际名称=%s",sParaId.c_str() ,t_base.getName().c_str());
  594. iParaId = strtol(sParaId.c_str(), NULL, HEX);
  595. string t_saddr;
  596. t_saddr = pdevice->getBase().getParam("站地址");
  597. int t_iaddr = 0;
  598. t_iaddr = strtol(t_saddr.c_str(), NULL, HEX);
  599. int frameFuncCode = (iParaId & 0x070000);
  600. log_i("stationAddr = %d,iParaId=0x%x,frameFuncCode = 0x%x",t_iaddr,iParaId,frameFuncCode);
  601. if (ppacket == nullptr || pitem == nullptr)
  602. {
  603. log_i("Invalid packet or item");
  604. return S_FALSE;
  605. }
  606. //判断寄存器是读寄存器
  607. if(frameFuncCode == 0x030000)
  608. {
  609. int maxRegAddr = getRegAddrMax(ppacket, pitem);
  610. int minRegAddr = getRegAddrMin(ppacket, pitem);
  611. log_i("onRead中判断出寄存器是读寄存器MaxRegAddr: 0x%x, MinRegAddr: 0x%x", maxRegAddr, minRegAddr);
  612. if (maxRegAddr < minRegAddr)
  613. {
  614. log_i("Invalid register address range");
  615. return S_FALSE;
  616. }
  617. int regNum = maxRegAddr - minRegAddr + 1;
  618. iParaId |= (t_iaddr << 19);
  619. pbuf[0] = retBigEndian(iParaId + minRegAddr, 24);
  620. pbuf[1] = retBigEndian(iParaId + minRegAddr, 16);
  621. pbuf[2] = retBigEndian(iParaId + minRegAddr, 8);
  622. pbuf[3] = retBigEndian(iParaId + minRegAddr, 0);
  623. pbuf[4] = retBigEndian(regNum, 8);
  624. pbuf[5] = retBigEndian(regNum, 0);
  625. len = 6;
  626. if (pbuf == nullptr)
  627. {
  628. log_i("pbuf is null");
  629. return S_FALSE;
  630. }
  631. for (int i = 0; i < len; i++)
  632. {
  633. log_i("onRead-读数据:pbuf[%d]:0x%x", i, pbuf[i]);
  634. }
  635. pdevice->getBase().setRwstate(READ_WAIT); //----设置设备状态
  636. }
  637. //寄存器是读写寄存器
  638. // if(frameFuncCode == 0x010000 )
  639. // {
  640. // pdevice->getBase().setRwstate(WRITE_O);
  641. // }
  642. //初始化数据库容器
  643. if (pC != NULL)
  644. {
  645. if (m_tmpItems.count(pC->getBase().getObjid().toString()) == 0)
  646. {
  647. log_i("初始化ZLink数据Temporary items not found for Channel ID: %s",
  648. pC->getBase().getObjid().toString().c_str());
  649. int ccount = pC->getDeviceCount();
  650. log_i("Channel device count: %d", ccount);
  651. std::multimap<int, Item*> tmpItems;
  652. for (int i = 0; i < ccount; i++)
  653. {
  654. for (size_t j = 0;
  655. j < pC->getVDevice().at(i)->getVitem().size(); j++)
  656. {
  657. string t_sId;
  658. string rsId;
  659. Base &t_base =
  660. pC->getVDevice().at(i)->getVitem().at(j)->getBase();
  661. t_sId = t_base.getParam("写功能码");
  662. int t_iId = 0;
  663. t_iId = strtol(t_sId.c_str(), NULL, HEX); //----获取帧ID
  664. //写功能是读寄存器响应
  665. if(t_iId == 0x04040000)
  666. {
  667. string t_stype;
  668. t_stype = t_base.getParam("帧类型");
  669. //log_i("帧类型: %s", t_stype.c_str());
  670. if (t_stype == "1")
  671. {
  672. t_iId |= 0x80000000;
  673. log_i("帧类型为1,功能码更新为: 0x%x", t_iId);
  674. }
  675. string sStartAddr;
  676. //sStartAddr = pC->getVDevice().at(i)->getBase().getParam("起始地址");
  677. sStartAddr = t_base.getParam("起始地址");
  678. //log_i("起始地址 =%s", sStartAddr.c_str());
  679. int iStartAddr = 0;
  680. iStartAddr = strtol(sStartAddr.c_str(), NULL, HEX);
  681. //log_i("起始地址转换为整数: 0x%x", iStartAddr);
  682. t_iId += iStartAddr;
  683. string t_saddr;
  684. t_saddr = pC->getVDevice().at(i)->getBase().getParam("站地址");
  685. int t_iaddr = 0;
  686. t_iaddr = strtol(t_saddr.c_str(), NULL, HEX);
  687. //log_i("站地址:%d",t_iaddr);
  688. t_iId |= (t_iaddr << 19);
  689. //log_i("t_Id = %d",t_iId);
  690. }
  691. else
  692. {
  693. if(t_iId == 0x04010000)
  694. {
  695. t_iId = 0x04040000;
  696. //log_i("2.t_iId = 0x%x",t_iId);
  697. string t_stype;
  698. t_stype = t_base.getParam("帧类型");
  699. //log_i("帧类型: %s", t_stype.c_str());
  700. if (t_stype == "1")
  701. {
  702. t_iId |= 0x80000000;
  703. log_i("帧类型为1,功能码更新为: 0x%x", t_iId);
  704. }
  705. string sStartAddr;
  706. //sStartAddr = pC->getVDevice().at(i)->getBase().getParam("起始地址");
  707. sStartAddr = t_base.getParam("起始地址");
  708. //log_i("起始地址 =%s", sStartAddr.c_str());
  709. int iStartAddr = 0;
  710. iStartAddr = strtol(sStartAddr.c_str(), NULL, HEX);
  711. //log_i("起始地址转换为整数: 0x%x", iStartAddr);
  712. t_iId += iStartAddr;
  713. string t_saddr;
  714. t_saddr = pC->getVDevice().at(i)->getBase().getParam("站地址");
  715. int t_iaddr = 0;
  716. t_iaddr = strtol(t_saddr.c_str(), NULL, HEX);
  717. //log_i("站地址:%d",t_iaddr);
  718. t_iId |= (t_iaddr << 19);
  719. //log_i("3.t_iId = 0x%x",t_iId);
  720. }
  721. }
  722. tmpItems.insert(
  723. make_pair(t_iId,
  724. pC->getVDevice().at(i)->getVitem().at(j)));
  725. //log_i("插入临时条目: ID=0x%x", t_iId);
  726. }
  727. }
  728. m_tmpItems.insert(
  729. make_pair(pC->getBase().getObjid().toString(), tmpItems));
  730. }
  731. else
  732. {
  733. log_i("Temporary items already exist for Channel ID: %s",
  734. pC->getBase().getObjid().toString().c_str());
  735. }
  736. }
  737. return S_OK;
  738. }
  739. }
  740. /**
  741. * @content:组织写数据报文
  742. * @time:2016-9-9
  743. * @author:Mr_zhu
  744. * @param: pdevice(设备句柄),ppacket(包句柄),pitem(点句柄),pbuf(数据缓冲区),len(返回报文长度)
  745. * @param: swritebuf(待写字符串),writelen(待写数据长度)
  746. * @return: HRESULT(S_OK,S_FALSE)
  747. * @decribe
  748. * 1#2016-9-9#V1.0#首次生成
  749. */
  750. HRESULT ProtocolImpl::onWrite(Device *pdevice, Packet *ppacket, Item *pitem,
  751. PBYTE pbuf, int &len, string swritebuf, const unsigned int writelen)
  752. {
  753. log_i("onWrite");
  754. int t_len = 0;
  755. Base &base = pitem->getBase();
  756. string t_sRWType;
  757. t_sRWType = base.getParam("读写类型"); //----获取点读写类型
  758. if (t_sRWType == "RO") //----只读
  759. {
  760. log_w("%s, 对只读点进行非法写操作,点信息(UUID-%s,名称-%s)",
  761. pdevice->getBase().getName().c_str(),
  762. base.getObjid().toString().c_str(), base.getName().c_str());
  763. return S_FALSE;
  764. }
  765. string t_sFuncCode;
  766. t_sFuncCode = base.getParam("写功能码");
  767. int t_iFuncCode = 0;
  768. t_iFuncCode = strtol(t_sFuncCode.c_str(), NULL, HEX); //----获取帧ID
  769. string t_sStartAddr;
  770. int t_iStartAddr = 0; //----起始地址
  771. t_sStartAddr = base.getParam("起始地址");
  772. t_iStartAddr = strtol(t_sStartAddr.c_str(), NULL, 16);
  773. t_iFuncCode += t_iStartAddr;
  774. string t_saddr;
  775. t_saddr = pdevice->getBase().getParam("站地址");
  776. int t_iaddr = 0;
  777. t_iaddr = strtol(t_saddr.c_str(), NULL, HEX);
  778. t_iFuncCode |= (t_iaddr << 19);
  779. log_i("采集点名称是:%s,站地址=%d,功能码=0x%x",base.getName().c_str(),t_iaddr,t_iFuncCode);
  780. *(pbuf + (t_len++)) = HHByte(t_iFuncCode);
  781. *(pbuf + (t_len++)) = HLByte(t_iFuncCode);
  782. *(pbuf + (t_len++)) = LHByte(t_iFuncCode);
  783. *(pbuf + (t_len++)) = LLByte(t_iFuncCode); //----发送帧ID
  784. if (ppacket != NULL && pdevice != NULL && pitem != NULL)
  785. {
  786. struct candata t_data =
  787. //{ 0, 0, 0, 0, 0, 0, 0, 0 };
  788. { 0, 0 };
  789. if (m_tmpwritedata.count(t_sFuncCode) > 0)
  790. {
  791. t_data = m_tmpwritedata.find(t_sFuncCode)->second;
  792. }
  793. *(pbuf + (t_len++)) = t_data.data0 & 0x00ff;
  794. *(pbuf + (t_len++)) = t_data.data1 & 0x00ff;
  795. string t_sDataType; //----数据类型
  796. t_sDataType = base.getParam("数据类型");
  797. string t_sByteOrder;
  798. t_sByteOrder = base.getParam("字节序");
  799. if (t_sDataType == "I" || t_sDataType == "UI")
  800. {
  801. long int value = 0;
  802. value = strtol(swritebuf.c_str(), NULL, 10);
  803. if (t_sByteOrder == "BA")
  804. {
  805. pbuf[4] = HByte(value);
  806. pbuf[5] = LByte(value);
  807. }
  808. else if (t_sByteOrder == "AB")
  809. {
  810. pbuf[4] = LByte(value);
  811. pbuf[5] = HByte(value);
  812. }
  813. }
  814. }
  815. len = 6;
  816. struct candata data;
  817. data.data0 = pbuf[4] & 0x00ff;
  818. data.data1 = pbuf[5] & 0x00ff;
  819. // data.data2 = pbuf[6] & 0x00ff;
  820. // data.data3 = pbuf[7] & 0x00ff;
  821. // data.data4 = pbuf[8] & 0x00ff;
  822. // data.data5 = pbuf[9] & 0x00ff;
  823. // data.data6 = pbuf[10] & 0x00ff;
  824. // data.data7 = pbuf[11] & 0x00ff;
  825. std::string sbuf;
  826. for (int i = 0; i < 12; i++)
  827. {
  828. char str[10];
  829. snprintf(str, 10, "%x", pbuf[i]);
  830. sbuf = sbuf + str;
  831. if (i != (12 - 1))
  832. {
  833. sbuf = sbuf + ",";
  834. }
  835. }
  836. log_i( "待发送数据为: %s", sbuf.c_str());
  837. log_i( "0x%x, 0x%x", data.data0, data.data1);
  838. m_tmpwritedata[t_sFuncCode] = data;
  839. //pitem->setValue(swritebuf);
  840. // pdevice->getBase().setRwstate(WRITE_O);
  841. pdevice->getBase().setRwstate(WRITE_WAIT);
  842. return S_OK;
  843. }
  844. /**
  845. * @content:判断回复数据是否接收完成
  846. * @time:2016-9-9
  847. * @author:Mr_zhu
  848. * @param: pdevice(设备句柄),ppacket(包句柄),pitem(点句柄),pbuf(数据缓冲区),len(返回报文长度)
  849. * @return: HRESULT(S_OK,S_FALSE)
  850. * @decribe
  851. * 1#2016-9-9#V1.0#首次生成
  852. */
  853. HRESULT ProtocolImpl::isResponseOK(Device *pdevice, Packet *ppacket,
  854. Item *pitem, PBYTE pbuf, const int len)
  855. {
  856. log_i("isResponseOk");
  857. int ret;
  858. if(findAddrFlag == 0)
  859. {
  860. return S_OK;
  861. }
  862. switch (pdevice->getBase().getRwstate())
  863. {
  864. case READ_O:
  865. case WRITE_WAIT:
  866. // return S_OK;
  867. //ret = retStateResponse(ppacket, pitem, len,pbuf);
  868. // log_i("写等待操作,isResponse 返回值 =%d",ret);
  869. // if(ret == S_OK)
  870. // {
  871. // return S_OK;
  872. // }
  873. // return S_FALSE;
  874. return S_OK;
  875. case READ_WAIT:
  876. ret = retStateResponse(ppacket, pitem, len,pbuf);
  877. log_i("读等待操作,isResponseOK返回值:%d", ret);
  878. if (ret == S_OK)
  879. {
  880. return S_OK;
  881. }
  882. else
  883. {
  884. if (ret == S_FALSE)
  885. {
  886. return S_FALSE;
  887. }
  888. }
  889. return S_FALSE;
  890. case WRITE_O:
  891. //case WRITE_WAIT:
  892. log_i("只写操作");
  893. return S_OK;
  894. }
  895. return S_FALSE;
  896. }
  897. //寻址未成功,解析寻址报文
  898. void ProtocolImpl::ioResponse(Packet *ppacket, Item *pitem,PBYTE pbuf, const int len)
  899. {
  900. // jisuan
  901. std::map<int, int> dataSets; // 存储寄存器地址和值
  902. dataSets=retIoDataSet(ppacket, pitem, pbuf, len);
  903. log_i("pbuf[4]= 0x%x,pbuf[5] = 0x%x,pbuf[6] = 0x%x,pbuf[7] = 0x%x",pbuf[4],pbuf[5],pbuf[6],pbuf[7]);
  904. // second,
  905. for (const auto &entry : dataSets)
  906. {
  907. log_i("addrFrame = 0x%x, value = 0x%x", entry.first,
  908. entry.second);
  909. }
  910. int id;
  911. int16_t buf;
  912. for (const auto &dataPair : dataSets)
  913. {
  914. log_i("addData.size=%d", dataSets.size());
  915. id = dataPair.first;
  916. id = (0x7fffffff) & id;
  917. buf = dataPair.second;
  918. log_i("id = 0x%x,dataPair.second =0x%x",id,buf);
  919. if(currentState == RECEIVED )
  920. {
  921. proceessReplyFrame(id,buf);
  922. }
  923. }
  924. }
  925. void ProtocolImpl::stringOutput(PBYTE pbuf, int data_len)
  926. {
  927. // 删除strlen计算,直接使用传入的data_len
  928. int groups = data_len / 12;
  929. int remainder = data_len % 12;
  930. int total_bytes = (groups + (remainder != 0)) * 12;
  931. char *result = (char *)malloc(total_bytes);
  932. if (!result) {
  933. fprintf(stderr, "内存分配失败\n");
  934. return;
  935. }
  936. memset(result, 0, total_bytes); // 更规范的写法
  937. int pos = 0;
  938. for (int i = 0; i < data_len; i += 12) {
  939. int bytes_to_copy = std::min(12, data_len - i);
  940. memcpy(result + pos, pbuf + i, bytes_to_copy);
  941. pos += 12;
  942. }
  943. // 以HEX格式打印二进制数据
  944. for (int i = 0; i < total_bytes; i += 12) {
  945. std::string hexStr;
  946. for (int j = 0; j < 12; ++j) {
  947. char buf[3];
  948. snprintf(buf, sizeof(buf), "%02X", static_cast<unsigned char>(result[i + j]));
  949. hexStr += buf;
  950. hexStr += " "; // 可选:增加空格提高可读性
  951. }
  952. log_i("接收到的数据展示:%s", hexStr.c_str());
  953. }
  954. free(result);
  955. }
  956. //寻址成功,解析BMS传的数据
  957. int ProtocolImpl::normalDatasResponse(Device* pdevice,Packet* ppacket,Item* pitem,PBYTE pbuf,const int len)
  958. {
  959. std::map<int, int> dataSet;
  960. int id;
  961. int16_t buf;
  962. Channel *pC = pdevice->getParent();
  963. if (pC == NULL)
  964. {
  965. log_e("%s, 父通道为空, 无法进行数据解析", pdevice->getBase().getName().c_str());
  966. return S_FALSE;
  967. }
  968. //stringOutput(pbuf,len);
  969. dataSet = retDataSet(ppacket, pitem,pbuf,len);
  970. // for (const auto &entry : dataSet)
  971. // {
  972. // log_i("dataSet填充返回值:addrFrame = 0x%x, value = 0x%x", entry.first,
  973. // entry.second);
  974. // }
  975. log_i("数据集开始时间");
  976. for (const auto &dataPair : dataSet)
  977. {
  978. //log_i("addData.size=%d", dataSet.size());
  979. id = dataPair.first;
  980. id = (0x7fffffff) & id;
  981. buf = dataPair.second;
  982. log_i("当前时间:Processing data pair with ID: 0x%x", id);
  983. if (m_tmpItems.count(pC->getBase().getObjid().toString()) > 0)
  984. {
  985. std::multimap<int, Item*> tmpItms = m_tmpItems.find(
  986. pC->getBase().getObjid().toString())->second; //是否有效
  987. std::multimap<int, Item*>::size_type cnt = tmpItms.count(id);
  988. std::multimap<int, Item*>::iterator iter = tmpItms.find(id);
  989. if (iter != tmpItms.end())
  990. {
  991. log_i("遍历容器条目开始时间,容器中含有条目当前0x%x,%d个",id,cnt);
  992. for (; cnt > 0; cnt--, iter++)
  993. {
  994. //log_i("Processing item %zu for ID 0x%x", cnt, id);
  995. Item *t_item = iter->second;
  996. //Device *ptdevice = (Device*) (t_item->getParent());
  997. if (t_item != NULL && pdevice != NULL)
  998. {
  999. int iwId = iGetItemParaConfig(t_item,"写功能码");
  1000. int iStartAddr = iGetItemParaConfig(t_item,"起始地址");
  1001. string t_stype = sGetItemParaConfig(t_item,"帧类型");
  1002. string t_sDataType = sGetItemParaConfig(t_item,"数据类型");
  1003. string t_sByteOrder = sGetItemParaConfig(t_item,"字节序");
  1004. string t_sBits= sGetItemParaConfig(t_item ,"位地址");
  1005. iwId += iStartAddr;
  1006. string t_saddr;
  1007. t_saddr = pdevice->getBase().getParam("站地址");
  1008. int t_iaddr = 0;
  1009. t_iaddr = strtol(t_saddr.c_str(), NULL, HEX);
  1010. //log_i("t_iId = 0x%x,t_iaddr =%d,",iId,t_iaddr);
  1011. int itemFuncCode = (iwId & 0x070000);
  1012. //条目写功能码解析是读响应
  1013. if(itemFuncCode == 0x040000)
  1014. {
  1015. iwId |= (t_iaddr << 19);
  1016. //log_i("设置的数据buf=%d,paraID = 0x%x",buf,iId);
  1017. log_i("进入设置函数");
  1018. setData(t_item, buf,id,iwId,t_sDataType,t_sByteOrder,t_sBits);
  1019. }
  1020. else
  1021. {
  1022. //条目写功能码解析是写功能码
  1023. if(itemFuncCode == 0x010000)
  1024. {
  1025. iwId = iwId | 0x00040000;
  1026. iwId = iwId & 0xfff4ffff;
  1027. iwId |= (t_iaddr << 19);
  1028. setData(t_item, buf,id,iwId,t_sDataType,t_sByteOrder,t_sBits);
  1029. }
  1030. }
  1031. }
  1032. else
  1033. {
  1034. if(t_item == NULL)
  1035. {
  1036. log_i("......item== NULL......");
  1037. }
  1038. return S_FALSE;
  1039. }
  1040. }
  1041. log_i("遍历容器条目结束时间,容器中含有条目当前0x%x,%d个",id,cnt);
  1042. }
  1043. }
  1044. else
  1045. {
  1046. log_i("m_tmpItems.count(pC->getBase().getObjid().toString()) <0");
  1047. return S_FALSE;
  1048. }
  1049. }
  1050. log_i("数据集结束时间");
  1051. return S_OK;
  1052. }
  1053. /**
  1054. * @content:解析数据
  1055. * @time:2016-9-9
  1056. * @author:Mr_zhu
  1057. * @param: pdevice(设备句柄),ppacket(包句柄),pitem(点句柄),pbuf(数据缓冲区),len(返回报文长度),deletelen(待删除数据长度)
  1058. * @return: HRESULT(S_OK,S_FALSE)
  1059. * @decribe
  1060. * 1#2016-9-9#V1.0#首次生成
  1061. */
  1062. HRESULT ProtocolImpl::onResponse(Device *pdevice, Packet *ppacket, Item *pitem,
  1063. PBYTE pbuf, const int len, int &deletelen)
  1064. {
  1065. log_i("onResponse");
  1066. int validlen = len;
  1067. int t_iRWState = pdevice->getBase().getRwstate(); //----设备读写状态
  1068. std::vector<Item*> items = ppacket->getVitem();
  1069. switch (t_iRWState)
  1070. {
  1071. case READ_O:
  1072. case READ_WAIT:
  1073. case WRITE_WAIT:
  1074. log_i("WRITE_WAIT");
  1075. log_i("当前状态:%d ---0-初始化,1-发送,2-接收,3-结束",currentState);
  1076. if (validlen >= 6)
  1077. {
  1078. if(findAddrFlag == 0)
  1079. {
  1080. //寻址成功前,BCU -BAU寻址数据回应处理
  1081. ioResponse(ppacket, pitem, pbuf, len);
  1082. return S_OK;
  1083. }
  1084. else
  1085. {
  1086. //寻址成功,正常解析bms上传数据
  1087. normalDatasResponse(pdevice, ppacket, pitem,pbuf,len);
  1088. }
  1089. }
  1090. break;
  1091. case WRITE_O:
  1092. break;
  1093. default:
  1094. break;
  1095. }
  1096. return S_OK;
  1097. }
  1098. #ifdef __cplusplus
  1099. extern "C" IUnknown* CreateInstance()
  1100. {
  1101. IUnknown *pI = static_cast<ProtocolI*>(new ProtocolImpl());
  1102. pI->addRef();
  1103. return pI;
  1104. }
  1105. #endif