add parser class for serial and ethernet gateways

This commit is contained in:
Marcelo Aquino
2015-02-19 21:39:46 -02:00
parent 70b476ede4
commit c358d8705a
8 changed files with 162 additions and 180 deletions
+5
View File
@@ -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
+4
View File
@@ -0,0 +1,4 @@
#include "MyParser.h"
MyParser::MyParser() {
}
+16
View File
@@ -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
+81
View File
@@ -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;
}
+15
View File
@@ -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
+1
View File
@@ -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;