/* * UartContext.cpp * */ #include #include #include #include #include #include #include #include "uart/UartContext.h" #include "utils/Log.h" #include "base/strings.hpp" #include "service/BusinessConfig.h" #define UART_DATA_BUF_LEN 16384 // 16KB extern int parseProtocol(const BYTE *pData, UINT len); extern void buildProtocolData(std::string info); static const char* getBaudRate(UINT baudRate) { struct { UINT baud; const char *pBaudStr; } baudInfoTab[] = { { B1200, "B1200" }, { B2400, "B2400" }, { B4800, "B4800" }, { B9600, "B9600" }, { B19200, "B19200" }, { B38400, "B38400" }, { B57600, "B57600" }, { B115200, "B115200" }, { B230400, "B230400" }, { B460800, "B460800" }, { B921600, "B921600" } }; int len = sizeof(baudInfoTab) / sizeof(baudInfoTab[0]); for (int i = 0; i < len; ++i) { if (baudInfoTab[i].baud == baudRate) { return baudInfoTab[i].pBaudStr; } } return NULL; } UartContext::UartContext(int uartNum) : mIsOpen(false), mUartID(0), mDataBufPtr(NULL), mDataBufLen(0), mUartNumber(uartNum){ } UartContext::~UartContext() { delete[] mDataBufPtr; closeUart(); } static bool mUart1IsOpen = false; static bool mUart2IsOpen = false; static bool mUart3IsOpen = false; // 打开串口,pFileName为串口号,baudRate为波特率 bool UartContext::openUart(const char *pFileName, UINT baudRate) { // LOGD("打开串口 串口号 = %s, 波特率 = %s\n", pFileName, getBaudRate(baudRate)); mUartID = open(pFileName, O_RDWR|O_NOCTTY); // mUartID等于打开的串口 LOGD("mUartNumber == %d", mUartNumber); if (mUartID <= 0) { mIsOpen = false; if (mUartNumber == 1) { mUart1IsOpen = false; } if (mUartNumber == 2) { mUart2IsOpen = false; } if (mUartNumber == 3) { mUart3IsOpen = false; } LOGD("uart%d open error", mUartNumber); } else { struct termios oldtio = { 0 }; struct termios newtio = { 0 }; tcgetattr(mUartID, &oldtio); newtio.c_cflag = baudRate|CS8|CLOCAL|CREAD; newtio.c_iflag = 0; // IGNPAR | ICRNL newtio.c_oflag = 0; newtio.c_lflag = 0; // ICANON newtio.c_cc[VTIME] = 0; /* inter-character timer unused */ newtio.c_cc[VMIN] = 1; /* blocking read until 1 character arrives */ tcflush(mUartID, TCIOFLUSH); tcsetattr(mUartID, TCSANOW, &newtio); // 设置为非阻塞 Set to non-blocking fcntl(mUartID, F_SETFL, O_NONBLOCK); mIsOpen = run("uart"); if (!mIsOpen) { close(mUartID); mUartID = 0; } if (mUartNumber == 1) { mUart1IsOpen = true; } if (mUartNumber == 2) { mUart2IsOpen = true; } if (mUartNumber == 3) { mUart3IsOpen = true; } LOGD("openUart mIsOpen = %d\n", mIsOpen); } return mIsOpen; } void UartContext::closeUart() { LOGD("closeUart mIsOpen: %d...\n", mIsOpen); if (mIsOpen) { requestExit(); close(mUartID); mUartID = 0; mIsOpen = false; } } // 发送串口消息 bool UartContext::send(const BYTE *pData, UINT len) { // 这里是串口没有打开 if (!mIsOpen) { LOGD("uart%d not opend", mUartNumber); return false; } int ret = write(mUartID, pData, len); // 这是发送串口消息 if (ret != (int) len) { // 这里是发送失败 LOGD("发送串口消息失败\n"); return false; } std::string logInfo = " >>> "; for (int i = 0; i < len; ++i) { logInfo += base::format("%02x",pData[i]); } LOGD("%s",logInfo.c_str()); // success LOGD("send Success\n"); return true; } //UartContext* UartContext::getInstance() { // static UartContext sUC; // return &sUC; //} bool UartContext::readyToRun() { if (mDataBufPtr == NULL) { mDataBufPtr = new BYTE[UART_DATA_BUF_LEN]; } if (mDataBufPtr == NULL) { closeUart(); } return (mDataBufPtr != NULL); } bool UartContext::threadLoop() { if (mIsOpen) { #if 0 // 可能上一次解析后有残留数据,需要拼接起来 int readNum = read(mUartID, mDataBufPtr + mDataBufLen, UART_DATA_BUF_LEN - mDataBufLen); if (readNum > 0) { mDataBufLen += readNum; // 解析协议 int len = parseProtocol(mDataBufPtr, mDataBufLen); if ((len > 0) && (len < mDataBufLen)) { // 将未解析的数据移到头部 memcpy(mDataBufPtr, mDataBufPtr + len, mDataBufLen - len); } mDataBufLen -= len; } else { Thread::sleep(50); } #else unsigned char buffer[1024] = {0}; int ret = read(mUartID, buffer, sizeof(buffer)); if (ret > 0) { if (mUartID == 32) { if (buffer[0]==CMD_HEAD && buffer[ret-2] == CMD_END1 && buffer[ret-1] == CMD_END2){ std::string revStr = ""; //std::string logInfo = " <<< "; //依次将读取到的数据输出到日志 for (int i = 0; i < ret; ++i) { if (i==0 || i==ret-1 || i==ret-2){ continue; } //LOGD(" <<< %02x", buffer[i]); revStr += buffer[i]; //logInfo += base::format("%02x",buffer[i]); } //LOGD(" %s",logInfo.c_str()); buildProtocolData(revStr); } } else if (mUartID == 33) { if (buffer[0] == 0xfe && buffer[2] == 0x03) { if (buffer[1] == 0x08) { std::string revStr = ""; for (int i = 0; i < ret; ++i) { if (i==0 || i==1 || i==2 || i==3 || i==4 || i==ret-1){ continue; } char buf[1024]; sprintf(buf, "%02x", buffer[i]); revStr += buf; } LOGD("revStr == %s", revStr.c_str()); nfcLogin(revStr); } } } else if (mUartID == 31) { std::string revStr = ""; for (int i = 0; i < ret; ++i) { char buf[1024]; sprintf(buf, "%02x", buffer[i]); revStr += buf; } LOGD("revStr == %s", revStr.c_str()); } } else { //没收到数据时,休眠50ms,防止过度消耗cpu usleep(1000 * 50); } #endif return true; } return false; } static UartContext* uart0 = NULL; static UartContext* uart1 = NULL; static UartContext* uart2 = NULL; static UartContext* uart3 = NULL; void UartContext::init() { // uart0 = new UartContext(UART_TTYS0); // uart0->openUart("/dev/ttyS0", B115200); uart1 = new UartContext(UART_TTYS1); uart1->openUart("/dev/ttyS1", B115200); // 20221108的板子打开了串口2 uart2 = new UartContext(UART_TTYS2); uart2->openUart("/dev/ttyS2", B115200); uart3 = new UartContext(UART_TTYS3); uart3->openUart("/dev/ttyS3", B115200); LOGD("打开串口"); } void UartContext::destroy() { if (uart0) { delete uart0; uart0 = NULL; } if (uart1) { delete uart1; uart1 = NULL; } if (uart2) { delete uart1; uart2 = NULL; } if (uart3) { delete uart1; uart3 = NULL; } } bool UartContext::sendTo(int uart, const BYTE* pData, UINT len) { switch (uart) { case UART_TTYS0: return uart0->send(pData, len); case UART_TTYS1: return uart1->send(pData, len); case UART_TTYS2: return uart2->send(pData, len); case UART_TTYS3: return uart3->send(pData, len); } LOGD("无效的串口号"); return false; } bool UartContext::Uart1IsOpen() {return mUart1IsOpen;} bool UartContext::Uart2IsOpen() {return mUart2IsOpen;} bool UartContext::Uart3IsOpen() {return mUart3IsOpen;}