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);
}
/*---------------------------------------------------------------------------*/