dev
Dependencies: MTS-Serial libmDot-mbed5
Fork of Dot-AT-Firmware by
Diff: CommandTerminal/CommandTerminal.cpp
- Revision:
- 9:ff62b20f7000
- Parent:
- 6:e27eaad36a0c
- Child:
- 11:05e0f30c03a6
diff -r a8be708e0e56 -r ff62b20f7000 CommandTerminal/CommandTerminal.cpp --- a/CommandTerminal/CommandTerminal.cpp Mon Apr 04 13:17:44 2016 +0000 +++ b/CommandTerminal/CommandTerminal.cpp Mon Apr 04 09:00:31 2016 -0500 @@ -3,7 +3,6 @@ #include "Command.h" #include "MTSLog.h" #include <cstdarg> - #include <deque> const char CommandTerminal::banner[] = "\r\n\nMultiTech Systems LoRa XBee Module\r\n\n"; @@ -17,35 +16,43 @@ // Response texts... const char CommandTerminal::help[] = "\r\nHelp\r\n"; const char CommandTerminal::cmd_error[] = "Invalid command\r\n"; +const char CommandTerminal::connect[] = "\r\nCONNECT\r\n"; +const char CommandTerminal::no_carrier[] = "\r\nNO CARRIER\r\n"; const char CommandTerminal::done[] = "\r\nOK\r\n"; const char CommandTerminal::error[] = "\r\nERROR\r\n"; // Escape sequence... const char CommandTerminal::escape_sequence[] = "+++"; -mts::MTSSerial* CommandTerminal::_serialp = NULL; +mts::ATSerial* CommandTerminal::_serialp = NULL; + +static bool serial_data_mode = false; +static bool peer_to_peer = false; void CommandTerminal::addCommand(Command* cmd) { _commands.push_back(cmd); } -CommandTerminal::CommandTerminal(mts::MTSSerial& serial, mDot* dot) +CommandTerminal::CommandTerminal(mts::ATSerial& serial, mDot* dot) : _serial(serial), _dot(dot), + _events(new RadioEvent(serial)), _mode(mDot::COMMAND_MODE), _idle_thread(idle, NULL, osPriorityLow), _sleep_standby(true), - _xbee_on_sleep(XBEE_ON_SLEEP), - _serial_up(false) { + _xbee_on_sleep(XBEE_ON_SLEEP) { + _dot->setEvents(_events); + _dot->setWakeupCallback(this, &CommandTerminal::wakeup); _serialp = &serial; addCommand(new CmdAttention(_dot)); addCommand(new CmdIdentification(_dot, serial)); addCommand(new CmdResetCpu(_dot, serial)); - addCommand(new CmdDummy(_dot, "Enable/Disable Echo", "ATE0/1", "ATE0: disable, ATE1: enable")); - addCommand(new CmdDummy(_dot, "Enable/Disable Verbose", "ATV0/1", "ATV0: disable, ATV1: enable")); + addCommand(new CmdDummy(_dot, "Enable/Disable Echo", "ATE", "ATE0: disable, ATE1: enable")); + addCommand(new CmdDummy(_dot, "Enable/Disable Verbose", "ATV", "ATV0: disable, ATV1: enable")); + addCommand(new CmdDummy(_dot, "Hardware Flow Control", "AT&K", "AT&K0: disable, AT&K3: enable")); addCommand(new CmdFactoryDefault(_dot)); addCommand(new CmdSaveConfig(_dot)); @@ -60,17 +67,25 @@ addCommand(new CmdFrequencySubBand(_dot, serial)); addCommand(new CmdPublicNetwork(_dot, serial)); addCommand(new CmdDeviceId(_dot, serial)); + addCommand(new CmdDeviceClass(_dot, serial)); + addCommand(new CmdAppPort(_dot, serial)); addCommand(new CmdNetworkAddress(_dot, serial)); addCommand(new CmdNetworkSessionKey(_dot, serial)); addCommand(new CmdDataSessionKey(_dot, serial)); + addCommand(new CmdUplinkCounter(_dot, serial)); + addCommand(new CmdDownlinkCounter(_dot, serial)); + addCommand(new CmdSaveSession(_dot, serial)); + addCommand(new CmdRestoreSession(_dot, serial)); addCommand(new CmdNetworkKey(_dot, serial)); addCommand(new CmdNetworkId(_dot, serial)); + addCommand(new CmdJoinDelay(_dot, serial)); addCommand(new CmdJoinRequest(_dot, serial)); addCommand(new CmdJoinRetries(_dot, serial)); addCommand(new CmdJoinByteOrder(_dot, serial)); addCommand(new CmdNetworkJoinMode(_dot, serial)); + addCommand(new CmdPreserveSession(_dot, serial)); addCommand(new CmdNetworkJoinStatus(_dot, serial)); addCommand(new CmdNetworkLinkCheck(_dot, serial)); addCommand(new CmdLinkCheckCount(_dot, serial)); @@ -81,8 +96,11 @@ addCommand(new CmdSnr(_dot, serial)); addCommand(new CmdDataPending(_dot, serial)); + addCommand(new CmdSessionDataRate(_dot, serial)); + addCommand(new CmdTxDataRate(_dot, serial)); addCommand(new CmdTxPower(_dot, serial)); + addCommand(new CmdAntennaGain(_dot, serial)); addCommand(new CmdTxFrequency(_dot, serial)); addCommand(new CmdTxInverted(_dot, serial)); addCommand(new CmdTxWait(_dot, serial)); @@ -90,8 +108,7 @@ addCommand(new CmdTxNextMs(_dot, serial)); addCommand(new CmdTimeOnAir(_dot, serial)); - addCommand(new CmdRxDataRate(_dot, serial)); - addCommand(new CmdRxFrequency(_dot, serial)); + addCommand(new CmdRxDelay(_dot, serial)); addCommand(new CmdRxOutput(_dot, serial)); addCommand(new CmdRxInverted(_dot, serial)); @@ -100,23 +117,28 @@ addCommand(new CmdAdaptiveDataRate(_dot, serial)); addCommand(new CmdACKAttempts(_dot, serial)); + addCommand(new CmdRepeat(_dot, serial)); addCommand(new CmdSendString(_dot, serial)); - addCommand(new CmdSendStringHighBW(_dot, serial)); addCommand(new CmdSendBinary(_dot, serial)); - addCommand(new CmdSendStringOnInterval(_dot, serial)); addCommand(new CmdReceiveOnce(_dot, serial)); - addCommand(new CmdReceiveContinuous(_dot, serial)); - addCommand(new CmdDummy(_dot, "Serial Data Mode", "AT+SD", "Reads serial data, sends packet, then sleeps using wake settings")); - addCommand(new CmdDummy(_dot, "Sleep Mode", "AT+SLEEP", "Enter sleep mode")); + addCommand(new CmdDummy(_dot, "Serial Data Mode", "AT+SD", "Enter serial data mode, exit with '+++'")); + addCommand(new CmdDummy(_dot, "Sleep Mode", "AT+SLEEP", "Enter sleep mode (0:deepsleep,1:sleep)")); + addCommand(new CmdSerialClearOnError(_dot, serial)); addCommand(new CmdWakeMode(_dot, serial)); addCommand(new CmdWakeInterval(_dot, serial)); - // addCommand(new CmdWakePin(_dot, serial)); + addCommand(new CmdWakePin(_dot, serial)); addCommand(new CmdWakeDelay(_dot, serial)); addCommand(new CmdWakeTimeout(_dot, serial)); addCommand(new CmdPing(_dot, serial)); addCommand(new CmdLogLevel(_dot, serial)); + + addCommand(new CmdDummy(_dot, "***** Test Commands *****", "", "")); + addCommand(new CmdRxDataRate(_dot, serial)); + addCommand(new CmdRxFrequency(_dot, serial)); + addCommand(new CmdReceiveContinuous(_dot, serial)); + addCommand(new CmdSendStringOnInterval(_dot, serial)); } void CommandTerminal::printHelp() { @@ -191,129 +213,133 @@ va_end(ap); } -void CommandTerminal::serial_loop() { +void CommandTerminal::serialLoop() { Timer serial_read_timer; std::vector<uint8_t> serial_buffer; - std::string escape_buffer; - Timer escape_timer; - int escape_delay = 100; - uint8_t max_send_size; - - _serial_up = true; - _xbee_on_sleep = GPIO_PIN_SET; + std::vector<uint8_t> data; + int timeout = 0; - if (_dot->getFrequencyBand() == mDot::FB_915) - max_send_size = mDot::MaxLengths_915[_dot->getTxDataRate()]; - else - max_send_size = mDot::MaxLengths_868[_dot->getTxDataRate()]; - - logDebug("Awake\r\n"); - wakeup(_sleep_standby); - - char ch; + serial_read_timer.start(); - if (readable()) { - ch = read(); - serial_buffer.push_back(ch); + if (_dot->getStartUpMode() == mDot::SERIAL_MODE) { + _xbee_on_sleep = GPIO_PIN_SET; - if (escape_timer.read_ms() > escape_delay && ch == '+') { - escape_buffer += ch; - escape_timer.reset(); - } else { - _serial_up = true; - escape_buffer.clear(); - } + timeout = _dot->getWakeDelay(); - if (escape_buffer.length() == 3 && escape_buffer.find(escape_sequence) == 0) { - _mode = mDot::COMMAND_MODE; - logDebug("Exit serial mode\r\n"); - escape_timer.stop(); - escape_buffer.clear(); - write(done); - return; + // wait for timeout or start of serial data + while (!readable() && serial_read_timer.read_ms() < timeout && !_serial.escaped()) { + osDelay(2); } } - if (_serial_up) { - serial_read_timer.start(); - uint32_t timeout = _dot->getWakeDelay(); - - // wait for timeout or start of serial data - while (!readable() && serial_read_timer.read_ms() < timeout) { - osDelay(10); - } + if (readable() && !_serial.escaped()) { serial_read_timer.reset(); timeout = _dot->getWakeTimeout(); - while (_serial_up && serial_read_timer.read_ms() < timeout) { - while (readable() && serial_buffer.size() < max_send_size) { + + while (serial_read_timer.read_ms() < timeout && serial_buffer.size() <= _dot->getMaxPacketLength()) { + while (readable() && serial_buffer.size() < _dot->getMaxPacketLength()) { serial_buffer.push_back(read()); serial_read_timer.reset(); + + if (_serial.escaped()) + break; } } + serial_read_timer.stop(), serial_read_timer.reset(); if (!serial_buffer.empty()) { - _serial_up = false; - _xbee_on_sleep = GPIO_PIN_RESET; + if (_dot->getStartUpMode() == mDot::SERIAL_MODE) + _xbee_on_sleep = GPIO_PIN_RESET; + + // wait for any duty cycle limit to expire + while (_dot->getNextTxMs() > 0 && !_serial.escaped()) { + osDelay(10); + } + if (!_dot->getIsTransmitting()) { - std::vector<uint8_t> recv_buffer; - logDebug("Received serial data, sending out radio.\r\n"); + logDebug("Received serial data, sending out radio."); + + if (_dot->send(serial_buffer, false) != mDot::MDOT_OK) { + logDebug("Send failed."); + // If the data should be tossed after send failure, clear buffer + if (_dot->getSerialClearOnError()) { + serial_buffer.clear(); + } + } else { - if (_dot->send(serial_buffer) != mDot::MDOT_OK) - logDebug("Send failed.\r\n"); - if (_dot->recv(recv_buffer)) - _serial.writef("%s\r\n", formatPacketData(recv_buffer, _dot->getRxOutput()).c_str()); + // wait for send to finish + while (_dot->getIsTransmitting() && !_serial.escaped()) + osDelay(10); + + // call recv to wait for any packet before sending again + if (!_serial.escaped()) + _dot->recv(data); + + // Clear the serial buffer if send is success + serial_buffer.clear(); + } } else { logDebug("Radio is busy, cannot send.\r\n"); + osDelay(10); } - serial_buffer.clear(); } else { logDebug("No data received from serial to send.\r\n"); } - _serial_up = false; + } + + if (!_serial.readable() && _dot->getStartUpMode() == mDot::SERIAL_MODE && !_serial.escaped()) { + _xbee_on_sleep = GPIO_PIN_RESET; + sleep(_sleep_standby); } - sleep(_sleep_standby); + + if (_serial.escaped()) { + _serial.clearEscaped(); + _serial.rxClear(); + serial_data_mode = false; + _mode = mDot::COMMAND_MODE; + logDebug("Exit Serial Mode"); + write(done); + return; + } + + if (!_dot->getNetworkJoinStatus()) { + serial_data_mode = false; + _mode = mDot::COMMAND_MODE; + logDebug("Exit Serial Mode"); + write(no_carrier); + return; + } } bool CommandTerminal::autoJoinCheck() { std::string escape_buffer; - char ch; int sleep = 1000; - int escape_timeout = 1000; Timer tmr; - Timer escape_tmr; + tmr.start(); int cnt = 0; while (!_dot->getNetworkJoinStatus()) { - wakeup(_sleep_standby); write("\r\nJoining network... "); - // wait one second for possible escape - tmr.reset(); - tmr.start(); - escape_tmr.reset(); - escape_tmr.start(); - while (tmr.read_ms() < 1000) { - if (_serial.readable()) { - _serial.read(&ch, 1); - escape_buffer += ch; + if (_dot->getNextTxMs() > 0) { + int rand_time = rand() % 10000; + writef("\r\nWaiting %lu s before next join attempt\r\n", (_dot->getNextTxMs() + rand_time) / 1000); + + tmr.reset(); + while (_dot->getNextTxMs() > 0 && !_serial.escaped()) { + osDelay(2); } - if (escape_buffer.find(escape_sequence) != std::string::npos) { - _mode = mDot::COMMAND_MODE; - write("Join Canceled\r\n"); - write(done); - return true; - } - - if (escape_tmr.read_ms() > escape_timeout) - escape_buffer.clear(); + tmr.reset(); + while (tmr.read_ms() < rand_time && !_serial.escaped()) + osDelay(10); } - if (_dot->joinNetworkOnce() == mDot::MDOT_OK) { + if (!_serial.escaped() && _dot->joinNetworkOnce() == mDot::MDOT_OK) { write("Network Joined\r\n"); write(done); return false; @@ -322,12 +348,12 @@ write("Network Join failed\r\n"); write(error); - if (cnt++ > _dot->getJoinRetries()) { + if (!_serial.escaped() && _dot->getJoinRetries() > 0 && cnt++ > _dot->getJoinRetries()) { cnt = 0; if (_dot->getFrequencyBand() == mDot::FB_915) { uint8_t band = ((_dot->getFrequencySubBand()) % 8) + 1; - logDebug("Join retries exhausted, switching to sub band %u\r\n", band); + logWarning("Join retries exhausted, switching to sub band %u", band); _dot->setFrequencySubBand(band); } @@ -336,24 +362,18 @@ } tmr.reset(); - tmr.start(); - escape_tmr.reset(); - escape_tmr.start(); - while (tmr.read_ms() < sleep) { - if (_serial.readable()) { - _serial.read(&ch, 1); - escape_buffer += ch; - } - - if (escape_buffer.find(escape_sequence) != std::string::npos) { - _mode = mDot::COMMAND_MODE; - return true; - } - - if (escape_tmr.read_ms() > escape_timeout) - escape_buffer.clear(); + while (tmr.read_ms() < sleep && !_serial.escaped()) { + osDelay(10); } + if (_serial.escaped()) { + _serial.clearEscaped(); + serial_data_mode = false; + _mode = mDot::COMMAND_MODE; + write("Join Canceled\r\n"); + write(done); + return true; + } } return false; @@ -361,8 +381,6 @@ void CommandTerminal::start() { - wakeup(_sleep_standby); - char ch; bool running = true; bool echo = _dot->getEcho(); @@ -370,65 +388,98 @@ std::deque<std::string> history; int history_index = -1; std::vector<std::string> args; + bool join_canceled = false; if (_dot->getStartUpMode() == mDot::SERIAL_MODE) { - command = "AT+SD\n"; + + serial_data_mode = true; + _mode = mDot::SERIAL_MODE; std::string escape_buffer; char ch; - int escape_timeout = 1000; - Timer tmr; - Timer escape_tmr; + if (!_dot->getStandbyFlag()) { + // wake up from power-on/reset + + int escape_timeout = 1000; + Timer tmr; + Timer escape_tmr; - // wait one second for possible escape - tmr.reset(); - tmr.start(); - escape_tmr.reset(); - escape_tmr.start(); - while (tmr.read_ms() < escape_timeout) { - if (_serial.readable()) { - _serial.read(&ch, 1); - escape_buffer += ch; - } + // wait one second for possible escape by user pressing '+' key + tmr.reset(); + tmr.start(); + escape_tmr.reset(); + escape_tmr.start(); + while (tmr.read_ms() < escape_timeout) { + if (_serial.readable()) { + _serial.read(&ch, 1); + escape_buffer += ch; + } - if (escape_buffer.find(escape_sequence) != std::string::npos) { - _mode = mDot::COMMAND_MODE; - command.clear(); - break; + if (escape_buffer.find("+") != std::string::npos) { + logInfo("Escape detected"); + join_canceled = true; + serial_data_mode = false; + _mode = mDot::COMMAND_MODE; + command.clear(); + break; + } + + if (escape_tmr.read_ms() > escape_timeout) + escape_buffer.clear(); + + osDelay(1); } - - if (escape_tmr.read_ms() > escape_timeout) - escape_buffer.clear(); - - osDelay(1); } + if (_mode == mDot::SERIAL_MODE && !_dot->getNetworkJoinStatus() && _dot->getJoinMode() == mDot::OTA) { + if (_dot->joinNetworkOnce() != mDot::MDOT_OK) { + serial_data_mode = false; + _mode = mDot::COMMAND_MODE; + + logWarning("Start Up Mode set to SERIAL_MODE, but join failed."); + _serial.writef("Network Not Joined\r\n"); + _serial.writef(error); + } + } } - bool join_canceled = false; + if (_dot->getJoinMode() == mDot::PEER_TO_PEER) { + peer_to_peer = true; + } else { + peer_to_peer = false; + } + + //Run terminal session while (running) { - if (!join_canceled && _dot->getJoinMode() == mDot::AUTO_OTA) { - join_canceled = autoJoinCheck(); - if (join_canceled) - command.clear(); - } + + // wait for input to reduce at command idle current + while (!readable() || _mode == mDot::SERIAL_MODE) { + if (!join_canceled && _dot->getJoinMode() == mDot::AUTO_OTA) { + join_canceled = autoJoinCheck(); + if (join_canceled) + command.clear(); + } - if (_dot->getJoinMode() != mDot::AUTO_OTA || (!join_canceled && _dot->getJoinMode() == mDot::AUTO_OTA)) { - switch (_mode) { - case mDot::SERIAL_MODE: - // signal wakeup, read serial and output to radio - serial_loop(); - continue; - break; - default: - break; + if (_dot->getJoinMode() != mDot::AUTO_OTA || (!join_canceled && _dot->getJoinMode() == mDot::AUTO_OTA)) { + switch (_mode) { + case mDot::SERIAL_MODE: + // signal wakeup, read serial and output to radio + serialLoop(); + continue; + break; + default: + break; + } } - } + + ch = '\0'; - ch = '\0'; + wait(0.00001); // 10 us + _serial.escaped(); + } // read characters if (readable()) { @@ -443,7 +494,7 @@ } else if (ch == 0x1b || ch == 0x09) { osDelay(20); // catch escape sequence, or tab - char ch1, ch2; + char ch1 = 0x00, ch2 = 0x00; if (readable()) { ch1 = read(); @@ -452,11 +503,11 @@ if (ch1 == 0x5b && ch2 == 0x41) { // up key - for (int i = 0; i < command.size()+1; i++) { + for (size_t i = 0; i < command.size() + 1; i++) { writef("\b \b"); } if (history.size() > 0) { - if (++history_index >= history.size() - 1) + if (++history_index >= int(history.size() - 1)) history_index = history.size() - 1; command = history[history_index]; @@ -467,7 +518,7 @@ } else if (ch1 == 0x5b && ch2 == 0x42) { // down key - for (int i = 0; i < command.size()+1; i++) { + for (size_t i = 0; i < command.size() + 1; i++) { writef("\b \b"); } @@ -480,7 +531,8 @@ } } } - while (readable()) read(); + while (readable()) + read(); continue; } else { command += ch; @@ -537,6 +589,9 @@ if ((args[0].find("?") == 0 || args[0].find("HELP") == 0) && args.size() == 1) { printHelp(); command.clear(); + } else if ((args[0].find("ATE?") == 0 && args[0].length() == 4) || (args[0].find("ATE") == 0 && args[0].length() == 3)) { + writef("%d\r\n", _dot->getEcho()); + write(done); } else if (args[0].find("ATE0") == 0 && args[0].length() == 4) { _dot->setEcho(false); write(done); @@ -545,28 +600,48 @@ _dot->setEcho(true); write(done); echo = _dot->getEcho(); + } else if ((args[0].find("ATV?") == 0 && args[0].length() == 4) || (args[0].find("ATV") == 0 && args[0].length() == 3)) { + writef("%d\r\n", _dot->getVerbose()); + write(done); } else if (args[0].find("ATV0") == 0 && args[0].length() == 4) { _dot->setVerbose(false); write(done); } else if (args[0].find("ATV1") == 0 && args[0].length() == 4) { _dot->setVerbose(true); write(done); + } else if ((args[0].find("AT&K?") == 0 && args[0].length() == 5) || (args[0].find("AT&K") == 0 && args[0].length() == 4)) { + writef("%d\r\n", (_dot->getFlowControl() ? 3 : 0)); + write(done); + } else if (args[0].find("AT&K0") == 0 && args[0].length() == 5) { + _dot->setFlowControl(false); + write(done); + } else if (args[0].find("AT&K3") == 0 && args[0].length() == 5) { + _dot->setFlowControl(true); + write(done); } else if (args[0] == "AT+SD") { - logDebug("Enter Serial Mode\r\n"); - _mode = mDot::SERIAL_MODE; + if (_dot->getNetworkJoinStatus()) { + logDebug("Enter Serial Mode"); + write(connect); + serial_data_mode = true; + _mode = mDot::SERIAL_MODE; + } else { + logDebug("Network Not Joined"); + write("Network Not Joined\r\n"); + write(error); + } } else if (args[0] == "AT+SLEEP") { - if (args.size() > 1 && (args[1] != "?")) { + if (args.size() > 2 && (args[1] != "?")) { write("Invalid argument\r\n"); write(error); } else { if (args.size() > 1 && args[1] == "?") { - write("AT+SLEEP: NONE\r\n"); + write("(0:deepsleep,1:sleep)\r\n"); write(done); } else { _sleep_standby = !(args.size() > 1 && args[1] == "1"); + write(done); this->sleep(_sleep_standby); wait(0.1); - write(done); } } } else { @@ -638,7 +713,6 @@ } void CommandTerminal::sleep(bool standby) { - _serial_up = false; _xbee_on_sleep = GPIO_PIN_RESET; _serial.rxClear(); @@ -649,9 +723,6 @@ bool CommandTerminal::waitForEscape(int timeout, mDot* dot, WaitType wait) { Timer timer; - Timer escape_timer; - std::string escape_buffer; - int escape_timeout = 1000; timer.start(); while (timer.read_ms() < timeout) { @@ -662,18 +733,9 @@ } } - if (_serialp != NULL && _serialp->readable()) { - if (escape_buffer == "") - escape_timer.start(); - char ch; - _serialp->read(&ch, 1); - escape_buffer += ch; - if (escape_buffer == CommandTerminal::escape_sequence) - return true; - } - if (escape_timer.read_ms() > escape_timeout) { - escape_buffer = ""; - escape_timer.stop(), escape_timer.reset(); + if (_serialp != NULL && _serialp->escaped()) { + _serialp->clearEscaped(); + return true; } osDelay(10); @@ -682,6 +744,66 @@ return false; } -void CommandTerminal::wakeup(bool standby) { +void CommandTerminal::wakeup(void) { + if (_dot->getWakePin() == XBEE_DIN) { + _serial.reattach(XBEE_DOUT, XBEE_DIN); + logInfo("Wakeup pin was serial input"); + } +} + +void CommandTerminal::RadioEvent::MacEvent(LoRaMacEventFlags* flags, LoRaMacEventInfo* info) { + if (mts::MTSLog::getLogLevel() == mts::MTSLog::TRACE_LEVEL) { + std::string msg = "OK"; + switch (info->Status) { + case LORAMAC_EVENT_INFO_STATUS_ERROR: + msg = "ERROR"; + break; + case LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT: + msg = "TX_TIMEOUT"; + break; + case LORAMAC_EVENT_INFO_STATUS_RX_TIMEOUT: + msg = "RX_TIMEOUT"; + break; + case LORAMAC_EVENT_INFO_STATUS_RX_ERROR: + msg = "RX_ERROR"; + break; + case LORAMAC_EVENT_INFO_STATUS_JOIN_FAIL: + msg = "JOIN_FAIL"; + break; + case LORAMAC_EVENT_INFO_STATUS_DOWNLINK_FAIL: + msg = "DOWNLINK_FAIL"; + break; + case LORAMAC_EVENT_INFO_STATUS_ADDRESS_FAIL: + msg = "ADDRESS_FAIL"; + break; + case LORAMAC_EVENT_INFO_STATUS_MIC_FAIL: + msg = "MIC_FAIL"; + break; + default: + break; + } + logTrace("Event: %s", msg.c_str()); + + logTrace("Flags Tx: %d Rx: %d RxData: %d RxSlot: %d LinkCheck: %d JoinAccept: %d", + flags->Bits.Tx, flags->Bits.Rx, flags->Bits.RxData, flags->Bits.RxSlot, flags->Bits.LinkCheck, flags->Bits.JoinAccept); + logTrace("Info: Status: %d ACK: %d Retries: %d TxDR: %d RxPort: %d RxSize: %d RSSI: %d SNR: %d Energy: %d Margin: %d Gateways: %d", + info->Status, info->TxAckReceived, info->TxNbRetries, info->TxDatarate, info->RxPort, info->RxBufferSize, + info->RxRssi, info->RxSnr, info->Energy, info->DemodMargin, info->NbGateways); + } + + if (flags->Bits.Rx) { + if (serial_data_mode) { + logDebug("Rx %d bytes", info->RxBufferSize); + if (info->RxBufferSize > 0) { + _serial.write((char*) info->RxBuffer, info->RxBufferSize); + } + } + + delete[] info->RxBuffer; + } } + +CommandTerminal::~CommandTerminal() { + delete _events; +}