UartContext.cpp 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378
  1. /*
  2. * UartContext.cpp
  3. *
  4. */
  5. #include <stdio.h>
  6. #include <unistd.h>
  7. #include <fcntl.h>
  8. #include <memory.h>
  9. #include <termio.h>
  10. #include <string>
  11. #include <sys/ioctl.h>
  12. #include "uart/UartContext.h"
  13. #include "utils/Log.h"
  14. #include "utils/ByteUtil.h"
  15. #include "base/strings.hpp"
  16. #include "service/BusinessConfig.h"
  17. #define UART_DATA_BUF_LEN 16384 // 16KB
  18. extern int parseProtocol(const BYTE *pData, UINT len);
  19. extern void buildProtocolData(std::string info);
  20. static const char* getBaudRate(UINT baudRate) {
  21. struct {
  22. UINT baud;
  23. const char *pBaudStr;
  24. } baudInfoTab[] = {
  25. { B1200, "B1200" },
  26. { B2400, "B2400" },
  27. { B4800, "B4800" },
  28. { B9600, "B9600" },
  29. { B19200, "B19200" },
  30. { B38400, "B38400" },
  31. { B57600, "B57600" },
  32. { B115200, "B115200" },
  33. { B230400, "B230400" },
  34. { B460800, "B460800" },
  35. { B921600, "B921600" }
  36. };
  37. int len = sizeof(baudInfoTab) / sizeof(baudInfoTab[0]);
  38. for (int i = 0; i < len; ++i) {
  39. if (baudInfoTab[i].baud == baudRate) {
  40. return baudInfoTab[i].pBaudStr;
  41. }
  42. }
  43. return NULL;
  44. }
  45. UartContext::UartContext(int uartNum) :
  46. mIsOpen(false),
  47. mUartID(0),
  48. mDataBufPtr(NULL),
  49. mDataBufLen(0),
  50. mUartNumber(uartNum){
  51. }
  52. UartContext::~UartContext() {
  53. delete[] mDataBufPtr;
  54. closeUart();
  55. }
  56. static bool mUart1IsOpen = false;
  57. static bool mUart2IsOpen = false;
  58. static bool mUart3IsOpen = false;
  59. // 打开串口,pFileName为串口号,baudRate为波特率
  60. bool UartContext::openUart(const char *pFileName, UINT baudRate) {
  61. // LOGD("打开串口 串口号 = %s, 波特率 = %s\n", pFileName, getBaudRate(baudRate));
  62. mUartID = open(pFileName, O_RDWR|O_NOCTTY); // mUartID等于打开的串口
  63. if (mUartID <= 0) {
  64. mIsOpen = false;
  65. if(mUartNumber == 1) {
  66. mUart1IsOpen = false;
  67. }
  68. if(mUartNumber == 2) {
  69. mUart2IsOpen = false;
  70. }
  71. if(mUartNumber == 3) {
  72. mUart3IsOpen = false;
  73. }
  74. LOGD("uart%d open error", mUartNumber);
  75. } else {
  76. struct termios oldtio = { 0 };
  77. struct termios newtio = { 0 };
  78. tcgetattr(mUartID, &oldtio);
  79. newtio.c_cflag = baudRate|CS8|CLOCAL|CREAD;
  80. newtio.c_iflag = 0; // IGNPAR | ICRNL
  81. newtio.c_oflag = 0;
  82. newtio.c_lflag = 0; // ICANON
  83. newtio.c_cc[VTIME] = 0; /* inter-character timer unused */
  84. newtio.c_cc[VMIN] = 1; /* blocking read until 1 character arrives */
  85. tcflush(mUartID, TCIOFLUSH);
  86. tcsetattr(mUartID, TCSANOW, &newtio);
  87. // 设置为非阻塞 Set to non-blocking
  88. fcntl(mUartID, F_SETFL, O_NONBLOCK);
  89. mIsOpen = run("uart");
  90. if (!mIsOpen) {
  91. close(mUartID);
  92. mUartID = 0;
  93. }
  94. if(mUartNumber == 1) {
  95. mUart1IsOpen = true;
  96. }
  97. if(mUartNumber == 2) {
  98. mUart2IsOpen = true;
  99. }
  100. if(mUartNumber == 3) {
  101. mUart3IsOpen = true;
  102. }
  103. LOGD("openUart mIsOpen = %d\n", mIsOpen);
  104. }
  105. return mIsOpen;
  106. }
  107. void UartContext::closeUart() {
  108. LOGD("closeUart mIsOpen: %d...\n", mIsOpen);
  109. if (mIsOpen) {
  110. requestExit();
  111. close(mUartID);
  112. mUartID = 0;
  113. mIsOpen = false;
  114. }
  115. }
  116. // 发送串口消息
  117. bool UartContext::send(const BYTE *pData, UINT len) {
  118. // 这里是串口没有打开
  119. if (!mIsOpen) {
  120. LOGD("uart%d not opend", mUartNumber);
  121. return false;
  122. }
  123. int ret = write(mUartID, pData, len); // 这是发送串口消息
  124. if (ret != (int) len) { // 这里是发送失败
  125. LOGD("发送串口消息失败\n");
  126. return false;
  127. }
  128. std::string logInfo = " >>> ";
  129. for (int i = 0; i < len; ++i) {
  130. logInfo += base::format("%02x",pData[i]);
  131. }
  132. LOGD("%s",logInfo.c_str());
  133. // success
  134. LOGD("send Success\n");
  135. return true;
  136. }
  137. //UartContext* UartContext::getInstance() {
  138. // static UartContext sUC;
  139. // return &sUC;
  140. //}
  141. bool UartContext::readyToRun() {
  142. if (mDataBufPtr == NULL) {
  143. mDataBufPtr = new BYTE[UART_DATA_BUF_LEN];
  144. }
  145. if (mDataBufPtr == NULL) {
  146. closeUart();
  147. }
  148. return (mDataBufPtr != NULL);
  149. }
  150. void handleMsg(int ret, unsigned char* buffer) {
  151. std::string revStr = "";
  152. //依次将读取到的数据输出到日志
  153. for (int i = 1; i < ret - 2; ++i) {
  154. revStr += buffer[i];
  155. }
  156. buildProtocolData(revStr);
  157. }
  158. void handleMsg2(int ret, unsigned char* buffer) {
  159. std::string revStr = "";
  160. //std::string logInfo = " <<< ";
  161. //依次将读取到的数据输出到日志
  162. for (int i = 0; i < ret - 1; ++i) {
  163. revStr += buffer[i];
  164. }
  165. std::vector<std::string> tokens;
  166. std::string token;
  167. std::istringstream stream(revStr);
  168. while (std::getline(stream, token, 'F')) {
  169. if (!token.empty()) { // 确保 token 不为空
  170. size_t pos = token.find('$');
  171. if (pos != std::string::npos) {
  172. token = token.substr(pos + 1);
  173. tokens.push_back(token);
  174. }
  175. }
  176. }
  177. if (!tokens.empty()) {
  178. for (std::string t : tokens) {
  179. buildProtocolData(t);
  180. }
  181. }
  182. else {
  183. revStr = revStr.substr(1, revStr.length() - 3);
  184. buildProtocolData(revStr);
  185. }
  186. }
  187. void nfcMsg(int ret, unsigned char* buffer) {
  188. if (buffer[0] == 0xfe && buffer[2] == 0x03) {
  189. if (buffer[1] == 0x08) {
  190. std::string revStr = "";
  191. for (int i = 0; i < ret; ++i) {
  192. if (i==0 || i==1 || i==2 || i==3 || i==4 || i==ret-1){
  193. continue;
  194. }
  195. char buf[1024];
  196. sprintf(buf, "%02x", buffer[i]);
  197. revStr += buf;
  198. }
  199. LOGD("nfc卡号 == %s", revStr.c_str());
  200. // nfcLogin(revStr);
  201. navibarNfcLogin(revStr);
  202. }
  203. }
  204. }
  205. unsigned char handle2Buffer[1024] = {0};
  206. size_t offset = 0;
  207. bool UartContext::threadLoop() {
  208. if (mIsOpen) {
  209. #if 0
  210. // 可能上一次解析后有残留数据,需要拼接起来
  211. int readNum = read(mUartID, mDataBufPtr + mDataBufLen, UART_DATA_BUF_LEN - mDataBufLen);
  212. if (readNum > 0) {
  213. mDataBufLen += readNum;
  214. // 解析协议
  215. int len = parseProtocol(mDataBufPtr, mDataBufLen);
  216. if ((len > 0) && (len < mDataBufLen)) {
  217. // 将未解析的数据移到头部
  218. memcpy(mDataBufPtr, mDataBufPtr + len, mDataBufLen - len);
  219. }
  220. mDataBufLen -= len;
  221. } else {
  222. Thread::sleep(50);
  223. }
  224. #else
  225. unsigned char buffer[1024] = {0};
  226. int ret = read(mUartID, buffer, sizeof(buffer));
  227. if (ret > 0) {
  228. LOGD("收到串口消息");
  229. // std::string revStr = "";
  230. // std::string revStr2 = "";
  231. // for (int i = 0; i < ret; ++i) {
  232. // revStr += buffer[i];
  233. //
  234. // char buf[1024];
  235. // sprintf(buf, "%02x", buffer[i]);
  236. // revStr2 += buf;
  237. // }
  238. // LOGD("revStr == %s", revStr.c_str());
  239. // LOGD("revStr2 == %s", revStr2.c_str());
  240. if (mUartNumber == 2) {
  241. if (buffer[0]==CMD_HEAD && buffer[ret-2] == CMD_END1 && buffer[ret-1] == CMD_END2){
  242. handleMsg(ret, buffer);
  243. }
  244. }
  245. else if (mUartNumber == 1) {
  246. // LOGD("offset ===> %d", offset);
  247. ByteUtil::copyUnsignedCharArray(buffer, handle2Buffer, ret, offset);
  248. // LOGD("offset ===> %d", offset);
  249. if (handle2Buffer[0]==CMD_HEAD && handle2Buffer[offset-3] == CMD_END1) {
  250. handleMsg2(offset, handle2Buffer);
  251. offset = 0;
  252. std::fill(std::begin(handle2Buffer), std::end(handle2Buffer), 0);
  253. }
  254. else {
  255. if (handle2Buffer[0] != CMD_HEAD || offset > 70) {
  256. offset = 0;
  257. std::fill(std::begin(handle2Buffer), std::end(handle2Buffer), 0);
  258. LOGD("handle2Buffer 初始化");
  259. }
  260. }
  261. }
  262. else if (mUartNumber == 3) {
  263. nfcMsg(ret, buffer);
  264. }
  265. } else {
  266. //没收到数据时,休眠50ms,防止过度消耗cpu
  267. usleep(1000 * 50);
  268. }
  269. #endif
  270. return true;
  271. }
  272. return false;
  273. }
  274. static UartContext* uart0 = NULL;
  275. static UartContext* uart1 = NULL;
  276. static UartContext* uart2 = NULL;
  277. static UartContext* uart3 = NULL;
  278. void UartContext::init() {
  279. // uart0 = new UartContext(UART_TTYS0);
  280. // uart0->openUart("/dev/ttyS0", B115200);
  281. uart1 = new UartContext(UART_TTYS1);
  282. uart1->openUart("/dev/ttyS1", B115200);
  283. // 20221108的板子打开了串口2
  284. uart2 = new UartContext(UART_TTYS2);
  285. uart2->openUart("/dev/ttyS2", B115200);
  286. uart3 = new UartContext(UART_TTYS3);
  287. uart3->openUart("/dev/ttyS3", B115200);
  288. LOGD("打开串口");
  289. }
  290. void UartContext::destroy() {
  291. if (uart0) {
  292. delete uart0;
  293. uart0 = NULL;
  294. }
  295. if (uart1) {
  296. delete uart1;
  297. uart1 = NULL;
  298. }
  299. if (uart2) {
  300. delete uart1;
  301. uart2 = NULL;
  302. }
  303. if (uart3) {
  304. delete uart1;
  305. uart3 = NULL;
  306. }
  307. }
  308. bool UartContext::sendTo(int uart, const BYTE* pData, UINT len) {
  309. switch (uart) {
  310. case UART_TTYS0:
  311. return uart0->send(pData, len);
  312. case UART_TTYS1:
  313. return uart1->send(pData, len);
  314. case UART_TTYS2:
  315. return uart2->send(pData, len);
  316. case UART_TTYS3:
  317. return uart3->send(pData, len);
  318. }
  319. LOGD("无效的串口号");
  320. return false;
  321. }
  322. bool UartContext::Uart1IsOpen() {return mUart1IsOpen;}
  323. bool UartContext::Uart2IsOpen() {return mUart2IsOpen;}
  324. bool UartContext::Uart3IsOpen() {return mUart3IsOpen;}