summaryrefslogtreecommitdiff
path: root/Mode
diff options
context:
space:
mode:
authorLeon Lindenfelser <llindenfelser@multitech.com>2015-11-20 16:21:44 -0600
committerLeon Lindenfelser <llindenfelser@multitech.com>2015-11-20 16:21:44 -0600
commit4ea46cbfee73c43579ea657cabc7f1fc7de97874 (patch)
tree96c7451f54600d847e7d0231090bb79d02f0ac50 /Mode
parent393317f7d04753d6e9773393a96c311a88a27f7b (diff)
downloadmtdot-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.cpp346
-rw-r--r--Mode/ModeConfig.h58
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__