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.

200 lines
5.9 KiB

4 months ago
4 months ago
4 months ago
  1. #include <fcntl.h>
  2. #include <stdint.h>
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include <termios.h>
  7. #include <unistd.h>
  8. //
  9. #include <arpa/inet.h>
  10. #include <netinet/in.h>
  11. #include <sys/socket.h>
  12. #include <sys/types.h>
  13. //
  14. #include <map>
  15. #include <set>
  16. #include <string>
  17. #include "uart_channel.hpp"
  18. #include "utils/stringutils.hpp"
  19. using namespace nlohmann;
  20. using namespace iflytop;
  21. static map<int, uint32_t> g_baundmap = {
  22. {0, 0000000}, {50, 0000001}, {75, 0000002}, {110, 0000003}, //
  23. {134, 0000004}, {150, 0000005}, {200, 0000006}, {300, 0000007}, //
  24. {600, 0000010}, {1200, 0000011}, {1800, 0000012}, {2400, 0000013}, //
  25. {4800, 0000014}, {9600, 0000015}, {19200, 0000016}, {38400, 0000017}, //
  26. {57600, 0010001}, {115200, 0010002}, {230400, 0010003}, {460800, 0010004}, //
  27. {500000, 0010005}, {576000, 0010006}, {921600, 0010007}, {1000000, 0010010}, //
  28. {1152000, 0010011}, {1500000, 0010012}, {2000000, 0010013}, {2500000, 0010014}, //
  29. {3000000, 0010015}, {3500000, 0010016}, {4000000, 0010017},
  30. };
  31. int findBaudrate(int baudrate) {
  32. auto baundrate_find_result = g_baundmap.find(baudrate);
  33. if (baundrate_find_result == g_baundmap.end()) {
  34. return -1;
  35. }
  36. return baundrate_find_result->second;
  37. }
  38. UartChannel::UartChannel(string chname, string ifname, int baudrate, bool hexch, int rxovertime) {
  39. logger = LoggerFactory.createRotatingFileLogger(chname);
  40. m_chname = chname;
  41. m_ifname = ifname;
  42. m_baudrate = baudrate;
  43. m_hexch = hexch;
  44. m_rxovertime = rxovertime;
  45. if (m_rxovertime == 0) {
  46. m_rxovertime = 1;
  47. }
  48. }
  49. void UartChannel::initialize() {
  50. m_uartHandler.name = (char*)m_ifname.c_str();
  51. m_uartHandler.rate = findBaudrate(m_baudrate);
  52. if (m_uartHandler.rate == -1) {
  53. logger->error("unsupport baudrate:{}", m_baudrate);
  54. m_errorFlag = true;
  55. m_errorMsg = "unsupport baudrate";
  56. return;
  57. }
  58. int suc = uartStart(&m_uartHandler);
  59. if (suc != 0) {
  60. logger->error("uartStart fail");
  61. m_errorFlag = true;
  62. m_errorMsg = "uart open fail";
  63. return;
  64. }
  65. m_rxthread.reset(new Thread(fmt::format("{}-rxthread", m_chname), [this]() {
  66. logger->info("{} rxthread start", m_chname);
  67. ThisThread thisThread;
  68. char rxcache[4096] = {0};
  69. int rxlen = 0;
  70. while (!thisThread.getExitFlag()) {
  71. int ret = uartReceive(&m_uartHandler, &rxcache[rxlen], 1024); // send the received text over UART
  72. if (ret < 0) {
  73. logger->error("uartReceive fail, ret:{}", ret);
  74. thisThread.sleepForMs(1000);
  75. continue;
  76. }
  77. if (ret > 0) {
  78. rxlen += ret;
  79. ::usleep(m_rxovertime * 1000);
  80. continue;
  81. }
  82. if (rxlen != 0 && ret == 0) {
  83. if (m_hexch) { // hex channel
  84. string rxhexstr = StringUtils().bytesToString((uint8_t*)rxcache, rxlen);
  85. logger->info("{} RX:-> {}({})", m_chname, rxhexstr, rxlen);
  86. if (m_ondata) m_ondata(this, true, rxcache, rxlen);
  87. } else { // str channel
  88. string rxstr(rxcache, rxlen);
  89. logger->info("{} RX:-> {}({})", m_chname, rxstr, rxlen);
  90. if (m_ondata) m_ondata(this, false, rxcache, rxlen);
  91. }
  92. rxlen = 0;
  93. }
  94. ::usleep(m_rxovertime * 1000);
  95. //
  96. } // end while
  97. }));
  98. return;
  99. }
  100. void UartChannel::senddata(bool binary, const char* data, size_t len) {
  101. string txdata(data, len);
  102. if ((m_hexch ^ binary)) {
  103. logger->warn("{} Skip Tx | data format error, channel is a {} channel", m_chname, m_hexch ? "hex" : "str");
  104. return;
  105. }
  106. if (m_errorFlag) {
  107. logger->warn("{} Skip Tx, due to errorflag", m_chname, txdata, len);
  108. return;
  109. }
  110. string txdatastr;
  111. if (binary) {
  112. txdatastr = StringUtils().bytesToString((uint8_t*)data, len);
  113. } else {
  114. txdatastr = txdata;
  115. }
  116. logger->info("{} TX:-> {}({})", m_chname, txdatastr, len);
  117. int txlen = 0;
  118. if (binary) {
  119. txlen = uartSend(&m_uartHandler, (char*)data, len);
  120. if (txlen != (int)len) logger->warn("tx fail");
  121. } else {
  122. txlen = uartSend(&m_uartHandler, txdatastr.c_str(), txdatastr.size());
  123. if (txlen != (int)txdatastr.size()) logger->warn("tx fail");
  124. }
  125. }
  126. void UartChannel::registerOnDataCallback(OnData_t ondata) { m_ondata = ondata; }
  127. void UartChannel::callcmd(string cmd, unordered_map<string, string> param, json& receipt) {
  128. logger->info("{} callcmd {} {}", m_chname, cmd, paramToString(param));
  129. if (cmd == "setBaudrate") {
  130. int rate = atoi(param["baudrate"].c_str());
  131. if (rate == 0) {
  132. logger->error("rate is 0");
  133. receipt["status"] = -1;
  134. receipt["msg"] = "rate is not support";
  135. return;
  136. }
  137. int setrate = findBaudrate(rate);
  138. if (setrate == -1) {
  139. logger->error("unsupport baudrate:{}", m_baudrate);
  140. receipt["status"] = -1;
  141. receipt["msg"] = "unsupport baudrate";
  142. return;
  143. }
  144. int suc = uartSetRate(&m_uartHandler, setrate);
  145. if (suc != 0) {
  146. logger->error("uartSetRate fail ,ecode = {}", strerror(errno));
  147. receipt["status"] = -1;
  148. receipt["msg"] = fmt::format("uartSetRate fail ,ecode = {}", strerror(errno));
  149. return;
  150. }
  151. m_baudrate = rate;
  152. receipt["status"] = 0;
  153. receipt["msg"] = "ok";
  154. } else if (cmd == "getBaudrate") {
  155. receipt["status"] = 0;
  156. receipt["data"]["baudrate"] = m_baudrate;
  157. } else {
  158. logger->error("unsupport cmd:{}", cmd);
  159. receipt["status"] = -1;
  160. receipt["msg"] = "unsupport cmd";
  161. }
  162. }
  163. list<string> UartChannel::getCmdList() {
  164. list<string> cmdlist;
  165. return cmdlist;
  166. }
  167. json UartChannel::getChannelInfo() {
  168. json info;
  169. info["name"] = m_chname;
  170. info["alias"] = getAlias();
  171. info["type"] = "uart";
  172. info["ifname"] = m_ifname;
  173. info["baudrate"] = m_baudrate;
  174. info["hexch"] = m_hexch;
  175. info["rxovertime"] = m_rxovertime;
  176. info["error"]["status"] = m_errorFlag;
  177. info["error"]["msg"] = m_errorMsg;
  178. return info;
  179. }