SOOlink Winenet datalink protocol

I’m currently re-working out the Winenet protocol which is implemented as datalink protocol in SOOlink for wireless connectivity between smart objects.
Winenet uses the so-called Unibroad transmission mode which consists in broadcasting data packets to all known neighbours but actually using a unicast mode; it allows to take advantage of a much better bandwidth in the wireless connection and to implement a simple protocol using send with acknowledgment for each packet.

So far, Winenet implements a FSM with a couple of states such as Idle, Speaker, Listener, Speaker_wait_ack, etc. leading to a quite complex handling of various scenarios. The new proposed solution is now based on 3 states only: Idle, Speaker and Listener. All acknowledgment and possible retries of packets are managed within the Speaker state.

Furthermore, each smart object owns a list of neighbours as depicted on the figure below, and for each known neighbour, we also know the list of its neighbours. This will help in managing hidden nodes and to reduce interference when a smart object is sending data.


Hence, each smart object owns a list of neighbours and their “friends”. The friends are listed in bracket.

A smart object which is showing up in the environment is recognized by the beacon packets sent by the Discovery block (every second). The smart object becomes valid by the other SOO once it has been ping’d correctly.
Depending on its agency UID, it will send a PING REQUEST and waits for a RESPONSE. This exchange will determine which can become a speaker or listener (the lowest agencyUID has the priority and becomes a speaker). But the smart object becomes speaker only if the other one has no associated speaker yet (this information is now part of the private data encoded in the beacon).

The support for hidden nodes has been implemented in a first version and results are rather promising. See the documentation to get the first results with different topologies.

Well, preserving the friends did not bring so much interesting in order to manage hidden nodes. We have implemented a simpler approach based on “paired-to-speaker” field stored in the discovery beacon. The update callback which is called periodically can inform about the status of each neighbour and simple decision can be made based on it. The speaker state requires to have a self-reference in this field so, if the node suddenly appears to be not speaker anymore, it can be easily detected by consulting the list of neighbours and their pairing status.

Some updates regarding Winenet datalink protocol:
From now, the paired-to-speaker field is stored in the wnet_neighbour_t structure which is at the datalink level (and not in the Discovery itself).
A lot of improvements have been pushed onto the master branch including full support of hidden nodes. The whole processing of SPEAKER and LISTENER states have been completely revisited using an efficient iterator (with related actions) of valid neighbours.

The major change is that callbacks executed from the Discovery are used only to check if the neighbour is valid or not. If not, the standard PING procedure is performed.
Each neighbour (including ourself, valid being false) contains a private state structure which is transmitted along each beacon (of any type). Each smart object has the information about the paired-speaker field and the randnr random number used in case of beacon contentions.
The LISTENER state remains the only state where a transition to SPEAKER is allowed depending on the neighbour states.