#include #include #include #include #include #include #include // #include #include #include #include // #include #include #include #include "uart_channel.hpp" #include "utils/stringutils.hpp" using namespace nlohmann; using namespace iflytop; static map g_baundmap = { {0, 0000000}, {50, 0000001}, {75, 0000002}, {110, 0000003}, // {134, 0000004}, {150, 0000005}, {200, 0000006}, {300, 0000007}, // {600, 0000010}, {1200, 0000011}, {1800, 0000012}, {2400, 0000013}, // {4800, 0000014}, {9600, 0000015}, {19200, 0000016}, {38400, 0000017}, // {57600, 0010001}, {115200, 0010002}, {230400, 0010003}, {460800, 0010004}, // {500000, 0010005}, {576000, 0010006}, {921600, 0010007}, {1000000, 0010010}, // {1152000, 0010011}, {1500000, 0010012}, {2000000, 0010013}, {2500000, 0010014}, // {3000000, 0010015}, {3500000, 0010016}, {4000000, 0010017}, }; int findBaudrate(int baudrate) { auto baundrate_find_result = g_baundmap.find(baudrate); if (baundrate_find_result == g_baundmap.end()) { return -1; } return baundrate_find_result->second; } UartChannel::UartChannel(string chname, string ifname, int baudrate, bool hexch, int rxovertime) { logger = LoggerFactory.createRotatingFileLogger(chname); m_chname = chname; m_ifname = ifname; m_baudrate = baudrate; m_hexch = hexch; m_rxovertime = rxovertime; if (m_rxovertime == 0) { m_rxovertime = 1; } } void UartChannel::initialize() { m_uartHandler.name = (char*)m_ifname.c_str(); m_uartHandler.rate = findBaudrate(m_baudrate); if (m_uartHandler.rate == -1) { logger->error("unsupport baudrate:{}", m_baudrate); m_errorFlag = true; m_errorMsg = "unsupport baudrate"; return; } int suc = uartStart(&m_uartHandler); if (suc != 0) { logger->error("uartStart fail"); m_errorFlag = true; m_errorMsg = "uart open fail"; return; } m_rxthread.reset(new Thread(fmt::format("{}-rxthread", m_chname), [this]() { logger->info("{} rxthread start", m_chname); ThisThread thisThread; char rxcache[4096] = {0}; int rxlen = 0; while (!thisThread.getExitFlag()) { int ret = uartReceive(&m_uartHandler, &rxcache[rxlen], 1024); // send the received text over UART if (ret < 0) { logger->error("uartReceive fail, ret:{}", ret); thisThread.sleepForMs(1000); continue; } if (ret > 0) { rxlen += ret; ::usleep(m_rxovertime * 1000); continue; } if (rxlen != 0 && ret == 0) { if (m_hexch) { // hex channel string rxhexstr = StringUtils().bytesToString((uint8_t*)rxcache, rxlen); logger->info("{} RX:-> {}({})", m_chname, rxhexstr, rxlen); if (m_ondata) m_ondata(this, true, rxcache, rxlen); } else { // str channel string rxstr(rxcache, rxlen); logger->info("{} RX:-> {}({})", m_chname, rxstr, rxlen); if (m_ondata) m_ondata(this, false, rxcache, rxlen); } rxlen = 0; } ::usleep(m_rxovertime * 1000); // } // end while })); return; } void UartChannel::senddata(bool binary, const char* data, size_t len) { string txdata(data, len); if ((m_hexch ^ binary)) { logger->warn("{} Skip Tx | data format error, channel is a {} channel", m_chname, m_hexch ? "hex" : "str"); return; } if (m_errorFlag) { logger->warn("{} Skip Tx, due to errorflag", m_chname, txdata, len); return; } string txdatastr; if (binary) { txdatastr = StringUtils().bytesToString((uint8_t*)data, len); } else { txdatastr = txdata; } logger->info("{} TX:-> {}({})", m_chname, txdatastr, len); int txlen = 0; if (binary) { txlen = uartSend(&m_uartHandler, (char*)data, len); if (txlen != (int)len) logger->warn("tx fail"); } else { txlen = uartSend(&m_uartHandler, txdatastr.c_str(), txdatastr.size()); if (txlen != (int)txdatastr.size()) logger->warn("tx fail"); } } void UartChannel::registerOnDataCallback(OnData_t ondata) { m_ondata = ondata; } void UartChannel::callcmd(string cmd, unordered_map param, json& receipt) { logger->info("{} callcmd {} {}", m_chname, cmd, paramToString(param)); if (cmd == "setBaudrate") { int rate = atoi(param["baudrate"].c_str()); if (rate == 0) { logger->error("rate is 0"); receipt["status"] = -1; receipt["msg"] = "rate is not support"; return; } int setrate = findBaudrate(rate); if (setrate == -1) { logger->error("unsupport baudrate:{}", m_baudrate); receipt["status"] = -1; receipt["msg"] = "unsupport baudrate"; return; } int suc = uartSetRate(&m_uartHandler, setrate); if (suc != 0) { logger->error("uartSetRate fail ,ecode = {}", strerror(errno)); receipt["status"] = -1; receipt["msg"] = fmt::format("uartSetRate fail ,ecode = {}", strerror(errno)); return; } m_baudrate = rate; receipt["status"] = 0; receipt["msg"] = "ok"; } else if (cmd == "getBaudrate") { receipt["status"] = 0; receipt["data"]["baudrate"] = m_baudrate; } else { logger->error("unsupport cmd:{}", cmd); receipt["status"] = -1; receipt["msg"] = "unsupport cmd"; } } list UartChannel::getCmdList() { list cmdlist; return cmdlist; } json UartChannel::getChannelInfo() { json info; info["name"] = m_chname; info["alias"] = getAlias(); info["type"] = "uart"; info["ifname"] = m_ifname; info["baudrate"] = m_baudrate; info["hexch"] = m_hexch; info["rxovertime"] = m_rxovertime; info["error"]["status"] = m_errorFlag; info["error"]["msg"] = m_errorMsg; return info; }