Skip to content

Thingsquare device states

During a device operation, it will be in various kinds of states. It may be completely fresh from factory, or it may be connected to the server directly over TLS, and everything in between.

Knowing the state of a device can be useful to the application firmware eg to indicate to a human user that the ethernet cable is unplugged, or that a device should be invited to the network. It could also be used for operational parameters. For example, a device may choose to not perform any sensor sampling until it also can send data to the servers, in order to conserve energy.

Brief overview of device states

The set of states are defined in thsq.h. Some states are for internal use only, but are included in the overview for completeness and curiosity.

THSQ_STATE_WAITING_FOR_BOND
THSQ_STATE_WAITING_FOR_MUCHA
THSQ_STATE_WAITING_FOR_RPL
THSQ_STATE_WAITING_FOR_MASTER
THSQ_STATE_WAITING_FOR_PONG
THSQ_STATE_WAITING_FOR_DNS
THSQ_STATE_WAITING_FOR_TLS
THSQ_STATE_WAITING_FOR_AUTH
THSQ_STATE_WAITING_FOR_NOTHING
THSQ_STATE_WAITING_FOR_CABLE
THSQ_STATE_WAITING_FOR_NETWORK

Some states are not valid for all devices, eg THSQ_STATE_WAITING_FOR_CABLE which may only happen on ethernet-enabled devices.

States overview

State THSQ_STATE_WAITING_FOR_BOND

The state THSQ_STATE_WAITING_FOR_BOND means that a device is not paired with an access point yet. The device must be paired with an access point in order to join the network to be able to push and receive data with the backend servers.

State THSQ_STATE_WAITING_FOR_MUCHA

The state THSQ_STATE_WAITING_FOR_MUCHA means that the device has a pairing with an access point, but is waiting to synchronize with the channel hopping protocol before it can join the network. Internal use only.

State THSQ_STATE_WAITING_FOR_RPL

The state THSQ_STATE_WAITING_FOR_RPL means that the device waits for it to join the self-healing mesh network. Internal use only.

State THSQ_STATE_WAITING_FOR_MASTER

The state THSQ_STATE_WAITING_FOR_MASTER means that the device waits for a specific parent to ackowledge it before it can enter a more power-saving mode. Internal use only.

State THSQ_STATE_WAITING_FOR_PONG

The state THSQ_STATE_WAITING_FOR_PONG means that the device waits for the server. Internal use only.

State THSQ_STATE_WAITING_FOR_DNS

The state THSQ_STATE_WAITING_FOR_DNS means that the device waits for DNS response before being able to communicate with the servers. Internal use only.

State THSQ_STATE_WAITING_FOR_TLS

The state THSQ_STATE_WAITING_FOR_TLS means that the device is about to connect over TLS and is waiting for this to be completed. Internal use only.

State THSQ_STATE_WAITING_FOR_AUTH

The state THSQ_STATE_WAITING_FOR_AUTH means that the device is waiting for a response from the server. Internal use only.

State THSQ_STATE_WAITING_FOR_NOTHING

The state THSQ_STATE_WAITING_FOR_NOTHING means that the device has everything that it needs to fully start operating. This is the normal state once a device has been invited, or fully booted up.

State THSQ_STATE_WAITING_FOR_CABLE

The state THSQ_STATE_WAITING_FOR_CABLE means that the an ethernet-enabled device does not have the ethernet cable plugged in. It can also mean that the cable is faulty, or the router on the other end of the cable is not switched on or operational. Most commonly used with access points.

State THSQ_STATE_WAITING_FOR_NETWORK

The state THSQ_STATE_WAITING_FOR_NETWORK means that the device is waiting for a response from the access point. Internal use only.

A few states in detail

The following will go into a couple of states in more detail. These states are more likely than the others to be of use to an application.

Waiting for invitation

Before a device can ever do anything over a network, much less communicate with a remote backend server, it needs to set a few things up. For example, it needs to establish an identity with the server, and it needs to set up encryption keys and channel hopping with the network root. This initial set up is done once per device and is typically done when first plugging in a product to power.

The procedure to do this is called inviting, or bonding. A user must explicitly instruct an access point to allow a device to join the network. This can be done using the smartphone app in a number of ways, for example by finding the unbonded device with BLE and clicking it, then selecting the access point it should be invited to. Another way is to select the access point itself and clicking invite. It can also be done over the RESTful server API.

Before this initial invitation is performed, the device is in the state THSQ_STATE_WAITING_FOR_BOND. Thus, an application may use this to signal to a human user that they need to invite it, eg by showing a message on a display or blinking LEDs. Note that the setup procedure may take a couple of minutes the first time.

Normal operating state

When a device has been invited, it will perform some one-time setting up activities, including a TLS connect to the servers. When it is fully done and does not have anything in particular it must do before it can function normally, it will be in the state THSQ_STATE_WAITING_FOR_NOTHING.

Ethernet cable malfunction

Access Points are typically ethernet-enabled devices. There are a number of things that can be detected from the access point itself regarding the physical connection to the router.

  • cable not plugged in (at access point, or router)
  • cable broken (eg bad connector)
  • the router the access point is connected to is not powered up, or malfunctioning

Note that these errors are all treated and indicated the same way, through state THSQ_STATE_WAITING_FOR_CABLE. The access point cannot distinguish between them.

How to check for the current state

The current state is retrieved through int thsq_get_current_state(void);.

The following is an example of how the state can be used in the start-up routine to indicate to a human user that we are in a boot-up state.

/*---------------------------------------------------------------------------*/
PROCESS(startup_blink_process, "Startup blink process");
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(startup_blink_process, ev, data)
{
  PROCESS_BEGIN();
  while(thsq_get_current_state() != THSQ_STATE_WAITING_FOR_NOTHING) {
    static struct etimer et;
    leds_toggle(LEDS_RED);
    etimer_set(&et, CLOCK_SECOND * 5);
    PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et));
  }

  /* when we arrive here, we are done waiting and in normal operational mode */
  leds_off(LEDS_ALL);
  PROCESS_END();
}
/*---------------------------------------------------------------------------*/
void
app(void)
{
  /* ....after all the other normal things */
  process_start(&startup_blink_process, NULL);
}
/*---------------------------------------------------------------------------*/