#include "qt_serial_datachannel.hpp" // #include #include #pragma comment(lib, "ws2_32.lib") #include "logger.hpp" using namespace iflytop; using namespace std; #define TAG "QTDataChannel" void QTDataChannel::init() { m_thread.reset(new thread([this]() { while (true) { if (m_isOpen) { uint8_t rx[1024] = {0}; int rx_cnt = com_receive(rx, 1024); if (rx_cnt != 0) { ZLOGI(TAG, "rx %s ", zhex2str(rx, rx_cnt).c_str()); if (m_rxcb) m_rxcb(rx, rx_cnt); } this_thread::sleep_for(chrono::microseconds(1)); } else { this_thread::sleep_for(chrono::microseconds(1000)); } } })); } bool QTDataChannel::open() { char portnamebuf[256] = {0}; sprintf(portnamebuf, "\\\\.\\%s", m_name.c_str()); m_CommHandler = CreateFileA(portnamebuf, // port name GENERIC_READ | GENERIC_WRITE, // Read/Write 0, // No Sharing NULL, // No Security OPEN_EXISTING, // Open existing port only 0, // Non Overlapped I/O NULL); // Null for Comm Devices if (m_CommHandler == INVALID_HANDLE_VALUE) { ZLOGI(TAG, "Error in opening serial port"); return false; } DCB p; memset(&p, 0, sizeof(p)); p.DCBlength = sizeof(p); p.BaudRate = m_baudRate; // 波特率 switch (m_dataBits) { case QSerialPort::Data5: p.ByteSize = 5; break; case QSerialPort::Data6: p.ByteSize = 6; break; case QSerialPort::Data7: p.ByteSize = 7; break; case QSerialPort::Data8: p.ByteSize = 8; break; default: p.ByteSize = 8; break; } // QSerialPort::NoParity = 0, // QSerialPort::EvenParity = 2, // QSerialPort::OddParity = 3, // QSerialPort::SpaceParity = 4, // QSerialPort::MarkParity = 5, // QSerialPort::UnknownParity = -1 switch (m_parity) // 校验位 { case QSerialPort::NoParity: p.Parity = NOPARITY; // 无校验 break; case QSerialPort::EvenParity: p.Parity = EVENPARITY; // 奇校验 break; case QSerialPort::OddParity: p.Parity = ODDPARITY; // 偶校验 break; case QSerialPort::MarkParity: p.Parity = MARKPARITY; // 标记校验 break; default: p.Parity = NOPARITY; // 无校验 } switch (m_stopBits) // 停止位 { case QSerialPort::OneStop: p.StopBits = ONESTOPBIT; // 1位停止位 break; case QSerialPort::OneAndHalfStop: p.StopBits = TWOSTOPBITS; // 2位停止位 break; case QSerialPort::TwoStop: p.StopBits = ONE5STOPBITS; // 1.5位停止位 break; default: p.StopBits = ONESTOPBIT; // 无校验 } if (!SetCommState(m_CommHandler, &p)) { // 设置参数失败 CloseHandle(m_CommHandler); return false; } m_isOpen = true; return true; } void QTDataChannel::close() { CloseHandle(m_CommHandler); m_isOpen = false; } bool QTDataChannel::isOpen() { return m_isOpen; } bool QTDataChannel::send(const uint8_t *data, size_t len) { ZLOGI(TAG, "send %s", zhex2str(data, len).c_str()); DWORD dwBytesWrite = len; BOOL bWriteStat = WriteFile(m_CommHandler, // 串口句柄 (char *)data, // 数据首地址 dwBytesWrite, // 要发送的数据字节数 &dwBytesWrite, // DWORD*,用来接收返回成功发送的数据字节数 NULL); // NULL为同步发送,OVERLAPPED*为异步发送 return dwBytesWrite; } void QTDataChannel::regRxListener(function cb) { m_rxcb = cb; } int QTDataChannel::com_receive(uint8_t *rxbuf, int rxbufsize) { COMMTIMEOUTS TimeOuts; GetCommTimeouts(m_CommHandler, &TimeOuts); TimeOuts.ReadIntervalTimeout = 0; // 读间隔超时 TimeOuts.ReadTotalTimeoutMultiplier = 0; // 读时间系数 TimeOuts.ReadTotalTimeoutConstant = 1; // 读时间常量 SetCommTimeouts(m_CommHandler, &TimeOuts); // PurgeComm(m_CommHandler, PURGE_RXCLEAR); DWORD wCount = rxbufsize; // 成功读取的数据字节数 BOOL bReadStat = ReadFile(m_CommHandler, // 串口句柄 rxbuf, // 数据首地址 wCount, // 要读取的数据最大字节数 &wCount, // DWORD*,用来接收返回成功读取的数据字节数 NULL); return wCount; }