initial commit

This commit is contained in:
2019-12-04 23:10:53 +01:00
commit 42e7c98d46
17 changed files with 636 additions and 0 deletions

38
src/DummyStream.cpp Normal file
View File

@ -0,0 +1,38 @@
#include <DummyStream.h>
DummyStream::DummyStream()
{
}
DummyStream::~DummyStream()
{
}
int DummyStream::available()
{
return 0;
}
int DummyStream::read()
{
return -1;
}
int DummyStream::peek()
{
return -1;
}
void DummyStream::flush()
{
}
size_t DummyStream::write(uint8_t)
{
return 0;
}
size_t DummyStream::write(const uint8_t *buffer, size_t size)
{
return 0;
}

21
src/DummyStream.h Normal file
View File

@ -0,0 +1,21 @@
#ifndef DUMMYSTREAM_H
#define DUMMYSTREAM_H
#include <Stream.h>
class DummyStream : public Stream
{
public:
DummyStream();
~DummyStream();
int available();
int read();
int peek();
void flush();
size_t write(uint8_t);
size_t write(const uint8_t *buffer, size_t size);
};
#endif

10
src/bafang.cpp Normal file
View File

@ -0,0 +1,10 @@
#include <Arduino.h>
#include "utils.h"
#include "main.h"
#include "bafang.h"
namespace Huawei {
}

11
src/bafang.h Normal file
View File

@ -0,0 +1,11 @@
#ifndef BAFANG_H
#define BAFANG_H
#include <stdint.h>
namespace Bafang {
}
#endif

140
src/commands.cpp Normal file
View File

@ -0,0 +1,140 @@
#include <Arduino.h>
#include <WiFi.h>
#include "utils.h"
#include "main.h"
#include "bafang.h"
#include "commands.h"
namespace Commands {
int parseLine(char *line)
{
const int MAX_ARGV = 16;
char *lineStart = line;
char *argv[MAX_ARGV];
int argc = 0;
bool found = false;
bool end = false;
bool inString = false;
while(1)
{
if(*line == '"' && (line == lineStart || *(line - 1) != '\\'))
{
inString ^= true;
if(!inString)
{
found = true;
end = true;
lineStart++;
}
}
if(!inString && *line == ' ')
end = true;
if(end || !*line)
{
if(found && argc < MAX_ARGV)
argv[argc++] = lineStart;
found = false;
end = false;
if(!*line)
break;
*line = 0;
lineStart = ++line;
continue;
}
line++;
found = true;
}
if(!argc)
return -1;
for(int i = 0; g_Commands[i].cmd; i++)
{
if(strcmp(g_Commands[i].cmd, argv[0]) == 0)
{
int ret = g_Commands[i].fun(argc, argv);
return ret;
}
}
return -1;
}
int CMD_help(int argc, char **argv)
{
Main::channel()->println("Available Commands\n------------------");
int i = 0;
while(g_Commands[i].cmd)
{
Main::channel()->printf("%17s %s\n", g_Commands[i].cmd, g_Commands[i].help);
i++;
}
Main::channel()->println();
return 0;
}
int CMD_debug(int argc, char **argv)
{
if(argc != 2) {
Main::channel()->println("Usage: debug <0|1>");
return 1;
}
bool debug = false;
if(strtoul(argv[1], NULL, 10))
debug = true;
Main::g_Debug[Main::g_CurrentChannel] = debug;
return 0;
}
int CMD_wifi(int argc, char **argv)
{
Main::channel()->printf("connected: %d\n", WiFi.status());
Main::channel()->println(WiFi.localIP());
WiFi.printDiag(*Main::channel());
return 0;
}
int CMD_serial(int argc, char **argv)
{
if(argc != 3) {
Main::channel()->println("Usage: serial <0|1|2> <text>");
return 1;
}
int port = strtoul(argv[1], NULL, 10);
if(port == 0)
Serial.println(argv[2]);
else if(port == 1)
Serial1.println(argv[2]);
else if(port == 2)
Serial2.println(argv[2]);
return 0;
}
CommandEntry g_Commands[] =
{
{"help", CMD_help, " : Display list of commands"},
{"debug", CMD_debug, " : debug <0|1>"},
{"wifi", CMD_wifi, " : show wifi config"},
{"serial", CMD_serial, " : write to serial <0|1|2> <text>"},
{ 0, 0, 0 }
};
}

21
src/commands.h Normal file
View File

@ -0,0 +1,21 @@
#ifndef COMMANDS_H
#define COMMANDS_H
namespace Commands {
int parseLine(char *line);
struct CommandEntry
{
const char *cmd;
int (*fun)(int argc, char *argv[]);
const char *help;
};
extern CommandEntry g_Commands[];
}
#endif

160
src/main.cpp Normal file
View File

@ -0,0 +1,160 @@
#include <Arduino.h>
#include <WiFi.h>
#include <ArduinoOTA.h>
#include <BluetoothSerial.h>
#include "DummyStream.h"
#include "bafang.h"
#include "commands.h"
#include "main.h"
WiFiServer server(23);
WiFiClient serverClient;
BluetoothSerial SerialBT;
DummyStream SerialDummy;
const char g_WIFI_SSID[] = "BotoX";
const char g_WIFI_Passphrase[] = "D4701B981E5F34EF087DE8DA25F19B47F48E0FEA972FD10E3E6CFEE29C431A1F";
namespace Main
{
int g_CurrentChannel = HWSERIAL;
bool g_Debug[NUM_CHANNELS];
char g_SerialBuffer[NUM_CHANNELS][255];
int g_SerialBufferPos[NUM_CHANNELS];
unsigned long g_Time1000;
void init()
{
Serial.begin(115200);
while(!Serial);
Serial.println("BOOTED!");
Serial1.begin(115200);
Serial2.begin(115200);
WiFi.setHostname("ESP32-BAFANG");
if(!WiFi.begin(g_WIFI_SSID, g_WIFI_Passphrase))
Serial.println("WiFi config error!");
else {
WiFi.setAutoConnect(true);
}
SerialBT.begin("ESP32-BAFANG");
ArduinoOTA.onStart([]() {
String type;
if (ArduinoOTA.getCommand() == U_FLASH)
type = "sketch";
else // U_SPIFFS
type = "filesystem";
// NOTE: if updating SPIFFS this would be the place to unmount SPIFFS using SPIFFS.end()
Serial.println("Start updating " + type);
})
.onEnd([]() {
Serial.println("\nEnd");
})
.onProgress([](unsigned int progress, unsigned int total) {
Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
})
.onError([](ota_error_t error) {
Serial.printf("Error[%u]: ", error);
if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed");
else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed");
else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed");
else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed");
else if (error == OTA_END_ERROR) Serial.println("End Failed");
});
ArduinoOTA.begin();
server.begin();
server.setNoDelay(true);
}
Stream* channel(int num)
{
if(num == -1)
num = g_CurrentChannel;
if(num == BTSERIAL && SerialBT.hasClient())
return &SerialBT;
else if(num == TCPSERIAL && serverClient)
return &serverClient;
else if(num == HWSERIAL)
return &Serial;
return &SerialDummy;
}
void loop()
{
if(g_Debug[g_CurrentChannel])
{
while(Serial1.available())
{
channel()->write(Serial1.read());
}
while(Serial2.available())
{
channel()->write(Serial2.read());
}
}
ArduinoOTA.handle();
if(server.hasClient())
{
if(serverClient) // disconnect current client if any
serverClient.stop();
serverClient = server.available();
}
if(!serverClient)
serverClient.stop();
for(int i = 0; i < NUM_CHANNELS; i++)
{
while(channel(i)->available())
{
g_CurrentChannel = i;
int c = channel(i)->read();
if(c == '\r' || c == '\n' || g_SerialBufferPos[i] == sizeof(*g_SerialBuffer))
{
g_SerialBuffer[i][g_SerialBufferPos[i]] = 0;
if(g_SerialBufferPos[i])
Commands::parseLine(g_SerialBuffer[i]);
g_SerialBufferPos[i] = 0;
continue;
}
g_SerialBuffer[i][g_SerialBufferPos[i]] = c;
++g_SerialBufferPos[i];
}
}
if((millis() - g_Time1000) > 1000)
{
g_Time1000 = millis();
}
}
}
void setup()
{
Main::init();
}
void loop()
{
Main::loop();
}

30
src/main.h Normal file
View File

@ -0,0 +1,30 @@
#ifndef MAIN_H
#define MAIN_H
#include <Arduino.h>
#define MAX_SRV_CLIENTS 4
namespace Main {
enum {
NOSERIAL = -1,
HWSERIAL = 0,
BTSERIAL = 1,
TCPSERIAL = 2,
NUM_CHANNELS
};
void init();
void loop();
Stream* channel(int num = -1);
extern int g_CurrentChannel;
extern bool g_Debug[NUM_CHANNELS];
extern char g_SerialBuffer[NUM_CHANNELS][255];
extern int g_SerialBufferPos[NUM_CHANNELS];
};
#endif

63
src/utils.cpp Normal file
View File

@ -0,0 +1,63 @@
#include <string.h>
#include "utils.h"
static inline uint8_t _char2byte(char c)
{
if('0' <= c && c <= '9') return (uint8_t)(c - '0');
if('A' <= c && c <= 'F') return (uint8_t)(c - 'A' + 10);
if('a' <= c && c <= 'f') return (uint8_t)(c - 'a' + 10);
return 0xFF;
}
int hex2bytes(const char *str, uint8_t *bytes, int32_t length)
{
int result;
if(!str || !bytes || length <= 0)
return -1;
for(result = 0; *str; result++)
{
uint8_t msn = _char2byte(*str++);
if(msn == 0xFF) return -1;
uint8_t lsn = _char2byte(*str++);
if(lsn == 0xFF) return -1;
uint8_t bin = (msn << 4) + lsn;
if(length-- <= 0)
return -1;
*bytes++ = bin;
}
return result;
}
void bytes2hex(const uint8_t *bytes, int32_t length, char *str, int32_t strLength)
{
const char binHex[] = "0123456789ABCDEF";
if(!str || strLength < 3)
return;
*str = 0;
if(!bytes || length <= 0 || strLength <= 2 * length)
{
strncpy(str, "ERR", strLength);
return;
}
for(; length > 0; length--, strLength -= 2)
{
uint8_t byte = *bytes++;
*str++ = binHex[(byte >> 4) & 0x0F];
*str++ = binHex[byte & 0x0F];
}
if(strLength-- <= 0)
return;
*str++ = 0;
}

8
src/utils.h Normal file
View File

@ -0,0 +1,8 @@
#ifndef UTILS_H
#define UTILS_H
#include <stdint.h>
int hex2bytes(const char *str, uint8_t *bytes, int32_t length);
void bytes2hex(const uint8_t *bytes, int32_t length, char *str, int32_t strLength);
#endif