Folder structure for mMesh:
- src/spi # Serial Peripheral Interface (SPI)
- src/test # GTest
- src/test/mesh # GTest
- src/syscalls # Wrapper for calls like sleep and timers, differs between different platforms.
- src/netAlgorithm # Implementation for network algorithms for choosing parent, neighbour and routing for packets.
- src/mesh # Mesh implementation
- src/network # Network adapter and network drivers
- src/network/RF24 # RF24 driver ported from https://github.com/nRF24/RF24
- src/node # Is used for testing, a node simulates a radio with network functionality
- src/GPIO # General Purpose Input Output (GPIO)
- src/islands # Is used for testing, simulates physical boundaries, if two nodes reside in one island they are able to speak with each other.
Mesh class public methods:
In general, The mesh class is responsible for creating, updating and maintaining the mesh network.
It consists of a state machine with the important states STATE_MASTER, STATE_STARTING and STATE_STARTED
The starting state has six substates and the started state has five substates.
The struct stateDate holds information for the states.
- When starting up all nodes, one node must become master.
- All unpaired nodes is in the FSM state STATE_INIT and transitions to STATE_STARTING
- When one and only one master is online, the network can start to take form.
- The unpaired nodes sends a BROADCAST_ASSOCIATE_REQ, the master will then respond with an BROADCAST_ASSOCIATE_RSP.
- The unpaired node can now directly communicate with another node because it has the address. It will then send NETWORK_ASSIGNMENT_REQ to the master node.
- The master node will then send a NETWORK_ASSIGNMENT_RSP, in that message there is an entry for the child address.
- The node is now paired.
- The node will then send a REGISTER_TO_MASTER_REQ and then master will respond with an REGISTER_TO_MASTER_RSP.
- The node is now paired and connected to master, therefore fully connected to the network.
- The paired node is now in state STATE_STARTED.
- When the paired node is in STATE_STARTED it can assosciate childs, in the same way the master did.
- A master can have five connected childs, a node in the network can have four connected child at a given time. Data pipe 0 is for broadcast and pipe 1 is for master (and neighbours) communicating with the node.
- When the node is in STATE_STARTED it periodically pings it’s parent and neighbours.
- The pinging part is always the child. If a parent hasn’t got a ping from a child for a given time interval, it will consider the child to be disconnected. It will send a disconnect req to the child and consider it dead, being able to pair up a new child if there is a incoming BROADCAST_ASSOCIATE_REQ from a unconnected node.
- If a parent is not responding to pings after a given period, the node will consider the parent as dead. The node will send disconnects to all its childs and also send a disconnect to parent(?). It will then generate a new random address and try go get connected to the network again.
Note: the public methods needs to be updated, for now, there is no way to retrieve an incoming message or
get feedback if the last sent was delivered
/* In the constructor initial things is done as well as creating an instance of MeshNetworkHandler which is the layer communicating with the network adapter */
Mesh(NetworkInterface *nw, syscalls::SyscallsInterface *syscalls);
int run(); /* This is the method the node will be calling in order to run the mesh network */
void setName(char *name);
void getParent(struct net_address *addr);
bool setTemporaryMacAddr(const struct net_address *mac);
In general MeshNetworkHandler handles communication with the network adapter offloading this task from the mesh class.
int getSubnetToChild(struct net_address *address);
void network_recv(union mesh_internal_msg *msg) override;
/* Mesh related */
/* Formulate messages and send them to the adapter */
void doBroadcastAssociateRsp(union mesh_internal_msg *msg);
void doRegisterToMasterRsp(union mesh_internal_msg *msg);
void doRegisterToMasterReq(union mesh_internal_msg *msg);
void doNetworkAssignmentRsp(union mesh_internal_msg *msg);
void doDisconnectChildReq(struct node_data *node);
void doPingParentRsp(union mesh_internal_msg *msg);
void doNeighborRsp(union mesh_internal_msg *msg);
void doPingNeighbourRsp(union mesh_internal_msg *msg);