Register a Custom Callback to Follow the Join State#

As described in Event Handling with the Event Manager, it is possible to register custom callbacks for indications listed in sl_wisun_events.h/sl_wisun_msg_ind_id_t.

Note: This is all done in app.c.

To follow what is happening on your Wi-SUN network, a dedicated function is added to do whatever you need and is registered to be called on each join state change.

It is registered with the Event Manager in app.c/app_task() as follows:

  // Register our join state custom callback function with the event manager (aka 'em')
  app_wisun_em_custom_callback_register(SL_WISUN_MSG_JOIN_STATE_IND_ID, _join_state_custom_callback);

The callback function itself is app.c/_join_state_custom_callback(), relying on our 1-second timestamping to store time information. The function uses other parts of the code, so replacing the original app.c by this file is an easy way to get compilable code.

Code Behavior#

  • Check the join state.

  • Only do something when there is a join state change.

    • Do nothing for intermediate join states (with values above 5), which the Stack also handles. These are mainly intermediate stages between join state 4 and join state 5, such as DHCP and DNS, with code between 41 and 49.

    • Trace the previous and current join state when it changed.

    • Store the current time in app_join_state_sec[join_state]. This will be used in traces and to compute the app_join_state_delay_sec[join_state] values, indicating how much time was spent moving to the new join state.

    • If the join state is 'OPERATIONAL' (i.e. 'connected'):

      • Store the time in connection_time_sec.

      • Increase the number of connections.

      • If this is the first connection, clear disconnected_total_sec; otherwise, set it to the time spent since the disconnection.

      • Trace the duration spent connecting.

      • Because it is possible to retrieve the parent MAC address, set the parent_tag from it. This is a convenient way to identify devices using a shorter string than their entire MAC or IPv6 address. It also has the advantage of being visible in both the MAC and IPv6 addresses.

      • If a UDP socket has been opened with the Border Router, send it a connection message with all interesting values. It looks like: { "device":"8486", "chip":"xG25", "parent":"333a", "running":"0:00:00:23", "join_states_sec":[0,0,9,1,12] }. This simple message allows:

        • Identifying which devices are connected, and which part they are built on.

        • Knowing which device is their parent.

          • It becomes possible to draw the network topology based on this.

        • Knowing how much time has been spent moving between join states.

          • In the above example, we see that:

            • No time has been spent to reach join states 1 and 2, due to Wi-SUN stack optimizations allowing reuse of credentials if they are still valid.

            • It took 9 + 1 + 12 = 22 seconds to reconnect. No time spent in join states 1 and 2 means it was a reconnection with previously saved credentials.

    • If the previous join state was 'OPERATIONAL':

      • Store the time in disconnection_time_sec.

      • Trace the duration spent before disconnecting.

      • Add this to 'connected_total_sec'.

    • Set previous_join_state to the new join state.

Using the app_join_state_sec[] array, it becomes possible for the application to compute the values in the connection message.

Using the various timestamp values, it is possible to compute an availability ratio equal to:

availability = 100.0*(connected_total_sec)/(connected_total_sec + disconnected_total_sec).

This value gives an interesting indication on the network availability, even if it is 100+ days long, which should be common in Wi-SUN.