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:
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?

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 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 }