Added project
This commit is contained in:
parent
fe9aa14dfd
commit
2d73cc8845
186 changed files with 21174 additions and 0 deletions
77
lib/xnode-shared/XnodeConstants.h
Normal file
77
lib/xnode-shared/XnodeConstants.h
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
#ifndef XnodeBaseConstants_h
|
||||
#define XnodeBaseConstants_h
|
||||
|
||||
// Temp version here, todo move to makefile and use git --version
|
||||
#define XNODE_VERSION "1.3"
|
||||
|
||||
// Default serial baudrate for all devices
|
||||
#define SERIAL_SPEED 115200
|
||||
|
||||
// Default watchdog timeout
|
||||
#define WDT_TIMEOUT WDTO_8S
|
||||
|
||||
// RF Settings
|
||||
#define RF_BASE_NODE_ID 1
|
||||
#define RF_NETWORK_ID 98
|
||||
#define RF_FREQUENCY RF69_868MHZ
|
||||
#define RF_KEY_SIZE 16
|
||||
#define RF_KEY_FETCH_TIME 1000*5
|
||||
#define RF_KEY_ENCRYPT_TIME 1000*60*2
|
||||
#define RF_NO_DATA_FAIL_TIME RF_KEY_ENCRYPT_TIME*2
|
||||
|
||||
// Needed for total magic number free code
|
||||
#define ZERO 0
|
||||
#define ONE 1
|
||||
|
||||
// Net related sizes
|
||||
#define NET_BYTE_IP_SIZE 4
|
||||
#define NET_BYTE_MAC_SIZE 6
|
||||
#define NET_BYTE_NET_KEY_SIZE 16
|
||||
#define NET_BYTE_NET_ID_SIZE 6
|
||||
|
||||
// Net Xensit config
|
||||
//define NET_XNODE_HOST "xng.xensit.com" // XNodeGateway
|
||||
#define NET_XNODE_HOST "www.forwardfire.net"
|
||||
#define NET_XNODE_MAC_DEFAULT {0x74,0x69,0x69,0x4D,0x33,0xB1}
|
||||
#define NET_PING_BOOT_TIME 1000*3
|
||||
#define NET_PING_HOST_TIME 1000*60*90
|
||||
#define NET_DHCP_RETRY_TIME 1000*60*3
|
||||
#define NET_DNS_LOOKUP_TIME 1000*3600*1
|
||||
// TODO: make net time to secs as 1h is ~max for dns
|
||||
|
||||
// Net config for url; Input Xensit Node Version A
|
||||
#define NET_URL_POST "_a"
|
||||
#define NET_URL_PARA_POST_TYPE "pt="
|
||||
#define NET_URL_PARA_REQ_CNT "&rc="
|
||||
#define NET_URL_PARA_NET_ID "&ni="
|
||||
#define NET_URL_PARA_NODE_DATA "&nd="
|
||||
#define NET_URL_PARA_NODE_NUMBER "&nn="
|
||||
|
||||
// The different post types of the url
|
||||
#define NET_URL_PT_PING 'p'
|
||||
#define NET_URL_PT_INIT 'i'
|
||||
#define NET_URL_PT_DATA 'd'
|
||||
#define NET_URL_RESULT_OK 'X'
|
||||
|
||||
// Some characters for printing.
|
||||
#define CHAR_NEWLINE '\n'
|
||||
#define CHAR_SPACE ' '
|
||||
#define CHAR_DOT '.'
|
||||
#define CHAR_PROMT '$'
|
||||
#define CHAR_COMMENT '#'
|
||||
#define CHAR_EQUALS '='
|
||||
|
||||
// Full ascii messages
|
||||
#define MSG_RF_CHIP_INIT "Init radio"
|
||||
#define MSG_RF_CHIP_ERROR "ERR: No chip"
|
||||
#define MSG_RF_INFO_FREQ "rf_freq"
|
||||
#define MSG_RF_INFO_NETWORK "rf_network"
|
||||
#define MSG_RF_INFO_NODE "rf_node"
|
||||
#define MSG_RF_INFO_KEY "rf_key"
|
||||
#define MSG_RF_INFO_TX "rf_tx"
|
||||
#define MSG_RF_INFO_RX "rf_rx"
|
||||
#define MSG_RF_INFO_TXE "rf_txe"
|
||||
#define MSG_RF_INFO "rf_info"
|
||||
#define MSG_RF_ENCRYPT "rf_encrypt"
|
||||
|
||||
#endif
|
||||
38
lib/xnode-shared/XnodeProtocol.h
Normal file
38
lib/xnode-shared/XnodeProtocol.h
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
#ifndef XnodeProtocol_h
|
||||
#define XnodeProtocol_h
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <XnodeConstants.h>
|
||||
|
||||
#define RF_STRUCT_SUPER_SIZE 52
|
||||
#define RF_STRUCT_FLASH_SIZE 32
|
||||
#define RF_STRUCT_CHAR_SIZE 48
|
||||
|
||||
enum RFMessageType {
|
||||
RF_MSG_NODE_INIT, // sat tx+rx init_t
|
||||
RF_MSG_NODE_FLASH, // sat tx+rx flash_t
|
||||
RF_MSG_NODE_COMMAND, // sat rx char_t
|
||||
RF_MSG_NODE_DATA // sat tx char_t
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
byte msg_type;
|
||||
byte msg_data[RF_STRUCT_SUPER_SIZE];
|
||||
} xp_super_t;
|
||||
|
||||
typedef struct {
|
||||
byte rf_key[RF_KEY_SIZE];
|
||||
byte node_id;
|
||||
} xp_msg_init_t;
|
||||
|
||||
typedef struct {
|
||||
uint16_t offset;
|
||||
byte flash_data[RF_STRUCT_FLASH_SIZE];
|
||||
} xp_msg_flash_t;
|
||||
|
||||
typedef struct {
|
||||
char char_data[RF_STRUCT_CHAR_SIZE];
|
||||
} xp_msg_char_t;
|
||||
|
||||
#endif
|
||||
|
||||
14
lib/xnode-shared/XnodeSatelliteConfig.h
Normal file
14
lib/xnode-shared/XnodeSatelliteConfig.h
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
#ifndef XnodeSatelliteConfig_h
|
||||
#define XnodeSatelliteConfig_h
|
||||
|
||||
// Config data
|
||||
typedef struct {
|
||||
uint16_t eeprom_struct_size; // Config size changes it data defaults to zeros
|
||||
byte rf_key[RF_KEY_SIZE]; // rf key to encrypt radio
|
||||
byte node_id; // this node id to transmit to base
|
||||
unsigned long sys_boot; // boot counter
|
||||
|
||||
} xnode_satellite_config_t;
|
||||
|
||||
#endif
|
||||
|
||||
104
lib/xnode-shared/XnodeSerial.cpp
Normal file
104
lib/xnode-shared/XnodeSerial.cpp
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
#include <XnodeSerial.h>
|
||||
|
||||
char cmd_buff[CMD_BUFF_SIZE];
|
||||
volatile uint8_t cmd_process = ONE;
|
||||
volatile uint8_t cmd_buff_idx = ZERO;
|
||||
XnodeSerial XSerial;
|
||||
|
||||
void XnodeSerial::begin() {
|
||||
Serial.begin(SERIAL_SPEED);
|
||||
print(CHAR_NEWLINE);
|
||||
}
|
||||
|
||||
void XnodeSerial::loop() {
|
||||
if (cmd_process == ZERO) {
|
||||
executeCommand(cmd_buff);
|
||||
cmd_process = ONE;
|
||||
}
|
||||
while (Serial.available() > ZERO) {
|
||||
processSerialByte(Serial.read());
|
||||
}
|
||||
}
|
||||
|
||||
// Parse the cmd from a buffer
|
||||
void XnodeSerial::executeCommand(char* buff,bool echoBuff,bool echoPromt) {
|
||||
#ifdef DEBUG_SERIAL
|
||||
Serial.print(F("#D XSerial.processCommand buff="));
|
||||
Serial.print(buff);
|
||||
Serial.print(F(",echoBuff="));
|
||||
Serial.print(echoBuff);
|
||||
Serial.print(F(",echoPromt="));
|
||||
Serial.print(echoPromt);
|
||||
Serial.println();
|
||||
#endif
|
||||
if (echoBuff) {
|
||||
printChar(buff);
|
||||
print(CHAR_NEWLINE);
|
||||
}
|
||||
if (buff[ZERO] > ZERO) {
|
||||
XSystem.executeCommand(buff); // exe cmd
|
||||
printChar(XSystem.replyBuffer); // print result or error
|
||||
}
|
||||
if (echoPromt) {
|
||||
printPromt();
|
||||
}
|
||||
}
|
||||
|
||||
void XnodeSerial::processSerialByte(uint8_t c) {
|
||||
if (c < 0x07 || c > 0x7E) {
|
||||
return; // only process ascii chars
|
||||
}
|
||||
if (cmd_process == ZERO) {
|
||||
return; // skip serial data
|
||||
}
|
||||
if (cmd_buff_idx > CMD_BUFF_SIZE) {
|
||||
cmd_buff_idx = ZERO; // protect against to long input
|
||||
}
|
||||
if (c == '\b') {
|
||||
cmd_buff[cmd_buff_idx] = '\0'; // backspace
|
||||
cmd_buff_idx--;
|
||||
print(' ');
|
||||
print(c); // reply the backspace char for console like experience
|
||||
} else if (c == '\n') {
|
||||
cmd_buff[cmd_buff_idx] = '\0'; // newline
|
||||
cmd_buff_idx = ZERO;
|
||||
cmd_process = ZERO; // Start processing line
|
||||
} else {
|
||||
cmd_buff[cmd_buff_idx] = c; // store in buffer
|
||||
cmd_buff_idx++;
|
||||
}
|
||||
}
|
||||
|
||||
void XnodeSerial::executeCommandP(const char* cmd) {
|
||||
strcpy(cmd_buff, XUtil.UNPSTR(cmd)); // free buffer as gets used in strcmpP again..
|
||||
cmd_buff_idx = ZERO;
|
||||
executeCommand(cmd_buff,false,false);
|
||||
}
|
||||
|
||||
void XnodeSerial::printPromt() {
|
||||
printCharP(XSystem.hardware->getSystemHardwareTypeP());
|
||||
print(CHAR_PROMT);
|
||||
print(CHAR_SPACE);
|
||||
}
|
||||
|
||||
void XnodeSerial::printCommentLineP(const char* argu) {
|
||||
print(CHAR_COMMENT);
|
||||
print(CHAR_SPACE);
|
||||
printCharP(argu);
|
||||
print(CHAR_NEWLINE);
|
||||
}
|
||||
|
||||
void XnodeSerial::printCharP(const char* argu) {
|
||||
printChar(XUtil.UNPSTR(argu));
|
||||
}
|
||||
|
||||
void XnodeSerial::printChar(char* dstring) {
|
||||
while (*dstring != ZERO) {
|
||||
print(*dstring);
|
||||
dstring++;
|
||||
}
|
||||
}
|
||||
|
||||
void XnodeSerial::print(char value) {
|
||||
Serial.print(value);
|
||||
}
|
||||
32
lib/xnode-shared/XnodeSerial.h
Normal file
32
lib/xnode-shared/XnodeSerial.h
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
#ifndef XnodeSerial_h
|
||||
#define XnodeSerial_h
|
||||
|
||||
#define CMD_BUFF_SIZE 40 // max command length (40 is rf_key=9A2EE3A293486E9FE73D77EFC8087D2F)
|
||||
|
||||
#include <XnodeSystemModule.h>
|
||||
#include <XnodeSystemHardware.h>
|
||||
#include <XnodeConstants.h>
|
||||
#include <XnodeUtil.h>
|
||||
#include <XnodeSystem.h>
|
||||
|
||||
class XnodeSerial {
|
||||
private:
|
||||
void executeCommand(char* buff,bool echoBuff = true,bool echoPromt = true);
|
||||
void processSerialByte(uint8_t c);
|
||||
|
||||
public:
|
||||
void begin();
|
||||
void loop();
|
||||
|
||||
void executeCommandP(const char* cmd);
|
||||
void printPromt();
|
||||
void printCommentLineP(const char* argu);
|
||||
void printCharP(const char* argu);
|
||||
void printChar(char* argu);
|
||||
void print(char value);
|
||||
};
|
||||
|
||||
extern XnodeSerial XSerial;
|
||||
|
||||
#endif
|
||||
|
||||
323
lib/xnode-shared/XnodeSystem.cpp
Normal file
323
lib/xnode-shared/XnodeSystem.cpp
Normal file
|
|
@ -0,0 +1,323 @@
|
|||
#include <XnodeSystem.h>
|
||||
|
||||
#define CMD_MAX_ARGS 8 // max 8 arguments to command
|
||||
#define CMD_WHITE_SPACE " \r\t\n" // All diffent white space chars to split commands on
|
||||
|
||||
const char pmCmdHelp[] PROGMEM = "help";
|
||||
const char pmCmdReboot[] PROGMEM = "reboot";
|
||||
const char pmCmdSysCnfRst[] PROGMEM = "sys__cnf__rst"; // (internal)
|
||||
const char pmCmdSysInfo[] PROGMEM = "sys_info";
|
||||
|
||||
const char pmSysConfigSave[] PROGMEM = "Config saved";
|
||||
const char pmSysConfigLoad[] PROGMEM = "Config loaded";
|
||||
const char pmSysConfigReset[] PROGMEM = "Config reset";
|
||||
|
||||
const char pmSysInfoVNumber[] PROGMEM = "sys_vnum";
|
||||
const char pmSysInfoVDate[] PROGMEM = "sys_vdate";
|
||||
const char pmSysInfoVDateValue[] PROGMEM = __DATE__" "__TIME__; // Print compile date like; "Apr 22 2012 16:36:10"
|
||||
const char pmSysInfoType[] PROGMEM = "sys_type";
|
||||
const char pmSysInfoBoot[] PROGMEM = "sys_boot";
|
||||
const char pmSysInfoDebugLevel[] PROGMEM = "sys_debug";
|
||||
const char pmSysInfoFreeRam[] PROGMEM = "sys_sram";
|
||||
|
||||
const char pmSysBootDebugHeader[] PROGMEM = "==== DEBUGGING ENABLED ====";
|
||||
const char pmSysBootStart[] PROGMEM = "Booting ";
|
||||
const char pmSysBootDone[] PROGMEM = "boot done";
|
||||
const char pmSysBootDoneHelp[] PROGMEM = "Available commands;";
|
||||
|
||||
const char pmCmdErrArgument[] PROGMEM = "#ERR Missing argument: ";
|
||||
const char pmCmdErrUnknown[] PROGMEM = "#ERR Unknown command: ";
|
||||
|
||||
const char pmRemoteExecutePrefix[] PROGMEM = "remote@";
|
||||
|
||||
uint8_t reboot_requested = ZERO;
|
||||
uint8_t debug_level = ZERO;
|
||||
uint8_t replyBufferIndex = ZERO;
|
||||
uint8_t systemModuleIndex = ZERO;
|
||||
XnodeSystemModule* systemModules[SYSTEM_MODULE_ARRAY_SIZE];
|
||||
XnodeSystemHardware* hardware;
|
||||
XnodeSystem XSystem;
|
||||
|
||||
void XnodeSystem::begin(XnodeSystemHardware* hardwareNode) {
|
||||
hardware = hardwareNode;
|
||||
|
||||
// Print first line of boot process
|
||||
XSerial.print(CHAR_COMMENT);
|
||||
XSerial.print(CHAR_SPACE);
|
||||
XSerial.printCharP (pmSysBootStart); // has space
|
||||
XSerial.printCharP(hardware->getSystemHardwareTypeP());
|
||||
XSerial.print(CHAR_NEWLINE);
|
||||
|
||||
// Start debug asp
|
||||
beginDebug();
|
||||
|
||||
// Fixup config
|
||||
XSerial.printCommentLineP(pmSysConfigLoad);
|
||||
if (hardware->systemHardwareConfigBegin()) {
|
||||
hardware->systemHardwareConfigReset();
|
||||
XSerial.printCommentLineP(pmSysConfigReset);
|
||||
}
|
||||
hardware->systemHardwareConfigSave();
|
||||
|
||||
// Print system info
|
||||
XSerial.executeCommandP(pmCmdSysInfo);
|
||||
|
||||
// Enable the watchdog
|
||||
wdt_enable(WDT_TIMEOUT);
|
||||
}
|
||||
|
||||
void XnodeSystem::loop() {
|
||||
// Tickle the watchdog
|
||||
wdt_reset();
|
||||
|
||||
// Reboot countdown and action so reply can be send.
|
||||
if (reboot_requested > ONE) {
|
||||
reboot_requested--;
|
||||
} else if (reboot_requested > ZERO) {
|
||||
wdt_enable (WDTO_15MS); // reboot in 15ms.
|
||||
delay(30);
|
||||
}
|
||||
}
|
||||
|
||||
void XnodeSystem::beginDebug() {
|
||||
// Make sure human and machine are notified when debugging is turned on.
|
||||
#ifdef DEBUG_NETWORK
|
||||
// shift every flag on its on bit so machine can readout which flags is enabled.
|
||||
debug_level+=ONE << 0; // 1
|
||||
#endif
|
||||
#ifdef DEBUG_RADIO
|
||||
debug_level+=ONE << 1; // 2
|
||||
#endif
|
||||
#ifdef DEBUG_SYSTEM
|
||||
debug_level+=ONE << 2; // 4
|
||||
#endif
|
||||
#ifdef DEBUG_SERIAL
|
||||
debug_level+=ONE << 3; // 8
|
||||
#endif
|
||||
#ifdef DEBUG_SENSOR
|
||||
debug_level+=ONE << 4; // 16, all = 31
|
||||
#endif
|
||||
if (debug_level > ZERO) {
|
||||
XSerial.printCommentLineP(pmSysBootDebugHeader); // print line for human,machine version is in serialPrintInfo.
|
||||
}
|
||||
}
|
||||
|
||||
void XnodeSystem::bootDone() {
|
||||
XSerial.printCommentLineP(pmSysBootDoneHelp);
|
||||
XSerial.executeCommandP(pmCmdHelp);
|
||||
XSerial.printCommentLineP(pmSysBootDone);
|
||||
XSerial.printPromt();
|
||||
}
|
||||
|
||||
void XnodeSystem::configSave() {
|
||||
#ifdef DEBUG_SYSTEM
|
||||
Serial.println(F("#D XSystem.configSave"));
|
||||
#endif
|
||||
wdt_disable();
|
||||
hardware->systemHardwareConfigSave();
|
||||
wdt_enable (WDT_TIMEOUT);
|
||||
}
|
||||
|
||||
void XnodeSystem::cmdSysInfo() {
|
||||
buildReplyPValueP(pmSysInfoVNumber,hardware->getSystemHardwareVersionP());
|
||||
buildReplyPValueP(pmSysInfoVDate,pmSysInfoVDateValue);
|
||||
buildReplyPValue(pmSysInfoBoot,hardware->getSystemHardwareRebootCount());
|
||||
buildReplyPValueP(pmSysInfoType,hardware->getSystemHardwareTypeP());
|
||||
buildReplyPValue(pmSysInfoDebugLevel,debug_level);
|
||||
buildReplyPValue(pmSysInfoFreeRam,XUtil.freeRam());
|
||||
}
|
||||
|
||||
void XnodeSystem::cmdHelp() {
|
||||
for (uint8_t i = ZERO; i < SYSTEM_MODULE_ARRAY_SIZE; i++) {
|
||||
if (systemModules[i] == ZERO) {
|
||||
continue;
|
||||
}
|
||||
systemModules[i]->systemModuleCommandList();
|
||||
}
|
||||
buildReplyCommandListP(pmCmdSysInfo);
|
||||
buildReplyCommandListP(pmCmdReboot);
|
||||
buildReplyCommandListP(pmCmdHelp);
|
||||
}
|
||||
|
||||
void XnodeSystem::registrateSystemModule(XnodeSystemModule* module) {
|
||||
systemModules[systemModuleIndex++] = module;
|
||||
}
|
||||
|
||||
// execute cmd with the supplied argument
|
||||
bool XnodeSystem::executeCommandModule(char* cmd, char** args) {
|
||||
|
||||
// Check for system build in commands.
|
||||
if (XUtil.strcmpP(cmd, pmCmdHelp) == ZERO) {
|
||||
cmdHelp();
|
||||
return true;
|
||||
}
|
||||
if (XUtil.strcmpP(cmd, pmCmdReboot) == ZERO) {
|
||||
buildReplyPValue(pmCmdReboot,ONE);
|
||||
reboot_requested = 100; // let reply be send out/back
|
||||
return true;
|
||||
}
|
||||
if (XUtil.strcmpP(cmd, pmCmdSysInfo) == ZERO) {
|
||||
cmdSysInfo();
|
||||
return true;
|
||||
}
|
||||
if (XUtil.strcmpP(cmd, pmCmdSysCnfRst) == ZERO) {
|
||||
hardware->systemHardwareConfigReset();
|
||||
buildReplyPValue(pmCmdSysCnfRst,ONE);
|
||||
configSave();
|
||||
buildReplyPValue(pmCmdReboot,ONE);
|
||||
reboot_requested = 100;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check registated parses.
|
||||
for (uint8_t i = ZERO; i < SYSTEM_MODULE_ARRAY_SIZE; i++) {
|
||||
if (systemModules[i] == ZERO) {
|
||||
continue;
|
||||
}
|
||||
if (systemModules[i]->systemModuleCommandExecute(cmd, args)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false; // no command found
|
||||
}
|
||||
|
||||
// Parse the cmd from a buffer
|
||||
void XnodeSystem::executeCommand(char* input,bool isRemote) {
|
||||
#ifdef DEBUG_SYSTEM
|
||||
Serial.print(F("#D XSystem.executeCommand input="));
|
||||
Serial.print(input);
|
||||
Serial.println();
|
||||
#endif
|
||||
if (isRemote) {
|
||||
XSerial.printCharP(pmRemoteExecutePrefix);
|
||||
XSerial.printPromt();
|
||||
XSerial.printChar(input);
|
||||
XSerial.print(CHAR_NEWLINE);
|
||||
}
|
||||
replyBufferIndex = ZERO;
|
||||
uint8_t idx = ZERO;
|
||||
char *cmd, *ptr, *args[CMD_MAX_ARGS];
|
||||
if (strtok((char *) input, CMD_WHITE_SPACE) == NULL) {
|
||||
// no command given so just print new promt.
|
||||
buildReplyCharP(pmCmdErrUnknown); // TODO: replace with key+value
|
||||
buildReply(CHAR_NEWLINE);
|
||||
buildReply('\0');
|
||||
return;
|
||||
}
|
||||
cmd = (char *) input;
|
||||
while ((ptr = strtok(NULL, CMD_WHITE_SPACE)) != NULL) {
|
||||
args[idx] = ptr;
|
||||
if (++idx == (CMD_MAX_ARGS - ONE)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
args[idx] = NULL;
|
||||
bool parsed = executeCommandModule(cmd, args);
|
||||
if (!parsed) {
|
||||
buildReplyCharP(pmCmdErrUnknown);
|
||||
buildReplyChar(cmd); // TODO: add args
|
||||
buildReply(CHAR_NEWLINE);
|
||||
}
|
||||
buildReply('\0');
|
||||
}
|
||||
|
||||
void XnodeSystem::buildReply(unsigned long value, int base) {
|
||||
char buf[8 * sizeof(long) + ONE]; // Assumes 8-bit chars plus zero byte.
|
||||
char *str = &buf[sizeof(buf) - ONE];
|
||||
*str = ZERO; // reverse printing so start with termination.
|
||||
if (base < 2) {
|
||||
base = 10;// fix base 1 or 0 default to decimals
|
||||
}
|
||||
do {
|
||||
unsigned long m = value;
|
||||
value /= base;
|
||||
char c = m - base * value;
|
||||
*--str = c < 10 ? c + '0' : c + 'A' - 10;
|
||||
} while(value);
|
||||
return buildReplyChar(str);
|
||||
}
|
||||
void XnodeSystem::buildReply(float value,int digitsFull,int digitsDot) {
|
||||
dtostrf(value, digitsFull, digitsDot, (char*)replyBuffer+replyBufferIndex);
|
||||
replyBufferIndex += (digitsFull + 1 + digitsDot) - 1; // "999.9" "-99.9" and remove terminating zero.
|
||||
}
|
||||
void XnodeSystem::buildReply(char value) {
|
||||
replyBuffer[replyBufferIndex++] = value;
|
||||
if (replyBufferIndex > SYSTEM_REPLY_ARRAY_SIZE) {
|
||||
replyBufferIndex--;
|
||||
replyBuffer[replyBufferIndex] = ZERO; // terminate last char
|
||||
#ifdef DEBUG_SYSTEM
|
||||
Serial.print("#D+");
|
||||
Serial.print(value); // print overflow chars
|
||||
Serial.print("-");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
void XnodeSystem::buildReplyChar(char* value) {
|
||||
while (*value != ZERO) {
|
||||
buildReply(*value);
|
||||
value++;
|
||||
}
|
||||
}
|
||||
void XnodeSystem::buildReplyCharP(const char* value) {
|
||||
buildReplyChar(XUtil.UNPSTR(value));
|
||||
}
|
||||
void XnodeSystem::buildReplyCommandListP(const char* cmdName) {
|
||||
buildReplyCharP(cmdName);
|
||||
buildReply(CHAR_NEWLINE);
|
||||
}
|
||||
bool XnodeSystem::buildReplyCommandArgumentError(char* cmd, char** args) {
|
||||
if (args[ZERO] != NULL) {
|
||||
return false; // nothing printed
|
||||
}
|
||||
buildReplyCharP(pmCmdErrArgument);
|
||||
buildReplyChar(cmd);
|
||||
buildReply(CHAR_NEWLINE);
|
||||
return true;
|
||||
}
|
||||
void XnodeSystem::buildReplyPValueIP(const char* valueName,uint8_t ip[4]) {
|
||||
buildReplyCharP(valueName);
|
||||
buildReply(CHAR_EQUALS);
|
||||
buildReply(ip[0], DEC);
|
||||
buildReply(CHAR_DOT);
|
||||
buildReply(ip[1], DEC);
|
||||
buildReply(CHAR_DOT);
|
||||
buildReply(ip[2], DEC);
|
||||
buildReply(CHAR_DOT);
|
||||
buildReply(ip[3], DEC);
|
||||
buildReply(CHAR_NEWLINE);
|
||||
}
|
||||
|
||||
void XnodeSystem::buildReplyPValue(const char* valueName,unsigned long value) {
|
||||
buildReplyCharP(valueName);
|
||||
buildReply(CHAR_EQUALS);
|
||||
buildReply(value);
|
||||
buildReply(CHAR_NEWLINE);
|
||||
}
|
||||
void XnodeSystem::buildReplyPValue(const char* valueName,int value) {
|
||||
buildReplyPValue(valueName,(unsigned long)value);
|
||||
}
|
||||
void XnodeSystem::buildReplyPValue(const char* valueName,float value,int digitsFull,int digitsDot) {
|
||||
buildReplyCharP(valueName);
|
||||
buildReply(CHAR_EQUALS);
|
||||
buildReply(value,digitsFull,digitsDot);
|
||||
buildReply(CHAR_NEWLINE);
|
||||
}
|
||||
void XnodeSystem::buildReplyPValueP(const char* valueName,const char* valueP) {
|
||||
buildReplyCharP(valueName);
|
||||
buildReply(CHAR_EQUALS);
|
||||
buildReplyCharP(valueP);
|
||||
buildReply(CHAR_NEWLINE);
|
||||
}
|
||||
void XnodeSystem::buildReplyPValueByteA(const char* valueName,byte* value, byte data_len) {
|
||||
buildReplyCharP(valueName);
|
||||
buildReply(CHAR_EQUALS);
|
||||
for (byte i = ZERO; i < data_len; ++i) {
|
||||
byte d = value[i];
|
||||
if (d<0xF) {
|
||||
buildReply('0'); // exta zero to have two chars
|
||||
}
|
||||
buildReply(d, HEX);
|
||||
}
|
||||
buildReply(CHAR_NEWLINE);
|
||||
}
|
||||
|
||||
49
lib/xnode-shared/XnodeSystem.h
Normal file
49
lib/xnode-shared/XnodeSystem.h
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
#ifndef XnodeSystem_h
|
||||
#define XnodeSystem_h
|
||||
|
||||
#include <XnodeSystemHardware.h>
|
||||
#include <XnodeSystemModule.h>
|
||||
#include <XnodeConstants.h>
|
||||
#include <XnodeProtocol.h>
|
||||
#include <XnodeSerial.h>
|
||||
#include <XnodeUtil.h>
|
||||
#include <avr/wdt.h>
|
||||
|
||||
#define SYSTEM_MODULE_ARRAY_SIZE 4
|
||||
#define SYSTEM_REPLY_ARRAY_SIZE 250
|
||||
|
||||
class XnodeSystem {
|
||||
private:
|
||||
void beginDebug();
|
||||
bool executeCommandModule(char* cmd, char** args);
|
||||
void cmdHelp();
|
||||
void cmdSysInfo();
|
||||
void buildReply(char value);
|
||||
void buildReplyChar(char* value);
|
||||
void buildReply(unsigned long value, int = DEC);
|
||||
void buildReply(float value,int digitsFull,int digitsDot);
|
||||
public:
|
||||
char replyBuffer[SYSTEM_REPLY_ARRAY_SIZE];
|
||||
XnodeSystemHardware* hardware;
|
||||
void begin(XnodeSystemHardware* hardware);
|
||||
void loop();
|
||||
void bootDone();
|
||||
void configSave();
|
||||
void executeCommand(char* input,bool isRemote=false);
|
||||
void registrateSystemModule(XnodeSystemModule* module);
|
||||
|
||||
void buildReplyCommandListP(const char* cmdName);
|
||||
bool buildReplyCommandArgumentError(char* cmd, char** args);
|
||||
void buildReplyCharP(const char* value);
|
||||
void buildReplyPValueIP(const char* valueName,uint8_t ip[4]);
|
||||
void buildReplyPValue(const char* valueName,unsigned long value);
|
||||
void buildReplyPValue(const char* valueName,int value);
|
||||
void buildReplyPValue(const char* valueName,float value,int digitsFull = 3,int digitsDot = 1);
|
||||
void buildReplyPValueP(const char* valueName,const char* valueP);
|
||||
void buildReplyPValueByteA(const char* valueName,byte* value, byte data_len);
|
||||
};
|
||||
|
||||
extern XnodeSystem XSystem;
|
||||
|
||||
#endif
|
||||
|
||||
15
lib/xnode-shared/XnodeSystemHardware.h
Normal file
15
lib/xnode-shared/XnodeSystemHardware.h
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
#ifndef XnodeSystemHardware_h
|
||||
#define XnodeSystemHardware_h
|
||||
|
||||
class XnodeSystemHardware {
|
||||
public:
|
||||
virtual const char* getSystemHardwareTypeP();
|
||||
virtual const char* getSystemHardwareVersionP();
|
||||
virtual unsigned long getSystemHardwareRebootCount();
|
||||
virtual bool systemHardwareConfigBegin();
|
||||
virtual void systemHardwareConfigSave();
|
||||
virtual void systemHardwareConfigReset();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
11
lib/xnode-shared/XnodeSystemModule.h
Normal file
11
lib/xnode-shared/XnodeSystemModule.h
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
#ifndef XnodeSystemModule_h
|
||||
#define XnodeSystemModule_h
|
||||
|
||||
class XnodeSystemModule {
|
||||
public:
|
||||
virtual bool systemModuleCommandExecute(char* cmd, char** args);
|
||||
virtual void systemModuleCommandList();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
85
lib/xnode-shared/XnodeUtil.cpp
Normal file
85
lib/xnode-shared/XnodeUtil.cpp
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
#include <XnodeUtil.h>
|
||||
|
||||
char unpstr_buff[UNPSTR_BUFF_SIZE]; // buffer to copy progmem data into
|
||||
|
||||
// Uncopy from program/flash memory to sram
|
||||
char* XnodeUtil::UNPSTR(const char* ptr) {
|
||||
for (uint8_t i = ZERO; i < UNPSTR_BUFF_SIZE; i++) {
|
||||
unpstr_buff[i] = '\0'; // clean buffer
|
||||
}
|
||||
uint8_t i = ZERO;
|
||||
uint8_t c = ZERO;
|
||||
do {
|
||||
c = pgm_read_byte(ptr++);
|
||||
unpstr_buff[i++] = c;
|
||||
} while (c != ZERO);
|
||||
return unpstr_buff;
|
||||
}
|
||||
|
||||
// Fill pstr_buff from pointer
|
||||
char* XnodeUtil::UNPSTRA(const uint16_t* argu) {
|
||||
// rm readByte use word which auto size ptr
|
||||
uint8_t msb = pgm_read_byte((const char*) argu + 1);
|
||||
uint8_t lsb = pgm_read_byte((const char*) argu);
|
||||
const char*p = (const char*) ((msb * 256) + lsb);
|
||||
return UNPSTR(p);
|
||||
}
|
||||
|
||||
uint8_t XnodeUtil::strcmp(char *s1, char *s2) {
|
||||
while (*s1 && *s2 && *s1 == *s2) {
|
||||
s1++;
|
||||
s2++;
|
||||
}
|
||||
if (*s1 == *s2) {
|
||||
return 0;
|
||||
}
|
||||
if (*s1 < *s2) {
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint8_t XnodeUtil::strcmpP(char *s1, const char* s2) {
|
||||
return strcmp(s1, UNPSTR(s2));
|
||||
}
|
||||
|
||||
void XnodeUtil::charsToByteA(char* input,byte* data, byte data_len) {
|
||||
for (byte i = ZERO; i < data_len; i++) {
|
||||
data[i] = ZERO; // clear array
|
||||
}
|
||||
byte charIdx = ZERO;
|
||||
for (byte i = ZERO; i < data_len; i++) {
|
||||
char c1 = input[charIdx];
|
||||
char c2 = input[charIdx + ONE];
|
||||
if (c1 == ZERO || c2 == ZERO) {
|
||||
break;
|
||||
}
|
||||
data[i] = charsToByte(c1, c2);
|
||||
charIdx++;
|
||||
charIdx++;
|
||||
}
|
||||
}
|
||||
|
||||
byte XnodeUtil::charsToByte(char c1, char c2) {
|
||||
byte result = ZERO;
|
||||
result += charToNibble(c1) * 16;
|
||||
result += charToNibble(c2);
|
||||
return result;
|
||||
}
|
||||
|
||||
byte XnodeUtil::charToNibble(char c) {
|
||||
uint8_t result = ZERO;
|
||||
if (c > '0' && c <= '9') {
|
||||
result = c - '0';
|
||||
} else if (c >= 'A' && c <= 'F') {
|
||||
result = c - 'A' + 10;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int XnodeUtil::freeRam() {
|
||||
extern int __heap_start, *__brkval;
|
||||
int v;
|
||||
return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
|
||||
}
|
||||
|
||||
27
lib/xnode-shared/XnodeUtil.h
Normal file
27
lib/xnode-shared/XnodeUtil.h
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
#ifndef XnodeUtil_h
|
||||
#define XnodeUtil_h
|
||||
|
||||
#include <XnodeConstants.h>
|
||||
#include <avr/pgmspace.h>
|
||||
#include <Arduino.h>
|
||||
|
||||
#define UNPSTR_BUFF_SIZE 32
|
||||
|
||||
class XnodeUtil {
|
||||
public:
|
||||
static char* UNPSTR(const char* ptr);
|
||||
static char* UNPSTRA(const uint16_t* argu);
|
||||
static uint8_t strcmp(char *s1, char *s2);
|
||||
static uint8_t strcmpP(char *s1, const char* s2);
|
||||
|
||||
static void charsToByteA(char* input,byte* data, byte data_len);
|
||||
static byte charsToByte(char c1, char c2);
|
||||
static byte charToNibble(char s);
|
||||
|
||||
static int freeRam();
|
||||
};
|
||||
|
||||
extern XnodeUtil XUtil;
|
||||
|
||||
#endif
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue