MTDOT-BOX-EVB-Factory-Firmware

Dependencies:   NCP5623B GpsParser ISL29011 libmDot-mbed5 MTS-Serial MMA845x DOGS102 MPL3115A2

Committer:
Mike Fiore
Date:
Thu Feb 04 12:36:36 2016 -0600
Revision:
1:71125aa00e33
Child:
7:a31236c2e75c
add rest of source - version 2.0.0

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Mike Fiore 1:71125aa00e33 1 /* Copyright (c) <2016> <MultiTech Systems>, MIT License
Mike Fiore 1:71125aa00e33 2 *
Mike Fiore 1:71125aa00e33 3 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
Mike Fiore 1:71125aa00e33 4 * and associated documentation files (the "Software"), to deal in the Software without restriction,
Mike Fiore 1:71125aa00e33 5 * including without limitation the rights to use, copy, modify, merge, publish, distribute,
Mike Fiore 1:71125aa00e33 6 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
Mike Fiore 1:71125aa00e33 7 * furnished to do so, subject to the following conditions:
Mike Fiore 1:71125aa00e33 8 *
Mike Fiore 1:71125aa00e33 9 * The above copyright notice and this permission notice shall be included in all copies or
Mike Fiore 1:71125aa00e33 10 * substantial portions of the Software.
Mike Fiore 1:71125aa00e33 11 *
Mike Fiore 1:71125aa00e33 12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
Mike Fiore 1:71125aa00e33 13 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
Mike Fiore 1:71125aa00e33 14 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
Mike Fiore 1:71125aa00e33 15 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
Mike Fiore 1:71125aa00e33 16 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Mike Fiore 1:71125aa00e33 17 */
Mike Fiore 1:71125aa00e33 18
Mike Fiore 1:71125aa00e33 19 #include "ModeConfig.h"
Mike Fiore 1:71125aa00e33 20 #include "ctype.h"
Mike Fiore 1:71125aa00e33 21 #include "Command.h"
Mike Fiore 1:71125aa00e33 22 #include "ButtonHandler.h"
Mike Fiore 1:71125aa00e33 23 #include <cstdarg>
Mike Fiore 1:71125aa00e33 24 #include <deque>
Mike Fiore 1:71125aa00e33 25
Mike Fiore 1:71125aa00e33 26 const char ModeConfig::newline[] = "\r\n";
Mike Fiore 1:71125aa00e33 27
Mike Fiore 1:71125aa00e33 28 // Command error text...
Mike Fiore 1:71125aa00e33 29 const char ModeConfig::command_error[] = "Command not found!\r\n";
Mike Fiore 1:71125aa00e33 30
Mike Fiore 1:71125aa00e33 31 // Response texts...
Mike Fiore 1:71125aa00e33 32 const char ModeConfig::done[] = "\r\nOK\r\n";
Mike Fiore 1:71125aa00e33 33 const char ModeConfig::error[] = "\r\nERROR\r\n";
Mike Fiore 1:71125aa00e33 34
Mike Fiore 1:71125aa00e33 35 void ModeConfig::addCommand(Command* cmd) {
Mike Fiore 1:71125aa00e33 36 _commands.push_back(cmd);
Mike Fiore 1:71125aa00e33 37 }
Mike Fiore 1:71125aa00e33 38
Mike Fiore 1:71125aa00e33 39 ModeConfig::ModeConfig(DOGS102* lcd, ButtonHandler* buttons, mDot* dot, LoRaHandler* lora, GPSPARSER* gps, SensorHandler* sensors)
Mike Fiore 1:71125aa00e33 40 : Mode(lcd, buttons, dot, lora, gps, sensors),
Mike Fiore 1:71125aa00e33 41 _lc(lcd),
Mike Fiore 1:71125aa00e33 42 _serial(USBTX, USBRX, 512, 512)
Mike Fiore 1:71125aa00e33 43 {
Mike Fiore 1:71125aa00e33 44 _serial.baud(115200);
Mike Fiore 1:71125aa00e33 45
Mike Fiore 1:71125aa00e33 46 addCommand(new CmdAttention(_dot));
Mike Fiore 1:71125aa00e33 47 addCommand(new CmdIdentification(_dot, _serial));
Mike Fiore 1:71125aa00e33 48 addCommand(new CmdFactoryDefault(_dot));
Mike Fiore 1:71125aa00e33 49 addCommand(new CmdSaveConfig(_dot));
Mike Fiore 1:71125aa00e33 50 addCommand(new CmdDisplayConfig(_dot, _serial));
Mike Fiore 1:71125aa00e33 51
Mike Fiore 1:71125aa00e33 52 addCommand(new CmdFrequencyBand(_dot, _serial));
Mike Fiore 1:71125aa00e33 53 addCommand(new CmdFrequencySubBand(_dot, _serial));
Mike Fiore 1:71125aa00e33 54 addCommand(new CmdPublicNetwork(_dot, _serial));
Mike Fiore 1:71125aa00e33 55 addCommand(new CmdDeviceId(_dot, _serial));
Mike Fiore 1:71125aa00e33 56
Mike Fiore 1:71125aa00e33 57 addCommand(new CmdNetworkAddress(_dot, _serial));
Mike Fiore 1:71125aa00e33 58 addCommand(new CmdNetworkSessionKey(_dot, _serial));
Mike Fiore 1:71125aa00e33 59 addCommand(new CmdDataSessionKey(_dot, _serial));
Mike Fiore 1:71125aa00e33 60 addCommand(new CmdNetworkKey(_dot, _serial));
Mike Fiore 1:71125aa00e33 61 addCommand(new CmdNetworkId(_dot, _serial));
Mike Fiore 1:71125aa00e33 62
Mike Fiore 1:71125aa00e33 63 addCommand(new CmdNetworkJoinMode(_dot, _serial));
Mike Fiore 1:71125aa00e33 64 addCommand(new CmdTxDataRate(_dot, _serial));
Mike Fiore 1:71125aa00e33 65 addCommand(new CmdTxPower(_dot, _serial));
Mike Fiore 1:71125aa00e33 66
Mike Fiore 1:71125aa00e33 67 addCommand(new CmdMinimumSize(_dot, _serial));
Mike Fiore 1:71125aa00e33 68 addCommand(new CmdMaximumSize(_dot, _serial));
Mike Fiore 1:71125aa00e33 69 addCommand(new CmdMinimumPower(_dot, _serial));
Mike Fiore 1:71125aa00e33 70 addCommand(new CmdMaximumPower(_dot, _serial));
Mike Fiore 1:71125aa00e33 71 addCommand(new CmdData(_dot, _serial));
Mike Fiore 1:71125aa00e33 72 addCommand(new CmdGetSurveyDataFile(_dot, _serial));
Mike Fiore 1:71125aa00e33 73 addCommand(new CmdDeleteSurveyDataFile(_dot, _serial));
Mike Fiore 1:71125aa00e33 74 addCommand(new CmdDummy(_dot, "Exit to main menu", "AT+EXIT", "Exit configuration and return to the main menu"));
Mike Fiore 1:71125aa00e33 75
Mike Fiore 1:71125aa00e33 76 #if MTS_RADIO_DEBUG_COMMANDS
Mike Fiore 1:71125aa00e33 77 addCommand(new CmdWriteProtectedConfig(_dot));
Mike Fiore 1:71125aa00e33 78 #endif
Mike Fiore 1:71125aa00e33 79 }
Mike Fiore 1:71125aa00e33 80
Mike Fiore 1:71125aa00e33 81 void ModeConfig::printHelp() {
Mike Fiore 1:71125aa00e33 82 const char* name = NULL;
Mike Fiore 1:71125aa00e33 83 const char* text = NULL;
Mike Fiore 1:71125aa00e33 84 const char* desc = NULL;
Mike Fiore 1:71125aa00e33 85 const char* tab = "\t";
Mike Fiore 1:71125aa00e33 86
Mike Fiore 1:71125aa00e33 87 std::string header("Command");
Mike Fiore 1:71125aa00e33 88 header.append(tab);
Mike Fiore 1:71125aa00e33 89 header.append(tab);
Mike Fiore 1:71125aa00e33 90 header.append("Name");
Mike Fiore 1:71125aa00e33 91 header.append(tab);
Mike Fiore 1:71125aa00e33 92 header.append(tab);
Mike Fiore 1:71125aa00e33 93 header.append(tab);
Mike Fiore 1:71125aa00e33 94 header.append("Description");
Mike Fiore 1:71125aa00e33 95
Mike Fiore 1:71125aa00e33 96 write(newline);
Mike Fiore 1:71125aa00e33 97 write(header.c_str());
Mike Fiore 1:71125aa00e33 98 write(newline);
Mike Fiore 1:71125aa00e33 99 write(newline);
Mike Fiore 1:71125aa00e33 100 for (std::vector<Command*>::iterator it = _commands.begin(); it != _commands.end(); ++it) {
Mike Fiore 1:71125aa00e33 101 name = (*it)->name();
Mike Fiore 1:71125aa00e33 102 text = (*it)->text();
Mike Fiore 1:71125aa00e33 103 desc = (*it)->desc();
Mike Fiore 1:71125aa00e33 104 write(text);
Mike Fiore 1:71125aa00e33 105 if (strlen(text) < 8)
Mike Fiore 1:71125aa00e33 106 write(tab);
Mike Fiore 1:71125aa00e33 107 write(tab);
Mike Fiore 1:71125aa00e33 108 write(name);
Mike Fiore 1:71125aa00e33 109 if (strlen(name) < 8)
Mike Fiore 1:71125aa00e33 110 write(tab);
Mike Fiore 1:71125aa00e33 111 if (strlen(name) < 16)
Mike Fiore 1:71125aa00e33 112 write(tab);
Mike Fiore 1:71125aa00e33 113 write(tab);
Mike Fiore 1:71125aa00e33 114 write(desc);
Mike Fiore 1:71125aa00e33 115 write(newline);
Mike Fiore 1:71125aa00e33 116 }
Mike Fiore 1:71125aa00e33 117
Mike Fiore 1:71125aa00e33 118 write(newline);
Mike Fiore 1:71125aa00e33 119 }
Mike Fiore 1:71125aa00e33 120
Mike Fiore 1:71125aa00e33 121 bool ModeConfig::writeable() {
Mike Fiore 1:71125aa00e33 122 return _serial.writeable();
Mike Fiore 1:71125aa00e33 123 }
Mike Fiore 1:71125aa00e33 124
Mike Fiore 1:71125aa00e33 125 bool ModeConfig::readable() {
Mike Fiore 1:71125aa00e33 126 return _serial.readable();
Mike Fiore 1:71125aa00e33 127 }
Mike Fiore 1:71125aa00e33 128
Mike Fiore 1:71125aa00e33 129 char ModeConfig::read() {
Mike Fiore 1:71125aa00e33 130 char ch;
Mike Fiore 1:71125aa00e33 131 _serial.read(&ch, 1);
Mike Fiore 1:71125aa00e33 132 return ch;
Mike Fiore 1:71125aa00e33 133 }
Mike Fiore 1:71125aa00e33 134
Mike Fiore 1:71125aa00e33 135 void ModeConfig::write(const char* message) {
Mike Fiore 1:71125aa00e33 136 while (!writeable())
Mike Fiore 1:71125aa00e33 137 ;
Mike Fiore 1:71125aa00e33 138 _serial.write(message, strlen(message));
Mike Fiore 1:71125aa00e33 139 }
Mike Fiore 1:71125aa00e33 140
Mike Fiore 1:71125aa00e33 141 void ModeConfig::writef(const char* format, ...) {
Mike Fiore 1:71125aa00e33 142 char buff[256];
Mike Fiore 1:71125aa00e33 143
Mike Fiore 1:71125aa00e33 144 va_list ap;
Mike Fiore 1:71125aa00e33 145 va_start(ap, format);
Mike Fiore 1:71125aa00e33 146 int size = vsnprintf(buff, 256, format, ap);
Mike Fiore 1:71125aa00e33 147 while (!writeable())
Mike Fiore 1:71125aa00e33 148 ;
Mike Fiore 1:71125aa00e33 149 _serial.write(buff, size);
Mike Fiore 1:71125aa00e33 150 va_end(ap);
Mike Fiore 1:71125aa00e33 151 }
Mike Fiore 1:71125aa00e33 152
Mike Fiore 1:71125aa00e33 153 bool ModeConfig::start() {
Mike Fiore 1:71125aa00e33 154 char ch;
Mike Fiore 1:71125aa00e33 155 bool running = true;
Mike Fiore 1:71125aa00e33 156 bool echo = _dot->getEcho();
Mike Fiore 1:71125aa00e33 157 std::string command;
Mike Fiore 1:71125aa00e33 158 std::deque<std::string> history;
Mike Fiore 1:71125aa00e33 159 int history_index = -1;
Mike Fiore 1:71125aa00e33 160 std::vector<std::string> args;
Mike Fiore 1:71125aa00e33 161
Mike Fiore 1:71125aa00e33 162 osSignalClear(_main_id, buttonSignal);
Mike Fiore 1:71125aa00e33 163
Mike Fiore 1:71125aa00e33 164 _lc.display();
Mike Fiore 1:71125aa00e33 165
Mike Fiore 1:71125aa00e33 166 //Run terminal session
Mike Fiore 1:71125aa00e33 167 while (running) {
Mike Fiore 1:71125aa00e33 168 _lc.roll();
Mike Fiore 1:71125aa00e33 169
Mike Fiore 1:71125aa00e33 170 osEvent e = Thread::signal_wait(buttonSignal, 20);
Mike Fiore 1:71125aa00e33 171 if (e.status == osEventSignal) {
Mike Fiore 1:71125aa00e33 172 ButtonHandler::ButtonEvent _be = _buttons->getButtonEvent();
Mike Fiore 1:71125aa00e33 173 switch (_be) {
Mike Fiore 1:71125aa00e33 174 case ButtonHandler::sw1_press:
Mike Fiore 1:71125aa00e33 175 break;
Mike Fiore 1:71125aa00e33 176 case ButtonHandler::sw2_press:
Mike Fiore 1:71125aa00e33 177 break;
Mike Fiore 1:71125aa00e33 178 case ButtonHandler::sw1_hold:
Mike Fiore 1:71125aa00e33 179 return true;
Mike Fiore 1:71125aa00e33 180 default:
Mike Fiore 1:71125aa00e33 181 break;
Mike Fiore 1:71125aa00e33 182 }
Mike Fiore 1:71125aa00e33 183 }
Mike Fiore 1:71125aa00e33 184
Mike Fiore 1:71125aa00e33 185 ch = '\0';
Mike Fiore 1:71125aa00e33 186
Mike Fiore 1:71125aa00e33 187 // read characters
Mike Fiore 1:71125aa00e33 188 if (readable()) {
Mike Fiore 1:71125aa00e33 189 ch = read();
Mike Fiore 1:71125aa00e33 190
Mike Fiore 1:71125aa00e33 191 if (ch == '\b' || ch == 0x7f) {
Mike Fiore 1:71125aa00e33 192 if (!command.empty()) {
Mike Fiore 1:71125aa00e33 193 writef("\b \b");
Mike Fiore 1:71125aa00e33 194 command.erase(command.size() - 1);
Mike Fiore 1:71125aa00e33 195 }
Mike Fiore 1:71125aa00e33 196 continue;
Mike Fiore 1:71125aa00e33 197 } else if (ch == 0x1b || ch == 0x09) {
Mike Fiore 1:71125aa00e33 198 osDelay(20);
Mike Fiore 1:71125aa00e33 199 // catch escape sequence, or tab
Mike Fiore 1:71125aa00e33 200 char ch1, ch2;
Mike Fiore 1:71125aa00e33 201
Mike Fiore 1:71125aa00e33 202 if (readable()) {
Mike Fiore 1:71125aa00e33 203 ch1 = read();
Mike Fiore 1:71125aa00e33 204 if (readable())
Mike Fiore 1:71125aa00e33 205 ch2 = read();
Mike Fiore 1:71125aa00e33 206
Mike Fiore 1:71125aa00e33 207 if (ch1 == 0x5b && ch2 == 0x41) {
Mike Fiore 1:71125aa00e33 208 // up key
Mike Fiore 1:71125aa00e33 209 for (int i = 0; i < command.size()+1; i++) {
Mike Fiore 1:71125aa00e33 210 writef("\b \b");
Mike Fiore 1:71125aa00e33 211 }
Mike Fiore 1:71125aa00e33 212 if (history.size() > 0) {
Mike Fiore 1:71125aa00e33 213 if (++history_index >= history.size() - 1)
Mike Fiore 1:71125aa00e33 214 history_index = history.size() - 1;
Mike Fiore 1:71125aa00e33 215
Mike Fiore 1:71125aa00e33 216 command = history[history_index];
Mike Fiore 1:71125aa00e33 217 writef("%s", history[history_index].c_str());
Mike Fiore 1:71125aa00e33 218 } else {
Mike Fiore 1:71125aa00e33 219 command.clear();
Mike Fiore 1:71125aa00e33 220 }
Mike Fiore 1:71125aa00e33 221 } else if (ch1 == 0x5b && ch2 == 0x42) {
Mike Fiore 1:71125aa00e33 222
Mike Fiore 1:71125aa00e33 223 // down key
Mike Fiore 1:71125aa00e33 224 for (int i = 0; i < command.size()+1; i++) {
Mike Fiore 1:71125aa00e33 225 writef("\b \b");
Mike Fiore 1:71125aa00e33 226 }
Mike Fiore 1:71125aa00e33 227
Mike Fiore 1:71125aa00e33 228 if (--history_index < 0) {
Mike Fiore 1:71125aa00e33 229 history_index = -1;
Mike Fiore 1:71125aa00e33 230 command.clear();
Mike Fiore 1:71125aa00e33 231 } else {
Mike Fiore 1:71125aa00e33 232 command = history[history_index];
Mike Fiore 1:71125aa00e33 233 writef("%s", history[history_index].c_str());
Mike Fiore 1:71125aa00e33 234 }
Mike Fiore 1:71125aa00e33 235 }
Mike Fiore 1:71125aa00e33 236 }
Mike Fiore 1:71125aa00e33 237 while (readable()) read();
Mike Fiore 1:71125aa00e33 238 continue;
Mike Fiore 1:71125aa00e33 239 } else {
Mike Fiore 1:71125aa00e33 240 command += ch;
Mike Fiore 1:71125aa00e33 241 }
Mike Fiore 1:71125aa00e33 242
Mike Fiore 1:71125aa00e33 243 // echo chars if enabled
Mike Fiore 1:71125aa00e33 244 if (echo && !(ch == '\r' || ch == '\n'))
Mike Fiore 1:71125aa00e33 245 writef("%c", ch);
Mike Fiore 1:71125aa00e33 246 }
Mike Fiore 1:71125aa00e33 247
Mike Fiore 1:71125aa00e33 248 // look for end of command line
Mike Fiore 1:71125aa00e33 249 if (command.find("\n") != std::string::npos || command.find("\r") != std::string::npos) {
Mike Fiore 1:71125aa00e33 250 // remove new line or cr character
Mike Fiore 1:71125aa00e33 251 command.erase(command.size() - 1);
Mike Fiore 1:71125aa00e33 252 write("\r"); // match standard modem output
Mike Fiore 1:71125aa00e33 253 write(newline);
Mike Fiore 1:71125aa00e33 254 } else {
Mike Fiore 1:71125aa00e33 255 continue;
Mike Fiore 1:71125aa00e33 256 }
Mike Fiore 1:71125aa00e33 257
Mike Fiore 1:71125aa00e33 258 // trim whitespace from command
Mike Fiore 1:71125aa00e33 259 mts::Text::trim(command, "\r\n\t ");
Mike Fiore 1:71125aa00e33 260
Mike Fiore 1:71125aa00e33 261 if (command.size() < 1) {
Mike Fiore 1:71125aa00e33 262 command.clear();
Mike Fiore 1:71125aa00e33 263 continue;
Mike Fiore 1:71125aa00e33 264 }
Mike Fiore 1:71125aa00e33 265
Mike Fiore 1:71125aa00e33 266 // parse command and args
Mike Fiore 1:71125aa00e33 267 args.clear();
Mike Fiore 1:71125aa00e33 268
Mike Fiore 1:71125aa00e33 269 // find first '=' character
Mike Fiore 1:71125aa00e33 270 size_t delim_index = command.find("=");
Mike Fiore 1:71125aa00e33 271 if (delim_index != std::string::npos) {
Mike Fiore 1:71125aa00e33 272 args.push_back(command.substr(0, delim_index));
Mike Fiore 1:71125aa00e33 273 } else {
Mike Fiore 1:71125aa00e33 274 // find first ' ' character
Mike Fiore 1:71125aa00e33 275 delim_index = command.find(" ");
Mike Fiore 1:71125aa00e33 276 if (delim_index != std::string::npos) {
Mike Fiore 1:71125aa00e33 277 args.push_back(command.substr(0, delim_index));
Mike Fiore 1:71125aa00e33 278 } else {
Mike Fiore 1:71125aa00e33 279 args.push_back(command);
Mike Fiore 1:71125aa00e33 280 }
Mike Fiore 1:71125aa00e33 281 }
Mike Fiore 1:71125aa00e33 282
Mike Fiore 1:71125aa00e33 283 if (delim_index != std::string::npos) {
Mike Fiore 1:71125aa00e33 284 std::vector<std::string> params = mts::Text::split(command.substr(delim_index + 1), ",");
Mike Fiore 1:71125aa00e33 285 args.insert(args.end(), params.begin(), params.end());
Mike Fiore 1:71125aa00e33 286 }
Mike Fiore 1:71125aa00e33 287
Mike Fiore 1:71125aa00e33 288 args[0] = mts::Text::toUpper(args[0]);
Mike Fiore 1:71125aa00e33 289
Mike Fiore 1:71125aa00e33 290 // print help
Mike Fiore 1:71125aa00e33 291 if ((args[0].find("?") == 0 || args[0].find("HELP") == 0) && args.size() == 1) {
Mike Fiore 1:71125aa00e33 292 printHelp();
Mike Fiore 1:71125aa00e33 293 command.clear();
Mike Fiore 1:71125aa00e33 294 } else if (args[0].find("AT+EXIT") == 0 && args[0].length() == 7) {
Mike Fiore 1:71125aa00e33 295 write(done);
Mike Fiore 1:71125aa00e33 296 return true;
Mike Fiore 1:71125aa00e33 297 } else {
Mike Fiore 1:71125aa00e33 298 bool found = false;
Mike Fiore 1:71125aa00e33 299 bool query = false;
Mike Fiore 1:71125aa00e33 300
Mike Fiore 1:71125aa00e33 301 std::string lookfor = args[0];
Mike Fiore 1:71125aa00e33 302
Mike Fiore 1:71125aa00e33 303 // per command help
Mike Fiore 1:71125aa00e33 304 if ((args[0].find("?") == 0 || args[0].find("HELP") == 0))
Mike Fiore 1:71125aa00e33 305 lookfor = mts::Text::toUpper(args[1]);
Mike Fiore 1:71125aa00e33 306
Mike Fiore 1:71125aa00e33 307 // trim off any trailing '?' and mark as a query command
Mike Fiore 1:71125aa00e33 308 if (args[0].rfind("?") == args[0].length() - 1) {
Mike Fiore 1:71125aa00e33 309 query = true;
Mike Fiore 1:71125aa00e33 310 lookfor = args[0].substr(0, args[0].length() - 1);
Mike Fiore 1:71125aa00e33 311 }
Mike Fiore 1:71125aa00e33 312
Mike Fiore 1:71125aa00e33 313 // search for command
Mike Fiore 1:71125aa00e33 314 for (std::vector<Command*>::iterator it = _commands.begin(); it != _commands.end() && !found; ++it) {
Mike Fiore 1:71125aa00e33 315 Command* cmd = *it;
Mike Fiore 1:71125aa00e33 316
Mike Fiore 1:71125aa00e33 317 // match CMD or CMD? syntax if command is queryable
Mike Fiore 1:71125aa00e33 318 if (lookfor == cmd->text() && (!query || (query && cmd->queryable()))) {
Mike Fiore 1:71125aa00e33 319 found = true;
Mike Fiore 1:71125aa00e33 320 if (args[0] == "HELP") {
Mike Fiore 1:71125aa00e33 321 writef("%s%s", cmd->help(), newline);
Mike Fiore 1:71125aa00e33 322 write(done);
Mike Fiore 1:71125aa00e33 323 }
Mike Fiore 1:71125aa00e33 324
Mike Fiore 1:71125aa00e33 325 else if (args.size() > 1 && args[1] == "?") {
Mike Fiore 1:71125aa00e33 326 writef("%s%s", cmd->usage().c_str(), newline);
Mike Fiore 1:71125aa00e33 327 write(done);
Mike Fiore 1:71125aa00e33 328 } else if (!cmd->verify(args)) {
Mike Fiore 1:71125aa00e33 329 writef("%s%s", cmd->errorMessage().c_str(), newline);
Mike Fiore 1:71125aa00e33 330 writef("%s", error);
Mike Fiore 1:71125aa00e33 331 } else {
Mike Fiore 1:71125aa00e33 332 if (cmd->action(args) == 0) {
Mike Fiore 1:71125aa00e33 333 writef("%s", done);
Mike Fiore 1:71125aa00e33 334 } else {
Mike Fiore 1:71125aa00e33 335 writef("%s%s", cmd->errorMessage().c_str(), newline);
Mike Fiore 1:71125aa00e33 336 writef("%s", error);
Mike Fiore 1:71125aa00e33 337 }
Mike Fiore 1:71125aa00e33 338 }
Mike Fiore 1:71125aa00e33 339 }
Mike Fiore 1:71125aa00e33 340 }
Mike Fiore 1:71125aa00e33 341
Mike Fiore 1:71125aa00e33 342 if (!found) {
Mike Fiore 1:71125aa00e33 343 writef("%s", command_error);
Mike Fiore 1:71125aa00e33 344 writef("%s", error);
Mike Fiore 1:71125aa00e33 345 }
Mike Fiore 1:71125aa00e33 346 }
Mike Fiore 1:71125aa00e33 347
Mike Fiore 1:71125aa00e33 348 if (history.size() == 0 || history.front() != command)
Mike Fiore 1:71125aa00e33 349 history.push_front(command);
Mike Fiore 1:71125aa00e33 350 history_index = -1;
Mike Fiore 1:71125aa00e33 351 command.clear();
Mike Fiore 1:71125aa00e33 352
Mike Fiore 1:71125aa00e33 353 while (history.size() > 10)
Mike Fiore 1:71125aa00e33 354 history.pop_back();
Mike Fiore 1:71125aa00e33 355
Mike Fiore 1:71125aa00e33 356 }
Mike Fiore 1:71125aa00e33 357 return false;
Mike Fiore 1:71125aa00e33 358 }