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.

191 lines
6.6 KiB

2 years ago
1 year ago
2 years ago
1 year ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
1 year ago
2 years ago
1 year ago
2 years ago
2 years ago
1 year ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
1 year ago
2 years ago
2 years ago
1 year ago
2 years ago
1 year ago
2 years ago
2 years ago
2 years ago
1 year ago
1 year ago
1 year ago
2 years ago
2 years ago
2 years ago
  1. #include "zcanreceiverhost.hpp"
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. using namespace iflytop;
  6. #define TAG "ZCanReceiver"
  7. #define OVER_TIME_MS 5
  8. using namespace iflytop;
  9. ZCanReceiverHost::ZCanReceiverHost() {}
  10. void ZCanReceiverHost::initialize(string can_if_name, int baudrate, bool enablLoopback) {
  11. // m_iflytopCanProtocolStack.reset(new IflytopCanProtocolStack());
  12. m_can_if_name = can_if_name;
  13. m_baudrate = baudrate;
  14. m_enablLoopback = enablLoopback;
  15. resetSocketCan();
  16. }
  17. void ZCanReceiverHost::registerListener(onpacket_t onpacket) { m_onpacket = onpacket; }
  18. void ZCanReceiverHost::registerReportMsgListener(onreport_t onpacket) { m_onReportPacket = onpacket; }
  19. shared_ptr<ZCanReceiverCMD> ZCanReceiverHost::sendcmdblock(shared_ptr<ZCanReceiverCMD> cmd, int overtime_ms) { //
  20. lock_guard<mutex> lock(m_txblocklock);
  21. // 加这个延时是因为,曾经出现一个BUG,当发送一条指令成功后,立马下发第二条指令,第二条指令会发送失败,原因未知
  22. usleep(10 * 1000);
  23. m_index++;
  24. if (m_index == 0) {
  25. m_index = 1;
  26. }
  27. if (m_index == UINT16_MAX) {
  28. m_index = 1;
  29. }
  30. cmd->packetindex = m_index;
  31. {
  32. lock_guard<mutex> lock(m_txContextLock);
  33. m_txContext.txcmdcache = cmd;
  34. m_txContext.isReady = false;
  35. }
  36. auto enter = zsteady_clock().now();
  37. sendcmd(cmd->packetindex, cmd->cmdid, cmd->subcmdid, cmd->data, cmd->len);
  38. while (true) {
  39. if (m_txContext.isReady) {
  40. break;
  41. }
  42. if (zsteady_clock().elapsedTimeMs(enter) > overtime_ms) {
  43. break;
  44. }
  45. this_thread::sleep_for(chrono::milliseconds(1));
  46. }
  47. if (!m_txContext.isReady) {
  48. logger->warn("sendcmdblock(index {},cmd {},subcmd {}) fail,timeout", cmd->packetindex, cmd->cmdid, cmd->subcmdid);
  49. return nullptr;
  50. }
  51. usleep(10 * 1000);
  52. return m_txContext.rx;
  53. }
  54. void ZCanReceiverHost::sendcmd(uint16_t packetindex, uint16_t cmdid, uint8_t subcmdid, uint8_t *data, size_t len) {
  55. transmit_disinfection_protocol_header_t *header = (transmit_disinfection_protocol_header_t *)m_sendbuf;
  56. header->packetindex = packetindex;
  57. header->cmdid = cmdid;
  58. header->subcmdid = subcmdid;
  59. header->packetType = 0x00;
  60. memcpy(header->data, data, len);
  61. // printf("sendcmd(%d:%d:%d) ", packetindex, cmdid, subcmdid);
  62. // for (size_t i = 0; i < len; i++) {
  63. // printf("%02x ", data[i]);
  64. // }
  65. sendPacket(m_sendbuf, sizeof(transmit_disinfection_protocol_header_t) + len);
  66. }
  67. void ZCanReceiverHost::sendPacket(uint8_t *packet, size_t len) {
  68. /**
  69. * @brief
  70. */
  71. int npacket = len / 8 + (len % 8 == 0 ? 0 : 1);
  72. if (npacket > 255) {
  73. return;
  74. }
  75. int finalpacketlen = len % 8 == 0 ? 8 : len % 8;
  76. for (uint8_t i = 0; i < npacket; i++) {
  77. bool suc = false;
  78. if (i == npacket - 1) {
  79. suc = sendPacketSub(npacket, i, packet + i * 8, finalpacketlen, OVER_TIME_MS);
  80. } else {
  81. suc = sendPacketSub(npacket, i, packet + i * 8, 8, OVER_TIME_MS);
  82. }
  83. if (!suc) {
  84. logger->warn("sendPacket fail, packet(%d:%d)\n", npacket, i);
  85. return;
  86. }
  87. }
  88. }
  89. bool ZCanReceiverHost::sendPacketSub(int npacket, int packetIndex, uint8_t *packet, size_t len, int overtimems) {
  90. uint32_t id = (m_deviceId << 16) | (npacket << 8) | packetIndex;
  91. // m_comcan.sendframe(CANUSB_FRAME_EXTENDED, id, packet, len);
  92. // printf("sendPacketSub(%d:%d) ", npacket, packetIndex);
  93. // for (size_t i = 0; i < len; i++) {
  94. // printf("%02x ", packet[i]);
  95. // }
  96. // printf("\n");
  97. shared_ptr<SocketCanFrame> frame = SocketCanFrame::createExtDataFrame(id, packet, 8); /*TODO,这里如果不写8,会报错,原因未知*/
  98. m_socketCan->sendFrame(frame, overtimems);
  99. return true;
  100. }
  101. void ZCanReceiverHost::processOnePacket(CanPacketRxBuffer *rxbuf, uint8_t *packet, size_t len) { //
  102. transmit_disinfection_protocol_header_t *header = (transmit_disinfection_protocol_header_t *)packet;
  103. // uint8_t from = rxbuf->id;
  104. shared_ptr<ZCanReceiverCMD> rx = make_shared<ZCanReceiverCMD>();
  105. rx->packetindex = header->packetindex;
  106. rx->cmdid = header->cmdid;
  107. rx->subcmdid = header->subcmdid;
  108. rx->packetType = header->packetType;
  109. rx->len = len - sizeof(transmit_disinfection_protocol_header_t);
  110. memcpy(rx->data, header->data, rx->len);
  111. /**
  112. * @brief
  113. */
  114. // logger->info("processOnePacket(index {}, packetType {} ,cmd {},subcmd {}),rx(index {})", header->packetindex, header->packetType, header->cmdid,
  115. // header->subcmdid, rx->packetindex);
  116. if (header->packetType == kpt_ack || header->packetType == kpt_error_ack) {
  117. if (header->packetindex == m_txContext.txcmdcache->packetindex) {
  118. lock_guard<mutex> lock(m_txContextLock);
  119. logger->debug("rx ack");
  120. m_txContext.rx = rx;
  121. m_txContext.isReady = true;
  122. }
  123. return;
  124. } else if (header->packetType == kpt_status_report) {
  125. if (header->cmdid == kreport_h2o2_sensor_data) {
  126. if (m_onReportPacket) m_onReportPacket(packet, len);
  127. }
  128. }
  129. }
  130. void ZCanReceiverHost::processRx(shared_ptr<SocketCanFrame> frame) {
  131. uint8_t from = (frame->getId() >> 16 & 0xFF);
  132. uint8_t nframe = (frame->getId() & 0xFF00) >> 8;
  133. uint8_t frameId = (frame->getId() & 0x00FF);
  134. CanPacketRxBuffer *rxbuf = &m_canPacketRxBuffer[from];
  135. rxbuf->id = from;
  136. if (frameId == 0) {
  137. rxbuf->m_canPacketNum = 0;
  138. rxbuf->m_rxdataLen = 0;
  139. }
  140. if (rxbuf->m_canPacketNum < 255) {
  141. rxbuf->m_canPacket[rxbuf->m_canPacketNum] = frame;
  142. rxbuf->m_canPacketNum++;
  143. memcpy(rxbuf->m_rxdata + rxbuf->m_rxdataLen, frame->getData(), frame->getDlc());
  144. rxbuf->m_rxdataLen += frame->getDlc();
  145. }
  146. if (nframe == frameId + 1) {
  147. /**
  148. * @brief
  149. */
  150. processOnePacket(rxbuf, rxbuf->m_rxdata, rxbuf->m_rxdataLen);
  151. }
  152. }
  153. void ZCanReceiverHost::resetSocketCan() {
  154. auto socketCanConfig = make_shared<SocketCanConfig>();
  155. socketCanConfig->enablLoopback = m_enablLoopback; // 根据 SocketCan::dumpCanDriverInfo() 的输出,确定该标志位是false还是true
  156. socketCanConfig->m_canName = m_can_if_name;
  157. socketCanConfig->m_canBaudrate = m_baudrate;
  158. socketCanConfig->m_canfilters = {};
  159. logger->info("initialize() m_canName:{} {}", socketCanConfig->m_canName, socketCanConfig->m_canBaudrate);
  160. m_socketCan.reset(new SocketCan());
  161. m_socketCan->initialize(socketCanConfig);
  162. m_socketCan->startListen();
  163. m_socketCan->onSocketCanFrame.connect([this](shared_ptr<SocketCanFrame> canframe) { //
  164. logger->debug("onSocketCanFrame {}", canframe->toString());
  165. processRx(canframe);
  166. });
  167. }