diff --git a/platformio.ini b/platformio.ini
index 11ad2ab..2ebb608 100644
--- a/platformio.ini
+++ b/platformio.ini
@@ -53,6 +53,8 @@ monitor_baud = ${common.monitor_baud}
framework = ${common.framework}
lib_deps = ${common.lib_deps}
painlessMesh
+ ESP8266mDNS
+ ArduinoOTA
[env:meshMqttBridge]
src_filter = +<*> - +
diff --git a/src/Plugin.h b/src/Plugin.h
index c331e60..c046e3e 100644
--- a/src/Plugin.h
+++ b/src/Plugin.h
@@ -3,13 +3,16 @@
#include
#include
+#include
class Plugin {
protected:
Scheduler* scheduler;
public:
- virtual void enable(Scheduler*, Network*);
+ virtual void setup(Scheduler*, Network*);
+ virtual void enable();
virtual void disable();
+ virtual void onMessage(MeshMessage msg);
};
#endif
\ No newline at end of file
diff --git a/src/base/MeshMessage.h b/src/base/MeshMessage.h
new file mode 100644
index 0000000..6eb8240
--- /dev/null
+++ b/src/base/MeshMessage.h
@@ -0,0 +1,77 @@
+#ifndef __MESH_MESSAGE__
+#define __MESH_MESSAGE__
+
+#include
+#include
+
+#define JSON_DOMAIN "domain"
+#define JSON_FROM "from"
+#define JSON_TO "target"
+#define JSON_MSG "msg"
+
+struct MeshMessage {
+ String domain;
+ String to;
+ String from;
+ String msg;
+ enum MeshMessageType { NONE, SYSTEM, OTA } type;
+ int valid = 0;
+ // ------------------------------------------------------------------------------------------
+ void init() {
+ //from = reinterpret_cast(ESP.getChipId());
+ }
+ int verifyJsonObject(JsonObject& json){
+ return json.success()
+ //&& json.containsKey(JSON_DOMAIN)
+ //&& json.containsKey(JSON_TO)
+ //&& json.containsKey(JSON_FROM)
+ && json.containsKey(JSON_MSG);
+ };
+ String toJsonString(){
+ //StaticJsonBuffer<200> jsonBuffer;
+ DynamicJsonBuffer jsonBuffer(JSON_ARRAY_SIZE(300));
+ JsonObject& root = jsonBuffer.createObject();
+ root[JSON_DOMAIN] = domain;
+ root[JSON_TO] = to;
+ root[JSON_FROM] = from;
+ root[JSON_MSG] = msg;
+ String jsonString;
+ root.printTo(jsonString);
+ return jsonString;
+ }
+ String getAttrFromJson(JsonObject& json, const char* attr){
+ if(json.containsKey(attr)){
+ return json[attr];
+ }
+ return "";
+ }
+ int getIntAttrFromJson(JsonObject& json, const char* attr){
+ if(json.containsKey(attr)){
+ return json[attr];
+ }
+ return 0;
+ }
+ // Map a json object to this struct.
+ void fromJsonObject(JsonObject& json){
+ if(!verifyJsonObject(json)){
+ Serial.println("ERROR: cannot parse MeshMessage JSON object");
+ valid = 0;
+ //return;
+ }
+ domain = getAttrFromJson(json, JSON_DOMAIN);
+ to = getAttrFromJson(json, JSON_TO);
+ from = getAttrFromJson(json, JSON_FROM);
+ msg = getAttrFromJson(json, JSON_MSG);
+ type = (MeshMessageType) getIntAttrFromJson(json, "type");
+ valid = 1;
+ };
+ // Parse a json string and map parsed object
+ void fromJsonString(String& str){
+ //StaticJsonBuffer<200> jsonBuffer;
+ DynamicJsonBuffer jsonBuffer(JSON_ARRAY_SIZE(300));
+ JsonObject& json = jsonBuffer.parseObject(str);
+ fromJsonObject(json);
+ };
+};
+
+#endif
\ No newline at end of file
diff --git a/src/base/MeshSprocket.h b/src/base/MeshSprocket.h
index 085bd06..9bed0ab 100644
--- a/src/base/MeshSprocket.h
+++ b/src/base/MeshSprocket.h
@@ -2,9 +2,11 @@
#define __MESH_SPROCKET__
#define DEBUG_ESP_OTA
+#include
#include
#include
#include
+#include
#include
#include "config.h"
@@ -14,17 +16,37 @@ using namespace std::placeholders;
class MeshSprocket : public Sprocket {
public:
MeshNet* net;
- OtaTcpPlugin* ota;
+ std::vector plugins;
MeshSprocket(SprocketConfig cfg, OtaConfig otaCfg) : Sprocket(cfg) {
- ota = new OtaTcpPlugin(otaCfg);
+ addPlugin(new OtaTcpPlugin(otaCfg));
}
+ void addPlugin(Plugin* p){
+ plugins.reserve(1);
+ plugins.push_back(p);
+ }
+
+ void setupPlugins(Scheduler* scheduler, Network* network){
+ for(Plugin* p : plugins){
+ p->setup(scheduler, network);
+ }
+ }
+
+ void dispatchMessageToPlugins(MeshMessage msg){
+ for(Plugin* p : plugins){
+ if(msg.type != MeshMessage::NONE){
+ Serial.println("dispatch to plugins");
+ p->onMessage(msg);
+ }
+ }
+ }
+
Sprocket* activate(Scheduler* scheduler, Network* network) {
net = static_cast(network);
net->onReceive(bind(&MeshSprocket::dispatch,this, _1, _2));
- // enable plugins
- ota->enable(scheduler, network);
+ // setup plugins
+ setupPlugins(scheduler, network);
return this;
} using Sprocket::activate;
@@ -34,6 +56,11 @@ class MeshSprocket : public Sprocket {
void dispatch( uint32_t from, String &msg ) {
// TODO handle OTA before passing to onMessage
+ MeshMessage mMsg;
+ mMsg.fromJsonString(msg);
+ if(mMsg.valid){
+ dispatchMessageToPlugins(mMsg);
+ }
onMessage(from, msg);
}
diff --git a/src/examples/mesh/MeshApp.cpp b/src/examples/mesh/MeshApp.cpp
index 81150a6..cb44b72 100644
--- a/src/examples/mesh/MeshApp.cpp
+++ b/src/examples/mesh/MeshApp.cpp
@@ -28,8 +28,13 @@ class MeshApp : public MeshSprocket {
} using MeshSprocket::activate;
void heartbeat(MeshNet* network){
- String msg = "{ \"payload \": 1 }";
- network->mesh.sendBroadcast(msg, true);
+ MeshMessage msg; // = { "wirelos", "broadcast", "local", "alive", 0, };
+ msg.domain = "wirelos";
+ msg.to = "broadcast";
+ msg.msg = "alive";
+ String msgStr = msg.toJsonString();
+ //String msg = "{ \"domain\": \"wirelos\",\"from\": \"0\",\"target\": \"broadcast\", \"msg \": \"alive\" }";
+ network->mesh.sendBroadcast(msgStr, true);
}
void onMessage( uint32_t from, String &msg ) {
Serial.printf("MeshApp onMessage: received from %u msg=%s\n", from, msg.c_str());
diff --git a/src/examples/mesh/config.h b/src/examples/mesh/config.h
index ab23017..f958da0 100644
--- a/src/examples/mesh/config.h
+++ b/src/examples/mesh/config.h
@@ -10,15 +10,15 @@
#define STARTUP_DELAY 3000
// Mesh config
-#define STATION_MODE 0
+#define STATION_MODE 1
#define WIFI_CHANNEL 11
#define MESH_PORT 5555
#define MESH_PREFIX "whateverYouLike"
#define MESH_PASSWORD "somethingSneaky"
-#define STATION_SSID "Th1ngs4P"
-#define STATION_PASSWORD "th3r31sn0sp00n"
+#define STATION_SSID "tErAx1d"
+#define STATION_PASSWORD "ramalamadingdong"
#define HOSTNAME "mesh-node"
-#define MESH_DEBUG_TYPES ERROR | STARTUP | CONNECTION
+#define MESH_DEBUG_TYPES ERROR | STARTUP
//ERROR | MESH_STATUS | CONNECTION | SYNC | COMMUNICATION | GENERAL | MSG_TYPES | REMOTE
// OTA config
diff --git a/src/plugins/OtaTcpPlugin.cpp b/src/plugins/OtaTcpPlugin.cpp
index 6ff0a1b..4f2d73f 100644
--- a/src/plugins/OtaTcpPlugin.cpp
+++ b/src/plugins/OtaTcpPlugin.cpp
@@ -18,21 +18,31 @@ class OtaTcpPlugin : public Plugin {
private:
OtaConfig config;
Task otaTask;
+ MeshNet* network;
public:
OtaTcpPlugin(OtaConfig cfg){
config = cfg;
+
}
- void enable(Scheduler* userScheduler, Network* network){
- scheduler = userScheduler;
-
- // connect to network
- if(!network->isConnected()){
- // TODO when config is refactored, cast is not necessary anymore
- static_cast(network)->config.stationMode = 1;
- network->connectStation();
- // TODO set service message to mesh to announce station IP
- }
+ void connectUpdateNetwork(Network* network) {
+ // if(!network->isConnected()){
+ // static_cast(network)->config.stationMode = 1;
+ // }
+ network->connectStation();
+ }
+ void enable() {
+ ArduinoOTA.begin();
+ otaTask.enable();
+ }
+ void onMessage(MeshMessage msg) {
+ //enable();
+ Serial.println("OTA msg received");
+ }
+ void setup(Scheduler* userScheduler, Network* network){
+ // connect done in network class
+ //connectUpdateNetwork(network);
// setup task
+ scheduler = userScheduler;
otaTask.set(TASK_MILLISECOND * 100, TASK_FOREVER, [](){
ArduinoOTA.handle();
});
@@ -62,8 +72,7 @@ class OtaTcpPlugin : public Plugin {
else if (error == OTA_RECEIVE_ERROR) Serial.println("OTA: Receive Failed");
else if (error == OTA_END_ERROR) Serial.println("OTA: End Failed");
});
- ArduinoOTA.begin();
- otaTask.enable();
+ enable();
}
void disable(){
otaTask.disable();