diff options
author | Leon Lindenfelser <llindenfelser@multitech.com> | 2015-11-20 16:21:44 -0600 |
---|---|---|
committer | Leon Lindenfelser <llindenfelser@multitech.com> | 2015-11-20 16:21:44 -0600 |
commit | 4ea46cbfee73c43579ea657cabc7f1fc7de97874 (patch) | |
tree | 96c7451f54600d847e7d0231090bb79d02f0ac50 /Mode | |
parent | 393317f7d04753d6e9773393a96c311a88a27f7b (diff) | |
download | mtdot-box-evb-factory-firmware-4ea46cbfee73c43579ea657cabc7f1fc7de97874.tar.gz mtdot-box-evb-factory-firmware-4ea46cbfee73c43579ea657cabc7f1fc7de97874.tar.bz2 mtdot-box-evb-factory-firmware-4ea46cbfee73c43579ea657cabc7f1fc7de97874.zip |
1. Merged CommandTerminal into ModeConfig and deleted CommandTerminal.
2. Fixed AT&V output.
3. Cleaned up some unused code.
4. Added +FREQ back in.
5. Removed CmdExit and put the +EXIT command right in the command parsing code.
Diffstat (limited to 'Mode')
-rw-r--r-- | Mode/ModeConfig.cpp | 346 | ||||
-rw-r--r-- | Mode/ModeConfig.h | 58 |
2 files changed, 380 insertions, 24 deletions
diff --git a/Mode/ModeConfig.cpp b/Mode/ModeConfig.cpp index 523c5ce..2d24716 100644 --- a/Mode/ModeConfig.cpp +++ b/Mode/ModeConfig.cpp @@ -1,25 +1,343 @@ #include "ModeConfig.h" +#include "ctype.h" +#include "Command.h" #include "MTSLog.h" -#include "MTSText.h" -#include "CommandTerminal.h" +#include "ButtonHandler.h" +#include <cstdarg> +#include <deque> -ModeConfig::ModeConfig(DOGS102* lcd, ButtonHandler* buttons, mDot* dot) - : Mode(lcd, buttons), - _lc(lcd), - _dot(dot) -{} +const char ModeConfig::newline[] = "\r\n"; -ModeConfig::~ModeConfig() {} +// Command error text... +const char ModeConfig::command_error[] = "Command not found!\r\n"; + +// Response texts... +const char ModeConfig::done[] = "\r\nOK\r\n"; +const char ModeConfig::error[] = "\r\nERROR\r\n"; + +mts::MTSSerial* ModeConfig::_serialp = NULL; + +void ModeConfig::addCommand(Command* cmd) { + _commands.push_back(cmd); +} + +ModeConfig::ModeConfig(DOGS102* lcd, mts::MTSSerial& serial, mDot* dot, ButtonHandler* buttons) +: Mode(lcd, buttons), + _lc(lcd), + _serial(serial), + _dot(dot), + _mode(mDot::COMMAND_MODE), + _idle_thread(idle, NULL, osPriorityLow), + _serial_up(false), + _buttons(buttons) { + + _serialp = &serial; + + addCommand(new CmdAttention(_dot)); + addCommand(new CmdIdentification(_dot, serial)); + addCommand(new CmdFactoryDefault(_dot)); + addCommand(new CmdSaveConfig(_dot)); + addCommand(new CmdDisplayConfig(_dot, serial)); + + addCommand(new CmdFrequencyBand(_dot, serial)); + addCommand(new CmdFrequencySubBand(_dot, serial)); + addCommand(new CmdPublicNetwork(_dot, serial)); + addCommand(new CmdDeviceId(_dot, serial)); + + addCommand(new CmdNetworkAddress(_dot, serial)); + addCommand(new CmdNetworkSessionKey(_dot, serial)); + addCommand(new CmdDataSessionKey(_dot, serial)); + addCommand(new CmdNetworkKey(_dot, serial)); + addCommand(new CmdNetworkId(_dot, serial)); + + addCommand(new CmdNetworkJoinMode(_dot, serial)); + addCommand(new CmdTxDataRate(_dot, serial)); + addCommand(new CmdTxPower(_dot, serial)); + + addCommand(new CmdMinimumSize(_dot, serial)); + addCommand(new CmdMaximumSize(_dot, serial)); + addCommand(new CmdMinimumPower(_dot, serial)); + addCommand(new CmdMaximumPower(_dot, serial)); + addCommand(new CmdData(_dot, serial)); + addCommand(new CmdGetSurveyDataFile(_dot, serial)); + addCommand(new CmdDeleteSurveyDataFile(_dot, serial)); + +} + +void ModeConfig::printHelp() { + const char* name = NULL; + const char* text = NULL; + const char* desc = NULL; + const char* tab = "\t"; + + std::string header("Command"); + header.append(tab); + header.append(tab); + header.append("Name"); + header.append(tab); + header.append(tab); + header.append(tab); + header.append("Description"); + + write(newline); + write(header.c_str()); + write(newline); + write(newline); + for (std::vector<Command*>::iterator it = _commands.begin(); it != _commands.end(); ++it) { + name = (*it)->name(); + text = (*it)->text(); + desc = (*it)->desc(); + write(text); + if (strlen(text) < 8) + write(tab); + write(tab); + write(name); + if (strlen(name) < 8) + write(tab); + if (strlen(name) < 16) + write(tab); + write(tab); + write(desc); + write(newline); + } + + write(newline); +} + +bool ModeConfig::writeable() { + return _serial.writeable(); +} + +bool ModeConfig::readable() { + return _serial.readable(); +} + +char ModeConfig::read() { + char ch; + _serial.read(&ch, 1); + return ch; +} + +void ModeConfig::write(const char* message) { + while (!writeable()) + ; + _serial.write(message, strlen(message)); +} + +void ModeConfig::writef(const char* format, ...) { + char buff[256]; + + va_list ap; + va_start(ap, format); + int size = vsnprintf(buff, 256, format, ap); + while (!writeable()) + ; + _serial.write(buff, size); + va_end(ap); +} bool ModeConfig::start() { - // clear any stale signals + char ch; + bool running = true; + bool echo = _dot->getEcho(); + std::string command; + std::deque<std::string> history; + int history_index = -1; + std::vector<std::string> args; + osSignalClear(_main_id, buttonSignal); _lc.display(); - mts::MTSSerial serial(USBTX, USBRX, 512, 512); - serial.baud(115200); + //Run terminal session + while (running) { + + osEvent e = Thread::signal_wait(buttonSignal, 20); + if (e.status == osEventSignal) { + ButtonHandler::ButtonEvent _be = _buttons->getButtonEvent(); + switch (_be) { + case ButtonHandler::sw1_press: + break; + case ButtonHandler::sw2_press: + break; + case ButtonHandler::sw1_hold: + return true; + default: + break; + } + } + + ch = '\0'; + + // read characters + if (readable()) { + ch = read(); + + if (ch == '\b' || ch == 0x7f) { + if (!command.empty()) { + writef("\b \b"); + command.erase(command.size() - 1); + } + continue; + } else if (ch == 0x1b || ch == 0x09) { + osDelay(20); + // catch escape sequence, or tab + char ch1, ch2; + + if (readable()) { + ch1 = read(); + if (readable()) + ch2 = read(); + + if (ch1 == 0x5b && ch2 == 0x41) { + // up key + for (int i = 0; i < command.size()+1; i++) { + writef("\b \b"); + } + if (history.size() > 0) { + if (++history_index >= history.size() - 1) + history_index = history.size() - 1; + + command = history[history_index]; + writef("%s", history[history_index].c_str()); + } else { + command.clear(); + } + } else if (ch1 == 0x5b && ch2 == 0x42) { + + // down key + for (int i = 0; i < command.size()+1; i++) { + writef("\b \b"); + } + + if (--history_index < 0) { + history_index = -1; + command.clear(); + } else { + command = history[history_index]; + writef("%s", history[history_index].c_str()); + } + } + } + while (readable()) read(); + continue; + } else { + command += ch; + } + + // echo chars if enabled + if (echo && !(ch == '\r' || ch == '\n')) + writef("%c", ch); + } + + // look for end of command line + if (command.find("\n") != std::string::npos || command.find("\r") != std::string::npos) { + // remove new line or cr character + command.erase(command.size() - 1); + write("\r"); // match standard modem output + write(newline); + } else { + continue; + } + + // trim whitespace from command + mts::Text::trim(command, "\r\n\t "); + + if (command.size() < 1) { + command.clear(); + continue; + } + + // parse command and args + args.clear(); + + // find first '=' character + size_t delim_index = command.find("="); + if (delim_index != std::string::npos) { + args.push_back(command.substr(0, delim_index)); + } else { + // find first ' ' character + delim_index = command.find(" "); + if (delim_index != std::string::npos) { + args.push_back(command.substr(0, delim_index)); + } else { + args.push_back(command); + } + } + + if (delim_index != std::string::npos) { + std::vector<std::string> params = mts::Text::split(command.substr(delim_index + 1), ","); + args.insert(args.end(), params.begin(), params.end()); + } + + args[0] = mts::Text::toUpper(args[0]); + + // print help + if ((args[0].find("?") == 0 || args[0].find("HELP") == 0) && args.size() == 1) { + printHelp(); + command.clear(); + } else if (args[0].find("AT+EXIT") == 0 && args[0].length() == 7) { + write(done); + return true; + } else { + bool found = false; + bool query = false; + + std::string lookfor = args[0]; + + // per command help + if ((args[0].find("?") == 0 || args[0].find("HELP") == 0)) + lookfor = mts::Text::toUpper(args[1]); + + // trim off any trailing '?' and mark as a query command + if (args[0].rfind("?") == args[0].length() - 1) { + query = true; + lookfor = args[0].substr(0, args[0].length() - 1); + } + + // search for command + for (std::vector<Command*>::iterator it = _commands.begin(); it != _commands.end() && !found; ++it) { + Command* cmd = *it; + + // match CMD or CMD? syntax if command is queryable + if (lookfor == cmd->text() && (!query || (query && cmd->queryable()))) { + found = true; + if (args[0] == "HELP") { + writef("%s%s", cmd->help(), newline); + write(done); + } + + else if (args.size() > 1 && args[1] == "?") { + writef("%s%s", cmd->usage().c_str(), newline); + write(done); + } else if (!cmd->verify(args)) { + writef("%s%s", cmd->errorMessage().c_str(), newline); + writef("%s", error); + } else { + if (cmd->action(args) == 0) { + writef("%s", done); + } else { + writef("%s%s", cmd->errorMessage().c_str(), newline); + writef("%s", error); + } + } + } + } + + if (!found) { + writef("%s", command_error); + writef("%s", error); + } + } + + if (history.size() == 0 || history.front() != command) + history.push_front(command); + history_index = -1; + command.clear(); + + while (history.size() > 10) + history.pop_back(); - CommandTerminal term(serial, _dot, _buttons); - return term.start(); -} + } + return false; +} diff --git a/Mode/ModeConfig.h b/Mode/ModeConfig.h index be478dd..ade3093 100644 --- a/Mode/ModeConfig.h +++ b/Mode/ModeConfig.h @@ -2,20 +2,58 @@ #define __MODECONFIG_H__ #include "Mode.h" -#include "LayoutConfig.h" +#include "LayoutConfig.h" +#include "mbed.h" +#include "MTSSerial.h" +#include "Commands.h" #include "mDot.h" +#include "ButtonHandler.h" class ModeConfig : public Mode { - public: - ModeConfig(DOGS102* lcd, ButtonHandler* buttons, mDot* dot); - ~ModeConfig(); - bool start(); +public: - private: - LayoutConfig _lc; - mDot* _dot; - ButtonHandler::ButtonEvent _be; + ModeConfig(DOGS102* lcd, mts::MTSSerial& serial, mDot* dot, ButtonHandler* buttons); + + // Command error text... + static const char command_error[]; + + // Response texts... + static const char newline[]; + static const char done[]; + static const char error[]; + + bool start(); + +private: + + static void idle(void const* args) { + while (1) + __WFI(); + } + + mts::MTSSerial& _serial; + static mts::MTSSerial* _serialp; + + LayoutConfig _lc; + ButtonHandler::ButtonEvent _be; + ButtonHandler* _buttons; + mDot* _dot; + mDot::Mode _mode; + std::vector<Command*> _commands; + Thread _idle_thread; + bool _serial_up; + + void addCommand(Command* cmd); + + void printHelp(); + + bool readable(); + bool writeable(); + char read(); + void write(const char* message); + void writef(const char* format, ... ); + }; -#endif +#endif // __MODECONFIG_H__ |