add parser class for serial and ethernet gateways
This commit is contained in:
@@ -35,6 +35,11 @@ typedef class MyRFDriverNRF24 MyRFDriverClass;
|
||||
typedef class MyRFDriverRF69 MyRFDriverClass;
|
||||
#endif
|
||||
|
||||
#if defined(MYSENSORS_SERIAL_GATEWAY) || defined(MYSENSORS_ETHERNET_GATEWAY)
|
||||
#include "MyParserSerial.h"
|
||||
typedef class MyParserSerial MyParserClass;
|
||||
#endif
|
||||
|
||||
#ifdef MYSENSORS_SIGNING_DUMMY
|
||||
#include "MySigningDriverDummy.h"
|
||||
#define SIGNING_IDENTIFIER (0) // Reserved for dummy implementation, will not work with other backends
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
#include "MyParser.h"
|
||||
|
||||
MyParser::MyParser() {
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
#ifndef MyParser_h
|
||||
#define MyParser_h
|
||||
|
||||
#include "MyMessage.h"
|
||||
|
||||
class MyParser
|
||||
{
|
||||
public:
|
||||
// MyParser constructor
|
||||
MyParser();
|
||||
// parse(message, inputString)
|
||||
// parse a string into a message element
|
||||
// returns true if successfully parsed the input string
|
||||
virtual bool parse(MyMessage &message, char *inputString) = 0;
|
||||
};
|
||||
#endif
|
||||
@@ -0,0 +1,81 @@
|
||||
#include "MyParser.h"
|
||||
#include "MyParserSerial.h"
|
||||
|
||||
MyParserSerial::MyParserSerial() : MyParser() {}
|
||||
|
||||
bool MyParserSerial::parse(MyMessage &message, char *inputString) {
|
||||
char *str, *p, *value=NULL;
|
||||
uint8_t bvalue[MAX_PAYLOAD];
|
||||
uint8_t blen = 0;
|
||||
int i = 0;
|
||||
uint8_t command = 0;
|
||||
uint8_t ack = 0;
|
||||
|
||||
// Extract command data coming on serial line
|
||||
for (str = strtok_r(inputString, ";", &p); // split using semicolon
|
||||
str && i < 6; // loop while str is not null an max 5 times
|
||||
str = strtok_r(NULL, ";", &p) // get subsequent tokens
|
||||
) {
|
||||
switch (i) {
|
||||
case 0: // Radioid (destination)
|
||||
message.destination = atoi(str);
|
||||
break;
|
||||
case 1: // Childid
|
||||
message.sensor = atoi(str);
|
||||
break;
|
||||
case 2: // Message type
|
||||
command = atoi(str);
|
||||
mSetCommand(message, command);
|
||||
break;
|
||||
case 3: // Should we request ack from destination?
|
||||
ack = atoi(str);
|
||||
break;
|
||||
case 4: // Data type
|
||||
message.type = atoi(str);
|
||||
break;
|
||||
case 5: // Variable value
|
||||
if (command == C_STREAM) {
|
||||
blen = 0;
|
||||
uint8_t val;
|
||||
while (*str) {
|
||||
val = h2i(*str++) << 4;
|
||||
val += h2i(*str++);
|
||||
bvalue[blen] = val;
|
||||
blen++;
|
||||
}
|
||||
} else {
|
||||
value = str;
|
||||
// Remove ending carriage return character (if it exists)
|
||||
uint8_t lastCharacter = strlen(value)-1;
|
||||
if (value[lastCharacter] == '\r')
|
||||
value[lastCharacter] = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
// Check for invalid input
|
||||
if (i < 5)
|
||||
return false;
|
||||
|
||||
message.sender = GATEWAY_ADDRESS;
|
||||
message.last = GATEWAY_ADDRESS;
|
||||
mSetRequestAck(message, ack?1:0);
|
||||
mSetAck(message, false);
|
||||
if (command == C_STREAM)
|
||||
message.set(bvalue, blen);
|
||||
else
|
||||
message.set(value);
|
||||
return true;
|
||||
}
|
||||
|
||||
uint8_t MyParserSerial::h2i(char c) {
|
||||
uint8_t i = 0;
|
||||
if (c <= '9')
|
||||
i += c - '0';
|
||||
else if (c >= 'a')
|
||||
i += c - 'a' + 10;
|
||||
else
|
||||
i += c - 'A' + 10;
|
||||
return i;
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
#ifndef MyParserSerial_h
|
||||
#define MyParserSerial_h
|
||||
|
||||
#include "MyConfig.h"
|
||||
#include "MyParser.h"
|
||||
|
||||
class MyParserSerial : public MyParser
|
||||
{
|
||||
public:
|
||||
MyParserSerial();
|
||||
bool parse(MyMessage &message, char *inputString);
|
||||
private:
|
||||
uint8_t h2i(char c);
|
||||
};
|
||||
#endif
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
#include "Version.h" // Auto generated by bot
|
||||
#include "MyRFDriver.h"
|
||||
#include "MyParser.h"
|
||||
#include "MySigningDriver.h"
|
||||
#include "MyConfig.h"
|
||||
#include "MyMessage.h"
|
||||
|
||||
@@ -23,7 +23,7 @@ volatile uint8_t countErr;
|
||||
boolean inclusionMode; // Keeps track on inclusion mode
|
||||
void (*serial)(const char *fmt, ... );
|
||||
|
||||
MyMessage msg;
|
||||
MyParserClass parser;
|
||||
|
||||
void setInclusionMode(boolean newMode);
|
||||
void txBlink(uint8_t cnt);
|
||||
@@ -104,102 +104,32 @@ void checkInclusionFinished() {
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t h2i(char c) {
|
||||
uint8_t i = 0;
|
||||
if (c <= '9')
|
||||
i += c - '0';
|
||||
else if (c >= 'a')
|
||||
i += c - 'a' + 10;
|
||||
else
|
||||
i += c - 'A' + 10;
|
||||
return i;
|
||||
}
|
||||
|
||||
void parseAndSend(MySensor gw, char *commandBuffer) {
|
||||
boolean ok = false;
|
||||
char *str, *p, *value=NULL;
|
||||
uint8_t bvalue[MAX_PAYLOAD];
|
||||
uint8_t blen = 0;
|
||||
int i = 0;
|
||||
uint16_t destination = 0;
|
||||
uint8_t sensor = 0;
|
||||
uint8_t command = 0;
|
||||
uint8_t type = 0;
|
||||
uint8_t ack = 0;
|
||||
boolean ok;
|
||||
MyMessage &msg = gw.getLastMessage();
|
||||
|
||||
// Extract command data coming on serial line
|
||||
for (str = strtok_r(commandBuffer, ";", &p); // split using semicolon
|
||||
str && i < 6; // loop while str is not null an max 5 times
|
||||
str = strtok_r(NULL, ";", &p) // get subsequent tokens
|
||||
) {
|
||||
switch (i) {
|
||||
case 0: // Radioid (destination)
|
||||
destination = atoi(str);
|
||||
break;
|
||||
case 1: // Childid
|
||||
sensor = atoi(str);
|
||||
break;
|
||||
case 2: // Message type
|
||||
command = atoi(str);
|
||||
break;
|
||||
case 3: // Should we request ack from destination?
|
||||
ack = atoi(str);
|
||||
break;
|
||||
case 4: // Data type
|
||||
type = atoi(str);
|
||||
break;
|
||||
case 5: // Variable value
|
||||
if (command == C_STREAM) {
|
||||
blen = 0;
|
||||
uint8_t val;
|
||||
while (*str) {
|
||||
val = h2i(*str++) << 4;
|
||||
val += h2i(*str++);
|
||||
bvalue[blen] = val;
|
||||
blen++;
|
||||
}
|
||||
} else {
|
||||
value = str;
|
||||
// Remove ending carriage return character (if it exists)
|
||||
uint8_t lastCharacter = strlen(value)-1;
|
||||
if (value[lastCharacter] == '\r')
|
||||
value[lastCharacter] = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if (parser.parse(msg, commandBuffer)) {
|
||||
uint8_t command = mGetCommand(msg);
|
||||
|
||||
if (destination==GATEWAY_ADDRESS && command==C_INTERNAL) {
|
||||
// Handle messages directed to gateway
|
||||
if (type == I_VERSION) {
|
||||
// Request for version
|
||||
serial(PSTR("0;0;%d;0;%d;%s\n"), C_INTERNAL, I_VERSION, LIBRARY_VERSION);
|
||||
} else if (type == I_INCLUSION_MODE) {
|
||||
// Request to change inclusion mode
|
||||
setInclusionMode(atoi(value) == 1);
|
||||
}
|
||||
} else {
|
||||
txBlink(1);
|
||||
msg.sender = GATEWAY_ADDRESS;
|
||||
msg.destination = destination;
|
||||
msg.sensor = sensor;
|
||||
msg.type = type;
|
||||
mSetCommand(msg,command);
|
||||
mSetRequestAck(msg,ack?1:0);
|
||||
mSetAck(msg,false);
|
||||
if (command == C_STREAM)
|
||||
msg.set(bvalue, blen);
|
||||
else
|
||||
msg.set(value);
|
||||
ok = gw.sendRoute(msg);
|
||||
if (!ok) {
|
||||
errBlink(1);
|
||||
if (msg.destination==GATEWAY_ADDRESS && command==C_INTERNAL) {
|
||||
// Handle messages directed to gateway
|
||||
if (msg.type == I_VERSION) {
|
||||
// Request for version
|
||||
serial(PSTR("0;0;%d;0;%d;%s\n"), C_INTERNAL, I_VERSION, LIBRARY_VERSION);
|
||||
} else if (msg.type == I_INCLUSION_MODE) {
|
||||
// Request to change inclusion mode
|
||||
setInclusionMode(atoi(msg.data) == 1);
|
||||
}
|
||||
} else {
|
||||
txBlink(1);
|
||||
ok = gw.sendRoute(msg);
|
||||
if (!ok) {
|
||||
errBlink(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void setInclusionMode(boolean newMode) {
|
||||
if (newMode != inclusionMode)
|
||||
inclusionMode = newMode;
|
||||
|
||||
@@ -23,7 +23,7 @@ volatile uint8_t countErr;
|
||||
boolean inclusionMode; // Keeps track on inclusion mode
|
||||
void (*serial)(const char *fmt, ... );
|
||||
|
||||
MyMessage msg;
|
||||
MyParserClass parser;
|
||||
|
||||
void setInclusionMode(boolean newMode);
|
||||
void txBlink(uint8_t cnt);
|
||||
@@ -104,102 +104,32 @@ void checkInclusionFinished() {
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t h2i(char c) {
|
||||
uint8_t i = 0;
|
||||
if (c <= '9')
|
||||
i += c - '0';
|
||||
else if (c >= 'a')
|
||||
i += c - 'a' + 10;
|
||||
else
|
||||
i += c - 'A' + 10;
|
||||
return i;
|
||||
}
|
||||
|
||||
void parseAndSend(MySensor gw, char *commandBuffer) {
|
||||
boolean ok = false;
|
||||
char *str, *p, *value=NULL;
|
||||
uint8_t bvalue[MAX_PAYLOAD];
|
||||
uint8_t blen = 0;
|
||||
int i = 0;
|
||||
uint16_t destination = 0;
|
||||
uint8_t sensor = 0;
|
||||
uint8_t command = 0;
|
||||
uint8_t type = 0;
|
||||
uint8_t ack = 0;
|
||||
boolean ok;
|
||||
MyMessage &msg = gw.getLastMessage();
|
||||
|
||||
// Extract command data coming on serial line
|
||||
for (str = strtok_r(commandBuffer, ";", &p); // split using semicolon
|
||||
str && i < 6; // loop while str is not null an max 5 times
|
||||
str = strtok_r(NULL, ";", &p) // get subsequent tokens
|
||||
) {
|
||||
switch (i) {
|
||||
case 0: // Radioid (destination)
|
||||
destination = atoi(str);
|
||||
break;
|
||||
case 1: // Childid
|
||||
sensor = atoi(str);
|
||||
break;
|
||||
case 2: // Message type
|
||||
command = atoi(str);
|
||||
break;
|
||||
case 3: // Should we request ack from destination?
|
||||
ack = atoi(str);
|
||||
break;
|
||||
case 4: // Data type
|
||||
type = atoi(str);
|
||||
break;
|
||||
case 5: // Variable value
|
||||
if (command == C_STREAM) {
|
||||
blen = 0;
|
||||
uint8_t val;
|
||||
while (*str) {
|
||||
val = h2i(*str++) << 4;
|
||||
val += h2i(*str++);
|
||||
bvalue[blen] = val;
|
||||
blen++;
|
||||
}
|
||||
} else {
|
||||
value = str;
|
||||
// Remove ending carriage return character (if it exists)
|
||||
uint8_t lastCharacter = strlen(value)-1;
|
||||
if (value[lastCharacter] == '\r')
|
||||
value[lastCharacter] = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if (parser.parse(msg, commandBuffer)) {
|
||||
uint8_t command = mGetCommand(msg);
|
||||
|
||||
if (destination==GATEWAY_ADDRESS && command==C_INTERNAL) {
|
||||
// Handle messages directed to gateway
|
||||
if (type == I_VERSION) {
|
||||
// Request for version
|
||||
serial(PSTR("0;0;%d;0;%d;%s\n"), C_INTERNAL, I_VERSION, LIBRARY_VERSION);
|
||||
} else if (type == I_INCLUSION_MODE) {
|
||||
// Request to change inclusion mode
|
||||
setInclusionMode(atoi(value) == 1);
|
||||
}
|
||||
} else {
|
||||
txBlink(1);
|
||||
msg.sender = GATEWAY_ADDRESS;
|
||||
msg.destination = destination;
|
||||
msg.sensor = sensor;
|
||||
msg.type = type;
|
||||
mSetCommand(msg,command);
|
||||
mSetRequestAck(msg,ack?1:0);
|
||||
mSetAck(msg,false);
|
||||
if (command == C_STREAM)
|
||||
msg.set(bvalue, blen);
|
||||
else
|
||||
msg.set(value);
|
||||
ok = gw.sendRoute(msg);
|
||||
if (!ok) {
|
||||
errBlink(1);
|
||||
if (msg.destination==GATEWAY_ADDRESS && command==C_INTERNAL) {
|
||||
// Handle messages directed to gateway
|
||||
if (msg.type == I_VERSION) {
|
||||
// Request for version
|
||||
serial(PSTR("0;0;%d;0;%d;%s\n"), C_INTERNAL, I_VERSION, LIBRARY_VERSION);
|
||||
} else if (msg.type == I_INCLUSION_MODE) {
|
||||
// Request to change inclusion mode
|
||||
setInclusionMode(atoi(msg.data) == 1);
|
||||
}
|
||||
} else {
|
||||
txBlink(1);
|
||||
ok = gw.sendRoute(msg);
|
||||
if (!ok) {
|
||||
errBlink(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void setInclusionMode(boolean newMode) {
|
||||
if (newMode != inclusionMode)
|
||||
inclusionMode = newMode;
|
||||
|
||||
Reference in New Issue
Block a user