AT command firmware for MultiTech Dot devices.

Fork of mDot_AT_firmware by MultiTech

Dot Library Not Included!

Because these example programs can be used for both mDot and xDot devices, the LoRa stack is not included. The libmDot library should be imported if building for mDot devices. The libxDot library should be imported if building for xDot devices. The AT firmware was last tested with mbed-os-5.4.7. Using a version past mbed-os-5.4.7 will cause the build to fail. The library used with the AT firmware has to match the mbed-os version.

Dot Library Version 3 Updates

Dot Library versions 3.x.x require a channel plan to be injected into the stack. The Dot-Examples and Dot-AT-Firmware do this by defining a macro called "CHANNEL_PLAN" that controls the channel plan that will be used in the examples. Available channel plans will be in the Dot Library repository in the plans folder.

Revision 20 and earlier of Dot-Examples and revision 15 and earlier of Dot-AT-Firmware should be used with Dot Library versions prior to 3.0.0.

Fota Library

Th Fota Library must be added to compile for mDot 3.1.0 with Fota support. Latest dev libraries and 3.2.0 release will include Fota with libmDot/libxDot.

AT Firmware Description

This AT Firmware is what ships on mDot and xDot devices. It provides an AT command interface for using the mDot or xDot for LoRa communication.

AT command documentation can be found on Multitech.com.

The firmware changelog can be found here. The library changelog can be found here.

Dot Libraries

Dot Library Limitations

The commit messages in libmDot-mbed5 and libmDot-dev-mbed5 specify the version of the Dot library the commit contains and the version of mbed-os it was compiled against. We recommend building your application with the version of mbed-os specified in the commit message of the version of the Dot library you're using. This will ensure that you don't run into any runtime issues caused by differences in the mbed-os versions.

Stable and development libraries are available for both mDot and xDot platforms. The library chosen must match the target platform. Compiling for the mDot platform with the xDot library or vice versa will not succeed.

mDot Library

Development library for mDot.

libmDot-dev

Stable library for mDot.

libmDot

xDot Library

Development library for xDot.

libxDot-dev

Stable library for xDot.

libxDot

Committer:
Mike Fiore
Date:
Fri Jan 29 14:01:05 2016 -0600
Revision:
6:e27eaad36a0c
Parent:
4:666017851052
Child:
9:ff62b20f7000
update to AT firmware version 0.1.4

Who changed what in which revision?

UserRevisionLine numberNew 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 6:e27eaad36a0c 210 logDebug("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 6:e27eaad36a0c 229 logDebug("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 6:e27eaad36a0c 238 serial_read_timer.start();
Mike Fiore 6:e27eaad36a0c 239 uint32_t timeout = _dot->getWakeDelay();
Mike Fiore 1:e52ae6584f1c 240
Mike Fiore 6:e27eaad36a0c 241 // wait for timeout or start of serial data
Mike Fiore 6:e27eaad36a0c 242 while (!readable() && serial_read_timer.read_ms() < timeout) {
Mike Fiore 6:e27eaad36a0c 243 osDelay(10);
Mike Fiore 6:e27eaad36a0c 244 }
Mike Fiore 6:e27eaad36a0c 245
Mike Fiore 6:e27eaad36a0c 246 serial_read_timer.reset();
Mike Fiore 6:e27eaad36a0c 247 timeout = _dot->getWakeTimeout();
Mike Fiore 4:666017851052 248 while (_serial_up && serial_read_timer.read_ms() < timeout) {
Mike Fiore 1:e52ae6584f1c 249 while (readable() && serial_buffer.size() < max_send_size) {
Mike Fiore 1:e52ae6584f1c 250 serial_buffer.push_back(read());
Mike Fiore 1:e52ae6584f1c 251 serial_read_timer.reset();
Mike Fiore 1:e52ae6584f1c 252 }
Mike Fiore 1:e52ae6584f1c 253 }
Mike Fiore 1:e52ae6584f1c 254 serial_read_timer.stop(), serial_read_timer.reset();
Mike Fiore 1:e52ae6584f1c 255
Mike Fiore 1:e52ae6584f1c 256 if (!serial_buffer.empty()) {
Mike Fiore 1:e52ae6584f1c 257 _serial_up = false;
Mike Fiore 1:e52ae6584f1c 258 _xbee_on_sleep = GPIO_PIN_RESET;
Mike Fiore 1:e52ae6584f1c 259 if (!_dot->getIsTransmitting()) {
Mike Fiore 1:e52ae6584f1c 260 std::vector<uint8_t> recv_buffer;
Mike Fiore 6:e27eaad36a0c 261 logDebug("Received serial data, sending out radio.\r\n");
Mike Fiore 1:e52ae6584f1c 262
Mike Fiore 4:666017851052 263 if (_dot->send(serial_buffer) != mDot::MDOT_OK)
Mike Fiore 6:e27eaad36a0c 264 logDebug("Send failed.\r\n");
Mike Fiore 1:e52ae6584f1c 265 if (_dot->recv(recv_buffer))
Mike Fiore 1:e52ae6584f1c 266 _serial.writef("%s\r\n", formatPacketData(recv_buffer, _dot->getRxOutput()).c_str());
Mike Fiore 1:e52ae6584f1c 267 } else {
Mike Fiore 6:e27eaad36a0c 268 logDebug("Radio is busy, cannot send.\r\n");
Mike Fiore 1:e52ae6584f1c 269 }
Mike Fiore 1:e52ae6584f1c 270
Mike Fiore 1:e52ae6584f1c 271 serial_buffer.clear();
Mike Fiore 1:e52ae6584f1c 272 } else {
Mike Fiore 6:e27eaad36a0c 273 logDebug("No data received from serial to send.\r\n");
Mike Fiore 1:e52ae6584f1c 274 }
Mike Fiore 1:e52ae6584f1c 275 _serial_up = false;
Mike Fiore 1:e52ae6584f1c 276 }
Mike Fiore 1:e52ae6584f1c 277 sleep(_sleep_standby);
Mike Fiore 1:e52ae6584f1c 278 }
Mike Fiore 1:e52ae6584f1c 279
Mike Fiore 1:e52ae6584f1c 280 bool CommandTerminal::autoJoinCheck() {
Mike Fiore 1:e52ae6584f1c 281
Mike Fiore 1:e52ae6584f1c 282 std::string escape_buffer;
Mike Fiore 1:e52ae6584f1c 283 char ch;
Mike Fiore 1:e52ae6584f1c 284 int sleep = 1000;
Mike Fiore 1:e52ae6584f1c 285 int escape_timeout = 1000;
Mike Fiore 1:e52ae6584f1c 286 Timer tmr;
Mike Fiore 1:e52ae6584f1c 287 Timer escape_tmr;
Mike Fiore 1:e52ae6584f1c 288 int cnt = 0;
Mike Fiore 1:e52ae6584f1c 289
Mike Fiore 1:e52ae6584f1c 290 while (!_dot->getNetworkJoinStatus()) {
Mike Fiore 1:e52ae6584f1c 291 wakeup(_sleep_standby);
Mike Fiore 1:e52ae6584f1c 292 write("\r\nJoining network... ");
Mike Fiore 1:e52ae6584f1c 293
Mike Fiore 1:e52ae6584f1c 294 // wait one second for possible escape
Mike Fiore 1:e52ae6584f1c 295 tmr.reset();
Mike Fiore 1:e52ae6584f1c 296 tmr.start();
Mike Fiore 1:e52ae6584f1c 297 escape_tmr.reset();
Mike Fiore 1:e52ae6584f1c 298 escape_tmr.start();
Mike Fiore 1:e52ae6584f1c 299 while (tmr.read_ms() < 1000) {
Mike Fiore 1:e52ae6584f1c 300 if (_serial.readable()) {
Mike Fiore 1:e52ae6584f1c 301 _serial.read(&ch, 1);
Mike Fiore 1:e52ae6584f1c 302 escape_buffer += ch;
Mike Fiore 1:e52ae6584f1c 303 }
Mike Fiore 1:e52ae6584f1c 304
Mike Fiore 1:e52ae6584f1c 305 if (escape_buffer.find(escape_sequence) != std::string::npos) {
Mike Fiore 1:e52ae6584f1c 306 _mode = mDot::COMMAND_MODE;
Mike Fiore 1:e52ae6584f1c 307 write("Join Canceled\r\n");
Mike Fiore 1:e52ae6584f1c 308 write(done);
Mike Fiore 1:e52ae6584f1c 309 return true;
Mike Fiore 1:e52ae6584f1c 310 }
Mike Fiore 1:e52ae6584f1c 311
Mike Fiore 1:e52ae6584f1c 312 if (escape_tmr.read_ms() > escape_timeout)
Mike Fiore 1:e52ae6584f1c 313 escape_buffer.clear();
Mike Fiore 1:e52ae6584f1c 314 }
Mike Fiore 1:e52ae6584f1c 315
Mike Fiore 1:e52ae6584f1c 316 if (_dot->joinNetworkOnce() == mDot::MDOT_OK) {
Mike Fiore 1:e52ae6584f1c 317 write("Network Joined\r\n");
Mike Fiore 1:e52ae6584f1c 318 write(done);
Mike Fiore 1:e52ae6584f1c 319 return false;
Mike Fiore 1:e52ae6584f1c 320 }
Mike Fiore 1:e52ae6584f1c 321
Mike Fiore 1:e52ae6584f1c 322 write("Network Join failed\r\n");
Mike Fiore 1:e52ae6584f1c 323 write(error);
Mike Fiore 1:e52ae6584f1c 324
Mike Fiore 1:e52ae6584f1c 325 if (cnt++ > _dot->getJoinRetries()) {
Mike Fiore 1:e52ae6584f1c 326 cnt = 0;
Mike Fiore 1:e52ae6584f1c 327
Mike Fiore 1:e52ae6584f1c 328 if (_dot->getFrequencyBand() == mDot::FB_915) {
Mike Fiore 1:e52ae6584f1c 329 uint8_t band = ((_dot->getFrequencySubBand()) % 8) + 1;
Mike Fiore 6:e27eaad36a0c 330 logDebug("Join retries exhausted, switching to sub band %u\r\n", band);
Mike Fiore 1:e52ae6584f1c 331 _dot->setFrequencySubBand(band);
Mike Fiore 1:e52ae6584f1c 332 }
Mike Fiore 1:e52ae6584f1c 333
Mike Fiore 1:e52ae6584f1c 334 if (sleep < 60 * 60 * 1000)
Mike Fiore 1:e52ae6584f1c 335 sleep *= 2;
Mike Fiore 1:e52ae6584f1c 336 }
Mike Fiore 1:e52ae6584f1c 337
Mike Fiore 1:e52ae6584f1c 338 tmr.reset();
Mike Fiore 1:e52ae6584f1c 339 tmr.start();
Mike Fiore 1:e52ae6584f1c 340 escape_tmr.reset();
Mike Fiore 1:e52ae6584f1c 341 escape_tmr.start();
Mike Fiore 1:e52ae6584f1c 342 while (tmr.read_ms() < sleep) {
Mike Fiore 1:e52ae6584f1c 343 if (_serial.readable()) {
Mike Fiore 1:e52ae6584f1c 344 _serial.read(&ch, 1);
Mike Fiore 1:e52ae6584f1c 345 escape_buffer += ch;
Mike Fiore 1:e52ae6584f1c 346 }
Mike Fiore 1:e52ae6584f1c 347
Mike Fiore 1:e52ae6584f1c 348 if (escape_buffer.find(escape_sequence) != std::string::npos) {
Mike Fiore 1:e52ae6584f1c 349 _mode = mDot::COMMAND_MODE;
Mike Fiore 1:e52ae6584f1c 350 return true;
Mike Fiore 1:e52ae6584f1c 351 }
Mike Fiore 1:e52ae6584f1c 352
Mike Fiore 1:e52ae6584f1c 353 if (escape_tmr.read_ms() > escape_timeout)
Mike Fiore 1:e52ae6584f1c 354 escape_buffer.clear();
Mike Fiore 1:e52ae6584f1c 355 }
Mike Fiore 1:e52ae6584f1c 356
Mike Fiore 1:e52ae6584f1c 357 }
Mike Fiore 1:e52ae6584f1c 358
Mike Fiore 1:e52ae6584f1c 359 return false;
Mike Fiore 1:e52ae6584f1c 360 }
Mike Fiore 1:e52ae6584f1c 361
Mike Fiore 1:e52ae6584f1c 362 void CommandTerminal::start() {
Mike Fiore 1:e52ae6584f1c 363
Mike Fiore 4:666017851052 364 wakeup(_sleep_standby);
Mike Fiore 1:e52ae6584f1c 365
Mike Fiore 1:e52ae6584f1c 366 char ch;
Mike Fiore 1:e52ae6584f1c 367 bool running = true;
Mike Fiore 1:e52ae6584f1c 368 bool echo = _dot->getEcho();
Mike Fiore 1:e52ae6584f1c 369 std::string command;
Mike Fiore 4:666017851052 370 std::deque<std::string> history;
Mike Fiore 4:666017851052 371 int history_index = -1;
Mike Fiore 1:e52ae6584f1c 372 std::vector<std::string> args;
Mike Fiore 1:e52ae6584f1c 373
Mike Fiore 1:e52ae6584f1c 374 if (_dot->getStartUpMode() == mDot::SERIAL_MODE) {
Mike Fiore 1:e52ae6584f1c 375 command = "AT+SD\n";
Mike Fiore 1:e52ae6584f1c 376
Mike Fiore 1:e52ae6584f1c 377 std::string escape_buffer;
Mike Fiore 1:e52ae6584f1c 378 char ch;
Mike Fiore 1:e52ae6584f1c 379
Mike Fiore 1:e52ae6584f1c 380 int escape_timeout = 1000;
Mike Fiore 1:e52ae6584f1c 381 Timer tmr;
Mike Fiore 1:e52ae6584f1c 382 Timer escape_tmr;
Mike Fiore 1:e52ae6584f1c 383
Mike Fiore 1:e52ae6584f1c 384 // wait one second for possible escape
Mike Fiore 1:e52ae6584f1c 385 tmr.reset();
Mike Fiore 1:e52ae6584f1c 386 tmr.start();
Mike Fiore 1:e52ae6584f1c 387 escape_tmr.reset();
Mike Fiore 1:e52ae6584f1c 388 escape_tmr.start();
Mike Fiore 1:e52ae6584f1c 389 while (tmr.read_ms() < escape_timeout) {
Mike Fiore 1:e52ae6584f1c 390 if (_serial.readable()) {
Mike Fiore 1:e52ae6584f1c 391 _serial.read(&ch, 1);
Mike Fiore 1:e52ae6584f1c 392 escape_buffer += ch;
Mike Fiore 1:e52ae6584f1c 393 }
Mike Fiore 1:e52ae6584f1c 394
Mike Fiore 1:e52ae6584f1c 395 if (escape_buffer.find(escape_sequence) != std::string::npos) {
Mike Fiore 1:e52ae6584f1c 396 _mode = mDot::COMMAND_MODE;
Mike Fiore 1:e52ae6584f1c 397 command.clear();
Mike Fiore 1:e52ae6584f1c 398 break;
Mike Fiore 1:e52ae6584f1c 399 }
Mike Fiore 1:e52ae6584f1c 400
Mike Fiore 1:e52ae6584f1c 401 if (escape_tmr.read_ms() > escape_timeout)
Mike Fiore 1:e52ae6584f1c 402 escape_buffer.clear();
Mike Fiore 1:e52ae6584f1c 403
Mike Fiore 1:e52ae6584f1c 404 osDelay(1);
Mike Fiore 1:e52ae6584f1c 405 }
Mike Fiore 1:e52ae6584f1c 406
Mike Fiore 1:e52ae6584f1c 407 }
Mike Fiore 1:e52ae6584f1c 408
Mike Fiore 1:e52ae6584f1c 409 bool join_canceled = false;
Mike Fiore 1:e52ae6584f1c 410
Mike Fiore 1:e52ae6584f1c 411 //Run terminal session
Mike Fiore 1:e52ae6584f1c 412 while (running) {
Mike Fiore 1:e52ae6584f1c 413 if (!join_canceled && _dot->getJoinMode() == mDot::AUTO_OTA) {
Mike Fiore 1:e52ae6584f1c 414 join_canceled = autoJoinCheck();
Mike Fiore 1:e52ae6584f1c 415 if (join_canceled)
Mike Fiore 1:e52ae6584f1c 416 command.clear();
Mike Fiore 1:e52ae6584f1c 417 }
Mike Fiore 1:e52ae6584f1c 418
Mike Fiore 1:e52ae6584f1c 419 if (_dot->getJoinMode() != mDot::AUTO_OTA || (!join_canceled && _dot->getJoinMode() == mDot::AUTO_OTA)) {
Mike Fiore 1:e52ae6584f1c 420 switch (_mode) {
Mike Fiore 1:e52ae6584f1c 421 case mDot::SERIAL_MODE:
Mike Fiore 1:e52ae6584f1c 422 // signal wakeup, read serial and output to radio
Mike Fiore 1:e52ae6584f1c 423 serial_loop();
Mike Fiore 1:e52ae6584f1c 424 continue;
Mike Fiore 1:e52ae6584f1c 425 break;
Mike Fiore 1:e52ae6584f1c 426 default:
Mike Fiore 1:e52ae6584f1c 427 break;
Mike Fiore 1:e52ae6584f1c 428 }
Mike Fiore 1:e52ae6584f1c 429 }
Mike Fiore 1:e52ae6584f1c 430
Mike Fiore 1:e52ae6584f1c 431 ch = '\0';
Mike Fiore 1:e52ae6584f1c 432
Mike Fiore 1:e52ae6584f1c 433 // read characters
Mike Fiore 1:e52ae6584f1c 434 if (readable()) {
Mike Fiore 1:e52ae6584f1c 435 ch = read();
Mike Fiore 1:e52ae6584f1c 436
Mike Fiore 4:666017851052 437 if (ch == '\b' || ch == 0x7f) {
Mike Fiore 1:e52ae6584f1c 438 if (!command.empty()) {
Mike Fiore 1:e52ae6584f1c 439 writef("\b \b");
Mike Fiore 1:e52ae6584f1c 440 command.erase(command.size() - 1);
Mike Fiore 1:e52ae6584f1c 441 }
Mike Fiore 1:e52ae6584f1c 442 continue;
Mike Fiore 4:666017851052 443 } else if (ch == 0x1b || ch == 0x09) {
Mike Fiore 4:666017851052 444 osDelay(20);
Mike Fiore 4:666017851052 445 // catch escape sequence, or tab
Mike Fiore 4:666017851052 446 char ch1, ch2;
Mike Fiore 4:666017851052 447
Mike Fiore 4:666017851052 448 if (readable()) {
Mike Fiore 4:666017851052 449 ch1 = read();
Mike Fiore 4:666017851052 450 if (readable())
Mike Fiore 4:666017851052 451 ch2 = read();
Mike Fiore 4:666017851052 452
Mike Fiore 4:666017851052 453 if (ch1 == 0x5b && ch2 == 0x41) {
Mike Fiore 4:666017851052 454 // up key
Mike Fiore 4:666017851052 455 for (int i = 0; i < command.size()+1; i++) {
Mike Fiore 4:666017851052 456 writef("\b \b");
Mike Fiore 4:666017851052 457 }
Mike Fiore 4:666017851052 458 if (history.size() > 0) {
Mike Fiore 4:666017851052 459 if (++history_index >= history.size() - 1)
Mike Fiore 4:666017851052 460 history_index = history.size() - 1;
Mike Fiore 4:666017851052 461
Mike Fiore 4:666017851052 462 command = history[history_index];
Mike Fiore 4:666017851052 463 writef("%s", history[history_index].c_str());
Mike Fiore 4:666017851052 464 } else {
Mike Fiore 4:666017851052 465 command.clear();
Mike Fiore 4:666017851052 466 }
Mike Fiore 4:666017851052 467 } else if (ch1 == 0x5b && ch2 == 0x42) {
Mike Fiore 4:666017851052 468
Mike Fiore 4:666017851052 469 // down key
Mike Fiore 4:666017851052 470 for (int i = 0; i < command.size()+1; i++) {
Mike Fiore 4:666017851052 471 writef("\b \b");
Mike Fiore 4:666017851052 472 }
Mike Fiore 4:666017851052 473
Mike Fiore 4:666017851052 474 if (--history_index < 0) {
Mike Fiore 4:666017851052 475 history_index = -1;
Mike Fiore 4:666017851052 476 command.clear();
Mike Fiore 4:666017851052 477 } else {
Mike Fiore 4:666017851052 478 command = history[history_index];
Mike Fiore 4:666017851052 479 writef("%s", history[history_index].c_str());
Mike Fiore 4:666017851052 480 }
Mike Fiore 4:666017851052 481 }
Mike Fiore 4:666017851052 482 }
Mike Fiore 4:666017851052 483 while (readable()) read();
Mike Fiore 4:666017851052 484 continue;
Mike Fiore 1:e52ae6584f1c 485 } else {
Mike Fiore 1:e52ae6584f1c 486 command += ch;
Mike Fiore 1:e52ae6584f1c 487 }
Mike Fiore 1:e52ae6584f1c 488
Mike Fiore 1:e52ae6584f1c 489 // echo chars if enabled
Mike Fiore 1:e52ae6584f1c 490 if (echo && !(ch == '\r' || ch == '\n'))
Mike Fiore 1:e52ae6584f1c 491 writef("%c", ch);
Mike Fiore 1:e52ae6584f1c 492 }
Mike Fiore 1:e52ae6584f1c 493
Mike Fiore 1:e52ae6584f1c 494 // look for end of command line
Mike Fiore 1:e52ae6584f1c 495 if (command.find("\n") != std::string::npos || command.find("\r") != std::string::npos) {
Mike Fiore 1:e52ae6584f1c 496 // remove new line or cr character
Mike Fiore 1:e52ae6584f1c 497 command.erase(command.size() - 1);
Mike Fiore 1:e52ae6584f1c 498 write("\r"); // match standard modem output
Mike Fiore 1:e52ae6584f1c 499 write(newline);
Mike Fiore 1:e52ae6584f1c 500 } else {
Mike Fiore 1:e52ae6584f1c 501 continue;
Mike Fiore 1:e52ae6584f1c 502 }
Mike Fiore 1:e52ae6584f1c 503
Mike Fiore 1:e52ae6584f1c 504 // trim whitespace from command
Mike Fiore 1:e52ae6584f1c 505 mts::Text::trim(command, "\r\n\t ");
Mike Fiore 1:e52ae6584f1c 506
Mike Fiore 1:e52ae6584f1c 507 if (command.size() < 1) {
Mike Fiore 1:e52ae6584f1c 508 command.clear();
Mike Fiore 1:e52ae6584f1c 509 continue;
Mike Fiore 1:e52ae6584f1c 510 }
Mike Fiore 1:e52ae6584f1c 511
Mike Fiore 1:e52ae6584f1c 512 // parse command and args
Mike Fiore 1:e52ae6584f1c 513 args.clear();
Mike Fiore 1:e52ae6584f1c 514
Mike Fiore 1:e52ae6584f1c 515 // find first '=' character
Mike Fiore 1:e52ae6584f1c 516 size_t delim_index = command.find("=");
Mike Fiore 1:e52ae6584f1c 517 if (delim_index != std::string::npos) {
Mike Fiore 1:e52ae6584f1c 518 args.push_back(command.substr(0, delim_index));
Mike Fiore 1:e52ae6584f1c 519 } else {
Mike Fiore 1:e52ae6584f1c 520 // find first ' ' character
Mike Fiore 1:e52ae6584f1c 521 delim_index = command.find(" ");
Mike Fiore 1:e52ae6584f1c 522 if (delim_index != std::string::npos) {
Mike Fiore 1:e52ae6584f1c 523 args.push_back(command.substr(0, delim_index));
Mike Fiore 1:e52ae6584f1c 524 } else {
Mike Fiore 1:e52ae6584f1c 525 args.push_back(command);
Mike Fiore 1:e52ae6584f1c 526 }
Mike Fiore 1:e52ae6584f1c 527 }
Mike Fiore 1:e52ae6584f1c 528
Mike Fiore 1:e52ae6584f1c 529 if (delim_index != std::string::npos) {
Mike Fiore 1:e52ae6584f1c 530 std::vector<std::string> params = mts::Text::split(command.substr(delim_index + 1), ",");
Mike Fiore 1:e52ae6584f1c 531 args.insert(args.end(), params.begin(), params.end());
Mike Fiore 1:e52ae6584f1c 532 }
Mike Fiore 1:e52ae6584f1c 533
Mike Fiore 1:e52ae6584f1c 534 args[0] = mts::Text::toUpper(args[0]);
Mike Fiore 1:e52ae6584f1c 535
Mike Fiore 1:e52ae6584f1c 536 // print help
Mike Fiore 1:e52ae6584f1c 537 if ((args[0].find("?") == 0 || args[0].find("HELP") == 0) && args.size() == 1) {
Mike Fiore 1:e52ae6584f1c 538 printHelp();
Mike Fiore 1:e52ae6584f1c 539 command.clear();
Mike Fiore 1:e52ae6584f1c 540 } else if (args[0].find("ATE0") == 0 && args[0].length() == 4) {
Mike Fiore 1:e52ae6584f1c 541 _dot->setEcho(false);
Mike Fiore 1:e52ae6584f1c 542 write(done);
Mike Fiore 1:e52ae6584f1c 543 echo = _dot->getEcho();
Mike Fiore 1:e52ae6584f1c 544 } else if (args[0].find("ATE1") == 0 && args[0].length() == 4) {
Mike Fiore 1:e52ae6584f1c 545 _dot->setEcho(true);
Mike Fiore 1:e52ae6584f1c 546 write(done);
Mike Fiore 1:e52ae6584f1c 547 echo = _dot->getEcho();
Mike Fiore 1:e52ae6584f1c 548 } else if (args[0].find("ATV0") == 0 && args[0].length() == 4) {
Mike Fiore 1:e52ae6584f1c 549 _dot->setVerbose(false);
Mike Fiore 1:e52ae6584f1c 550 write(done);
Mike Fiore 1:e52ae6584f1c 551 } else if (args[0].find("ATV1") == 0 && args[0].length() == 4) {
Mike Fiore 1:e52ae6584f1c 552 _dot->setVerbose(true);
Mike Fiore 1:e52ae6584f1c 553 write(done);
Mike Fiore 1:e52ae6584f1c 554 } else if (args[0] == "AT+SD") {
Mike Fiore 6:e27eaad36a0c 555 logDebug("Enter Serial Mode\r\n");
Mike Fiore 1:e52ae6584f1c 556 _mode = mDot::SERIAL_MODE;
Mike Fiore 4:666017851052 557 } else if (args[0] == "AT+SLEEP") {
Mike Fiore 4:666017851052 558 if (args.size() > 1 && (args[1] != "?")) {
Mike Fiore 4:666017851052 559 write("Invalid argument\r\n");
Mike Fiore 4:666017851052 560 write(error);
Mike Fiore 4:666017851052 561 } else {
Mike Fiore 4:666017851052 562 if (args.size() > 1 && args[1] == "?") {
Mike Fiore 4:666017851052 563 write("AT+SLEEP: NONE\r\n");
Mike Fiore 4:666017851052 564 write(done);
Mike Fiore 4:666017851052 565 } else {
Mike Fiore 4:666017851052 566 _sleep_standby = !(args.size() > 1 && args[1] == "1");
Mike Fiore 4:666017851052 567 this->sleep(_sleep_standby);
Mike Fiore 4:666017851052 568 wait(0.1);
Mike Fiore 4:666017851052 569 write(done);
Mike Fiore 4:666017851052 570 }
Mike Fiore 4:666017851052 571 }
Mike Fiore 1:e52ae6584f1c 572 } else {
Mike Fiore 1:e52ae6584f1c 573 bool found = false;
Mike Fiore 1:e52ae6584f1c 574 bool query = false;
Mike Fiore 1:e52ae6584f1c 575
Mike Fiore 1:e52ae6584f1c 576 std::string lookfor = args[0];
Mike Fiore 1:e52ae6584f1c 577
Mike Fiore 1:e52ae6584f1c 578 // per command help
Mike Fiore 1:e52ae6584f1c 579 if ((args[0].find("?") == 0 || args[0].find("HELP") == 0))
Mike Fiore 1:e52ae6584f1c 580 lookfor = mts::Text::toUpper(args[1]);
Mike Fiore 1:e52ae6584f1c 581
Mike Fiore 1:e52ae6584f1c 582 // trim off any trailing '?' and mark as a query command
Mike Fiore 1:e52ae6584f1c 583 if (args[0].rfind("?") == args[0].length() - 1) {
Mike Fiore 1:e52ae6584f1c 584 query = true;
Mike Fiore 1:e52ae6584f1c 585 lookfor = args[0].substr(0, args[0].length() - 1);
Mike Fiore 1:e52ae6584f1c 586 }
Mike Fiore 1:e52ae6584f1c 587
Mike Fiore 1:e52ae6584f1c 588 // search for command
Mike Fiore 1:e52ae6584f1c 589 for (std::vector<Command*>::iterator it = _commands.begin(); it != _commands.end() && !found; ++it) {
Mike Fiore 1:e52ae6584f1c 590 Command* cmd = *it;
Mike Fiore 1:e52ae6584f1c 591
Mike Fiore 1:e52ae6584f1c 592 // match CMD or CMD? syntax if command is queryable
Mike Fiore 1:e52ae6584f1c 593 if (lookfor == cmd->text() && (!query || (query && cmd->queryable()))) {
Mike Fiore 1:e52ae6584f1c 594 found = true;
Mike Fiore 1:e52ae6584f1c 595 if (args[0] == "HELP") {
Mike Fiore 1:e52ae6584f1c 596 writef("%s%s", cmd->help(), newline);
Mike Fiore 1:e52ae6584f1c 597 write(done);
Mike Fiore 1:e52ae6584f1c 598 }
Mike Fiore 1:e52ae6584f1c 599
Mike Fiore 1:e52ae6584f1c 600 else if (args.size() > 1 && args[1] == "?") {
Mike Fiore 1:e52ae6584f1c 601 writef("%s%s", cmd->usage().c_str(), newline);
Mike Fiore 1:e52ae6584f1c 602 write(done);
Mike Fiore 1:e52ae6584f1c 603 } else if (!cmd->verify(args)) {
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 } else {
Mike Fiore 1:e52ae6584f1c 607 if (cmd->action(args) == 0) {
Mike Fiore 1:e52ae6584f1c 608 writef("%s", done);
Mike Fiore 1:e52ae6584f1c 609 } else {
Mike Fiore 1:e52ae6584f1c 610 writef("%s%s", cmd->errorMessage().c_str(), newline);
Mike Fiore 1:e52ae6584f1c 611 writef("%s", error);
Mike Fiore 1:e52ae6584f1c 612 }
Mike Fiore 1:e52ae6584f1c 613 }
Mike Fiore 1:e52ae6584f1c 614 }
Mike Fiore 1:e52ae6584f1c 615 }
Mike Fiore 1:e52ae6584f1c 616
Mike Fiore 1:e52ae6584f1c 617 if (!found) {
Mike Fiore 1:e52ae6584f1c 618 writef("%s", command_error);
Mike Fiore 1:e52ae6584f1c 619 writef("%s", error);
Mike Fiore 1:e52ae6584f1c 620 }
Mike Fiore 1:e52ae6584f1c 621 }
Mike Fiore 1:e52ae6584f1c 622
Mike Fiore 4:666017851052 623 if (history.size() == 0 || history.front() != command)
Mike Fiore 4:666017851052 624 history.push_front(command);
Mike Fiore 4:666017851052 625 history_index = -1;
Mike Fiore 1:e52ae6584f1c 626 command.clear();
Mike Fiore 1:e52ae6584f1c 627
Mike Fiore 4:666017851052 628 while (history.size() > 10)
Mike Fiore 4:666017851052 629 history.pop_back();
Mike Fiore 1:e52ae6584f1c 630 }
Mike Fiore 1:e52ae6584f1c 631 }
Mike Fiore 1:e52ae6584f1c 632
Mike Fiore 1:e52ae6584f1c 633 std::string CommandTerminal::formatPacketData(const std::vector<uint8_t>& data, const uint8_t& format) {
Mike Fiore 2:e5eebd74d36d 634 if (format == mDot::HEXADECIMAL)
Mike Fiore 1:e52ae6584f1c 635 return mts::Text::bin2hexString(data);
Mike Fiore 2:e5eebd74d36d 636 else
Mike Fiore 2:e5eebd74d36d 637 return std::string(data.begin(), data.end());
Mike Fiore 1:e52ae6584f1c 638 }
Mike Fiore 1:e52ae6584f1c 639
Mike Fiore 1:e52ae6584f1c 640 void CommandTerminal::sleep(bool standby) {
Mike Fiore 1:e52ae6584f1c 641 _serial_up = false;
Mike Fiore 1:e52ae6584f1c 642 _xbee_on_sleep = GPIO_PIN_RESET;
Mike Fiore 1:e52ae6584f1c 643
Mike Fiore 4:666017851052 644 _serial.rxClear();
Mike Fiore 4:666017851052 645 _serial.txClear();
Mike Fiore 1:e52ae6584f1c 646
Mike Fiore 4:666017851052 647 _dot->sleep(_dot->getWakeInterval(), _dot->getWakeMode(), standby);
Mike Fiore 1:e52ae6584f1c 648 }
Mike Fiore 1:e52ae6584f1c 649
Mike Fiore 1:e52ae6584f1c 650 bool CommandTerminal::waitForEscape(int timeout, mDot* dot, WaitType wait) {
Mike Fiore 1:e52ae6584f1c 651 Timer timer;
Mike Fiore 1:e52ae6584f1c 652 Timer escape_timer;
Mike Fiore 1:e52ae6584f1c 653 std::string escape_buffer;
Mike Fiore 1:e52ae6584f1c 654 int escape_timeout = 1000;
Mike Fiore 1:e52ae6584f1c 655
Mike Fiore 1:e52ae6584f1c 656 timer.start();
Mike Fiore 1:e52ae6584f1c 657 while (timer.read_ms() < timeout) {
Mike Fiore 1:e52ae6584f1c 658
Mike Fiore 1:e52ae6584f1c 659 if (dot != NULL) {
Mike Fiore 1:e52ae6584f1c 660 if (wait == WAIT_SEND && (!dot->getIsTransmitting())) {
Mike Fiore 1:e52ae6584f1c 661 return false;
Mike Fiore 1:e52ae6584f1c 662 }
Mike Fiore 1:e52ae6584f1c 663 }
Mike Fiore 1:e52ae6584f1c 664
Mike Fiore 1:e52ae6584f1c 665 if (_serialp != NULL && _serialp->readable()) {
Mike Fiore 1:e52ae6584f1c 666 if (escape_buffer == "")
Mike Fiore 1:e52ae6584f1c 667 escape_timer.start();
Mike Fiore 1:e52ae6584f1c 668 char ch;
Mike Fiore 1:e52ae6584f1c 669 _serialp->read(&ch, 1);
Mike Fiore 1:e52ae6584f1c 670 escape_buffer += ch;
Mike Fiore 1:e52ae6584f1c 671 if (escape_buffer == CommandTerminal::escape_sequence)
Mike Fiore 1:e52ae6584f1c 672 return true;
Mike Fiore 1:e52ae6584f1c 673 }
Mike Fiore 1:e52ae6584f1c 674 if (escape_timer.read_ms() > escape_timeout) {
Mike Fiore 1:e52ae6584f1c 675 escape_buffer = "";
Mike Fiore 1:e52ae6584f1c 676 escape_timer.stop(), escape_timer.reset();
Mike Fiore 1:e52ae6584f1c 677 }
Mike Fiore 1:e52ae6584f1c 678
Mike Fiore 1:e52ae6584f1c 679 osDelay(10);
Mike Fiore 1:e52ae6584f1c 680 }
Mike Fiore 1:e52ae6584f1c 681
Mike Fiore 1:e52ae6584f1c 682 return false;
Mike Fiore 1:e52ae6584f1c 683 }
Mike Fiore 1:e52ae6584f1c 684
Mike Fiore 1:e52ae6584f1c 685 void CommandTerminal::wakeup(bool standby) {
Mike Fiore 1:e52ae6584f1c 686
Mike Fiore 1:e52ae6584f1c 687 }