mMESH – Technical deep dive

Folder structure for mMesh[1]:

  • 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

Public methods:

/* 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);
virtual ~Mesh();
void setMaster();
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);
bool getPaired();
bool getRegisteredToMaster();
int getNeighbourCount();
char *getName();

MeshNetworkHandler

In general MeshNetworkHandler handles communication with the network adapter offloading this task from the mesh class.

Public methods:

MeshNetworkHandler(NetworkData *network,
network::NetworkInterface *nw,
NetAlgorithm::NetAlgorithmInterface *algorithm);
virtual ~MeshNetworkHandler();
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 doBroadcastAssociateReq();
void doBroadcastAssociateRsp(union mesh_internal_msg *msg);
void doRegisterReq();
void doPingParentReq();
void doRegisterToMasterRsp(union mesh_internal_msg *msg);
int doChooseParent();
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 doSeekNeighbours();
void doNeighborRsp(union mesh_internal_msg *msg);
void doPingNeighbours();
void doPingNeighbourRsp(union mesh_internal_msg *msg);

[1] https://github.com/payano/mMesh

Leave a Reply

Your email address will not be published. Required fields are marked *