mDot AT-Firmware for testing
Dependencies: MTS-Serial libmDot-mbed5
Fork of Dot-AT-Firmware by
CommandTerminal/CommandTerminal.cpp@11:05e0f30c03a6, 2016-08-22 (annotated)
- Committer:
- mfiore
- Date:
- Mon Aug 22 19:34:26 2016 +0000
- Revision:
- 11:05e0f30c03a6
- Parent:
- 9:ff62b20f7000
- Child:
- 14:f9a77400b622
update libmDot to 2.0.3 and update mbed libs to compatible versions: mbed 121, mbed-rtos 117
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Mike Fiore |
1:e52ae6584f1c | 1 | #include "ctype.h" |
Mike Fiore |
1:e52ae6584f1c | 2 | #include "CommandTerminal.h" |
Mike Fiore |
1:e52ae6584f1c | 3 | #include "Command.h" |
Mike Fiore |
4:666017851052 | 4 | #include "MTSLog.h" |
Mike Fiore |
1:e52ae6584f1c | 5 | #include <cstdarg> |
Mike Fiore |
4:666017851052 | 6 | #include <deque> |
Mike Fiore |
1:e52ae6584f1c | 7 | |
Mike Fiore |
1:e52ae6584f1c | 8 | const char CommandTerminal::banner[] = "\r\n\nMultiTech Systems LoRa XBee Module\r\n\n"; |
Mike Fiore |
1:e52ae6584f1c | 9 | const char CommandTerminal::helpline[] = "Enter '?' for help\r\n"; |
Mike Fiore |
1:e52ae6584f1c | 10 | |
Mike Fiore |
1:e52ae6584f1c | 11 | const char CommandTerminal::newline[] = "\r\n"; |
Mike Fiore |
1:e52ae6584f1c | 12 | |
Mike Fiore |
1:e52ae6584f1c | 13 | // Command error text... |
Mike Fiore |
1:e52ae6584f1c | 14 | const char CommandTerminal::command_error[] = "Command not found!\r\n"; |
Mike Fiore |
1:e52ae6584f1c | 15 | |
Mike Fiore |
1:e52ae6584f1c | 16 | // Response texts... |
Mike Fiore |
1:e52ae6584f1c | 17 | const char CommandTerminal::help[] = "\r\nHelp\r\n"; |
Mike Fiore |
1:e52ae6584f1c | 18 | const char CommandTerminal::cmd_error[] = "Invalid command\r\n"; |
Mike Fiore |
9:ff62b20f7000 | 19 | const char CommandTerminal::connect[] = "\r\nCONNECT\r\n"; |
Mike Fiore |
9:ff62b20f7000 | 20 | const char CommandTerminal::no_carrier[] = "\r\nNO CARRIER\r\n"; |
Mike Fiore |
1:e52ae6584f1c | 21 | const char CommandTerminal::done[] = "\r\nOK\r\n"; |
Mike Fiore |
1:e52ae6584f1c | 22 | const char CommandTerminal::error[] = "\r\nERROR\r\n"; |
Mike Fiore |
1:e52ae6584f1c | 23 | |
Mike Fiore |
1:e52ae6584f1c | 24 | // Escape sequence... |
Mike Fiore |
1:e52ae6584f1c | 25 | const char CommandTerminal::escape_sequence[] = "+++"; |
Mike Fiore |
1:e52ae6584f1c | 26 | |
Mike Fiore |
9:ff62b20f7000 | 27 | mts::ATSerial* CommandTerminal::_serialp = NULL; |
Mike Fiore |
9:ff62b20f7000 | 28 | |
Mike Fiore |
9:ff62b20f7000 | 29 | static bool serial_data_mode = false; |
Mike Fiore |
9:ff62b20f7000 | 30 | static bool peer_to_peer = false; |
Mike Fiore |
1:e52ae6584f1c | 31 | |
Mike Fiore |
1:e52ae6584f1c | 32 | void CommandTerminal::addCommand(Command* cmd) { |
Mike Fiore |
1:e52ae6584f1c | 33 | _commands.push_back(cmd); |
Mike Fiore |
1:e52ae6584f1c | 34 | } |
Mike Fiore |
1:e52ae6584f1c | 35 | |
Mike Fiore |
9:ff62b20f7000 | 36 | CommandTerminal::CommandTerminal(mts::ATSerial& serial, mDot* dot) |
Mike Fiore |
1:e52ae6584f1c | 37 | : |
Mike Fiore |
1:e52ae6584f1c | 38 | _serial(serial), |
Mike Fiore |
1:e52ae6584f1c | 39 | _dot(dot), |
Mike Fiore |
9:ff62b20f7000 | 40 | _events(new RadioEvent(serial)), |
Mike Fiore |
1:e52ae6584f1c | 41 | _mode(mDot::COMMAND_MODE), |
Mike Fiore |
4:666017851052 | 42 | _idle_thread(idle, NULL, osPriorityLow), |
Mike Fiore |
4:666017851052 | 43 | _sleep_standby(true), |
Mike Fiore |
9:ff62b20f7000 | 44 | _xbee_on_sleep(XBEE_ON_SLEEP) { |
Mike Fiore |
1:e52ae6584f1c | 45 | |
Mike Fiore |
9:ff62b20f7000 | 46 | _dot->setEvents(_events); |
Mike Fiore |
9:ff62b20f7000 | 47 | _dot->setWakeupCallback(this, &CommandTerminal::wakeup); |
Mike Fiore |
1:e52ae6584f1c | 48 | _serialp = &serial; |
Mike Fiore |
1:e52ae6584f1c | 49 | |
Mike Fiore |
1:e52ae6584f1c | 50 | addCommand(new CmdAttention(_dot)); |
Mike Fiore |
1:e52ae6584f1c | 51 | addCommand(new CmdIdentification(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 52 | addCommand(new CmdResetCpu(_dot, serial)); |
Mike Fiore |
9:ff62b20f7000 | 53 | addCommand(new CmdDummy(_dot, "Enable/Disable Echo", "ATE", "ATE0: disable, ATE1: enable")); |
Mike Fiore |
9:ff62b20f7000 | 54 | addCommand(new CmdDummy(_dot, "Enable/Disable Verbose", "ATV", "ATV0: disable, ATV1: enable")); |
Mike Fiore |
9:ff62b20f7000 | 55 | addCommand(new CmdDummy(_dot, "Hardware Flow Control", "AT&K", "AT&K0: disable, AT&K3: enable")); |
Mike Fiore |
1:e52ae6584f1c | 56 | |
Mike Fiore |
1:e52ae6584f1c | 57 | addCommand(new CmdFactoryDefault(_dot)); |
Mike Fiore |
1:e52ae6584f1c | 58 | addCommand(new CmdSaveConfig(_dot)); |
Mike Fiore |
1:e52ae6584f1c | 59 | addCommand(new CmdDisplayConfig(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 60 | addCommand(new CmdDisplayStats(_dot, serial)); |
Mike Fiore |
4:666017851052 | 61 | addCommand(new CmdResetStats(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 62 | addCommand(new CmdSerialBaudRate(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 63 | addCommand(new CmdDebugBaudRate(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 64 | addCommand(new CmdStartUpMode(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 65 | |
Mike Fiore |
1:e52ae6584f1c | 66 | addCommand(new CmdFrequencyBand(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 67 | addCommand(new CmdFrequencySubBand(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 68 | addCommand(new CmdPublicNetwork(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 69 | addCommand(new CmdDeviceId(_dot, serial)); |
Mike Fiore |
9:ff62b20f7000 | 70 | addCommand(new CmdDeviceClass(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 71 | |
Mike Fiore |
9:ff62b20f7000 | 72 | addCommand(new CmdAppPort(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 73 | addCommand(new CmdNetworkAddress(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 74 | addCommand(new CmdNetworkSessionKey(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 75 | addCommand(new CmdDataSessionKey(_dot, serial)); |
Mike Fiore |
9:ff62b20f7000 | 76 | addCommand(new CmdUplinkCounter(_dot, serial)); |
Mike Fiore |
9:ff62b20f7000 | 77 | addCommand(new CmdDownlinkCounter(_dot, serial)); |
Mike Fiore |
9:ff62b20f7000 | 78 | addCommand(new CmdSaveSession(_dot, serial)); |
Mike Fiore |
9:ff62b20f7000 | 79 | addCommand(new CmdRestoreSession(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 80 | addCommand(new CmdNetworkKey(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 81 | addCommand(new CmdNetworkId(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 82 | |
Mike Fiore |
9:ff62b20f7000 | 83 | addCommand(new CmdJoinDelay(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 84 | addCommand(new CmdJoinRequest(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 85 | addCommand(new CmdJoinRetries(_dot, serial)); |
Mike Fiore |
4:666017851052 | 86 | addCommand(new CmdJoinByteOrder(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 87 | addCommand(new CmdNetworkJoinMode(_dot, serial)); |
Mike Fiore |
9:ff62b20f7000 | 88 | addCommand(new CmdPreserveSession(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 89 | addCommand(new CmdNetworkJoinStatus(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 90 | addCommand(new CmdNetworkLinkCheck(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 91 | addCommand(new CmdLinkCheckCount(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 92 | addCommand(new CmdLinkCheckThreshold(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 93 | addCommand(new CmdEncryption(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 94 | |
Mike Fiore |
1:e52ae6584f1c | 95 | addCommand(new CmdRssi(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 96 | addCommand(new CmdSnr(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 97 | addCommand(new CmdDataPending(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 98 | |
Mike Fiore |
9:ff62b20f7000 | 99 | addCommand(new CmdSessionDataRate(_dot, serial)); |
Mike Fiore |
9:ff62b20f7000 | 100 | |
Mike Fiore |
1:e52ae6584f1c | 101 | addCommand(new CmdTxDataRate(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 102 | addCommand(new CmdTxPower(_dot, serial)); |
Mike Fiore |
9:ff62b20f7000 | 103 | addCommand(new CmdAntennaGain(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 104 | addCommand(new CmdTxFrequency(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 105 | addCommand(new CmdTxInverted(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 106 | addCommand(new CmdTxWait(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 107 | addCommand(new CmdTxChannel(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 108 | addCommand(new CmdTxNextMs(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 109 | addCommand(new CmdTimeOnAir(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 110 | |
Mike Fiore |
9:ff62b20f7000 | 111 | addCommand(new CmdRxDelay(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 112 | addCommand(new CmdRxOutput(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 113 | addCommand(new CmdRxInverted(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 114 | |
Mike Fiore |
1:e52ae6584f1c | 115 | addCommand(new CmdErrorCorrection(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 116 | addCommand(new CmdCRC(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 117 | addCommand(new CmdAdaptiveDataRate(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 118 | |
Mike Fiore |
1:e52ae6584f1c | 119 | addCommand(new CmdACKAttempts(_dot, serial)); |
Mike Fiore |
9:ff62b20f7000 | 120 | addCommand(new CmdRepeat(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 121 | |
Mike Fiore |
1:e52ae6584f1c | 122 | addCommand(new CmdSendString(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 123 | addCommand(new CmdSendBinary(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 124 | addCommand(new CmdReceiveOnce(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 125 | |
Mike Fiore |
9:ff62b20f7000 | 126 | addCommand(new CmdDummy(_dot, "Serial Data Mode", "AT+SD", "Enter serial data mode, exit with '+++'")); |
Mike Fiore |
9:ff62b20f7000 | 127 | addCommand(new CmdDummy(_dot, "Sleep Mode", "AT+SLEEP", "Enter sleep mode (0:deepsleep,1:sleep)")); |
Mike Fiore |
9:ff62b20f7000 | 128 | addCommand(new CmdSerialClearOnError(_dot, serial)); |
Mike Fiore |
4:666017851052 | 129 | addCommand(new CmdWakeMode(_dot, serial)); |
Mike Fiore |
4:666017851052 | 130 | addCommand(new CmdWakeInterval(_dot, serial)); |
Mike Fiore |
9:ff62b20f7000 | 131 | addCommand(new CmdWakePin(_dot, serial)); |
Mike Fiore |
4:666017851052 | 132 | addCommand(new CmdWakeDelay(_dot, serial)); |
Mike Fiore |
4:666017851052 | 133 | addCommand(new CmdWakeTimeout(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 134 | addCommand(new CmdPing(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 135 | addCommand(new CmdLogLevel(_dot, serial)); |
Mike Fiore |
9:ff62b20f7000 | 136 | |
Mike Fiore |
9:ff62b20f7000 | 137 | addCommand(new CmdDummy(_dot, "***** Test Commands *****", "", "")); |
Mike Fiore |
9:ff62b20f7000 | 138 | addCommand(new CmdRxDataRate(_dot, serial)); |
Mike Fiore |
9:ff62b20f7000 | 139 | addCommand(new CmdRxFrequency(_dot, serial)); |
Mike Fiore |
9:ff62b20f7000 | 140 | addCommand(new CmdReceiveContinuous(_dot, serial)); |
Mike Fiore |
9:ff62b20f7000 | 141 | addCommand(new CmdSendStringOnInterval(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 142 | } |
Mike Fiore |
1:e52ae6584f1c | 143 | |
Mike Fiore |
1:e52ae6584f1c | 144 | void CommandTerminal::printHelp() { |
Mike Fiore |
1:e52ae6584f1c | 145 | const char* name = NULL; |
Mike Fiore |
1:e52ae6584f1c | 146 | const char* text = NULL; |
Mike Fiore |
1:e52ae6584f1c | 147 | const char* desc = NULL; |
Mike Fiore |
1:e52ae6584f1c | 148 | const char* tab = "\t"; |
Mike Fiore |
1:e52ae6584f1c | 149 | |
Mike Fiore |
1:e52ae6584f1c | 150 | std::string header("Command"); |
Mike Fiore |
1:e52ae6584f1c | 151 | header.append(tab); |
Mike Fiore |
1:e52ae6584f1c | 152 | header.append(tab); |
Mike Fiore |
1:e52ae6584f1c | 153 | header.append("Name"); |
Mike Fiore |
1:e52ae6584f1c | 154 | header.append(tab); |
Mike Fiore |
1:e52ae6584f1c | 155 | header.append(tab); |
Mike Fiore |
1:e52ae6584f1c | 156 | header.append(tab); |
Mike Fiore |
1:e52ae6584f1c | 157 | header.append("Description"); |
Mike Fiore |
1:e52ae6584f1c | 158 | |
Mike Fiore |
1:e52ae6584f1c | 159 | write(newline); |
Mike Fiore |
1:e52ae6584f1c | 160 | write(header.c_str()); |
Mike Fiore |
1:e52ae6584f1c | 161 | write(newline); |
Mike Fiore |
1:e52ae6584f1c | 162 | write(newline); |
Mike Fiore |
1:e52ae6584f1c | 163 | for (std::vector<Command*>::iterator it = _commands.begin(); it != _commands.end(); ++it) { |
Mike Fiore |
1:e52ae6584f1c | 164 | name = (*it)->name(); |
Mike Fiore |
1:e52ae6584f1c | 165 | text = (*it)->text(); |
Mike Fiore |
1:e52ae6584f1c | 166 | desc = (*it)->desc(); |
Mike Fiore |
1:e52ae6584f1c | 167 | write(text); |
Mike Fiore |
1:e52ae6584f1c | 168 | if (strlen(text) < 8) |
Mike Fiore |
1:e52ae6584f1c | 169 | write(tab); |
Mike Fiore |
1:e52ae6584f1c | 170 | write(tab); |
Mike Fiore |
1:e52ae6584f1c | 171 | write(name); |
Mike Fiore |
1:e52ae6584f1c | 172 | if (strlen(name) < 8) |
Mike Fiore |
1:e52ae6584f1c | 173 | write(tab); |
Mike Fiore |
1:e52ae6584f1c | 174 | if (strlen(name) < 16) |
Mike Fiore |
1:e52ae6584f1c | 175 | write(tab); |
Mike Fiore |
1:e52ae6584f1c | 176 | write(tab); |
Mike Fiore |
1:e52ae6584f1c | 177 | write(desc); |
Mike Fiore |
1:e52ae6584f1c | 178 | write(newline); |
Mike Fiore |
1:e52ae6584f1c | 179 | } |
Mike Fiore |
1:e52ae6584f1c | 180 | |
Mike Fiore |
1:e52ae6584f1c | 181 | write(newline); |
Mike Fiore |
1:e52ae6584f1c | 182 | } |
Mike Fiore |
1:e52ae6584f1c | 183 | |
Mike Fiore |
1:e52ae6584f1c | 184 | bool CommandTerminal::writeable() { |
Mike Fiore |
1:e52ae6584f1c | 185 | return _serial.writeable(); |
Mike Fiore |
1:e52ae6584f1c | 186 | } |
Mike Fiore |
1:e52ae6584f1c | 187 | |
Mike Fiore |
1:e52ae6584f1c | 188 | bool CommandTerminal::readable() { |
Mike Fiore |
1:e52ae6584f1c | 189 | return _serial.readable(); |
Mike Fiore |
1:e52ae6584f1c | 190 | } |
Mike Fiore |
1:e52ae6584f1c | 191 | |
Mike Fiore |
1:e52ae6584f1c | 192 | char CommandTerminal::read() { |
Mike Fiore |
1:e52ae6584f1c | 193 | char ch; |
Mike Fiore |
1:e52ae6584f1c | 194 | _serial.read(&ch, 1); |
Mike Fiore |
1:e52ae6584f1c | 195 | return ch; |
Mike Fiore |
1:e52ae6584f1c | 196 | } |
Mike Fiore |
1:e52ae6584f1c | 197 | |
Mike Fiore |
1:e52ae6584f1c | 198 | void CommandTerminal::write(const char* message) { |
Mike Fiore |
1:e52ae6584f1c | 199 | while (!writeable()) |
Mike Fiore |
1:e52ae6584f1c | 200 | ; |
Mike Fiore |
1:e52ae6584f1c | 201 | _serial.write(message, strlen(message)); |
Mike Fiore |
1:e52ae6584f1c | 202 | } |
Mike Fiore |
1:e52ae6584f1c | 203 | |
Mike Fiore |
1:e52ae6584f1c | 204 | void CommandTerminal::writef(const char* format, ...) { |
Mike Fiore |
1:e52ae6584f1c | 205 | char buff[256]; |
Mike Fiore |
1:e52ae6584f1c | 206 | |
Mike Fiore |
1:e52ae6584f1c | 207 | va_list ap; |
Mike Fiore |
1:e52ae6584f1c | 208 | va_start(ap, format); |
Mike Fiore |
1:e52ae6584f1c | 209 | int size = vsnprintf(buff, 256, format, ap); |
Mike Fiore |
1:e52ae6584f1c | 210 | while (!writeable()) |
Mike Fiore |
1:e52ae6584f1c | 211 | ; |
Mike Fiore |
1:e52ae6584f1c | 212 | _serial.write(buff, size); |
Mike Fiore |
1:e52ae6584f1c | 213 | va_end(ap); |
Mike Fiore |
1:e52ae6584f1c | 214 | } |
Mike Fiore |
1:e52ae6584f1c | 215 | |
Mike Fiore |
9:ff62b20f7000 | 216 | void CommandTerminal::serialLoop() { |
Mike Fiore |
1:e52ae6584f1c | 217 | Timer serial_read_timer; |
Mike Fiore |
1:e52ae6584f1c | 218 | std::vector<uint8_t> serial_buffer; |
Mike Fiore |
9:ff62b20f7000 | 219 | std::vector<uint8_t> data; |
Mike Fiore |
9:ff62b20f7000 | 220 | int timeout = 0; |
Mike Fiore |
1:e52ae6584f1c | 221 | |
Mike Fiore |
9:ff62b20f7000 | 222 | serial_read_timer.start(); |
Mike Fiore |
1:e52ae6584f1c | 223 | |
Mike Fiore |
9:ff62b20f7000 | 224 | if (_dot->getStartUpMode() == mDot::SERIAL_MODE) { |
Mike Fiore |
9:ff62b20f7000 | 225 | _xbee_on_sleep = GPIO_PIN_SET; |
Mike Fiore |
1:e52ae6584f1c | 226 | |
Mike Fiore |
9:ff62b20f7000 | 227 | timeout = _dot->getWakeDelay(); |
Mike Fiore |
1:e52ae6584f1c | 228 | |
Mike Fiore |
9:ff62b20f7000 | 229 | // wait for timeout or start of serial data |
Mike Fiore |
9:ff62b20f7000 | 230 | while (!readable() && serial_read_timer.read_ms() < timeout && !_serial.escaped()) { |
Mike Fiore |
9:ff62b20f7000 | 231 | osDelay(2); |
Mike Fiore |
1:e52ae6584f1c | 232 | } |
Mike Fiore |
1:e52ae6584f1c | 233 | } |
Mike Fiore |
1:e52ae6584f1c | 234 | |
Mike Fiore |
9:ff62b20f7000 | 235 | if (readable() && !_serial.escaped()) { |
Mike Fiore |
6:e27eaad36a0c | 236 | |
Mike Fiore |
6:e27eaad36a0c | 237 | serial_read_timer.reset(); |
Mike Fiore |
6:e27eaad36a0c | 238 | timeout = _dot->getWakeTimeout(); |
Mike Fiore |
9:ff62b20f7000 | 239 | |
Mike Fiore |
9:ff62b20f7000 | 240 | while (serial_read_timer.read_ms() < timeout && serial_buffer.size() <= _dot->getMaxPacketLength()) { |
Mike Fiore |
9:ff62b20f7000 | 241 | while (readable() && serial_buffer.size() < _dot->getMaxPacketLength()) { |
Mike Fiore |
1:e52ae6584f1c | 242 | serial_buffer.push_back(read()); |
Mike Fiore |
1:e52ae6584f1c | 243 | serial_read_timer.reset(); |
Mike Fiore |
9:ff62b20f7000 | 244 | |
Mike Fiore |
9:ff62b20f7000 | 245 | if (_serial.escaped()) |
Mike Fiore |
9:ff62b20f7000 | 246 | break; |
Mike Fiore |
1:e52ae6584f1c | 247 | } |
Mike Fiore |
1:e52ae6584f1c | 248 | } |
Mike Fiore |
9:ff62b20f7000 | 249 | |
Mike Fiore |
1:e52ae6584f1c | 250 | serial_read_timer.stop(), serial_read_timer.reset(); |
Mike Fiore |
1:e52ae6584f1c | 251 | |
Mike Fiore |
1:e52ae6584f1c | 252 | if (!serial_buffer.empty()) { |
Mike Fiore |
9:ff62b20f7000 | 253 | if (_dot->getStartUpMode() == mDot::SERIAL_MODE) |
Mike Fiore |
9:ff62b20f7000 | 254 | _xbee_on_sleep = GPIO_PIN_RESET; |
Mike Fiore |
9:ff62b20f7000 | 255 | |
Mike Fiore |
9:ff62b20f7000 | 256 | // wait for any duty cycle limit to expire |
Mike Fiore |
9:ff62b20f7000 | 257 | while (_dot->getNextTxMs() > 0 && !_serial.escaped()) { |
Mike Fiore |
9:ff62b20f7000 | 258 | osDelay(10); |
Mike Fiore |
9:ff62b20f7000 | 259 | } |
Mike Fiore |
9:ff62b20f7000 | 260 | |
Mike Fiore |
1:e52ae6584f1c | 261 | if (!_dot->getIsTransmitting()) { |
Mike Fiore |
9:ff62b20f7000 | 262 | logDebug("Received serial data, sending out radio."); |
Mike Fiore |
9:ff62b20f7000 | 263 | |
Mike Fiore |
9:ff62b20f7000 | 264 | if (_dot->send(serial_buffer, false) != mDot::MDOT_OK) { |
Mike Fiore |
9:ff62b20f7000 | 265 | logDebug("Send failed."); |
Mike Fiore |
9:ff62b20f7000 | 266 | // If the data should be tossed after send failure, clear buffer |
Mike Fiore |
9:ff62b20f7000 | 267 | if (_dot->getSerialClearOnError()) { |
Mike Fiore |
9:ff62b20f7000 | 268 | serial_buffer.clear(); |
Mike Fiore |
9:ff62b20f7000 | 269 | } |
Mike Fiore |
9:ff62b20f7000 | 270 | } else { |
Mike Fiore |
1:e52ae6584f1c | 271 | |
Mike Fiore |
9:ff62b20f7000 | 272 | // wait for send to finish |
Mike Fiore |
9:ff62b20f7000 | 273 | while (_dot->getIsTransmitting() && !_serial.escaped()) |
Mike Fiore |
9:ff62b20f7000 | 274 | osDelay(10); |
Mike Fiore |
9:ff62b20f7000 | 275 | |
Mike Fiore |
9:ff62b20f7000 | 276 | // call recv to wait for any packet before sending again |
Mike Fiore |
9:ff62b20f7000 | 277 | if (!_serial.escaped()) |
Mike Fiore |
9:ff62b20f7000 | 278 | _dot->recv(data); |
Mike Fiore |
9:ff62b20f7000 | 279 | |
Mike Fiore |
9:ff62b20f7000 | 280 | // Clear the serial buffer if send is success |
Mike Fiore |
9:ff62b20f7000 | 281 | serial_buffer.clear(); |
Mike Fiore |
9:ff62b20f7000 | 282 | } |
Mike Fiore |
1:e52ae6584f1c | 283 | } else { |
Mike Fiore |
6:e27eaad36a0c | 284 | logDebug("Radio is busy, cannot send.\r\n"); |
Mike Fiore |
9:ff62b20f7000 | 285 | osDelay(10); |
Mike Fiore |
1:e52ae6584f1c | 286 | } |
Mike Fiore |
1:e52ae6584f1c | 287 | |
Mike Fiore |
1:e52ae6584f1c | 288 | } else { |
Mike Fiore |
6:e27eaad36a0c | 289 | logDebug("No data received from serial to send.\r\n"); |
Mike Fiore |
1:e52ae6584f1c | 290 | } |
Mike Fiore |
9:ff62b20f7000 | 291 | } |
Mike Fiore |
9:ff62b20f7000 | 292 | |
Mike Fiore |
9:ff62b20f7000 | 293 | if (!_serial.readable() && _dot->getStartUpMode() == mDot::SERIAL_MODE && !_serial.escaped()) { |
Mike Fiore |
9:ff62b20f7000 | 294 | _xbee_on_sleep = GPIO_PIN_RESET; |
Mike Fiore |
9:ff62b20f7000 | 295 | sleep(_sleep_standby); |
Mike Fiore |
1:e52ae6584f1c | 296 | } |
Mike Fiore |
9:ff62b20f7000 | 297 | |
Mike Fiore |
9:ff62b20f7000 | 298 | if (_serial.escaped()) { |
Mike Fiore |
9:ff62b20f7000 | 299 | _serial.clearEscaped(); |
Mike Fiore |
9:ff62b20f7000 | 300 | _serial.rxClear(); |
Mike Fiore |
9:ff62b20f7000 | 301 | serial_data_mode = false; |
Mike Fiore |
9:ff62b20f7000 | 302 | _mode = mDot::COMMAND_MODE; |
Mike Fiore |
9:ff62b20f7000 | 303 | logDebug("Exit Serial Mode"); |
Mike Fiore |
9:ff62b20f7000 | 304 | write(done); |
Mike Fiore |
9:ff62b20f7000 | 305 | return; |
Mike Fiore |
9:ff62b20f7000 | 306 | } |
Mike Fiore |
9:ff62b20f7000 | 307 | |
Mike Fiore |
9:ff62b20f7000 | 308 | if (!_dot->getNetworkJoinStatus()) { |
Mike Fiore |
9:ff62b20f7000 | 309 | serial_data_mode = false; |
Mike Fiore |
9:ff62b20f7000 | 310 | _mode = mDot::COMMAND_MODE; |
Mike Fiore |
9:ff62b20f7000 | 311 | logDebug("Exit Serial Mode"); |
Mike Fiore |
9:ff62b20f7000 | 312 | write(no_carrier); |
Mike Fiore |
9:ff62b20f7000 | 313 | return; |
Mike Fiore |
9:ff62b20f7000 | 314 | } |
Mike Fiore |
1:e52ae6584f1c | 315 | } |
Mike Fiore |
1:e52ae6584f1c | 316 | |
Mike Fiore |
1:e52ae6584f1c | 317 | bool CommandTerminal::autoJoinCheck() { |
Mike Fiore |
1:e52ae6584f1c | 318 | |
Mike Fiore |
1:e52ae6584f1c | 319 | std::string escape_buffer; |
Mike Fiore |
1:e52ae6584f1c | 320 | int sleep = 1000; |
Mike Fiore |
1:e52ae6584f1c | 321 | Timer tmr; |
Mike Fiore |
9:ff62b20f7000 | 322 | tmr.start(); |
Mike Fiore |
1:e52ae6584f1c | 323 | int cnt = 0; |
Mike Fiore |
1:e52ae6584f1c | 324 | |
Mike Fiore |
1:e52ae6584f1c | 325 | while (!_dot->getNetworkJoinStatus()) { |
Mike Fiore |
1:e52ae6584f1c | 326 | write("\r\nJoining network... "); |
Mike Fiore |
1:e52ae6584f1c | 327 | |
Mike Fiore |
9:ff62b20f7000 | 328 | if (_dot->getNextTxMs() > 0) { |
Mike Fiore |
9:ff62b20f7000 | 329 | int rand_time = rand() % 10000; |
Mike Fiore |
9:ff62b20f7000 | 330 | writef("\r\nWaiting %lu s before next join attempt\r\n", (_dot->getNextTxMs() + rand_time) / 1000); |
Mike Fiore |
9:ff62b20f7000 | 331 | |
Mike Fiore |
9:ff62b20f7000 | 332 | tmr.reset(); |
Mike Fiore |
9:ff62b20f7000 | 333 | while (_dot->getNextTxMs() > 0 && !_serial.escaped()) { |
Mike Fiore |
9:ff62b20f7000 | 334 | osDelay(2); |
Mike Fiore |
1:e52ae6584f1c | 335 | } |
Mike Fiore |
1:e52ae6584f1c | 336 | |
Mike Fiore |
9:ff62b20f7000 | 337 | tmr.reset(); |
Mike Fiore |
9:ff62b20f7000 | 338 | while (tmr.read_ms() < rand_time && !_serial.escaped()) |
Mike Fiore |
9:ff62b20f7000 | 339 | osDelay(10); |
Mike Fiore |
1:e52ae6584f1c | 340 | } |
Mike Fiore |
1:e52ae6584f1c | 341 | |
Mike Fiore |
9:ff62b20f7000 | 342 | if (!_serial.escaped() && _dot->joinNetworkOnce() == mDot::MDOT_OK) { |
Mike Fiore |
1:e52ae6584f1c | 343 | write("Network Joined\r\n"); |
Mike Fiore |
1:e52ae6584f1c | 344 | write(done); |
Mike Fiore |
1:e52ae6584f1c | 345 | return false; |
Mike Fiore |
1:e52ae6584f1c | 346 | } |
Mike Fiore |
1:e52ae6584f1c | 347 | |
Mike Fiore |
1:e52ae6584f1c | 348 | write("Network Join failed\r\n"); |
Mike Fiore |
1:e52ae6584f1c | 349 | write(error); |
Mike Fiore |
1:e52ae6584f1c | 350 | |
Mike Fiore |
9:ff62b20f7000 | 351 | if (!_serial.escaped() && _dot->getJoinRetries() > 0 && cnt++ > _dot->getJoinRetries()) { |
Mike Fiore |
1:e52ae6584f1c | 352 | cnt = 0; |
Mike Fiore |
1:e52ae6584f1c | 353 | |
Mike Fiore |
1:e52ae6584f1c | 354 | if (_dot->getFrequencyBand() == mDot::FB_915) { |
Mike Fiore |
1:e52ae6584f1c | 355 | uint8_t band = ((_dot->getFrequencySubBand()) % 8) + 1; |
Mike Fiore |
9:ff62b20f7000 | 356 | logWarning("Join retries exhausted, switching to sub band %u", band); |
Mike Fiore |
1:e52ae6584f1c | 357 | _dot->setFrequencySubBand(band); |
Mike Fiore |
1:e52ae6584f1c | 358 | } |
Mike Fiore |
1:e52ae6584f1c | 359 | |
Mike Fiore |
1:e52ae6584f1c | 360 | if (sleep < 60 * 60 * 1000) |
Mike Fiore |
1:e52ae6584f1c | 361 | sleep *= 2; |
Mike Fiore |
1:e52ae6584f1c | 362 | } |
Mike Fiore |
1:e52ae6584f1c | 363 | |
Mike Fiore |
1:e52ae6584f1c | 364 | tmr.reset(); |
Mike Fiore |
9:ff62b20f7000 | 365 | while (tmr.read_ms() < sleep && !_serial.escaped()) { |
Mike Fiore |
9:ff62b20f7000 | 366 | osDelay(10); |
Mike Fiore |
1:e52ae6584f1c | 367 | } |
Mike Fiore |
1:e52ae6584f1c | 368 | |
Mike Fiore |
9:ff62b20f7000 | 369 | if (_serial.escaped()) { |
Mike Fiore |
9:ff62b20f7000 | 370 | _serial.clearEscaped(); |
Mike Fiore |
9:ff62b20f7000 | 371 | serial_data_mode = false; |
Mike Fiore |
9:ff62b20f7000 | 372 | _mode = mDot::COMMAND_MODE; |
Mike Fiore |
9:ff62b20f7000 | 373 | write("Join Canceled\r\n"); |
Mike Fiore |
9:ff62b20f7000 | 374 | write(done); |
Mike Fiore |
9:ff62b20f7000 | 375 | return true; |
Mike Fiore |
9:ff62b20f7000 | 376 | } |
Mike Fiore |
1:e52ae6584f1c | 377 | } |
Mike Fiore |
1:e52ae6584f1c | 378 | |
Mike Fiore |
1:e52ae6584f1c | 379 | return false; |
Mike Fiore |
1:e52ae6584f1c | 380 | } |
Mike Fiore |
1:e52ae6584f1c | 381 | |
Mike Fiore |
1:e52ae6584f1c | 382 | void CommandTerminal::start() { |
Mike Fiore |
1:e52ae6584f1c | 383 | |
Mike Fiore |
1:e52ae6584f1c | 384 | char ch; |
Mike Fiore |
1:e52ae6584f1c | 385 | bool running = true; |
Mike Fiore |
1:e52ae6584f1c | 386 | bool echo = _dot->getEcho(); |
Mike Fiore |
1:e52ae6584f1c | 387 | std::string command; |
Mike Fiore |
4:666017851052 | 388 | std::deque<std::string> history; |
Mike Fiore |
4:666017851052 | 389 | int history_index = -1; |
Mike Fiore |
1:e52ae6584f1c | 390 | std::vector<std::string> args; |
Mike Fiore |
9:ff62b20f7000 | 391 | bool join_canceled = false; |
Mike Fiore |
1:e52ae6584f1c | 392 | |
Mike Fiore |
1:e52ae6584f1c | 393 | if (_dot->getStartUpMode() == mDot::SERIAL_MODE) { |
Mike Fiore |
9:ff62b20f7000 | 394 | |
Mike Fiore |
9:ff62b20f7000 | 395 | serial_data_mode = true; |
Mike Fiore |
9:ff62b20f7000 | 396 | _mode = mDot::SERIAL_MODE; |
Mike Fiore |
1:e52ae6584f1c | 397 | |
Mike Fiore |
1:e52ae6584f1c | 398 | std::string escape_buffer; |
Mike Fiore |
1:e52ae6584f1c | 399 | char ch; |
Mike Fiore |
1:e52ae6584f1c | 400 | |
Mike Fiore |
9:ff62b20f7000 | 401 | if (!_dot->getStandbyFlag()) { |
Mike Fiore |
9:ff62b20f7000 | 402 | // wake up from power-on/reset |
Mike Fiore |
9:ff62b20f7000 | 403 | |
Mike Fiore |
9:ff62b20f7000 | 404 | int escape_timeout = 1000; |
Mike Fiore |
9:ff62b20f7000 | 405 | Timer tmr; |
Mike Fiore |
9:ff62b20f7000 | 406 | Timer escape_tmr; |
Mike Fiore |
1:e52ae6584f1c | 407 | |
Mike Fiore |
9:ff62b20f7000 | 408 | // wait one second for possible escape by user pressing '+' key |
Mike Fiore |
9:ff62b20f7000 | 409 | tmr.reset(); |
Mike Fiore |
9:ff62b20f7000 | 410 | tmr.start(); |
Mike Fiore |
9:ff62b20f7000 | 411 | escape_tmr.reset(); |
Mike Fiore |
9:ff62b20f7000 | 412 | escape_tmr.start(); |
Mike Fiore |
9:ff62b20f7000 | 413 | while (tmr.read_ms() < escape_timeout) { |
Mike Fiore |
9:ff62b20f7000 | 414 | if (_serial.readable()) { |
Mike Fiore |
9:ff62b20f7000 | 415 | _serial.read(&ch, 1); |
Mike Fiore |
9:ff62b20f7000 | 416 | escape_buffer += ch; |
Mike Fiore |
9:ff62b20f7000 | 417 | } |
Mike Fiore |
1:e52ae6584f1c | 418 | |
Mike Fiore |
9:ff62b20f7000 | 419 | if (escape_buffer.find("+") != std::string::npos) { |
Mike Fiore |
9:ff62b20f7000 | 420 | logInfo("Escape detected"); |
Mike Fiore |
9:ff62b20f7000 | 421 | join_canceled = true; |
Mike Fiore |
9:ff62b20f7000 | 422 | serial_data_mode = false; |
Mike Fiore |
9:ff62b20f7000 | 423 | _mode = mDot::COMMAND_MODE; |
Mike Fiore |
9:ff62b20f7000 | 424 | command.clear(); |
Mike Fiore |
9:ff62b20f7000 | 425 | break; |
Mike Fiore |
9:ff62b20f7000 | 426 | } |
Mike Fiore |
9:ff62b20f7000 | 427 | |
Mike Fiore |
9:ff62b20f7000 | 428 | if (escape_tmr.read_ms() > escape_timeout) |
Mike Fiore |
9:ff62b20f7000 | 429 | escape_buffer.clear(); |
Mike Fiore |
9:ff62b20f7000 | 430 | |
Mike Fiore |
9:ff62b20f7000 | 431 | osDelay(1); |
Mike Fiore |
1:e52ae6584f1c | 432 | } |
Mike Fiore |
1:e52ae6584f1c | 433 | } |
Mike Fiore |
1:e52ae6584f1c | 434 | |
Mike Fiore |
9:ff62b20f7000 | 435 | if (_mode == mDot::SERIAL_MODE && !_dot->getNetworkJoinStatus() && _dot->getJoinMode() == mDot::OTA) { |
Mike Fiore |
9:ff62b20f7000 | 436 | if (_dot->joinNetworkOnce() != mDot::MDOT_OK) { |
Mike Fiore |
9:ff62b20f7000 | 437 | serial_data_mode = false; |
Mike Fiore |
9:ff62b20f7000 | 438 | _mode = mDot::COMMAND_MODE; |
Mike Fiore |
9:ff62b20f7000 | 439 | |
Mike Fiore |
9:ff62b20f7000 | 440 | logWarning("Start Up Mode set to SERIAL_MODE, but join failed."); |
Mike Fiore |
9:ff62b20f7000 | 441 | _serial.writef("Network Not Joined\r\n"); |
Mike Fiore |
9:ff62b20f7000 | 442 | _serial.writef(error); |
Mike Fiore |
9:ff62b20f7000 | 443 | } |
Mike Fiore |
9:ff62b20f7000 | 444 | } |
Mike Fiore |
1:e52ae6584f1c | 445 | } |
Mike Fiore |
1:e52ae6584f1c | 446 | |
Mike Fiore |
9:ff62b20f7000 | 447 | if (_dot->getJoinMode() == mDot::PEER_TO_PEER) { |
Mike Fiore |
9:ff62b20f7000 | 448 | peer_to_peer = true; |
Mike Fiore |
9:ff62b20f7000 | 449 | } else { |
Mike Fiore |
9:ff62b20f7000 | 450 | peer_to_peer = false; |
Mike Fiore |
9:ff62b20f7000 | 451 | } |
Mike Fiore |
9:ff62b20f7000 | 452 | |
Mike Fiore |
9:ff62b20f7000 | 453 | |
Mike Fiore |
1:e52ae6584f1c | 454 | |
Mike Fiore |
1:e52ae6584f1c | 455 | //Run terminal session |
Mike Fiore |
1:e52ae6584f1c | 456 | while (running) { |
Mike Fiore |
9:ff62b20f7000 | 457 | |
Mike Fiore |
9:ff62b20f7000 | 458 | // wait for input to reduce at command idle current |
Mike Fiore |
9:ff62b20f7000 | 459 | while (!readable() || _mode == mDot::SERIAL_MODE) { |
Mike Fiore |
9:ff62b20f7000 | 460 | if (!join_canceled && _dot->getJoinMode() == mDot::AUTO_OTA) { |
Mike Fiore |
9:ff62b20f7000 | 461 | join_canceled = autoJoinCheck(); |
Mike Fiore |
9:ff62b20f7000 | 462 | if (join_canceled) |
Mike Fiore |
9:ff62b20f7000 | 463 | command.clear(); |
Mike Fiore |
9:ff62b20f7000 | 464 | } |
Mike Fiore |
1:e52ae6584f1c | 465 | |
Mike Fiore |
9:ff62b20f7000 | 466 | if (_dot->getJoinMode() != mDot::AUTO_OTA || (!join_canceled && _dot->getJoinMode() == mDot::AUTO_OTA)) { |
Mike Fiore |
9:ff62b20f7000 | 467 | switch (_mode) { |
Mike Fiore |
9:ff62b20f7000 | 468 | case mDot::SERIAL_MODE: |
Mike Fiore |
9:ff62b20f7000 | 469 | // signal wakeup, read serial and output to radio |
Mike Fiore |
9:ff62b20f7000 | 470 | serialLoop(); |
Mike Fiore |
9:ff62b20f7000 | 471 | continue; |
Mike Fiore |
9:ff62b20f7000 | 472 | break; |
Mike Fiore |
9:ff62b20f7000 | 473 | default: |
Mike Fiore |
9:ff62b20f7000 | 474 | break; |
Mike Fiore |
9:ff62b20f7000 | 475 | } |
Mike Fiore |
1:e52ae6584f1c | 476 | } |
Mike Fiore |
9:ff62b20f7000 | 477 | |
Mike Fiore |
9:ff62b20f7000 | 478 | ch = '\0'; |
Mike Fiore |
1:e52ae6584f1c | 479 | |
Mike Fiore |
9:ff62b20f7000 | 480 | wait(0.00001); // 10 us |
Mike Fiore |
9:ff62b20f7000 | 481 | _serial.escaped(); |
Mike Fiore |
9:ff62b20f7000 | 482 | } |
Mike Fiore |
1:e52ae6584f1c | 483 | |
Mike Fiore |
1:e52ae6584f1c | 484 | // read characters |
Mike Fiore |
1:e52ae6584f1c | 485 | if (readable()) { |
Mike Fiore |
1:e52ae6584f1c | 486 | ch = read(); |
Mike Fiore |
1:e52ae6584f1c | 487 | |
Mike Fiore |
4:666017851052 | 488 | if (ch == '\b' || ch == 0x7f) { |
Mike Fiore |
1:e52ae6584f1c | 489 | if (!command.empty()) { |
Mike Fiore |
1:e52ae6584f1c | 490 | writef("\b \b"); |
Mike Fiore |
1:e52ae6584f1c | 491 | command.erase(command.size() - 1); |
Mike Fiore |
1:e52ae6584f1c | 492 | } |
Mike Fiore |
1:e52ae6584f1c | 493 | continue; |
Mike Fiore |
4:666017851052 | 494 | } else if (ch == 0x1b || ch == 0x09) { |
Mike Fiore |
4:666017851052 | 495 | osDelay(20); |
Mike Fiore |
4:666017851052 | 496 | // catch escape sequence, or tab |
Mike Fiore |
9:ff62b20f7000 | 497 | char ch1 = 0x00, ch2 = 0x00; |
Mike Fiore |
4:666017851052 | 498 | |
Mike Fiore |
4:666017851052 | 499 | if (readable()) { |
Mike Fiore |
4:666017851052 | 500 | ch1 = read(); |
Mike Fiore |
4:666017851052 | 501 | if (readable()) |
Mike Fiore |
4:666017851052 | 502 | ch2 = read(); |
Mike Fiore |
4:666017851052 | 503 | |
Mike Fiore |
4:666017851052 | 504 | if (ch1 == 0x5b && ch2 == 0x41) { |
Mike Fiore |
4:666017851052 | 505 | // up key |
Mike Fiore |
9:ff62b20f7000 | 506 | for (size_t i = 0; i < command.size() + 1; i++) { |
Mike Fiore |
4:666017851052 | 507 | writef("\b \b"); |
Mike Fiore |
4:666017851052 | 508 | } |
Mike Fiore |
4:666017851052 | 509 | if (history.size() > 0) { |
Mike Fiore |
9:ff62b20f7000 | 510 | if (++history_index >= int(history.size() - 1)) |
Mike Fiore |
4:666017851052 | 511 | history_index = history.size() - 1; |
Mike Fiore |
4:666017851052 | 512 | |
Mike Fiore |
4:666017851052 | 513 | command = history[history_index]; |
Mike Fiore |
4:666017851052 | 514 | writef("%s", history[history_index].c_str()); |
Mike Fiore |
4:666017851052 | 515 | } else { |
Mike Fiore |
4:666017851052 | 516 | command.clear(); |
Mike Fiore |
4:666017851052 | 517 | } |
Mike Fiore |
4:666017851052 | 518 | } else if (ch1 == 0x5b && ch2 == 0x42) { |
Mike Fiore |
4:666017851052 | 519 | |
Mike Fiore |
4:666017851052 | 520 | // down key |
Mike Fiore |
9:ff62b20f7000 | 521 | for (size_t i = 0; i < command.size() + 1; i++) { |
Mike Fiore |
4:666017851052 | 522 | writef("\b \b"); |
Mike Fiore |
4:666017851052 | 523 | } |
Mike Fiore |
4:666017851052 | 524 | |
Mike Fiore |
4:666017851052 | 525 | if (--history_index < 0) { |
Mike Fiore |
4:666017851052 | 526 | history_index = -1; |
Mike Fiore |
4:666017851052 | 527 | command.clear(); |
Mike Fiore |
4:666017851052 | 528 | } else { |
Mike Fiore |
4:666017851052 | 529 | command = history[history_index]; |
Mike Fiore |
4:666017851052 | 530 | writef("%s", history[history_index].c_str()); |
Mike Fiore |
4:666017851052 | 531 | } |
Mike Fiore |
4:666017851052 | 532 | } |
Mike Fiore |
4:666017851052 | 533 | } |
Mike Fiore |
9:ff62b20f7000 | 534 | while (readable()) |
Mike Fiore |
9:ff62b20f7000 | 535 | read(); |
Mike Fiore |
4:666017851052 | 536 | continue; |
Mike Fiore |
1:e52ae6584f1c | 537 | } else { |
Mike Fiore |
1:e52ae6584f1c | 538 | command += ch; |
Mike Fiore |
1:e52ae6584f1c | 539 | } |
Mike Fiore |
1:e52ae6584f1c | 540 | |
Mike Fiore |
1:e52ae6584f1c | 541 | // echo chars if enabled |
Mike Fiore |
1:e52ae6584f1c | 542 | if (echo && !(ch == '\r' || ch == '\n')) |
Mike Fiore |
1:e52ae6584f1c | 543 | writef("%c", ch); |
Mike Fiore |
1:e52ae6584f1c | 544 | } |
Mike Fiore |
1:e52ae6584f1c | 545 | |
Mike Fiore |
1:e52ae6584f1c | 546 | // look for end of command line |
Mike Fiore |
1:e52ae6584f1c | 547 | if (command.find("\n") != std::string::npos || command.find("\r") != std::string::npos) { |
Mike Fiore |
1:e52ae6584f1c | 548 | // remove new line or cr character |
Mike Fiore |
1:e52ae6584f1c | 549 | command.erase(command.size() - 1); |
Mike Fiore |
1:e52ae6584f1c | 550 | write("\r"); // match standard modem output |
Mike Fiore |
1:e52ae6584f1c | 551 | write(newline); |
Mike Fiore |
1:e52ae6584f1c | 552 | } else { |
Mike Fiore |
1:e52ae6584f1c | 553 | continue; |
Mike Fiore |
1:e52ae6584f1c | 554 | } |
Mike Fiore |
1:e52ae6584f1c | 555 | |
Mike Fiore |
1:e52ae6584f1c | 556 | // trim whitespace from command |
Mike Fiore |
1:e52ae6584f1c | 557 | mts::Text::trim(command, "\r\n\t "); |
Mike Fiore |
1:e52ae6584f1c | 558 | |
Mike Fiore |
1:e52ae6584f1c | 559 | if (command.size() < 1) { |
Mike Fiore |
1:e52ae6584f1c | 560 | command.clear(); |
Mike Fiore |
1:e52ae6584f1c | 561 | continue; |
Mike Fiore |
1:e52ae6584f1c | 562 | } |
Mike Fiore |
1:e52ae6584f1c | 563 | |
Mike Fiore |
1:e52ae6584f1c | 564 | // parse command and args |
Mike Fiore |
1:e52ae6584f1c | 565 | args.clear(); |
Mike Fiore |
1:e52ae6584f1c | 566 | |
Mike Fiore |
1:e52ae6584f1c | 567 | // find first '=' character |
Mike Fiore |
1:e52ae6584f1c | 568 | size_t delim_index = command.find("="); |
Mike Fiore |
1:e52ae6584f1c | 569 | if (delim_index != std::string::npos) { |
Mike Fiore |
1:e52ae6584f1c | 570 | args.push_back(command.substr(0, delim_index)); |
Mike Fiore |
1:e52ae6584f1c | 571 | } else { |
Mike Fiore |
1:e52ae6584f1c | 572 | // find first ' ' character |
Mike Fiore |
1:e52ae6584f1c | 573 | delim_index = command.find(" "); |
Mike Fiore |
1:e52ae6584f1c | 574 | if (delim_index != std::string::npos) { |
Mike Fiore |
1:e52ae6584f1c | 575 | args.push_back(command.substr(0, delim_index)); |
Mike Fiore |
1:e52ae6584f1c | 576 | } else { |
Mike Fiore |
1:e52ae6584f1c | 577 | args.push_back(command); |
Mike Fiore |
1:e52ae6584f1c | 578 | } |
Mike Fiore |
1:e52ae6584f1c | 579 | } |
Mike Fiore |
1:e52ae6584f1c | 580 | |
Mike Fiore |
1:e52ae6584f1c | 581 | if (delim_index != std::string::npos) { |
Mike Fiore |
1:e52ae6584f1c | 582 | std::vector<std::string> params = mts::Text::split(command.substr(delim_index + 1), ","); |
Mike Fiore |
1:e52ae6584f1c | 583 | args.insert(args.end(), params.begin(), params.end()); |
Mike Fiore |
1:e52ae6584f1c | 584 | } |
Mike Fiore |
1:e52ae6584f1c | 585 | |
Mike Fiore |
1:e52ae6584f1c | 586 | args[0] = mts::Text::toUpper(args[0]); |
Mike Fiore |
1:e52ae6584f1c | 587 | |
Mike Fiore |
1:e52ae6584f1c | 588 | // print help |
Mike Fiore |
1:e52ae6584f1c | 589 | if ((args[0].find("?") == 0 || args[0].find("HELP") == 0) && args.size() == 1) { |
Mike Fiore |
1:e52ae6584f1c | 590 | printHelp(); |
Mike Fiore |
1:e52ae6584f1c | 591 | command.clear(); |
Mike Fiore |
9:ff62b20f7000 | 592 | } else if ((args[0].find("ATE?") == 0 && args[0].length() == 4) || (args[0].find("ATE") == 0 && args[0].length() == 3)) { |
Mike Fiore |
9:ff62b20f7000 | 593 | writef("%d\r\n", _dot->getEcho()); |
Mike Fiore |
9:ff62b20f7000 | 594 | write(done); |
Mike Fiore |
1:e52ae6584f1c | 595 | } else if (args[0].find("ATE0") == 0 && args[0].length() == 4) { |
Mike Fiore |
1:e52ae6584f1c | 596 | _dot->setEcho(false); |
Mike Fiore |
1:e52ae6584f1c | 597 | write(done); |
Mike Fiore |
1:e52ae6584f1c | 598 | echo = _dot->getEcho(); |
Mike Fiore |
1:e52ae6584f1c | 599 | } else if (args[0].find("ATE1") == 0 && args[0].length() == 4) { |
Mike Fiore |
1:e52ae6584f1c | 600 | _dot->setEcho(true); |
Mike Fiore |
1:e52ae6584f1c | 601 | write(done); |
Mike Fiore |
1:e52ae6584f1c | 602 | echo = _dot->getEcho(); |
Mike Fiore |
9:ff62b20f7000 | 603 | } else if ((args[0].find("ATV?") == 0 && args[0].length() == 4) || (args[0].find("ATV") == 0 && args[0].length() == 3)) { |
Mike Fiore |
9:ff62b20f7000 | 604 | writef("%d\r\n", _dot->getVerbose()); |
Mike Fiore |
9:ff62b20f7000 | 605 | write(done); |
Mike Fiore |
1:e52ae6584f1c | 606 | } else if (args[0].find("ATV0") == 0 && args[0].length() == 4) { |
Mike Fiore |
1:e52ae6584f1c | 607 | _dot->setVerbose(false); |
Mike Fiore |
1:e52ae6584f1c | 608 | write(done); |
Mike Fiore |
1:e52ae6584f1c | 609 | } else if (args[0].find("ATV1") == 0 && args[0].length() == 4) { |
Mike Fiore |
1:e52ae6584f1c | 610 | _dot->setVerbose(true); |
Mike Fiore |
1:e52ae6584f1c | 611 | write(done); |
Mike Fiore |
9:ff62b20f7000 | 612 | } else if ((args[0].find("AT&K?") == 0 && args[0].length() == 5) || (args[0].find("AT&K") == 0 && args[0].length() == 4)) { |
Mike Fiore |
9:ff62b20f7000 | 613 | writef("%d\r\n", (_dot->getFlowControl() ? 3 : 0)); |
Mike Fiore |
9:ff62b20f7000 | 614 | write(done); |
Mike Fiore |
9:ff62b20f7000 | 615 | } else if (args[0].find("AT&K0") == 0 && args[0].length() == 5) { |
Mike Fiore |
9:ff62b20f7000 | 616 | _dot->setFlowControl(false); |
Mike Fiore |
9:ff62b20f7000 | 617 | write(done); |
Mike Fiore |
9:ff62b20f7000 | 618 | } else if (args[0].find("AT&K3") == 0 && args[0].length() == 5) { |
Mike Fiore |
9:ff62b20f7000 | 619 | _dot->setFlowControl(true); |
Mike Fiore |
9:ff62b20f7000 | 620 | write(done); |
Mike Fiore |
1:e52ae6584f1c | 621 | } else if (args[0] == "AT+SD") { |
Mike Fiore |
9:ff62b20f7000 | 622 | if (_dot->getNetworkJoinStatus()) { |
Mike Fiore |
9:ff62b20f7000 | 623 | logDebug("Enter Serial Mode"); |
Mike Fiore |
9:ff62b20f7000 | 624 | write(connect); |
Mike Fiore |
9:ff62b20f7000 | 625 | serial_data_mode = true; |
Mike Fiore |
9:ff62b20f7000 | 626 | _mode = mDot::SERIAL_MODE; |
Mike Fiore |
9:ff62b20f7000 | 627 | } else { |
Mike Fiore |
9:ff62b20f7000 | 628 | logDebug("Network Not Joined"); |
Mike Fiore |
9:ff62b20f7000 | 629 | write("Network Not Joined\r\n"); |
Mike Fiore |
9:ff62b20f7000 | 630 | write(error); |
Mike Fiore |
9:ff62b20f7000 | 631 | } |
Mike Fiore |
4:666017851052 | 632 | } else if (args[0] == "AT+SLEEP") { |
Mike Fiore |
9:ff62b20f7000 | 633 | if (args.size() > 2 && (args[1] != "?")) { |
Mike Fiore |
4:666017851052 | 634 | write("Invalid argument\r\n"); |
Mike Fiore |
4:666017851052 | 635 | write(error); |
Mike Fiore |
4:666017851052 | 636 | } else { |
Mike Fiore |
4:666017851052 | 637 | if (args.size() > 1 && args[1] == "?") { |
Mike Fiore |
9:ff62b20f7000 | 638 | write("(0:deepsleep,1:sleep)\r\n"); |
Mike Fiore |
4:666017851052 | 639 | write(done); |
Mike Fiore |
4:666017851052 | 640 | } else { |
Mike Fiore |
4:666017851052 | 641 | _sleep_standby = !(args.size() > 1 && args[1] == "1"); |
Mike Fiore |
9:ff62b20f7000 | 642 | write(done); |
Mike Fiore |
4:666017851052 | 643 | this->sleep(_sleep_standby); |
Mike Fiore |
4:666017851052 | 644 | wait(0.1); |
Mike Fiore |
4:666017851052 | 645 | } |
Mike Fiore |
4:666017851052 | 646 | } |
Mike Fiore |
1:e52ae6584f1c | 647 | } else { |
Mike Fiore |
1:e52ae6584f1c | 648 | bool found = false; |
Mike Fiore |
1:e52ae6584f1c | 649 | bool query = false; |
Mike Fiore |
1:e52ae6584f1c | 650 | |
Mike Fiore |
1:e52ae6584f1c | 651 | std::string lookfor = args[0]; |
Mike Fiore |
1:e52ae6584f1c | 652 | |
Mike Fiore |
1:e52ae6584f1c | 653 | // per command help |
Mike Fiore |
1:e52ae6584f1c | 654 | if ((args[0].find("?") == 0 || args[0].find("HELP") == 0)) |
Mike Fiore |
1:e52ae6584f1c | 655 | lookfor = mts::Text::toUpper(args[1]); |
Mike Fiore |
1:e52ae6584f1c | 656 | |
Mike Fiore |
1:e52ae6584f1c | 657 | // trim off any trailing '?' and mark as a query command |
Mike Fiore |
1:e52ae6584f1c | 658 | if (args[0].rfind("?") == args[0].length() - 1) { |
Mike Fiore |
1:e52ae6584f1c | 659 | query = true; |
Mike Fiore |
1:e52ae6584f1c | 660 | lookfor = args[0].substr(0, args[0].length() - 1); |
Mike Fiore |
1:e52ae6584f1c | 661 | } |
Mike Fiore |
1:e52ae6584f1c | 662 | |
Mike Fiore |
1:e52ae6584f1c | 663 | // search for command |
Mike Fiore |
1:e52ae6584f1c | 664 | for (std::vector<Command*>::iterator it = _commands.begin(); it != _commands.end() && !found; ++it) { |
Mike Fiore |
1:e52ae6584f1c | 665 | Command* cmd = *it; |
Mike Fiore |
1:e52ae6584f1c | 666 | |
Mike Fiore |
1:e52ae6584f1c | 667 | // match CMD or CMD? syntax if command is queryable |
Mike Fiore |
1:e52ae6584f1c | 668 | if (lookfor == cmd->text() && (!query || (query && cmd->queryable()))) { |
Mike Fiore |
1:e52ae6584f1c | 669 | found = true; |
Mike Fiore |
1:e52ae6584f1c | 670 | if (args[0] == "HELP") { |
Mike Fiore |
1:e52ae6584f1c | 671 | writef("%s%s", cmd->help(), newline); |
Mike Fiore |
1:e52ae6584f1c | 672 | write(done); |
Mike Fiore |
1:e52ae6584f1c | 673 | } |
Mike Fiore |
1:e52ae6584f1c | 674 | |
Mike Fiore |
1:e52ae6584f1c | 675 | else if (args.size() > 1 && args[1] == "?") { |
Mike Fiore |
1:e52ae6584f1c | 676 | writef("%s%s", cmd->usage().c_str(), newline); |
Mike Fiore |
1:e52ae6584f1c | 677 | write(done); |
Mike Fiore |
1:e52ae6584f1c | 678 | } else if (!cmd->verify(args)) { |
Mike Fiore |
1:e52ae6584f1c | 679 | writef("%s%s", cmd->errorMessage().c_str(), newline); |
Mike Fiore |
1:e52ae6584f1c | 680 | writef("%s", error); |
Mike Fiore |
1:e52ae6584f1c | 681 | } else { |
Mike Fiore |
1:e52ae6584f1c | 682 | if (cmd->action(args) == 0) { |
Mike Fiore |
1:e52ae6584f1c | 683 | writef("%s", done); |
Mike Fiore |
1:e52ae6584f1c | 684 | } else { |
Mike Fiore |
1:e52ae6584f1c | 685 | writef("%s%s", cmd->errorMessage().c_str(), newline); |
Mike Fiore |
1:e52ae6584f1c | 686 | writef("%s", error); |
Mike Fiore |
1:e52ae6584f1c | 687 | } |
Mike Fiore |
1:e52ae6584f1c | 688 | } |
Mike Fiore |
1:e52ae6584f1c | 689 | } |
Mike Fiore |
1:e52ae6584f1c | 690 | } |
Mike Fiore |
1:e52ae6584f1c | 691 | |
Mike Fiore |
1:e52ae6584f1c | 692 | if (!found) { |
Mike Fiore |
1:e52ae6584f1c | 693 | writef("%s", command_error); |
Mike Fiore |
1:e52ae6584f1c | 694 | writef("%s", error); |
Mike Fiore |
1:e52ae6584f1c | 695 | } |
Mike Fiore |
1:e52ae6584f1c | 696 | } |
Mike Fiore |
1:e52ae6584f1c | 697 | |
Mike Fiore |
4:666017851052 | 698 | if (history.size() == 0 || history.front() != command) |
Mike Fiore |
4:666017851052 | 699 | history.push_front(command); |
Mike Fiore |
4:666017851052 | 700 | history_index = -1; |
Mike Fiore |
1:e52ae6584f1c | 701 | command.clear(); |
Mike Fiore |
1:e52ae6584f1c | 702 | |
Mike Fiore |
4:666017851052 | 703 | while (history.size() > 10) |
Mike Fiore |
4:666017851052 | 704 | history.pop_back(); |
Mike Fiore |
1:e52ae6584f1c | 705 | } |
Mike Fiore |
1:e52ae6584f1c | 706 | } |
Mike Fiore |
1:e52ae6584f1c | 707 | |
Mike Fiore |
1:e52ae6584f1c | 708 | std::string CommandTerminal::formatPacketData(const std::vector<uint8_t>& data, const uint8_t& format) { |
Mike Fiore |
2:e5eebd74d36d | 709 | if (format == mDot::HEXADECIMAL) |
Mike Fiore |
1:e52ae6584f1c | 710 | return mts::Text::bin2hexString(data); |
Mike Fiore |
2:e5eebd74d36d | 711 | else |
Mike Fiore |
2:e5eebd74d36d | 712 | return std::string(data.begin(), data.end()); |
Mike Fiore |
1:e52ae6584f1c | 713 | } |
Mike Fiore |
1:e52ae6584f1c | 714 | |
Mike Fiore |
1:e52ae6584f1c | 715 | void CommandTerminal::sleep(bool standby) { |
Mike Fiore |
1:e52ae6584f1c | 716 | _xbee_on_sleep = GPIO_PIN_RESET; |
Mike Fiore |
1:e52ae6584f1c | 717 | |
Mike Fiore |
4:666017851052 | 718 | _serial.rxClear(); |
Mike Fiore |
4:666017851052 | 719 | _serial.txClear(); |
Mike Fiore |
1:e52ae6584f1c | 720 | |
Mike Fiore |
4:666017851052 | 721 | _dot->sleep(_dot->getWakeInterval(), _dot->getWakeMode(), standby); |
Mike Fiore |
1:e52ae6584f1c | 722 | } |
Mike Fiore |
1:e52ae6584f1c | 723 | |
Mike Fiore |
1:e52ae6584f1c | 724 | bool CommandTerminal::waitForEscape(int timeout, mDot* dot, WaitType wait) { |
Mike Fiore |
1:e52ae6584f1c | 725 | Timer timer; |
Mike Fiore |
1:e52ae6584f1c | 726 | |
Mike Fiore |
1:e52ae6584f1c | 727 | timer.start(); |
Mike Fiore |
1:e52ae6584f1c | 728 | while (timer.read_ms() < timeout) { |
Mike Fiore |
1:e52ae6584f1c | 729 | |
Mike Fiore |
1:e52ae6584f1c | 730 | if (dot != NULL) { |
Mike Fiore |
1:e52ae6584f1c | 731 | if (wait == WAIT_SEND && (!dot->getIsTransmitting())) { |
Mike Fiore |
1:e52ae6584f1c | 732 | return false; |
Mike Fiore |
1:e52ae6584f1c | 733 | } |
Mike Fiore |
1:e52ae6584f1c | 734 | } |
Mike Fiore |
1:e52ae6584f1c | 735 | |
Mike Fiore |
9:ff62b20f7000 | 736 | if (_serialp != NULL && _serialp->escaped()) { |
Mike Fiore |
9:ff62b20f7000 | 737 | _serialp->clearEscaped(); |
Mike Fiore |
9:ff62b20f7000 | 738 | return true; |
Mike Fiore |
1:e52ae6584f1c | 739 | } |
Mike Fiore |
1:e52ae6584f1c | 740 | |
Mike Fiore |
1:e52ae6584f1c | 741 | osDelay(10); |
Mike Fiore |
1:e52ae6584f1c | 742 | } |
Mike Fiore |
1:e52ae6584f1c | 743 | |
Mike Fiore |
1:e52ae6584f1c | 744 | return false; |
Mike Fiore |
1:e52ae6584f1c | 745 | } |
Mike Fiore |
1:e52ae6584f1c | 746 | |
Mike Fiore |
9:ff62b20f7000 | 747 | void CommandTerminal::wakeup(void) { |
Mike Fiore |
9:ff62b20f7000 | 748 | if (_dot->getWakePin() == XBEE_DIN) { |
Mike Fiore |
9:ff62b20f7000 | 749 | _serial.reattach(XBEE_DOUT, XBEE_DIN); |
Mike Fiore |
9:ff62b20f7000 | 750 | logInfo("Wakeup pin was serial input"); |
Mike Fiore |
9:ff62b20f7000 | 751 | } |
Mike Fiore |
9:ff62b20f7000 | 752 | } |
Mike Fiore |
9:ff62b20f7000 | 753 | |
Mike Fiore |
9:ff62b20f7000 | 754 | void CommandTerminal::RadioEvent::MacEvent(LoRaMacEventFlags* flags, LoRaMacEventInfo* info) { |
Mike Fiore |
1:e52ae6584f1c | 755 | |
Mike Fiore |
9:ff62b20f7000 | 756 | if (mts::MTSLog::getLogLevel() == mts::MTSLog::TRACE_LEVEL) { |
Mike Fiore |
9:ff62b20f7000 | 757 | std::string msg = "OK"; |
Mike Fiore |
9:ff62b20f7000 | 758 | switch (info->Status) { |
Mike Fiore |
9:ff62b20f7000 | 759 | case LORAMAC_EVENT_INFO_STATUS_ERROR: |
Mike Fiore |
9:ff62b20f7000 | 760 | msg = "ERROR"; |
Mike Fiore |
9:ff62b20f7000 | 761 | break; |
Mike Fiore |
9:ff62b20f7000 | 762 | case LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT: |
Mike Fiore |
9:ff62b20f7000 | 763 | msg = "TX_TIMEOUT"; |
Mike Fiore |
9:ff62b20f7000 | 764 | break; |
Mike Fiore |
9:ff62b20f7000 | 765 | case LORAMAC_EVENT_INFO_STATUS_RX_TIMEOUT: |
Mike Fiore |
9:ff62b20f7000 | 766 | msg = "RX_TIMEOUT"; |
Mike Fiore |
9:ff62b20f7000 | 767 | break; |
Mike Fiore |
9:ff62b20f7000 | 768 | case LORAMAC_EVENT_INFO_STATUS_RX_ERROR: |
Mike Fiore |
9:ff62b20f7000 | 769 | msg = "RX_ERROR"; |
Mike Fiore |
9:ff62b20f7000 | 770 | break; |
Mike Fiore |
9:ff62b20f7000 | 771 | case LORAMAC_EVENT_INFO_STATUS_JOIN_FAIL: |
Mike Fiore |
9:ff62b20f7000 | 772 | msg = "JOIN_FAIL"; |
Mike Fiore |
9:ff62b20f7000 | 773 | break; |
Mike Fiore |
9:ff62b20f7000 | 774 | case LORAMAC_EVENT_INFO_STATUS_DOWNLINK_FAIL: |
Mike Fiore |
9:ff62b20f7000 | 775 | msg = "DOWNLINK_FAIL"; |
Mike Fiore |
9:ff62b20f7000 | 776 | break; |
Mike Fiore |
9:ff62b20f7000 | 777 | case LORAMAC_EVENT_INFO_STATUS_ADDRESS_FAIL: |
Mike Fiore |
9:ff62b20f7000 | 778 | msg = "ADDRESS_FAIL"; |
Mike Fiore |
9:ff62b20f7000 | 779 | break; |
Mike Fiore |
9:ff62b20f7000 | 780 | case LORAMAC_EVENT_INFO_STATUS_MIC_FAIL: |
Mike Fiore |
9:ff62b20f7000 | 781 | msg = "MIC_FAIL"; |
Mike Fiore |
9:ff62b20f7000 | 782 | break; |
Mike Fiore |
9:ff62b20f7000 | 783 | default: |
Mike Fiore |
9:ff62b20f7000 | 784 | break; |
Mike Fiore |
9:ff62b20f7000 | 785 | } |
Mike Fiore |
9:ff62b20f7000 | 786 | logTrace("Event: %s", msg.c_str()); |
Mike Fiore |
9:ff62b20f7000 | 787 | |
Mike Fiore |
9:ff62b20f7000 | 788 | logTrace("Flags Tx: %d Rx: %d RxData: %d RxSlot: %d LinkCheck: %d JoinAccept: %d", |
Mike Fiore |
9:ff62b20f7000 | 789 | flags->Bits.Tx, flags->Bits.Rx, flags->Bits.RxData, flags->Bits.RxSlot, flags->Bits.LinkCheck, flags->Bits.JoinAccept); |
Mike Fiore |
9:ff62b20f7000 | 790 | logTrace("Info: Status: %d ACK: %d Retries: %d TxDR: %d RxPort: %d RxSize: %d RSSI: %d SNR: %d Energy: %d Margin: %d Gateways: %d", |
Mike Fiore |
9:ff62b20f7000 | 791 | info->Status, info->TxAckReceived, info->TxNbRetries, info->TxDatarate, info->RxPort, info->RxBufferSize, |
Mike Fiore |
9:ff62b20f7000 | 792 | info->RxRssi, info->RxSnr, info->Energy, info->DemodMargin, info->NbGateways); |
Mike Fiore |
9:ff62b20f7000 | 793 | } |
Mike Fiore |
9:ff62b20f7000 | 794 | |
Mike Fiore |
9:ff62b20f7000 | 795 | if (flags->Bits.Rx) { |
Mike Fiore |
9:ff62b20f7000 | 796 | if (serial_data_mode) { |
Mike Fiore |
9:ff62b20f7000 | 797 | logDebug("Rx %d bytes", info->RxBufferSize); |
Mike Fiore |
9:ff62b20f7000 | 798 | if (info->RxBufferSize > 0) { |
Mike Fiore |
9:ff62b20f7000 | 799 | _serial.write((char*) info->RxBuffer, info->RxBufferSize); |
Mike Fiore |
9:ff62b20f7000 | 800 | } |
Mike Fiore |
9:ff62b20f7000 | 801 | } |
Mike Fiore |
9:ff62b20f7000 | 802 | } |
Mike Fiore |
1:e52ae6584f1c | 803 | } |
Mike Fiore |
9:ff62b20f7000 | 804 | |
Mike Fiore |
9:ff62b20f7000 | 805 | CommandTerminal::~CommandTerminal() { |
Mike Fiore |
9:ff62b20f7000 | 806 | delete _events; |
Mike Fiore |
9:ff62b20f7000 | 807 | } |