I would modify a bit the existing implementation of EasyMesh, as currently it does not seem to implement node roles. Each node is equal and they can build connections only with each other. As I see there is no way to add a server to their routing tables nor to mark a specific connection record in the tables that has connectivity to a server.
The nodes use a connection list for message routing/forwarding. What you need is a node which has a connection record for the server, this is what the root node is.
Now, currently when a node is powered it will scan the available APs (Access Points), filters out the ones the do not start with the mesh prefix and then connects to the AP with the best RSSI. Also every node creates its own AP with a name mesh prefix + node unique chip ID.
If no other node is available, it will simply wait for others to connect. And this is the first point where changes should be applied. You could hardcode or make somehow configurable a unique AP with a name like mesh prefix + "Server" and if no other EasyMesh AP is available the node should connect to this AP and should store a pre-defined meshConnectionType
object in its connection list.
This object's filed won't be determined by message exchange between the server and the node but can be fixed values, except for the espconn
field. That one should be acquired like in the other cases. In the following struct you will only need the first to member variable.
struct meshConnectionType {
espconn *esp_conn;
uint32_t chipId = 0;
String subConnections;
timeSync time;
uint32_t lastRecieved = 0;
bool newConnection = true;
(...)
};
The chipId
will be the address of the server in the mesh network. You should choose one value that can't be an ESP8266 chip ID.
So basically the first node to power up in your network will be the "root" node. If other nodes want to send messages to the server then the message will be sent to the "root" node based on the in-direct connection (called sub-connections in the code) records.
The "root" node then will find out that it has direct connection to the server (to the router/internet) and as it is a message to the server that it should forward this message in an other way (not a mesh like way). Obviously additional information is needed here like the server's IP address and the used port for example. These also should be stored an the node (on every node) by default or by some configuration method.
So lastly the "root" node will send an IP message to the server, this should be implemented by you again.
TL;DR; Conclusion:
- There should be a server AP and the first node (only the first node to be powered up) should connect to it, this will be the root node.
- The server should have an address (
destId
) that will be used in the mesh network when sending messages to the server. This information should be available to all nodes by default.
- The root node should know that it is connected "directly" to the server/internet. This can be achieved by adding a connection record with the server's
destId
to the root node's connection list.
- The root node knowing that it is connected to the server can forward the messages appropriately via the Internet.
This is just a theoretical idea I come up with by reading through the implementation of the EasyMesh. I may have missed some important fact that would make this hard or impossible to implement. Also it may not the most efficient way to solve the problem. I am not a mesh network expert.
Having a root node in the network asks "What happen if the root gets disconnected? How a new root will be chosen?".