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

ProtocolImpl.cpp 21KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857
  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 "../../common/GUID.cpp"
  17. #include "../../servicemodel/Base.h"
  18. #include "../../servicemodel/Channel.h"
  19. #include "../../servicemodel/Device.h"
  20. #include "../../servicemodel/Item.h"
  21. #include "../../servicemodel/Packet.h"
  22. using namespace std;
  23. bool ProtocolImpl::hasInit = false;
  24. uint8_t ProtocolImpl::retBigEndian(uint32_t value, int offset)
  25. {
  26. uint8_t ret = 0;
  27. ret = (value >> offset) & 0xFF;
  28. return ret;
  29. }
  30. int ProtocolImpl::getRegAddrMax(Packet *ppacket, Item *pitem)
  31. {
  32. std::string sParaRegAddr;
  33. int iParaRegAddr;
  34. int maxRegAddr = -1;
  35. //Base& base = pitem->getBase();
  36. std::vector<Item*> items = ppacket->getVitem();
  37. for (size_t i = 0; i < items.size(); ++i) //遍历容器中的所有元素
  38. {
  39. sParaRegAddr = items[i]->getBase().getParam("起始地址");
  40. iParaRegAddr = strtol(sParaRegAddr.c_str(), NULL, HEX);
  41. if (iParaRegAddr > maxRegAddr) //更新寄存器数量最大值
  42. {
  43. maxRegAddr = iParaRegAddr;
  44. }
  45. else
  46. {
  47. }
  48. }
  49. log_i("最大的起始地址:0x%x", maxRegAddr);
  50. return maxRegAddr;
  51. }
  52. int ProtocolImpl::getRegAddrMin(Packet *ppacket, Item *pitem)
  53. {
  54. std::string sMinRegAddr;
  55. int iMinRegAddr = 0;
  56. std::string sParaRegAddr;
  57. int iParaRegAddr;
  58. std::vector<Item*> items = ppacket->getVitem();
  59. log_i("Items size: %zu", items.size());
  60. sMinRegAddr = items[0]->getBase().getParam("起始地址");
  61. iMinRegAddr = strtol(sMinRegAddr.c_str(), NULL, HEX);
  62. log_i("Initial minimum register address value: 0x%x", iMinRegAddr);
  63. for (size_t i = 0; i < items.size(); ++i)
  64. {
  65. log_i("Processing item %zu", i);
  66. sParaRegAddr = items[i]->getBase().getParam("起始地址");
  67. iParaRegAddr = strtol(sParaRegAddr.c_str(), NULL, HEX);
  68. if (iParaRegAddr < iMinRegAddr)
  69. {
  70. iMinRegAddr = iParaRegAddr;
  71. }
  72. }
  73. log_i("最小的寄存器起始地址:0x%x", iMinRegAddr);
  74. return iMinRegAddr;
  75. }
  76. int ProtocolImpl::retStateResponse(Packet *ppacket, Item *pitem, const int len)
  77. {
  78. int maxRegAddr = -1;
  79. int minRegAddr = 0;
  80. int regNum = 0;
  81. int datasLen = 0;
  82. maxRegAddr = getRegAddrMax(ppacket, pitem);
  83. minRegAddr = getRegAddrMin(ppacket, pitem);
  84. regNum = maxRegAddr - minRegAddr + 1;
  85. log_i("reg:%d", regNum);
  86. datasLen = getRealValidLen(regNum);
  87. log_i("最大寄存器地址:0x%x,最小寄存器数量:0x%x,寄存器个数:0x%x,数据长度:%d,合法的数据长度=%d", maxRegAddr,
  88. minRegAddr, regNum, datasLen, len);
  89. if (len >= datasLen)
  90. {
  91. return S_OK;
  92. }
  93. else
  94. {
  95. return S_FALSE;
  96. }
  97. return S_FALSE;
  98. }
  99. int ProtocolImpl::getRealValidLen(int maxRegNum)
  100. {
  101. int len = 0;
  102. if (maxRegNum <= 4 && maxRegNum > 0)
  103. {
  104. len = 4 + 2 * maxRegNum;
  105. log_i("寄存器数量小于等于4个,计算得出合法数据长度:%d", len);
  106. }
  107. else
  108. {
  109. if (maxRegNum % 4 == 0)
  110. {
  111. len = 12 * (maxRegNum / 4);
  112. log_i("寄存器请求数量:%d,回复帧长度:%d",maxRegNum,len);
  113. }
  114. else
  115. {
  116. len = 4*((maxRegNum / 4) +1) + (maxRegNum *2); //帧数据长度+寄存器长度
  117. log_i("寄存器请求数量:%d,回复帧长度:%d",maxRegNum,len);
  118. }
  119. }
  120. return len;
  121. }
  122. int ProtocolImpl::getRealFrame(PBYTE pbuf, int count)
  123. {
  124. PBYTE ptemp = pbuf;
  125. int id = (((ptemp[0 + count] << 24) & 0xff000000)
  126. | ((ptemp[1 + count] << 16) & 0x00ff0000)
  127. | ((ptemp[2 + count] << 8) & 0x0000ff00)
  128. | ((ptemp[3 + count]) & 0x000000ff));
  129. log_i("帧id:0x%x", id);
  130. return id;
  131. }
  132. std::map<int, int> ProtocolImpl::handleDataLess(PBYTE pbuf,int len,int regNum,int datasLen)
  133. {
  134. int iPbufId;
  135. std::map<int, int> dataSet;
  136. iPbufId = getRealFrame(pbuf, 0);
  137. for (int i = 0; i < regNum; i++)
  138. {
  139. uint16_t regValue = 0;
  140. if (i * 2 + 4 <= datasLen)
  141. {
  142. regValue = (pbuf[i * 2 + 4] << 8) | pbuf[i * 2 + 5]; // 提取寄存器值
  143. dataSet[iPbufId + i] = regValue; // 绑定到map
  144. }
  145. else
  146. {
  147. log_i(
  148. "Data insufficient for regNum %d, setting default value 0xFFFF",
  149. i);
  150. // 数据不足,处理错误或默认值
  151. regValue = 0xFFFF; // 默认值为;0xFFFF
  152. dataSet[iPbufId + i] = regValue; // 绑定到map
  153. log_i("Added to dataSet: addrFrame=0x%x, value=0x%x", iPbufId + i,
  154. regValue);
  155. }
  156. }
  157. for (const auto &entry : dataSet)
  158. {
  159. log_i("addrFrame = 0x%x, value = 0x%x", entry.first, entry.second);
  160. }
  161. return dataSet;
  162. }
  163. std::map<int,int> ProtocolImpl::handleDataGreater(PBYTE pbuf,int len,int regNum,int datasLen)
  164. {
  165. int validlen = len;
  166. int iPbufId;
  167. std::map<int, int> dataSet;
  168. for (int count = 0;
  169. ((count < validlen) && ((validlen - count) >= 12));
  170. count += 12)
  171. {
  172. iPbufId = getRealFrame(pbuf, count);
  173. for (int i = 0; i < 4 && regNum > 0; i++,regNum --) // i代表第i个寄存器
  174. {
  175. uint16_t regValue = 0;
  176. if (i * 2 + 4 + count <= datasLen) //当前寄存器数量的总帧数
  177. {
  178. regValue = (pbuf[i * 2 + 4 + count] << 8)
  179. | pbuf[i * 2 + 5 + count]; // 提取寄存器值
  180. dataSet[iPbufId + i % 4] = regValue; // 绑定到map
  181. }
  182. else
  183. {
  184. // 数据不足,处理错误或默认值
  185. regValue = 0xFFFF; // 默认值为0xFFFF
  186. dataSet[iPbufId + i % 4] = regValue; // 绑定到map
  187. }
  188. }
  189. for (const auto &entry : dataSet)
  190. {
  191. log_i("addrFrame = 0x%x, value = 0x%x", entry.first,
  192. entry.second);
  193. }
  194. }
  195. return dataSet;
  196. }
  197. std::map<int,int>ProtocolImpl::retDataSet(Packet *ppacket, Item *pitem,PBYTE pbuf,int len)
  198. {
  199. std::map<int, int> dataSet; // 存储寄存器地址和值
  200. int maxRegAddr, minRegAddr, regNum;
  201. int datasLen = 0;
  202. maxRegAddr = getRegAddrMax(ppacket, pitem);
  203. minRegAddr = getRegAddrMin(ppacket, pitem);
  204. regNum = maxRegAddr - minRegAddr + 1;
  205. datasLen = getRealValidLen(regNum);
  206. if (datasLen <= 12)
  207. {
  208. dataSet = handleDataLess(pbuf,len,regNum,datasLen);
  209. }
  210. else
  211. {
  212. dataSet = handleDataGreater(pbuf,len,regNum,datasLen);
  213. }
  214. return dataSet;
  215. }
  216. int ProtocolImpl::iGetItemParaConfig(Item *pitem,std::string attribute)
  217. {
  218. Item *t_item = pitem;
  219. Base &t_base = t_item->getBase();
  220. string sAttribute = "";
  221. int iAttribute = 0;
  222. sAttribute = t_base.getParam(attribute);
  223. log_i("%s: %s",attribute.c_str(), sAttribute.c_str());
  224. iAttribute = strtol(sAttribute.c_str(), NULL, HEX);
  225. log_i("retV:0x%x",iAttribute);
  226. return iAttribute;
  227. }
  228. std::string ProtocolImpl::sGetItemParaConfig(Item *pitem, std::string attribute)
  229. {
  230. Item *t_item = pitem;
  231. Base &t_base = t_item->getBase();
  232. string sAttribute = "";
  233. sAttribute = t_base.getParam(attribute);
  234. log_i("%s: %s",attribute.c_str(), sAttribute.c_str());
  235. return sAttribute;
  236. }
  237. void ProtocolImpl::setData(Item *pitem,int16_t pbuf,int receiveData,int paraData,std::string t_sDataType,std::string t_sByteOrder,string t_sBits)
  238. {
  239. Item* t_item = pitem;
  240. int16_t buf = pbuf;
  241. string t_str;
  242. char t[256];
  243. log_i("receiveData:0x%x,paraData:0x%x",receiveData,paraData);
  244. if(receiveData == paraData)
  245. {
  246. log_i("ID匹配,处理数据");
  247. if (t_sDataType == "I")
  248. {
  249. log_i("数据类型为I,调用merge16函数,buf=0x%x",buf);
  250. t_item->setValue(merge16(buf, t_sByteOrder));
  251. }
  252. else if (t_sDataType == "UI")
  253. {
  254. log_i("数据类型为UI,调用merge16函数");
  255. t_item->setValue(merge16(buf, t_sByteOrder));
  256. }
  257. else if (t_sDataType == "B")
  258. {
  259. int index = t_sBits.find(".");
  260. if (index != -1)
  261. {
  262. string t_sBitnum = t_sBits.substr(0,index);
  263. int t_iBitnum =(int) (strtol(t_sBitnum.c_str(),NULL, 10)); //----位起始地址
  264. int t_Bits =(int) (strtol(t_sBits.substr(index + 1).c_str(),NULL, 10));
  265. unsigned short t_usdata =(unsigned short) (strtol(merge16_u(buf,t_sByteOrder).c_str(),NULL, 10));
  266. unsigned short bits = 0;
  267. for (int i = 0; i < t_Bits; i++)
  268. {
  269. unsigned short bit = (t_usdata >> (t_iBitnum + i))& 0x0001;
  270. bits += bit * pow(2, i);
  271. }
  272. snprintf(t, 256, "%d", bits);
  273. t_str = t;
  274. t_item->setValue(t_str);
  275. }
  276. }
  277. }
  278. }
  279. HRESULT ProtocolImpl::queryInterface(const IID &iid, void **ppv)
  280. {
  281. if (iid == IID_IProtocol)
  282. {
  283. log_d( "成功返回Protocol-CANDEXN协议句柄");
  284. *ppv = static_cast<ProtocolI*>(this);
  285. }
  286. else if (iid == IID_IUnknown)
  287. {
  288. log_d( "成功返回Protocol-CANDEXN协议IUnknown句柄");
  289. *ppv = static_cast<IUnknown*>(this);
  290. }
  291. else
  292. {
  293. log_d( "未查询到接口");
  294. *ppv = NULL;
  295. return E_NOINTERFACE;
  296. }
  297. reinterpret_cast<IUnknown*>(*ppv)->addRef();
  298. return S_OK;
  299. }
  300. ULONG ProtocolImpl::addRef(void)
  301. {
  302. return ++m_cRef;
  303. }
  304. ULONG ProtocolImpl::release(void)
  305. {
  306. if (--m_cRef == 0)
  307. {
  308. delete this;
  309. return 0;
  310. }
  311. return m_cRef;
  312. }
  313. ULONG ProtocolImpl::getVersion()
  314. {
  315. return VERSION;
  316. }
  317. /**
  318. * @content:组织读数据报文
  319. * @time:2016-9-9
  320. * @author:Mr_zhu
  321. * @param: pdevice(设备句柄),ppacket(包句柄),pitem(点句柄),pbuf(数据缓冲区),len(返回报文长度)
  322. * @return: HRESULT(S_OK,S_FALSE)
  323. * @decribe
  324. * 1#2016-9-9#V1.0#首次生成
  325. */
  326. HRESULT ProtocolImpl::onRead(Device *pdevice, Packet *ppacket, Item *pitem,
  327. PBYTE pbuf, int &len)
  328. {
  329. log_i("onRead");
  330. if (ppacket->getVitem().size() == 0)
  331. {
  332. return S_FALSE;
  333. }
  334. pdevice->getBase().setRwstate(READ_WAIT); //----设置设备状态
  335. std::string sParaId;
  336. int iParaId;
  337. Base &t_base = ppacket->getVitem().at(0)->getBase();
  338. sParaId = t_base.getParam("功能码");
  339. log_i("Parameter ID: %s", sParaId.c_str());
  340. iParaId = strtol(sParaId.c_str(), NULL, HEX);
  341. log_i("Parameter ID: %s", sParaId.c_str());
  342. log_i("Converted Parameter ID: 0x%x", iParaId);
  343. int frameFuncCode = (iParaId & 0x070000);
  344. log_i("frameFuncCode = 0x%x",frameFuncCode);
  345. if (ppacket == nullptr || pitem == nullptr)
  346. {
  347. log_i("Invalid packet or item");
  348. return S_FALSE;
  349. }
  350. string t_saddr;
  351. t_saddr = pdevice->getBase().getParam("站地址");
  352. int t_iaddr = 0;
  353. t_iaddr = strtol(t_saddr.c_str(), NULL, HEX);
  354. log_i("stationAddr = %d",t_iaddr);
  355. iParaId |= (t_iaddr << 19);
  356. log_i("onread -addStation-id = 0x%x",iParaId);
  357. //判断寄存器是读寄存器
  358. if(frameFuncCode == 0x030000)
  359. {
  360. int maxRegAddr = getRegAddrMax(ppacket, pitem);
  361. int minRegAddr = getRegAddrMin(ppacket, pitem);
  362. log_i("MaxRegAddr: 0x%x, MinRegAddr: 0x%x", maxRegAddr, minRegAddr);
  363. if (maxRegAddr < minRegAddr)
  364. {
  365. log_i("Invalid register address range");
  366. return S_FALSE;
  367. }
  368. int regNum = maxRegAddr - minRegAddr + 1;
  369. pbuf[0] = retBigEndian(iParaId + minRegAddr, 24);
  370. pbuf[1] = retBigEndian(iParaId + minRegAddr, 16);
  371. pbuf[2] = retBigEndian(iParaId + minRegAddr, 8);
  372. pbuf[3] = retBigEndian(iParaId + minRegAddr, 0);
  373. pbuf[4] = retBigEndian(regNum, 8);
  374. pbuf[5] = retBigEndian(regNum, 0);
  375. len = 6;
  376. if (pbuf == nullptr)
  377. {
  378. log_i("pbuf is null");
  379. return S_FALSE;
  380. }
  381. for (int i = 0; i < 6; i++)
  382. {
  383. log_i("onRead-读数据:pbuf[%d]:0x%x", i, pbuf[i]);
  384. }
  385. }
  386. Channel *pC = pdevice->getParent();
  387. log_i("Channel pointer: %p", pC);
  388. if (pC == nullptr)
  389. {
  390. log_i("Channel pointer is null");
  391. return S_FALSE;
  392. }
  393. if (pC != NULL)
  394. {
  395. if (m_tmpItems.count(pC->getBase().getObjid().toString()) == 0)
  396. {
  397. log_i("Temporary items not found for Channel ID: %s",
  398. pC->getBase().getObjid().toString().c_str());
  399. int ccount = pC->getDeviceCount();
  400. log_i("Channel device count: %d", ccount);
  401. std::multimap<int, Item*> tmpItems;
  402. for (int i = 0; i < ccount; i++)
  403. {
  404. for (size_t j = 0;
  405. j < pC->getVDevice().at(i)->getVitem().size(); j++)
  406. {
  407. string t_sId;
  408. Base &t_base =
  409. pC->getVDevice().at(i)->getVitem().at(j)->getBase();
  410. t_sId = t_base.getParam("写功能码");
  411. log_i("写功能码: %s", t_sId.c_str());
  412. int t_iId = 0;
  413. t_iId = strtol(t_sId.c_str(), NULL, HEX); //----获取帧ID
  414. log_i("功能码转换为整数: 0x%x", t_iId);
  415. string t_stype;
  416. t_stype = t_base.getParam("帧类型");
  417. log_i("帧类型: %s", t_stype.c_str());
  418. if (t_stype == "1")
  419. {
  420. t_iId |= 0x80000000;
  421. log_i("帧类型为1,功能码更新为: 0x%x", t_iId);
  422. }
  423. string sStartAddr;
  424. //sStartAddr = pC->getVDevice().at(i)->getBase().getParam("起始地址");
  425. sStartAddr = t_base.getParam("起始地址");
  426. log_i("起始地址 =%s", sStartAddr.c_str());
  427. int iStartAddr = 0;
  428. iStartAddr = strtol(sStartAddr.c_str(), NULL, HEX);
  429. log_i("起始地址转换为整数: 0x%x", iStartAddr);
  430. t_iId += iStartAddr;
  431. string t_saddr;
  432. t_saddr = pC->getVDevice().at(i)->getBase().getParam("站地址");
  433. int t_iaddr = 0;
  434. t_iaddr = strtol(t_saddr.c_str(), NULL, HEX);
  435. t_iId |= (t_iaddr << 19);
  436. tmpItems.insert(
  437. make_pair(t_iId,
  438. pC->getVDevice().at(i)->getVitem().at(j)));
  439. log_i("插入临时条目: ID=0x%x", t_iId);
  440. }
  441. }
  442. m_tmpItems.insert(
  443. make_pair(pC->getBase().getObjid().toString(), tmpItems));
  444. }
  445. else
  446. {
  447. log_i("Temporary items already exist for Channel ID: %s",
  448. pC->getBase().getObjid().toString().c_str());
  449. }
  450. }
  451. return S_OK;
  452. }
  453. /**
  454. * @content:组织写数据报文
  455. * @time:2016-9-9
  456. * @author:Mr_zhu
  457. * @param: pdevice(设备句柄),ppacket(包句柄),pitem(点句柄),pbuf(数据缓冲区),len(返回报文长度)
  458. * @param: swritebuf(待写字符串),writelen(待写数据长度)
  459. * @return: HRESULT(S_OK,S_FALSE)
  460. * @decribe
  461. * 1#2016-9-9#V1.0#首次生成
  462. */
  463. HRESULT ProtocolImpl::onWrite(Device *pdevice, Packet *ppacket, Item *pitem,
  464. PBYTE pbuf, int &len, string swritebuf, const unsigned int writelen)
  465. {
  466. log_i("onWrite");
  467. int t_len = 0;
  468. Base &base = pitem->getBase();
  469. string t_sRWType;
  470. t_sRWType = base.getParam("读写类型"); //----获取点读写类型
  471. if (t_sRWType == "RO") //----只读
  472. {
  473. log_w("%s, 对只读点进行非法写操作,点信息(UUID-%s,名称-%s)",
  474. pdevice->getBase().getName().c_str(),
  475. base.getObjid().toString().c_str(), base.getName().c_str());
  476. return S_FALSE;
  477. }
  478. string t_sFuncCode;
  479. t_sFuncCode = base.getParam("功能码");
  480. int t_iFuncCode = 0;
  481. t_iFuncCode = strtol(t_sFuncCode.c_str(), NULL, HEX); //----获取帧ID
  482. string t_sStartAddr;
  483. int t_iStartAddr = 0; //----起始地址
  484. t_sStartAddr = base.getParam("起始地址");
  485. t_iStartAddr = strtol(t_sStartAddr.c_str(), NULL, 16);
  486. t_iFuncCode += t_iStartAddr;
  487. string t_saddr;
  488. t_saddr = pdevice->getBase().getParam("站地址");
  489. int t_iaddr = 0;
  490. t_iaddr = strtol(t_saddr.c_str(), NULL, HEX);
  491. t_iFuncCode |= (t_iaddr << 19);
  492. *(pbuf + (t_len++)) = HHByte(t_iFuncCode);
  493. *(pbuf + (t_len++)) = HLByte(t_iFuncCode);
  494. *(pbuf + (t_len++)) = LHByte(t_iFuncCode);
  495. *(pbuf + (t_len++)) = LLByte(t_iFuncCode); //----发送帧ID
  496. if (ppacket != NULL && pdevice != NULL && pitem != NULL)
  497. {
  498. struct candata t_data =
  499. //{ 0, 0, 0, 0, 0, 0, 0, 0 };
  500. { 0, 0 };
  501. if (m_tmpwritedata.count(t_sFuncCode) > 0)
  502. {
  503. t_data = m_tmpwritedata.find(t_sFuncCode)->second;
  504. }
  505. *(pbuf + (t_len++)) = t_data.data0 & 0x00ff;
  506. *(pbuf + (t_len++)) = t_data.data1 & 0x00ff;
  507. // *(pbuf + (t_len++)) = t_data.data2 & 0x00ff;
  508. // *(pbuf + (t_len++)) = t_data.data3 & 0x00ff;
  509. // *(pbuf + (t_len++)) = t_data.data4 & 0x00ff;
  510. // *(pbuf + (t_len++)) = t_data.data5 & 0x00ff;
  511. // *(pbuf + (t_len++)) = t_data.data6 & 0x00ff;
  512. // *(pbuf + (t_len++)) = t_data.data7 & 0x00ff;
  513. string t_sDataType; //----数据类型
  514. t_sDataType = base.getParam("数据类型");
  515. string t_sByteOrder;
  516. t_sByteOrder = base.getParam("字节序");
  517. if (t_sDataType == "I" || t_sDataType == "UI")
  518. {
  519. long int value = 0;
  520. value = strtol(swritebuf.c_str(), NULL, 10);
  521. if (t_sByteOrder == "BA")
  522. {
  523. pbuf[4] = HByte(value);
  524. pbuf[5] = LByte(value);
  525. }
  526. else if (t_sByteOrder == "AB")
  527. {
  528. pbuf[4] = LByte(value);
  529. pbuf[5] = HByte(value);
  530. }
  531. }
  532. }
  533. len = 6;
  534. struct candata data;
  535. data.data0 = pbuf[4] & 0x00ff;
  536. data.data1 = pbuf[5] & 0x00ff;
  537. // data.data2 = pbuf[6] & 0x00ff;
  538. // data.data3 = pbuf[7] & 0x00ff;
  539. // data.data4 = pbuf[8] & 0x00ff;
  540. // data.data5 = pbuf[9] & 0x00ff;
  541. // data.data6 = pbuf[10] & 0x00ff;
  542. // data.data7 = pbuf[11] & 0x00ff;
  543. std::string sbuf;
  544. for (int i = 0; i < 12; i++)
  545. {
  546. char str[10];
  547. snprintf(str, 10, "%x", pbuf[i]);
  548. sbuf = sbuf + str;
  549. if (i != (12 - 1))
  550. {
  551. sbuf = sbuf + ",";
  552. }
  553. }
  554. log_i( "待发送数据为: %s", sbuf.c_str());
  555. log_i( "%%x, %x", data.data0, data.data1);
  556. m_tmpwritedata[t_sFuncCode] = data;
  557. pitem->setValue(swritebuf);
  558. // pdevice->getBase().setRwstate(WRITE_O);
  559. pdevice->getBase().setRwstate(WRITE_WAIT);
  560. return S_OK;
  561. }
  562. /**
  563. * @content:判断回复数据是否接收完成
  564. * @time:2016-9-9
  565. * @author:Mr_zhu
  566. * @param: pdevice(设备句柄),ppacket(包句柄),pitem(点句柄),pbuf(数据缓冲区),len(返回报文长度)
  567. * @return: HRESULT(S_OK,S_FALSE)
  568. * @decribe
  569. * 1#2016-9-9#V1.0#首次生成
  570. */
  571. HRESULT ProtocolImpl::isResponseOK(Device *pdevice, Packet *ppacket,
  572. Item *pitem, PBYTE pbuf, const int len)
  573. {
  574. log_i("isResponseOk");
  575. int ret;
  576. switch (pdevice->getBase().getRwstate())
  577. {
  578. case READ_O:
  579. case WRITE_WAIT:
  580. case READ_WAIT:
  581. ret = retStateResponse(ppacket, pitem, len);
  582. log_i("isResponseOK返回值:%d", ret);
  583. if (ret == S_OK)
  584. {
  585. return S_OK;
  586. }
  587. else
  588. {
  589. if (ret == S_FALSE)
  590. {
  591. return S_FALSE;
  592. }
  593. }
  594. return S_FALSE;
  595. case WRITE_O:
  596. //case WRITE_WAIT:
  597. return S_OK;
  598. }
  599. return S_FALSE;
  600. }
  601. /**
  602. * @content:解析数据
  603. * @time:2016-9-9
  604. * @author:Mr_zhu
  605. * @param: pdevice(设备句柄),ppacket(包句柄),pitem(点句柄),pbuf(数据缓冲区),len(返回报文长度),deletelen(待删除数据长度)
  606. * @return: HRESULT(S_OK,S_FALSE)
  607. * @decribe
  608. * 1#2016-9-9#V1.0#首次生成
  609. */
  610. HRESULT ProtocolImpl::onResponse(Device *pdevice, Packet *ppacket, Item *pitem,
  611. PBYTE pbuf, const int len, int &deletelen)
  612. {
  613. log_i("onResponse");
  614. int validlen = len;
  615. int t_iRWState = pdevice->getBase().getRwstate(); //----设备读写状态
  616. Base *pbase = new Base();
  617. Base &base = *pbase;
  618. std::vector<Item*> items = ppacket->getVitem();
  619. std::map<int, int> dataSet; // 存储寄存器地址和值
  620. int id;
  621. int16_t buf;
  622. Channel *pC = pdevice->getParent();
  623. if (pC == NULL)
  624. {
  625. log_e("%s, 父通道为空, 无法进行数据解析", pdevice->getBase().getName().c_str());
  626. return S_FALSE;
  627. }
  628. switch (t_iRWState)
  629. {
  630. case READ_O:
  631. case READ_WAIT:
  632. case WRITE_WAIT:
  633. log_i("WRITE_WAIT");
  634. if (validlen >= 6)
  635. {
  636. dataSet=retDataSet(ppacket, pitem,pbuf,len);
  637. log_i("pbuf[4]= 0x%x,pbuf[5] = 0x%x",pbuf[4],pbuf[5]);
  638. for (const auto &entry : dataSet)
  639. {
  640. log_i("addrFrame = 0x%x, value = 0x%x", entry.first,
  641. entry.second);
  642. }
  643. for (const auto &dataPair : dataSet)
  644. {
  645. log_i("addData.size=%d", dataSet.size());
  646. id = dataPair.first;
  647. id = (0x7fffffff) & id;
  648. buf = dataPair.second;
  649. log_i("dataPair.second =0x%x",buf);
  650. //buf = (PBYTE) &dataPair.second;
  651. //log_i("buf[0] =0x%x,buf[1] =0x%x",buf[0],buf[1]);
  652. log_i("Processing data pair with ID: 0x%x", id);
  653. if (m_tmpItems.count(pC->getBase().getObjid().toString()) > 0)
  654. {
  655. log_i("Found temporary items for Channel ID: %s",
  656. pC->getBase().getObjid().toString().c_str());
  657. std::multimap<int, Item*> tmpItms = m_tmpItems.find(
  658. pC->getBase().getObjid().toString())->second; //是否有效
  659. for (const auto &data : tmpItms)
  660. {
  661. log_i("缓存条目中的缓存地址:0x%x,0x%x", data.first, data.second);
  662. }
  663. log_i("Temporary items size: %zu", tmpItms.size());
  664. std::multimap<int, Item*>::size_type cnt = tmpItms.count(
  665. id);
  666. log_i("Number of items with ID 0x%x: %zu", id, cnt);
  667. std::multimap<int, Item*>::iterator iter = tmpItms.find(id);
  668. if (iter != tmpItms.end())
  669. {
  670. for (; cnt > 0; cnt--, iter++)
  671. {
  672. log_i("Processing item %zu for ID 0x%x", cnt, id);
  673. Item *t_item = iter->second;
  674. //Device *ptdevice = (Device*) (t_item->getParent());
  675. if (t_item != NULL && pdevice != NULL)
  676. {
  677. log_i("Item and Device are valid");
  678. int iId = iGetItemParaConfig(t_item,"写功能码");
  679. int iStartAddr = iGetItemParaConfig(t_item,"起始地址");
  680. string t_stype = sGetItemParaConfig(t_item,"帧类型");
  681. string t_sDataType = sGetItemParaConfig(t_item,"数据类型");
  682. string t_sByteOrder = sGetItemParaConfig(t_item,"字节序");
  683. string t_sBits= sGetItemParaConfig(t_item ,"位地址");
  684. iId += 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. log_i("t_iId = 0x%x,t_iaddr =%d,",iId,t_iaddr);
  690. iId |= (t_iaddr << 19);
  691. log_i("设置的数据buf=%d,paraID = 0x%x",buf,iId);
  692. setData(t_item, buf,id,iId,t_sDataType,t_sByteOrder,t_sBits);
  693. }
  694. else
  695. {
  696. if(t_item == NULL)
  697. {
  698. log_i("......item== NULL......");
  699. }
  700. return S_FALSE;
  701. }
  702. }
  703. }
  704. }
  705. else
  706. {
  707. log_i("m_tmpItems.count(pC->getBase().getObjid().toString()) <0");
  708. return S_FALSE;
  709. }
  710. }
  711. return S_OK;
  712. }
  713. if (pitem != nullptr)
  714. {
  715. delete pitem;
  716. }
  717. break;
  718. case WRITE_O:
  719. break;
  720. default:
  721. break;
  722. }
  723. if (pbase != NULL)
  724. {
  725. delete pbase;
  726. pbase = NULL;
  727. }
  728. return S_OK;
  729. }
  730. #ifdef __cplusplus
  731. extern "C" IUnknown* CreateInstance()
  732. {
  733. IUnknown *pI = static_cast<ProtocolI*>(new ProtocolImpl());
  734. pI->addRef();
  735. return pI;
  736. }
  737. #endif