Working on command line processing.

This commit is contained in:
Kyle Isom 2023-10-07 16:25:17 -07:00
parent e5cf44c3a6
commit 4a888d23a5
5 changed files with 217 additions and 4 deletions

12
include/Commander.h Normal file
View File

@ -0,0 +1,12 @@
#ifndef KIMODEM_COMMANDER_H
#define KIMODEM_COMMANDER_H
#include "Mode.h"
#define MAX_COMMAND_LENGTH 80
void CommandMode();
#endif

View File

@ -1,5 +1,5 @@
#ifndef KIMODEM_PREFS_H #ifndef KIMODEM_CONFIG_H
#define KIMODEM_PREFS_H #define KIMODEM_CONFIG_H
namespace Config { namespace Config {

11
include/Mode.h Normal file
View File

@ -0,0 +1,11 @@
#ifndef KIMODEM_MODE_H
#define KIMODEM_MODE_H
static struct Mode {
bool (*Process)();
bool (*Update)();
} *currentMode(nullptr);
#endif

179
src/Commander.cc Normal file
View File

@ -0,0 +1,179 @@
#include <Arduino.h>
#include <string.h>
#include "Commander.h"
#include "Display.h"
#include "Mode.h"
#include "WiFi.h"
void resetATCommand();
static const char invalidATCommand[] = "INVALID AT COMMAND";
static struct {
char line[MAX_COMMAND_LENGTH];
uint8_t index;
uint8_t newLine;
} atCommand;
void
resetATCommand()
{
memset(atCommand.line, 0, MAX_COMMAND_LENGTH);
atCommand.newLine = 0;
atCommand.index = 0;
Serial.print("> ");
Serial.flush();
}
static bool
showConnectionState()
{
Display::Print("802.11 ");
switch (WiFi.status()) {
case WL_CONNECT_FAILED:
Display::Println("CONN FAIL");
break;
case WL_CONNECTED:
Display::Println("CONNECTED");
return true;
case WL_CONNECTION_LOST:
Display::Println("CONN LOST");
break;
case WL_DISCONNECTED:
Display::Println("DISCON");
break;
case WL_IDLE_STATUS:
Display::Println("IDLE");
break;
case WL_NO_SSID_AVAIL:
Display::Println("SSID UNAVAIL");
break;
case WL_SCAN_COMPLETED:
Display::Println("SCAN COMPLETE");
break;
default:
Display::Println("UNK STATE");
}
return false;
}
static bool
commanderConnect(const char *line, size_t length)
{
if (length == 0) {
if (showConnectionState()) {
Display::Print(" SSID: ");
Display::Println(WiFi.SSID().c_str());
Display::Print(" IP: ");
Display::Println(WiFi.localIP().toString().c_str());
Display::Print(" RSSI: ");
Display::Println(String(WiFi.RSSI()).c_str());
}
return true;
}
return false;
}
bool
commanderProcess()
{
static char line[MAX_COMMAND_LENGTH];
size_t length;
// commanderProcess tracks a second copy of a line buffer
// because the question of "when should we reset the AT
// command line buffer?" is pretty difficult to answer without
// overcomplicating the code. So, at the expense of a few
// (or MAX_COMMAND_LINE) bytes, it's easier to keep a static
// buffer that is reset on every call and reset the AT
// command buffer on every call.
length = strnlen(atCommand.line, MAX_COMMAND_LENGTH);
memset(line, 0, MAX_COMMAND_LENGTH);
memcpy(line, atCommand.line, length);
resetATCommand();
if (length < 2) {
Serial.println(invalidATCommand);
return false;
}
if ((line[0] != 'A') && (line[1] != 'T')) {
Serial.println(invalidATCommand);
return false;
}
switch (line[2]) {
case 'C':
return commanderConnect(line+3, length-3);
default:
Serial.print("UNKNOWN COMMAND ");
Serial.println(line);
return false;
}
return false;
}
static bool
commanderUpdate()
{
char readByte;
if (!Serial.available()) {
return false;
}
readByte = Serial.read();
if (readByte == '\r') {
if (atCommand.newLine != 0) {
Serial.println();
Serial.println(invalidATCommand);
resetATCommand();
return false;
}
atCommand.newLine++;
}
if (readByte == '\n') {
if (atCommand.newLine != 1) {
Serial.println();
Serial.println(invalidATCommand);
resetATCommand();
return false;
}
return true;
}
atCommand.line[atCommand.index++] = readByte;
if (atCommand.index == MAX_COMMAND_LENGTH-1) {
return true;
}
return false;
}
struct Mode commander = {commanderProcess, commanderUpdate};
void
CommandMode()
{
resetATCommand();
delete currentMode;
currentMode = new Mode{commanderProcess, commanderUpdate};
}

View File

@ -2,9 +2,11 @@
#include <SPIFFS.h> #include <SPIFFS.h>
#include "Arena.h" #include "Arena.h"
#include "Commander.h"
#include "Config.h" #include "Config.h"
#include "Dictionary.h" #include "Dictionary.h"
#include "Display.h" #include "Display.h"
#include "Mode.h"
#include "WiFiMgr.h" #include "WiFiMgr.h"
#include "WiFiMeter.h" #include "WiFiMeter.h"
#include "homenet.h" #include "homenet.h"
@ -82,10 +84,19 @@ void setup() {
} }
Display::Println("MODEM READY"); Display::Println("MODEM READY");
CommandMode();
Serial.println((uintptr_t)currentMode, HEX);
Serial.println((uintptr_t)(currentMode->Process), HEX);
Serial.println((uintptr_t)(currentMode->Update), HEX);
} }
void loop() { void loop() {
delay(1000); if (millis() % 1000 == 0) Meter::Update();
Meter::Update(); if (currentMode->Update()) {
currentMode->Process();
}
delay(1);
} }