协能can协议
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ProtocolImpl.cpp 27KB

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