mDot AT-Firmware for testing
Dependencies: MTS-Serial libmDot-mbed5
Fork of Dot-AT-Firmware by
CommandTerminal/CommandTerminal.cpp@4:666017851052, 2015-08-18 (annotated)
- Committer:
- Mike Fiore
- Date:
- Tue Aug 18 11:21:43 2015 -0500
- Revision:
- 4:666017851052
- Parent:
- 2:e5eebd74d36d
- Child:
- 6:e27eaad36a0c
update mdot-firmware to 0.1.2
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 |
1:e52ae6584f1c | 6 | |
Mike Fiore |
4:666017851052 | 7 | #include <deque> |
Mike Fiore |
1:e52ae6584f1c | 8 | |
Mike Fiore |
1:e52ae6584f1c | 9 | const char CommandTerminal::banner[] = "\r\n\nMultiTech Systems LoRa XBee Module\r\n\n"; |
Mike Fiore |
1:e52ae6584f1c | 10 | const char CommandTerminal::helpline[] = "Enter '?' for help\r\n"; |
Mike Fiore |
1:e52ae6584f1c | 11 | |
Mike Fiore |
1:e52ae6584f1c | 12 | const char CommandTerminal::newline[] = "\r\n"; |
Mike Fiore |
1:e52ae6584f1c | 13 | |
Mike Fiore |
1:e52ae6584f1c | 14 | // Command error text... |
Mike Fiore |
1:e52ae6584f1c | 15 | const char CommandTerminal::command_error[] = "Command not found!\r\n"; |
Mike Fiore |
1:e52ae6584f1c | 16 | |
Mike Fiore |
1:e52ae6584f1c | 17 | // Response texts... |
Mike Fiore |
1:e52ae6584f1c | 18 | const char CommandTerminal::help[] = "\r\nHelp\r\n"; |
Mike Fiore |
1:e52ae6584f1c | 19 | const char CommandTerminal::cmd_error[] = "Invalid command\r\n"; |
Mike Fiore |
1:e52ae6584f1c | 20 | const char CommandTerminal::done[] = "\r\nOK\r\n"; |
Mike Fiore |
1:e52ae6584f1c | 21 | const char CommandTerminal::error[] = "\r\nERROR\r\n"; |
Mike Fiore |
1:e52ae6584f1c | 22 | |
Mike Fiore |
1:e52ae6584f1c | 23 | // Escape sequence... |
Mike Fiore |
1:e52ae6584f1c | 24 | const char CommandTerminal::escape_sequence[] = "+++"; |
Mike Fiore |
1:e52ae6584f1c | 25 | |
Mike Fiore |
1:e52ae6584f1c | 26 | mts::MTSSerial* CommandTerminal::_serialp = NULL; |
Mike Fiore |
1:e52ae6584f1c | 27 | |
Mike Fiore |
1:e52ae6584f1c | 28 | void CommandTerminal::addCommand(Command* cmd) { |
Mike Fiore |
1:e52ae6584f1c | 29 | _commands.push_back(cmd); |
Mike Fiore |
1:e52ae6584f1c | 30 | } |
Mike Fiore |
1:e52ae6584f1c | 31 | |
Mike Fiore |
1:e52ae6584f1c | 32 | CommandTerminal::CommandTerminal(mts::MTSSerial& serial, mDot* dot) |
Mike Fiore |
1:e52ae6584f1c | 33 | : |
Mike Fiore |
1:e52ae6584f1c | 34 | _serial(serial), |
Mike Fiore |
1:e52ae6584f1c | 35 | _dot(dot), |
Mike Fiore |
1:e52ae6584f1c | 36 | _mode(mDot::COMMAND_MODE), |
Mike Fiore |
4:666017851052 | 37 | _idle_thread(idle, NULL, osPriorityLow), |
Mike Fiore |
4:666017851052 | 38 | _sleep_standby(true), |
Mike Fiore |
1:e52ae6584f1c | 39 | _xbee_on_sleep(XBEE_ON_SLEEP), |
Mike Fiore |
1:e52ae6584f1c | 40 | _serial_up(false) { |
Mike Fiore |
1:e52ae6584f1c | 41 | |
Mike Fiore |
1:e52ae6584f1c | 42 | _serialp = &serial; |
Mike Fiore |
1:e52ae6584f1c | 43 | |
Mike Fiore |
1:e52ae6584f1c | 44 | addCommand(new CmdAttention(_dot)); |
Mike Fiore |
1:e52ae6584f1c | 45 | addCommand(new CmdIdentification(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 46 | addCommand(new CmdResetCpu(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 47 | addCommand(new CmdDummy(_dot, "Enable/Disable Echo", "ATE0/1", "ATE0: disable, ATE1: enable")); |
Mike Fiore |
1:e52ae6584f1c | 48 | addCommand(new CmdDummy(_dot, "Enable/Disable Verbose", "ATV0/1", "ATV0: disable, ATV1: enable")); |
Mike Fiore |
1:e52ae6584f1c | 49 | |
Mike Fiore |
1:e52ae6584f1c | 50 | addCommand(new CmdFactoryDefault(_dot)); |
Mike Fiore |
1:e52ae6584f1c | 51 | addCommand(new CmdSaveConfig(_dot)); |
Mike Fiore |
1:e52ae6584f1c | 52 | addCommand(new CmdDisplayConfig(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 53 | addCommand(new CmdDisplayStats(_dot, serial)); |
Mike Fiore |
4:666017851052 | 54 | addCommand(new CmdResetStats(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 55 | addCommand(new CmdSerialBaudRate(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 56 | addCommand(new CmdDebugBaudRate(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 57 | addCommand(new CmdStartUpMode(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 58 | |
Mike Fiore |
1:e52ae6584f1c | 59 | addCommand(new CmdFrequencyBand(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 60 | addCommand(new CmdFrequencySubBand(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 61 | addCommand(new CmdPublicNetwork(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 62 | addCommand(new CmdDeviceId(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 63 | |
Mike Fiore |
1:e52ae6584f1c | 64 | addCommand(new CmdNetworkAddress(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 65 | addCommand(new CmdNetworkSessionKey(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 66 | addCommand(new CmdDataSessionKey(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 67 | addCommand(new CmdNetworkKey(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 68 | addCommand(new CmdNetworkId(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 69 | |
Mike Fiore |
1:e52ae6584f1c | 70 | addCommand(new CmdJoinRequest(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 71 | addCommand(new CmdJoinRetries(_dot, serial)); |
Mike Fiore |
4:666017851052 | 72 | addCommand(new CmdJoinByteOrder(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 73 | addCommand(new CmdNetworkJoinMode(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 74 | addCommand(new CmdNetworkJoinStatus(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 75 | addCommand(new CmdNetworkLinkCheck(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 76 | addCommand(new CmdLinkCheckCount(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 77 | addCommand(new CmdLinkCheckThreshold(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 78 | addCommand(new CmdEncryption(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 79 | |
Mike Fiore |
1:e52ae6584f1c | 80 | addCommand(new CmdRssi(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 81 | addCommand(new CmdSnr(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 82 | addCommand(new CmdDataPending(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 83 | |
Mike Fiore |
1:e52ae6584f1c | 84 | addCommand(new CmdTxDataRate(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 85 | addCommand(new CmdTxPower(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 86 | addCommand(new CmdTxFrequency(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 87 | addCommand(new CmdTxInverted(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 88 | addCommand(new CmdTxWait(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 89 | addCommand(new CmdTxChannel(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 90 | addCommand(new CmdTxNextMs(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 91 | addCommand(new CmdTimeOnAir(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 92 | |
Mike Fiore |
1:e52ae6584f1c | 93 | addCommand(new CmdRxDataRate(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 94 | addCommand(new CmdRxFrequency(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 95 | addCommand(new CmdRxOutput(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 96 | addCommand(new CmdRxInverted(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 97 | |
Mike Fiore |
1:e52ae6584f1c | 98 | addCommand(new CmdErrorCorrection(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 99 | addCommand(new CmdCRC(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 100 | addCommand(new CmdAdaptiveDataRate(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 101 | |
Mike Fiore |
1:e52ae6584f1c | 102 | addCommand(new CmdACKAttempts(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 103 | |
Mike Fiore |
1:e52ae6584f1c | 104 | addCommand(new CmdSendString(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 105 | addCommand(new CmdSendStringHighBW(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 106 | addCommand(new CmdSendBinary(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 107 | addCommand(new CmdSendStringOnInterval(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 108 | addCommand(new CmdReceiveOnce(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 109 | addCommand(new CmdReceiveContinuous(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 110 | |
Mike Fiore |
4:666017851052 | 111 | addCommand(new CmdDummy(_dot, "Serial Data Mode", "AT+SD", "Reads serial data, sends packet, then sleeps using wake settings")); |
Mike Fiore |
4:666017851052 | 112 | addCommand(new CmdDummy(_dot, "Sleep Mode", "AT+SLEEP", "Enter sleep mode")); |
Mike Fiore |
4:666017851052 | 113 | addCommand(new CmdWakeMode(_dot, serial)); |
Mike Fiore |
4:666017851052 | 114 | addCommand(new CmdWakeInterval(_dot, serial)); |
Mike Fiore |
4:666017851052 | 115 | // addCommand(new CmdWakePin(_dot, serial)); |
Mike Fiore |
4:666017851052 | 116 | addCommand(new CmdWakeDelay(_dot, serial)); |
Mike Fiore |
4:666017851052 | 117 | addCommand(new CmdWakeTimeout(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 118 | addCommand(new CmdPing(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 119 | addCommand(new CmdLogLevel(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 120 | } |
Mike Fiore |
1:e52ae6584f1c | 121 | |
Mike Fiore |
1:e52ae6584f1c | 122 | void CommandTerminal::printHelp() { |
Mike Fiore |
1:e52ae6584f1c | 123 | const char* name = NULL; |
Mike Fiore |
1:e52ae6584f1c | 124 | const char* text = NULL; |
Mike Fiore |
1:e52ae6584f1c | 125 | const char* desc = NULL; |
Mike Fiore |
1:e52ae6584f1c | 126 | const char* tab = "\t"; |
Mike Fiore |
1:e52ae6584f1c | 127 | |
Mike Fiore |
1:e52ae6584f1c | 128 | std::string header("Command"); |
Mike Fiore |
1:e52ae6584f1c | 129 | header.append(tab); |
Mike Fiore |
1:e52ae6584f1c | 130 | header.append(tab); |
Mike Fiore |
1:e52ae6584f1c | 131 | header.append("Name"); |
Mike Fiore |
1:e52ae6584f1c | 132 | header.append(tab); |
Mike Fiore |
1:e52ae6584f1c | 133 | header.append(tab); |
Mike Fiore |
1:e52ae6584f1c | 134 | header.append(tab); |
Mike Fiore |
1:e52ae6584f1c | 135 | header.append("Description"); |
Mike Fiore |
1:e52ae6584f1c | 136 | |
Mike Fiore |
1:e52ae6584f1c | 137 | write(newline); |
Mike Fiore |
1:e52ae6584f1c | 138 | write(header.c_str()); |
Mike Fiore |
1:e52ae6584f1c | 139 | write(newline); |
Mike Fiore |
1:e52ae6584f1c | 140 | write(newline); |
Mike Fiore |
1:e52ae6584f1c | 141 | for (std::vector<Command*>::iterator it = _commands.begin(); it != _commands.end(); ++it) { |
Mike Fiore |
1:e52ae6584f1c | 142 | name = (*it)->name(); |
Mike Fiore |
1:e52ae6584f1c | 143 | text = (*it)->text(); |
Mike Fiore |
1:e52ae6584f1c | 144 | desc = (*it)->desc(); |
Mike Fiore |
1:e52ae6584f1c | 145 | write(text); |
Mike Fiore |
1:e52ae6584f1c | 146 | if (strlen(text) < 8) |
Mike Fiore |
1:e52ae6584f1c | 147 | write(tab); |
Mike Fiore |
1:e52ae6584f1c | 148 | write(tab); |
Mike Fiore |
1:e52ae6584f1c | 149 | write(name); |
Mike Fiore |
1:e52ae6584f1c | 150 | if (strlen(name) < 8) |
Mike Fiore |
1:e52ae6584f1c | 151 | write(tab); |
Mike Fiore |
1:e52ae6584f1c | 152 | if (strlen(name) < 16) |
Mike Fiore |
1:e52ae6584f1c | 153 | write(tab); |
Mike Fiore |
1:e52ae6584f1c | 154 | write(tab); |
Mike Fiore |
1:e52ae6584f1c | 155 | write(desc); |
Mike Fiore |
1:e52ae6584f1c | 156 | write(newline); |
Mike Fiore |
1:e52ae6584f1c | 157 | } |
Mike Fiore |
1:e52ae6584f1c | 158 | |
Mike Fiore |
1:e52ae6584f1c | 159 | write(newline); |
Mike Fiore |
1:e52ae6584f1c | 160 | } |
Mike Fiore |
1:e52ae6584f1c | 161 | |
Mike Fiore |
1:e52ae6584f1c | 162 | bool CommandTerminal::writeable() { |
Mike Fiore |
1:e52ae6584f1c | 163 | return _serial.writeable(); |
Mike Fiore |
1:e52ae6584f1c | 164 | } |
Mike Fiore |
1:e52ae6584f1c | 165 | |
Mike Fiore |
1:e52ae6584f1c | 166 | bool CommandTerminal::readable() { |
Mike Fiore |
1:e52ae6584f1c | 167 | return _serial.readable(); |
Mike Fiore |
1:e52ae6584f1c | 168 | } |
Mike Fiore |
1:e52ae6584f1c | 169 | |
Mike Fiore |
1:e52ae6584f1c | 170 | char CommandTerminal::read() { |
Mike Fiore |
1:e52ae6584f1c | 171 | char ch; |
Mike Fiore |
1:e52ae6584f1c | 172 | _serial.read(&ch, 1); |
Mike Fiore |
1:e52ae6584f1c | 173 | return ch; |
Mike Fiore |
1:e52ae6584f1c | 174 | } |
Mike Fiore |
1:e52ae6584f1c | 175 | |
Mike Fiore |
1:e52ae6584f1c | 176 | void CommandTerminal::write(const char* message) { |
Mike Fiore |
1:e52ae6584f1c | 177 | while (!writeable()) |
Mike Fiore |
1:e52ae6584f1c | 178 | ; |
Mike Fiore |
1:e52ae6584f1c | 179 | _serial.write(message, strlen(message)); |
Mike Fiore |
1:e52ae6584f1c | 180 | } |
Mike Fiore |
1:e52ae6584f1c | 181 | |
Mike Fiore |
1:e52ae6584f1c | 182 | void CommandTerminal::writef(const char* format, ...) { |
Mike Fiore |
1:e52ae6584f1c | 183 | char buff[256]; |
Mike Fiore |
1:e52ae6584f1c | 184 | |
Mike Fiore |
1:e52ae6584f1c | 185 | va_list ap; |
Mike Fiore |
1:e52ae6584f1c | 186 | va_start(ap, format); |
Mike Fiore |
1:e52ae6584f1c | 187 | int size = vsnprintf(buff, 256, format, ap); |
Mike Fiore |
1:e52ae6584f1c | 188 | while (!writeable()) |
Mike Fiore |
1:e52ae6584f1c | 189 | ; |
Mike Fiore |
1:e52ae6584f1c | 190 | _serial.write(buff, size); |
Mike Fiore |
1:e52ae6584f1c | 191 | va_end(ap); |
Mike Fiore |
1:e52ae6584f1c | 192 | } |
Mike Fiore |
1:e52ae6584f1c | 193 | |
Mike Fiore |
1:e52ae6584f1c | 194 | void CommandTerminal::serial_loop() { |
Mike Fiore |
1:e52ae6584f1c | 195 | Timer serial_read_timer; |
Mike Fiore |
1:e52ae6584f1c | 196 | std::vector<uint8_t> serial_buffer; |
Mike Fiore |
1:e52ae6584f1c | 197 | std::string escape_buffer; |
Mike Fiore |
1:e52ae6584f1c | 198 | Timer escape_timer; |
Mike Fiore |
1:e52ae6584f1c | 199 | int escape_delay = 100; |
Mike Fiore |
1:e52ae6584f1c | 200 | uint8_t max_send_size; |
Mike Fiore |
1:e52ae6584f1c | 201 | |
Mike Fiore |
1:e52ae6584f1c | 202 | _serial_up = true; |
Mike Fiore |
1:e52ae6584f1c | 203 | _xbee_on_sleep = GPIO_PIN_SET; |
Mike Fiore |
1:e52ae6584f1c | 204 | |
Mike Fiore |
1:e52ae6584f1c | 205 | if (_dot->getFrequencyBand() == mDot::FB_915) |
Mike Fiore |
1:e52ae6584f1c | 206 | max_send_size = mDot::MaxLengths_915[_dot->getTxDataRate()]; |
Mike Fiore |
1:e52ae6584f1c | 207 | else |
Mike Fiore |
1:e52ae6584f1c | 208 | max_send_size = mDot::MaxLengths_868[_dot->getTxDataRate()]; |
Mike Fiore |
1:e52ae6584f1c | 209 | |
Mike Fiore |
1:e52ae6584f1c | 210 | DEBUG_PRINTF("Awake\r\n"); |
Mike Fiore |
1:e52ae6584f1c | 211 | wakeup(_sleep_standby); |
Mike Fiore |
1:e52ae6584f1c | 212 | |
Mike Fiore |
1:e52ae6584f1c | 213 | char ch; |
Mike Fiore |
1:e52ae6584f1c | 214 | |
Mike Fiore |
1:e52ae6584f1c | 215 | if (readable()) { |
Mike Fiore |
1:e52ae6584f1c | 216 | ch = read(); |
Mike Fiore |
1:e52ae6584f1c | 217 | serial_buffer.push_back(ch); |
Mike Fiore |
1:e52ae6584f1c | 218 | |
Mike Fiore |
1:e52ae6584f1c | 219 | if (escape_timer.read_ms() > escape_delay && ch == '+') { |
Mike Fiore |
1:e52ae6584f1c | 220 | escape_buffer += ch; |
Mike Fiore |
1:e52ae6584f1c | 221 | escape_timer.reset(); |
Mike Fiore |
1:e52ae6584f1c | 222 | } else { |
Mike Fiore |
1:e52ae6584f1c | 223 | _serial_up = true; |
Mike Fiore |
1:e52ae6584f1c | 224 | escape_buffer.clear(); |
Mike Fiore |
1:e52ae6584f1c | 225 | } |
Mike Fiore |
1:e52ae6584f1c | 226 | |
Mike Fiore |
1:e52ae6584f1c | 227 | if (escape_buffer.length() == 3 && escape_buffer.find(escape_sequence) == 0) { |
Mike Fiore |
1:e52ae6584f1c | 228 | _mode = mDot::COMMAND_MODE; |
Mike Fiore |
1:e52ae6584f1c | 229 | DEBUG_PRINTF("Exit serial mode\r\n"); |
Mike Fiore |
1:e52ae6584f1c | 230 | escape_timer.stop(); |
Mike Fiore |
1:e52ae6584f1c | 231 | escape_buffer.clear(); |
Mike Fiore |
1:e52ae6584f1c | 232 | write(done); |
Mike Fiore |
1:e52ae6584f1c | 233 | return; |
Mike Fiore |
1:e52ae6584f1c | 234 | } |
Mike Fiore |
1:e52ae6584f1c | 235 | } |
Mike Fiore |
1:e52ae6584f1c | 236 | |
Mike Fiore |
1:e52ae6584f1c | 237 | if (_serial_up) { |
Mike Fiore |
4:666017851052 | 238 | osDelay(_dot->getWakeDelay()); |
Mike Fiore |
1:e52ae6584f1c | 239 | |
Mike Fiore |
1:e52ae6584f1c | 240 | serial_read_timer.start(); |
Mike Fiore |
4:666017851052 | 241 | uint16_t timeout = _dot->getWakeTimeout(); |
Mike Fiore |
4:666017851052 | 242 | while (_serial_up && serial_read_timer.read_ms() < timeout) { |
Mike Fiore |
1:e52ae6584f1c | 243 | while (readable() && serial_buffer.size() < max_send_size) { |
Mike Fiore |
1:e52ae6584f1c | 244 | serial_buffer.push_back(read()); |
Mike Fiore |
1:e52ae6584f1c | 245 | serial_read_timer.reset(); |
Mike Fiore |
1:e52ae6584f1c | 246 | } |
Mike Fiore |
1:e52ae6584f1c | 247 | } |
Mike Fiore |
1:e52ae6584f1c | 248 | serial_read_timer.stop(), serial_read_timer.reset(); |
Mike Fiore |
1:e52ae6584f1c | 249 | |
Mike Fiore |
1:e52ae6584f1c | 250 | if (!serial_buffer.empty()) { |
Mike Fiore |
1:e52ae6584f1c | 251 | _serial_up = false; |
Mike Fiore |
1:e52ae6584f1c | 252 | _xbee_on_sleep = GPIO_PIN_RESET; |
Mike Fiore |
1:e52ae6584f1c | 253 | if (!_dot->getIsTransmitting()) { |
Mike Fiore |
1:e52ae6584f1c | 254 | std::vector<uint8_t> recv_buffer; |
Mike Fiore |
1:e52ae6584f1c | 255 | DEBUG_PRINTF("Received serial data, sending out radio.\r\n"); |
Mike Fiore |
1:e52ae6584f1c | 256 | |
Mike Fiore |
4:666017851052 | 257 | if (_dot->send(serial_buffer) != mDot::MDOT_OK) |
Mike Fiore |
1:e52ae6584f1c | 258 | DEBUG_PRINTF("Send failed.\r\n"); |
Mike Fiore |
1:e52ae6584f1c | 259 | if (_dot->recv(recv_buffer)) |
Mike Fiore |
1:e52ae6584f1c | 260 | _serial.writef("%s\r\n", formatPacketData(recv_buffer, _dot->getRxOutput()).c_str()); |
Mike Fiore |
1:e52ae6584f1c | 261 | } else { |
Mike Fiore |
1:e52ae6584f1c | 262 | DEBUG_PRINTF("Radio is busy, cannot send.\r\n"); |
Mike Fiore |
1:e52ae6584f1c | 263 | } |
Mike Fiore |
1:e52ae6584f1c | 264 | |
Mike Fiore |
1:e52ae6584f1c | 265 | serial_buffer.clear(); |
Mike Fiore |
1:e52ae6584f1c | 266 | } else { |
Mike Fiore |
1:e52ae6584f1c | 267 | DEBUG_PRINTF("No data received from serial to send.\r\n"); |
Mike Fiore |
1:e52ae6584f1c | 268 | } |
Mike Fiore |
1:e52ae6584f1c | 269 | _serial_up = false; |
Mike Fiore |
1:e52ae6584f1c | 270 | } |
Mike Fiore |
1:e52ae6584f1c | 271 | sleep(_sleep_standby); |
Mike Fiore |
1:e52ae6584f1c | 272 | } |
Mike Fiore |
1:e52ae6584f1c | 273 | |
Mike Fiore |
1:e52ae6584f1c | 274 | bool CommandTerminal::autoJoinCheck() { |
Mike Fiore |
1:e52ae6584f1c | 275 | |
Mike Fiore |
1:e52ae6584f1c | 276 | std::string escape_buffer; |
Mike Fiore |
1:e52ae6584f1c | 277 | char ch; |
Mike Fiore |
1:e52ae6584f1c | 278 | int sleep = 1000; |
Mike Fiore |
1:e52ae6584f1c | 279 | int escape_timeout = 1000; |
Mike Fiore |
1:e52ae6584f1c | 280 | Timer tmr; |
Mike Fiore |
1:e52ae6584f1c | 281 | Timer escape_tmr; |
Mike Fiore |
1:e52ae6584f1c | 282 | int cnt = 0; |
Mike Fiore |
1:e52ae6584f1c | 283 | |
Mike Fiore |
1:e52ae6584f1c | 284 | while (!_dot->getNetworkJoinStatus()) { |
Mike Fiore |
1:e52ae6584f1c | 285 | wakeup(_sleep_standby); |
Mike Fiore |
1:e52ae6584f1c | 286 | write("\r\nJoining network... "); |
Mike Fiore |
1:e52ae6584f1c | 287 | |
Mike Fiore |
1:e52ae6584f1c | 288 | // wait one second for possible escape |
Mike Fiore |
1:e52ae6584f1c | 289 | tmr.reset(); |
Mike Fiore |
1:e52ae6584f1c | 290 | tmr.start(); |
Mike Fiore |
1:e52ae6584f1c | 291 | escape_tmr.reset(); |
Mike Fiore |
1:e52ae6584f1c | 292 | escape_tmr.start(); |
Mike Fiore |
1:e52ae6584f1c | 293 | while (tmr.read_ms() < 1000) { |
Mike Fiore |
1:e52ae6584f1c | 294 | if (_serial.readable()) { |
Mike Fiore |
1:e52ae6584f1c | 295 | _serial.read(&ch, 1); |
Mike Fiore |
1:e52ae6584f1c | 296 | escape_buffer += ch; |
Mike Fiore |
1:e52ae6584f1c | 297 | } |
Mike Fiore |
1:e52ae6584f1c | 298 | |
Mike Fiore |
1:e52ae6584f1c | 299 | if (escape_buffer.find(escape_sequence) != std::string::npos) { |
Mike Fiore |
1:e52ae6584f1c | 300 | _mode = mDot::COMMAND_MODE; |
Mike Fiore |
1:e52ae6584f1c | 301 | write("Join Canceled\r\n"); |
Mike Fiore |
1:e52ae6584f1c | 302 | write(done); |
Mike Fiore |
1:e52ae6584f1c | 303 | return true; |
Mike Fiore |
1:e52ae6584f1c | 304 | } |
Mike Fiore |
1:e52ae6584f1c | 305 | |
Mike Fiore |
1:e52ae6584f1c | 306 | if (escape_tmr.read_ms() > escape_timeout) |
Mike Fiore |
1:e52ae6584f1c | 307 | escape_buffer.clear(); |
Mike Fiore |
1:e52ae6584f1c | 308 | } |
Mike Fiore |
1:e52ae6584f1c | 309 | |
Mike Fiore |
1:e52ae6584f1c | 310 | if (_dot->joinNetworkOnce() == mDot::MDOT_OK) { |
Mike Fiore |
1:e52ae6584f1c | 311 | write("Network Joined\r\n"); |
Mike Fiore |
1:e52ae6584f1c | 312 | write(done); |
Mike Fiore |
1:e52ae6584f1c | 313 | return false; |
Mike Fiore |
1:e52ae6584f1c | 314 | } |
Mike Fiore |
1:e52ae6584f1c | 315 | |
Mike Fiore |
1:e52ae6584f1c | 316 | write("Network Join failed\r\n"); |
Mike Fiore |
1:e52ae6584f1c | 317 | write(error); |
Mike Fiore |
1:e52ae6584f1c | 318 | |
Mike Fiore |
1:e52ae6584f1c | 319 | if (cnt++ > _dot->getJoinRetries()) { |
Mike Fiore |
1:e52ae6584f1c | 320 | cnt = 0; |
Mike Fiore |
1:e52ae6584f1c | 321 | |
Mike Fiore |
1:e52ae6584f1c | 322 | if (_dot->getFrequencyBand() == mDot::FB_915) { |
Mike Fiore |
1:e52ae6584f1c | 323 | uint8_t band = ((_dot->getFrequencySubBand()) % 8) + 1; |
Mike Fiore |
1:e52ae6584f1c | 324 | DEBUG_PRINTF("Join retries exhausted, switching to sub band %u\r\n", band); |
Mike Fiore |
1:e52ae6584f1c | 325 | _dot->setFrequencySubBand(band); |
Mike Fiore |
1:e52ae6584f1c | 326 | } |
Mike Fiore |
1:e52ae6584f1c | 327 | |
Mike Fiore |
1:e52ae6584f1c | 328 | if (sleep < 60 * 60 * 1000) |
Mike Fiore |
1:e52ae6584f1c | 329 | sleep *= 2; |
Mike Fiore |
1:e52ae6584f1c | 330 | } |
Mike Fiore |
1:e52ae6584f1c | 331 | |
Mike Fiore |
1:e52ae6584f1c | 332 | tmr.reset(); |
Mike Fiore |
1:e52ae6584f1c | 333 | tmr.start(); |
Mike Fiore |
1:e52ae6584f1c | 334 | escape_tmr.reset(); |
Mike Fiore |
1:e52ae6584f1c | 335 | escape_tmr.start(); |
Mike Fiore |
1:e52ae6584f1c | 336 | while (tmr.read_ms() < sleep) { |
Mike Fiore |
1:e52ae6584f1c | 337 | if (_serial.readable()) { |
Mike Fiore |
1:e52ae6584f1c | 338 | _serial.read(&ch, 1); |
Mike Fiore |
1:e52ae6584f1c | 339 | escape_buffer += ch; |
Mike Fiore |
1:e52ae6584f1c | 340 | } |
Mike Fiore |
1:e52ae6584f1c | 341 | |
Mike Fiore |
1:e52ae6584f1c | 342 | if (escape_buffer.find(escape_sequence) != std::string::npos) { |
Mike Fiore |
1:e52ae6584f1c | 343 | _mode = mDot::COMMAND_MODE; |
Mike Fiore |
1:e52ae6584f1c | 344 | return true; |
Mike Fiore |
1:e52ae6584f1c | 345 | } |
Mike Fiore |
1:e52ae6584f1c | 346 | |
Mike Fiore |
1:e52ae6584f1c | 347 | if (escape_tmr.read_ms() > escape_timeout) |
Mike Fiore |
1:e52ae6584f1c | 348 | escape_buffer.clear(); |
Mike Fiore |
1:e52ae6584f1c | 349 | } |
Mike Fiore |
1:e52ae6584f1c | 350 | |
Mike Fiore |
1:e52ae6584f1c | 351 | } |
Mike Fiore |
1:e52ae6584f1c | 352 | |
Mike Fiore |
1:e52ae6584f1c | 353 | return false; |
Mike Fiore |
1:e52ae6584f1c | 354 | } |
Mike Fiore |
1:e52ae6584f1c | 355 | |
Mike Fiore |
1:e52ae6584f1c | 356 | void CommandTerminal::start() { |
Mike Fiore |
1:e52ae6584f1c | 357 | |
Mike Fiore |
4:666017851052 | 358 | wakeup(_sleep_standby); |
Mike Fiore |
1:e52ae6584f1c | 359 | |
Mike Fiore |
1:e52ae6584f1c | 360 | char ch; |
Mike Fiore |
1:e52ae6584f1c | 361 | bool running = true; |
Mike Fiore |
1:e52ae6584f1c | 362 | bool echo = _dot->getEcho(); |
Mike Fiore |
1:e52ae6584f1c | 363 | std::string command; |
Mike Fiore |
4:666017851052 | 364 | std::deque<std::string> history; |
Mike Fiore |
4:666017851052 | 365 | int history_index = -1; |
Mike Fiore |
1:e52ae6584f1c | 366 | std::vector<std::string> args; |
Mike Fiore |
1:e52ae6584f1c | 367 | |
Mike Fiore |
1:e52ae6584f1c | 368 | if (_dot->getStartUpMode() == mDot::SERIAL_MODE) { |
Mike Fiore |
1:e52ae6584f1c | 369 | command = "AT+SD\n"; |
Mike Fiore |
1:e52ae6584f1c | 370 | |
Mike Fiore |
1:e52ae6584f1c | 371 | std::string escape_buffer; |
Mike Fiore |
1:e52ae6584f1c | 372 | char ch; |
Mike Fiore |
1:e52ae6584f1c | 373 | |
Mike Fiore |
1:e52ae6584f1c | 374 | int escape_timeout = 1000; |
Mike Fiore |
1:e52ae6584f1c | 375 | Timer tmr; |
Mike Fiore |
1:e52ae6584f1c | 376 | Timer escape_tmr; |
Mike Fiore |
1:e52ae6584f1c | 377 | |
Mike Fiore |
1:e52ae6584f1c | 378 | // wait one second for possible escape |
Mike Fiore |
1:e52ae6584f1c | 379 | tmr.reset(); |
Mike Fiore |
1:e52ae6584f1c | 380 | tmr.start(); |
Mike Fiore |
1:e52ae6584f1c | 381 | escape_tmr.reset(); |
Mike Fiore |
1:e52ae6584f1c | 382 | escape_tmr.start(); |
Mike Fiore |
1:e52ae6584f1c | 383 | while (tmr.read_ms() < escape_timeout) { |
Mike Fiore |
1:e52ae6584f1c | 384 | if (_serial.readable()) { |
Mike Fiore |
1:e52ae6584f1c | 385 | _serial.read(&ch, 1); |
Mike Fiore |
1:e52ae6584f1c | 386 | escape_buffer += ch; |
Mike Fiore |
1:e52ae6584f1c | 387 | } |
Mike Fiore |
1:e52ae6584f1c | 388 | |
Mike Fiore |
1:e52ae6584f1c | 389 | if (escape_buffer.find(escape_sequence) != std::string::npos) { |
Mike Fiore |
1:e52ae6584f1c | 390 | _mode = mDot::COMMAND_MODE; |
Mike Fiore |
1:e52ae6584f1c | 391 | command.clear(); |
Mike Fiore |
1:e52ae6584f1c | 392 | break; |
Mike Fiore |
1:e52ae6584f1c | 393 | } |
Mike Fiore |
1:e52ae6584f1c | 394 | |
Mike Fiore |
1:e52ae6584f1c | 395 | if (escape_tmr.read_ms() > escape_timeout) |
Mike Fiore |
1:e52ae6584f1c | 396 | escape_buffer.clear(); |
Mike Fiore |
1:e52ae6584f1c | 397 | |
Mike Fiore |
1:e52ae6584f1c | 398 | osDelay(1); |
Mike Fiore |
1:e52ae6584f1c | 399 | } |
Mike Fiore |
1:e52ae6584f1c | 400 | |
Mike Fiore |
1:e52ae6584f1c | 401 | } |
Mike Fiore |
1:e52ae6584f1c | 402 | |
Mike Fiore |
1:e52ae6584f1c | 403 | bool join_canceled = false; |
Mike Fiore |
1:e52ae6584f1c | 404 | |
Mike Fiore |
1:e52ae6584f1c | 405 | //Run terminal session |
Mike Fiore |
1:e52ae6584f1c | 406 | while (running) { |
Mike Fiore |
1:e52ae6584f1c | 407 | if (!join_canceled && _dot->getJoinMode() == mDot::AUTO_OTA) { |
Mike Fiore |
1:e52ae6584f1c | 408 | join_canceled = autoJoinCheck(); |
Mike Fiore |
1:e52ae6584f1c | 409 | if (join_canceled) |
Mike Fiore |
1:e52ae6584f1c | 410 | command.clear(); |
Mike Fiore |
1:e52ae6584f1c | 411 | } |
Mike Fiore |
1:e52ae6584f1c | 412 | |
Mike Fiore |
1:e52ae6584f1c | 413 | if (_dot->getJoinMode() != mDot::AUTO_OTA || (!join_canceled && _dot->getJoinMode() == mDot::AUTO_OTA)) { |
Mike Fiore |
1:e52ae6584f1c | 414 | switch (_mode) { |
Mike Fiore |
1:e52ae6584f1c | 415 | case mDot::SERIAL_MODE: |
Mike Fiore |
1:e52ae6584f1c | 416 | // signal wakeup, read serial and output to radio |
Mike Fiore |
1:e52ae6584f1c | 417 | serial_loop(); |
Mike Fiore |
1:e52ae6584f1c | 418 | continue; |
Mike Fiore |
1:e52ae6584f1c | 419 | break; |
Mike Fiore |
1:e52ae6584f1c | 420 | default: |
Mike Fiore |
1:e52ae6584f1c | 421 | break; |
Mike Fiore |
1:e52ae6584f1c | 422 | } |
Mike Fiore |
1:e52ae6584f1c | 423 | } |
Mike Fiore |
1:e52ae6584f1c | 424 | |
Mike Fiore |
1:e52ae6584f1c | 425 | ch = '\0'; |
Mike Fiore |
1:e52ae6584f1c | 426 | |
Mike Fiore |
1:e52ae6584f1c | 427 | // read characters |
Mike Fiore |
1:e52ae6584f1c | 428 | if (readable()) { |
Mike Fiore |
1:e52ae6584f1c | 429 | ch = read(); |
Mike Fiore |
1:e52ae6584f1c | 430 | |
Mike Fiore |
4:666017851052 | 431 | if (ch == '\b' || ch == 0x7f) { |
Mike Fiore |
1:e52ae6584f1c | 432 | if (!command.empty()) { |
Mike Fiore |
1:e52ae6584f1c | 433 | writef("\b \b"); |
Mike Fiore |
1:e52ae6584f1c | 434 | command.erase(command.size() - 1); |
Mike Fiore |
1:e52ae6584f1c | 435 | } |
Mike Fiore |
1:e52ae6584f1c | 436 | continue; |
Mike Fiore |
4:666017851052 | 437 | } else if (ch == 0x1b || ch == 0x09) { |
Mike Fiore |
4:666017851052 | 438 | osDelay(20); |
Mike Fiore |
4:666017851052 | 439 | // catch escape sequence, or tab |
Mike Fiore |
4:666017851052 | 440 | char ch1, ch2; |
Mike Fiore |
4:666017851052 | 441 | |
Mike Fiore |
4:666017851052 | 442 | if (readable()) { |
Mike Fiore |
4:666017851052 | 443 | ch1 = read(); |
Mike Fiore |
4:666017851052 | 444 | if (readable()) |
Mike Fiore |
4:666017851052 | 445 | ch2 = read(); |
Mike Fiore |
4:666017851052 | 446 | |
Mike Fiore |
4:666017851052 | 447 | if (ch1 == 0x5b && ch2 == 0x41) { |
Mike Fiore |
4:666017851052 | 448 | // up key |
Mike Fiore |
4:666017851052 | 449 | for (int i = 0; i < command.size()+1; i++) { |
Mike Fiore |
4:666017851052 | 450 | writef("\b \b"); |
Mike Fiore |
4:666017851052 | 451 | } |
Mike Fiore |
4:666017851052 | 452 | if (history.size() > 0) { |
Mike Fiore |
4:666017851052 | 453 | if (++history_index >= history.size() - 1) |
Mike Fiore |
4:666017851052 | 454 | history_index = history.size() - 1; |
Mike Fiore |
4:666017851052 | 455 | |
Mike Fiore |
4:666017851052 | 456 | command = history[history_index]; |
Mike Fiore |
4:666017851052 | 457 | writef("%s", history[history_index].c_str()); |
Mike Fiore |
4:666017851052 | 458 | } else { |
Mike Fiore |
4:666017851052 | 459 | command.clear(); |
Mike Fiore |
4:666017851052 | 460 | } |
Mike Fiore |
4:666017851052 | 461 | } else if (ch1 == 0x5b && ch2 == 0x42) { |
Mike Fiore |
4:666017851052 | 462 | |
Mike Fiore |
4:666017851052 | 463 | // down key |
Mike Fiore |
4:666017851052 | 464 | for (int i = 0; i < command.size()+1; i++) { |
Mike Fiore |
4:666017851052 | 465 | writef("\b \b"); |
Mike Fiore |
4:666017851052 | 466 | } |
Mike Fiore |
4:666017851052 | 467 | |
Mike Fiore |
4:666017851052 | 468 | if (--history_index < 0) { |
Mike Fiore |
4:666017851052 | 469 | history_index = -1; |
Mike Fiore |
4:666017851052 | 470 | command.clear(); |
Mike Fiore |
4:666017851052 | 471 | } else { |
Mike Fiore |
4:666017851052 | 472 | command = history[history_index]; |
Mike Fiore |
4:666017851052 | 473 | writef("%s", history[history_index].c_str()); |
Mike Fiore |
4:666017851052 | 474 | } |
Mike Fiore |
4:666017851052 | 475 | } |
Mike Fiore |
4:666017851052 | 476 | } |
Mike Fiore |
4:666017851052 | 477 | while (readable()) read(); |
Mike Fiore |
4:666017851052 | 478 | continue; |
Mike Fiore |
1:e52ae6584f1c | 479 | } else { |
Mike Fiore |
1:e52ae6584f1c | 480 | command += ch; |
Mike Fiore |
1:e52ae6584f1c | 481 | } |
Mike Fiore |
1:e52ae6584f1c | 482 | |
Mike Fiore |
1:e52ae6584f1c | 483 | // echo chars if enabled |
Mike Fiore |
1:e52ae6584f1c | 484 | if (echo && !(ch == '\r' || ch == '\n')) |
Mike Fiore |
1:e52ae6584f1c | 485 | writef("%c", ch); |
Mike Fiore |
1:e52ae6584f1c | 486 | } |
Mike Fiore |
1:e52ae6584f1c | 487 | |
Mike Fiore |
1:e52ae6584f1c | 488 | // look for end of command line |
Mike Fiore |
1:e52ae6584f1c | 489 | if (command.find("\n") != std::string::npos || command.find("\r") != std::string::npos) { |
Mike Fiore |
1:e52ae6584f1c | 490 | // remove new line or cr character |
Mike Fiore |
1:e52ae6584f1c | 491 | command.erase(command.size() - 1); |
Mike Fiore |
1:e52ae6584f1c | 492 | write("\r"); // match standard modem output |
Mike Fiore |
1:e52ae6584f1c | 493 | write(newline); |
Mike Fiore |
1:e52ae6584f1c | 494 | } else { |
Mike Fiore |
1:e52ae6584f1c | 495 | continue; |
Mike Fiore |
1:e52ae6584f1c | 496 | } |
Mike Fiore |
1:e52ae6584f1c | 497 | |
Mike Fiore |
1:e52ae6584f1c | 498 | // trim whitespace from command |
Mike Fiore |
1:e52ae6584f1c | 499 | mts::Text::trim(command, "\r\n\t "); |
Mike Fiore |
1:e52ae6584f1c | 500 | |
Mike Fiore |
1:e52ae6584f1c | 501 | if (command.size() < 1) { |
Mike Fiore |
1:e52ae6584f1c | 502 | command.clear(); |
Mike Fiore |
1:e52ae6584f1c | 503 | continue; |
Mike Fiore |
1:e52ae6584f1c | 504 | } |
Mike Fiore |
1:e52ae6584f1c | 505 | |
Mike Fiore |
1:e52ae6584f1c | 506 | // parse command and args |
Mike Fiore |
1:e52ae6584f1c | 507 | args.clear(); |
Mike Fiore |
1:e52ae6584f1c | 508 | |
Mike Fiore |
1:e52ae6584f1c | 509 | // find first '=' character |
Mike Fiore |
1:e52ae6584f1c | 510 | size_t delim_index = command.find("="); |
Mike Fiore |
1:e52ae6584f1c | 511 | if (delim_index != std::string::npos) { |
Mike Fiore |
1:e52ae6584f1c | 512 | args.push_back(command.substr(0, delim_index)); |
Mike Fiore |
1:e52ae6584f1c | 513 | } else { |
Mike Fiore |
1:e52ae6584f1c | 514 | // find first ' ' character |
Mike Fiore |
1:e52ae6584f1c | 515 | delim_index = command.find(" "); |
Mike Fiore |
1:e52ae6584f1c | 516 | if (delim_index != std::string::npos) { |
Mike Fiore |
1:e52ae6584f1c | 517 | args.push_back(command.substr(0, delim_index)); |
Mike Fiore |
1:e52ae6584f1c | 518 | } else { |
Mike Fiore |
1:e52ae6584f1c | 519 | args.push_back(command); |
Mike Fiore |
1:e52ae6584f1c | 520 | } |
Mike Fiore |
1:e52ae6584f1c | 521 | } |
Mike Fiore |
1:e52ae6584f1c | 522 | |
Mike Fiore |
1:e52ae6584f1c | 523 | if (delim_index != std::string::npos) { |
Mike Fiore |
1:e52ae6584f1c | 524 | std::vector<std::string> params = mts::Text::split(command.substr(delim_index + 1), ","); |
Mike Fiore |
1:e52ae6584f1c | 525 | args.insert(args.end(), params.begin(), params.end()); |
Mike Fiore |
1:e52ae6584f1c | 526 | } |
Mike Fiore |
1:e52ae6584f1c | 527 | |
Mike Fiore |
1:e52ae6584f1c | 528 | args[0] = mts::Text::toUpper(args[0]); |
Mike Fiore |
1:e52ae6584f1c | 529 | |
Mike Fiore |
1:e52ae6584f1c | 530 | // print help |
Mike Fiore |
1:e52ae6584f1c | 531 | if ((args[0].find("?") == 0 || args[0].find("HELP") == 0) && args.size() == 1) { |
Mike Fiore |
1:e52ae6584f1c | 532 | printHelp(); |
Mike Fiore |
1:e52ae6584f1c | 533 | command.clear(); |
Mike Fiore |
1:e52ae6584f1c | 534 | } else if (args[0].find("ATE0") == 0 && args[0].length() == 4) { |
Mike Fiore |
1:e52ae6584f1c | 535 | _dot->setEcho(false); |
Mike Fiore |
1:e52ae6584f1c | 536 | write(done); |
Mike Fiore |
1:e52ae6584f1c | 537 | echo = _dot->getEcho(); |
Mike Fiore |
1:e52ae6584f1c | 538 | } else if (args[0].find("ATE1") == 0 && args[0].length() == 4) { |
Mike Fiore |
1:e52ae6584f1c | 539 | _dot->setEcho(true); |
Mike Fiore |
1:e52ae6584f1c | 540 | write(done); |
Mike Fiore |
1:e52ae6584f1c | 541 | echo = _dot->getEcho(); |
Mike Fiore |
1:e52ae6584f1c | 542 | } else if (args[0].find("ATV0") == 0 && args[0].length() == 4) { |
Mike Fiore |
1:e52ae6584f1c | 543 | _dot->setVerbose(false); |
Mike Fiore |
1:e52ae6584f1c | 544 | write(done); |
Mike Fiore |
1:e52ae6584f1c | 545 | } else if (args[0].find("ATV1") == 0 && args[0].length() == 4) { |
Mike Fiore |
1:e52ae6584f1c | 546 | _dot->setVerbose(true); |
Mike Fiore |
1:e52ae6584f1c | 547 | write(done); |
Mike Fiore |
1:e52ae6584f1c | 548 | } else if (args[0] == "AT+SD") { |
Mike Fiore |
1:e52ae6584f1c | 549 | DEBUG_PRINTF("Enter Serial Mode\r\n"); |
Mike Fiore |
1:e52ae6584f1c | 550 | _mode = mDot::SERIAL_MODE; |
Mike Fiore |
4:666017851052 | 551 | } else if (args[0] == "AT+SLEEP") { |
Mike Fiore |
4:666017851052 | 552 | if (args.size() > 1 && (args[1] != "?")) { |
Mike Fiore |
4:666017851052 | 553 | write("Invalid argument\r\n"); |
Mike Fiore |
4:666017851052 | 554 | write(error); |
Mike Fiore |
4:666017851052 | 555 | } else { |
Mike Fiore |
4:666017851052 | 556 | if (args.size() > 1 && args[1] == "?") { |
Mike Fiore |
4:666017851052 | 557 | write("AT+SLEEP: NONE\r\n"); |
Mike Fiore |
4:666017851052 | 558 | write(done); |
Mike Fiore |
4:666017851052 | 559 | } else { |
Mike Fiore |
4:666017851052 | 560 | _sleep_standby = !(args.size() > 1 && args[1] == "1"); |
Mike Fiore |
4:666017851052 | 561 | this->sleep(_sleep_standby); |
Mike Fiore |
4:666017851052 | 562 | wait(0.1); |
Mike Fiore |
4:666017851052 | 563 | write(done); |
Mike Fiore |
4:666017851052 | 564 | } |
Mike Fiore |
4:666017851052 | 565 | } |
Mike Fiore |
1:e52ae6584f1c | 566 | } else { |
Mike Fiore |
1:e52ae6584f1c | 567 | bool found = false; |
Mike Fiore |
1:e52ae6584f1c | 568 | bool query = false; |
Mike Fiore |
1:e52ae6584f1c | 569 | |
Mike Fiore |
1:e52ae6584f1c | 570 | std::string lookfor = args[0]; |
Mike Fiore |
1:e52ae6584f1c | 571 | |
Mike Fiore |
1:e52ae6584f1c | 572 | // per command help |
Mike Fiore |
1:e52ae6584f1c | 573 | if ((args[0].find("?") == 0 || args[0].find("HELP") == 0)) |
Mike Fiore |
1:e52ae6584f1c | 574 | lookfor = mts::Text::toUpper(args[1]); |
Mike Fiore |
1:e52ae6584f1c | 575 | |
Mike Fiore |
1:e52ae6584f1c | 576 | // trim off any trailing '?' and mark as a query command |
Mike Fiore |
1:e52ae6584f1c | 577 | if (args[0].rfind("?") == args[0].length() - 1) { |
Mike Fiore |
1:e52ae6584f1c | 578 | query = true; |
Mike Fiore |
1:e52ae6584f1c | 579 | lookfor = args[0].substr(0, args[0].length() - 1); |
Mike Fiore |
1:e52ae6584f1c | 580 | } |
Mike Fiore |
1:e52ae6584f1c | 581 | |
Mike Fiore |
1:e52ae6584f1c | 582 | // search for command |
Mike Fiore |
1:e52ae6584f1c | 583 | for (std::vector<Command*>::iterator it = _commands.begin(); it != _commands.end() && !found; ++it) { |
Mike Fiore |
1:e52ae6584f1c | 584 | Command* cmd = *it; |
Mike Fiore |
1:e52ae6584f1c | 585 | |
Mike Fiore |
1:e52ae6584f1c | 586 | // match CMD or CMD? syntax if command is queryable |
Mike Fiore |
1:e52ae6584f1c | 587 | if (lookfor == cmd->text() && (!query || (query && cmd->queryable()))) { |
Mike Fiore |
1:e52ae6584f1c | 588 | found = true; |
Mike Fiore |
1:e52ae6584f1c | 589 | if (args[0] == "HELP") { |
Mike Fiore |
1:e52ae6584f1c | 590 | writef("%s%s", cmd->help(), newline); |
Mike Fiore |
1:e52ae6584f1c | 591 | write(done); |
Mike Fiore |
1:e52ae6584f1c | 592 | } |
Mike Fiore |
1:e52ae6584f1c | 593 | |
Mike Fiore |
1:e52ae6584f1c | 594 | else if (args.size() > 1 && args[1] == "?") { |
Mike Fiore |
1:e52ae6584f1c | 595 | writef("%s%s", cmd->usage().c_str(), newline); |
Mike Fiore |
1:e52ae6584f1c | 596 | write(done); |
Mike Fiore |
1:e52ae6584f1c | 597 | } else if (!cmd->verify(args)) { |
Mike Fiore |
1:e52ae6584f1c | 598 | writef("%s%s", cmd->errorMessage().c_str(), newline); |
Mike Fiore |
1:e52ae6584f1c | 599 | writef("%s", error); |
Mike Fiore |
1:e52ae6584f1c | 600 | } else { |
Mike Fiore |
1:e52ae6584f1c | 601 | if (cmd->action(args) == 0) { |
Mike Fiore |
1:e52ae6584f1c | 602 | writef("%s", done); |
Mike Fiore |
1:e52ae6584f1c | 603 | } else { |
Mike Fiore |
1:e52ae6584f1c | 604 | writef("%s%s", cmd->errorMessage().c_str(), newline); |
Mike Fiore |
1:e52ae6584f1c | 605 | writef("%s", error); |
Mike Fiore |
1:e52ae6584f1c | 606 | } |
Mike Fiore |
1:e52ae6584f1c | 607 | } |
Mike Fiore |
1:e52ae6584f1c | 608 | } |
Mike Fiore |
1:e52ae6584f1c | 609 | } |
Mike Fiore |
1:e52ae6584f1c | 610 | |
Mike Fiore |
1:e52ae6584f1c | 611 | if (!found) { |
Mike Fiore |
1:e52ae6584f1c | 612 | writef("%s", command_error); |
Mike Fiore |
1:e52ae6584f1c | 613 | writef("%s", error); |
Mike Fiore |
1:e52ae6584f1c | 614 | } |
Mike Fiore |
1:e52ae6584f1c | 615 | } |
Mike Fiore |
1:e52ae6584f1c | 616 | |
Mike Fiore |
4:666017851052 | 617 | if (history.size() == 0 || history.front() != command) |
Mike Fiore |
4:666017851052 | 618 | history.push_front(command); |
Mike Fiore |
4:666017851052 | 619 | history_index = -1; |
Mike Fiore |
1:e52ae6584f1c | 620 | command.clear(); |
Mike Fiore |
1:e52ae6584f1c | 621 | |
Mike Fiore |
4:666017851052 | 622 | while (history.size() > 10) |
Mike Fiore |
4:666017851052 | 623 | history.pop_back(); |
Mike Fiore |
1:e52ae6584f1c | 624 | } |
Mike Fiore |
1:e52ae6584f1c | 625 | } |
Mike Fiore |
1:e52ae6584f1c | 626 | |
Mike Fiore |
1:e52ae6584f1c | 627 | std::string CommandTerminal::formatPacketData(const std::vector<uint8_t>& data, const uint8_t& format) { |
Mike Fiore |
2:e5eebd74d36d | 628 | if (format == mDot::HEXADECIMAL) |
Mike Fiore |
1:e52ae6584f1c | 629 | return mts::Text::bin2hexString(data); |
Mike Fiore |
2:e5eebd74d36d | 630 | else |
Mike Fiore |
2:e5eebd74d36d | 631 | return std::string(data.begin(), data.end()); |
Mike Fiore |
1:e52ae6584f1c | 632 | } |
Mike Fiore |
1:e52ae6584f1c | 633 | |
Mike Fiore |
1:e52ae6584f1c | 634 | void CommandTerminal::sleep(bool standby) { |
Mike Fiore |
1:e52ae6584f1c | 635 | _serial_up = false; |
Mike Fiore |
1:e52ae6584f1c | 636 | _xbee_on_sleep = GPIO_PIN_RESET; |
Mike Fiore |
1:e52ae6584f1c | 637 | |
Mike Fiore |
4:666017851052 | 638 | _serial.rxClear(); |
Mike Fiore |
4:666017851052 | 639 | _serial.txClear(); |
Mike Fiore |
1:e52ae6584f1c | 640 | |
Mike Fiore |
4:666017851052 | 641 | _dot->sleep(_dot->getWakeInterval(), _dot->getWakeMode(), standby); |
Mike Fiore |
1:e52ae6584f1c | 642 | } |
Mike Fiore |
1:e52ae6584f1c | 643 | |
Mike Fiore |
1:e52ae6584f1c | 644 | bool CommandTerminal::waitForEscape(int timeout, mDot* dot, WaitType wait) { |
Mike Fiore |
1:e52ae6584f1c | 645 | Timer timer; |
Mike Fiore |
1:e52ae6584f1c | 646 | Timer escape_timer; |
Mike Fiore |
1:e52ae6584f1c | 647 | std::string escape_buffer; |
Mike Fiore |
1:e52ae6584f1c | 648 | int escape_timeout = 1000; |
Mike Fiore |
1:e52ae6584f1c | 649 | |
Mike Fiore |
1:e52ae6584f1c | 650 | timer.start(); |
Mike Fiore |
1:e52ae6584f1c | 651 | while (timer.read_ms() < timeout) { |
Mike Fiore |
1:e52ae6584f1c | 652 | |
Mike Fiore |
1:e52ae6584f1c | 653 | if (dot != NULL) { |
Mike Fiore |
1:e52ae6584f1c | 654 | if (wait == WAIT_SEND && (!dot->getIsTransmitting())) { |
Mike Fiore |
1:e52ae6584f1c | 655 | return false; |
Mike Fiore |
1:e52ae6584f1c | 656 | } |
Mike Fiore |
1:e52ae6584f1c | 657 | } |
Mike Fiore |
1:e52ae6584f1c | 658 | |
Mike Fiore |
1:e52ae6584f1c | 659 | if (_serialp != NULL && _serialp->readable()) { |
Mike Fiore |
1:e52ae6584f1c | 660 | if (escape_buffer == "") |
Mike Fiore |
1:e52ae6584f1c | 661 | escape_timer.start(); |
Mike Fiore |
1:e52ae6584f1c | 662 | char ch; |
Mike Fiore |
1:e52ae6584f1c | 663 | _serialp->read(&ch, 1); |
Mike Fiore |
1:e52ae6584f1c | 664 | escape_buffer += ch; |
Mike Fiore |
1:e52ae6584f1c | 665 | if (escape_buffer == CommandTerminal::escape_sequence) |
Mike Fiore |
1:e52ae6584f1c | 666 | return true; |
Mike Fiore |
1:e52ae6584f1c | 667 | } |
Mike Fiore |
1:e52ae6584f1c | 668 | if (escape_timer.read_ms() > escape_timeout) { |
Mike Fiore |
1:e52ae6584f1c | 669 | escape_buffer = ""; |
Mike Fiore |
1:e52ae6584f1c | 670 | escape_timer.stop(), escape_timer.reset(); |
Mike Fiore |
1:e52ae6584f1c | 671 | } |
Mike Fiore |
1:e52ae6584f1c | 672 | |
Mike Fiore |
1:e52ae6584f1c | 673 | osDelay(10); |
Mike Fiore |
1:e52ae6584f1c | 674 | } |
Mike Fiore |
1:e52ae6584f1c | 675 | |
Mike Fiore |
1:e52ae6584f1c | 676 | return false; |
Mike Fiore |
1:e52ae6584f1c | 677 | } |
Mike Fiore |
1:e52ae6584f1c | 678 | |
Mike Fiore |
1:e52ae6584f1c | 679 | void CommandTerminal::wakeup(bool standby) { |
Mike Fiore |
1:e52ae6584f1c | 680 | |
Mike Fiore |
1:e52ae6584f1c | 681 | } |