Skip to content

Commit

Permalink
Improved mesh handling.
Browse files Browse the repository at this point in the history
  • Loading branch information
Idorobots committed Nov 4, 2024
1 parent 668b077 commit 5fffa14
Show file tree
Hide file tree
Showing 8 changed files with 143 additions and 43 deletions.
25 changes: 6 additions & 19 deletions device/src/APIServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,30 +106,17 @@ void APIServer::handleApiMesh() {
this->system.log().debug("Serving /api/mesh");
JSONVar mesh;

JSONVar self;

self["hostname"] = this->system.device().name();
self["ip"] = WiFi.localIP().toString();
self["port"] = SSM_PORT;

mesh[0] = self;

uint16_t i = 0;
while(true) {
String hostname = MDNS.hostname(i); // FIXME Causes an error log on the serial.

if(hostname == "") break;

foreach<Host>(this->system.mesh().getHosts(), [&](Host h) {
JSONVar ssn;

ssn["hostname"] = hostname;
ssn["ip"] = MDNS.IP(i).toString();
ssn["port"] = MDNS.port(i);
ssn["hostname"] = h.hostname;
ssn["ip"] = h.ip;
ssn["port"] = h.port;

mesh[i + 1] = ssn;
mesh[i] = ssn;
i++;
}

});
this->sendHeader(CORS_HEADER, ALLOWED_ORIGIN);
this->sendJSON(200, mesh);
}
Expand Down
2 changes: 0 additions & 2 deletions device/src/APIServer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
#ifdef ESP8266
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>

#define WebServer ESP8266WebServer

Expand All @@ -13,7 +12,6 @@
#ifdef ESP32
#include <WiFi.h>
#include <WebServer.h>
#include <ESPmDNS.h>
#endif

#include <Arduino_JSON.h>
Expand Down
8 changes: 8 additions & 0 deletions device/src/List.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,12 @@ void foreach(const List<T> *i, std::function<void(T)> f) {
}
}

template<typename T>
bool contains(List<T> *list, T needle) {
if(list == nullptr) {
return false;
} else {
return list->item == needle || contains(list->next, needle);
}
}
#endif
55 changes: 55 additions & 0 deletions device/src/Mesh.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#include "Mesh.hpp"

Mesh::Mesh(): hosts(nullptr) {}

Mesh::~Mesh() {
if (this->hosts != nullptr) {
delete this->hosts;
}
}

void Mesh::addHost(Host h) {
this->hosts = new List<Host>(h, this->hosts);
}

const List<Host>* Mesh::getHosts() {
return this->hosts;
}

void Mesh::scan() {
MDNS.queryService("ssm", "tcp");

uint16_t i = 0;
while(true) {
String h = MDNS.hostname(i); // FIXME Causes an error log on the serial.

if(h == "") break;

String ip = MDNS.IP(i).toString();

Host host = Host(h, ip, MDNS.port(i));

if(!contains(this->hosts, host)) {
this->addHost(host);
}

i++;
}
}

void Mesh::update() {
#ifdef ESP8266
MDNS.update();
#endif
}

bool Mesh::begin(String hostname, String ip, uint16_t port) {
// NOTE Add self to start the mesh.
this->addHost(Host(hostname, ip, port));

bool ret = MDNS.begin(hostname.c_str());
MDNS.addService("http", "tcp", port);
MDNS.addService("ssm", "tcp", port);

return ret;
}
50 changes: 50 additions & 0 deletions device/src/Mesh.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#ifndef __MESH_HPP__
#define __MESH_HPP__

#include <Arduino.h>

#ifdef ESP8266
#include <ESP8266mDNS.h>
#endif

#ifdef ESP32
#include <ESPmDNS.h>
#endif

#include "List.hpp"

struct Host {
String hostname;
String ip;
uint16_t port;

Host(String h, String i, uint16_t p)
: hostname(h),
ip(i),
port(p)
{}

bool operator==(const Host& other) const {
return hostname == other.hostname && ip == other.ip && port == other.port;
}
};

class Mesh {
private:
List<Host> *hosts; // FIXME Could use Reading<any> here.

public:

Mesh();
~Mesh();

bool begin(String hostname, String ip, uint16_t port);

void scan();
void update();
void addHost(Host h);

const List<Host> *getHosts();
};

#endif
9 changes: 6 additions & 3 deletions device/src/System.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#include "System.hpp"
#include "Device.hpp"
#include "sensors/BMP.hpp"
#include "sensors/DallasTemp.hpp"
#include "sensors/DHT.hpp"
Expand All @@ -14,7 +13,8 @@
System::System(Timestamp slice):
l(Log()),
sched(Scheduler(slice, l)),
dev(Device())
dev(Device()),
m(Mesh())
{}

bool System::begin(JSONVar &config) {
Expand Down Expand Up @@ -195,7 +195,6 @@ bool System::begin(JSONVar &config) {
}

l.info("Device tree initialized");

return true;
}

Expand All @@ -220,3 +219,7 @@ Device& System::device() {
Log& System::log() {
return l;
}

Mesh& System::mesh() {
return m;
}
5 changes: 4 additions & 1 deletion device/src/System.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <Arduino.h>
#include <Arduino_JSON.h>
#include "Log.hpp"
#include "Mesh.hpp"
#include "Scheduler.hpp"
#include "Device.hpp"
#include "Sensor.hpp"
Expand All @@ -15,8 +16,9 @@
class System {
private:
Log l;
Scheduler sched;
Mesh m;
Device dev;
Scheduler sched;

public:
System(Timestamp slice);
Expand All @@ -27,6 +29,7 @@ class System {

Scheduler& scheduler();
Device& device();
Mesh& mesh();
Log& log();
};

Expand Down
32 changes: 14 additions & 18 deletions device/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

#ifdef ESP8266
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>

const int SDA_PIN = 4;
Expand All @@ -11,7 +10,6 @@ const int SCL_PIN = 5;

#ifdef ESP32
#include <WiFi.h>
#include <WebServer.h>
#include <ESPmDNS.h>

const int SDA_PIN = 21;
Expand Down Expand Up @@ -91,21 +89,6 @@ void setup(void){
ssn.log().info("- Password: %s", ssn.device().password().c_str());
ssn.log().info("- IP address: %s", WiFi.softAPIP().toString().c_str());

// SERVICE DISCOVERY
MDNS.begin(ssn.device().name().c_str());
MDNS.addService("ssm", "tcp", SSM_PORT);
ssn.scheduler().spawn("scan SSM services", 125, [](Task *t) {
ssn.log().debug("Querying for SSM services via mDNS.");
MDNS.queryService("ssm", "tcp");
t->sleep(SERVICE_QUERY_INTERVAL);
});
#ifdef ESP8266
ssn.scheduler().spawn("handle mDNS", 125, [](Task *t) {
MDNS.update();
});
#endif
ssn.log().info("mDNS responder initialized");

// API
APIServer *server = new APIServer(ssn, LittleFS);
server->begin();
Expand All @@ -132,8 +115,21 @@ void setup(void){
ElegantOTA.loop();
});

MDNS.addService("http", "tcp", SSM_PORT);
ssn.log().info("API server initialized");

// Service discovery
ssn.mesh().begin(ssn.device().name(), WiFi.localIP().toString(), SSM_PORT);

ssn.scheduler().spawn("scan for SSM services", 125, [](Task *t) {
ssn.log().debug("Querying for SSM services via mDNS.");
ssn.mesh().scan();
t->sleep(SERVICE_QUERY_INTERVAL);
});
ssn.scheduler().spawn("handle mesh", 125, [](Task *t) {
ssn.mesh().update();
});

ssn.log().info("Mesh responder initialized");
}

void loop(void) {
Expand Down

0 comments on commit 5fffa14

Please sign in to comment.