Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 8 Current »

User Application

This Chapter presents how to use the QSL in your application. We begin by presenting details about the API, followed by an example of how a user application might look.

More explicit examples of code are given for certain platforms in later chapters (currently only for the Raspberry Pi).

The QuickStart API

Instead of reading the full user guide for the SmartMesh IP network and mote serial API, the QuickStart Library allows you to get started with simple data publishing by familiarizing yourself with only a handful of functions. These functions define the API and are listed below, followed by a detailed explanation.

QuickStart API
bool dn_qsl_init(void);
bool dn_qsl_isConnected(void);
bool dn_qsl_connect(uint16_t netID, const uint8_t* joinKey, uint16_t srcPort, uint32_t service_ms);
bool dn_qsl_send(const uint8_t* payload, uint8_t payloadSize_B, uint16_t destPort);
uint8_t dn_qsl_read(uint8_t* readBuffer);

 

 

init

Upon startup, this always has to be run once. It will initialize the necessary structures and underlying modules, essentially establishing a serial connection to the Mote.

Parameters: None

Returns: Boolean indicating the success of the initialization. However, currently it will always return TRUE: The underlying init functions of the SmartMesh C Library does not have any return values (it is still included for forward compatability if these init functions are changed to include return values).

isConnected

Simple TRUE/FALSE query to QSL if the mote is currently connected to the SMIP network and ready to send/receive data. This way, the user application can check if it should reconnect (call connect again) in the case of a failed send (or if the send simply failed).

Parameters: None

Returns: Boolean indicating if the mote is connected to a network.

connect

Run after a successful init to make the mote search and join a network with the given network ID and join key, followed by requesting the given service. Further, a socket is opened and bound to the given port, ready to send/receive user data.

Subsequent calls to connect while still connected has a few different behaviours based on the parameter values:

  • A different network ID, join key and/or port will cause the mote to attempt to reconnect with the new parameters.
  • If only the requested service is different, the mote will simply make a new request.
  • If all parameters are the same, connect simply returns TRUE, essentially a way to check that the mote is still connected with the given parameters.

Parameters:

  • netID: The ID of the network the mote should attempt to join. If 0, the default ID is used. If 0xFFFF, the mote will join the first network heard.
  • joinKey: The join key to use in the connection attempt. If NULL, the default key is used.
  • srcPort: The port to expect downstream data on. If 0, the default port is used.
  • service_ms: The service to request after establishing a connection, given in milliseconds. If 0, no mote specific service is requested (and the user application should adhere to the base bandwidth granted by the manager).

Returns: Boolean indicating if the mote successfully connected to a network and was granted the requested service, if any.

send

If connected to a network, the mote will send a packet with the given payload to the given port. The packet is addressed to the manager by default, but it is possible to change this to any IPv6 address with the DN_DEST_IP define (this will require that the manager is connected to a computer correctly configured as a gateway, e.g. by using DustLink). Note that end-to-end delivery is not guaranteed with the utilized UDP, but the success rate of the mesh network is typically greater than 99.9 %.

Parameters:

  • payload: Pointer to a byte array containing the payload.
  • payloadSize_B: Byte size of the payload.
  • destPort: The destination port for the packet. If 0, the default port is used.

Returns: A boolean indicating if the packet was queued up for transmission at the mote.

read

The payload of downstream messages are pushed into a buffered FIFO inbox as they arrive. Calling read will pop the first one (oldest) stored into the provided buffer and return the byte size; 0 indicates that the inbox is empty. As the inbox has a limited size (can be changed with the DN_INBOX_SIZE define), old data will start to drop if the user application does not make sure to call read often enough.

Parameters:

  • readBuffer: Pointer to a byte array to store the read message payload.

Returns: The number of bytes read into the provided buffer.

 

Example Application

Assuming you have downloaded the libraries and ported the necessary functions, your application simply needs to include the QSL header file, dn_qsl_api.h, and use the API as described in the previous section.

Below is a short example of how an application can send a data struct every 5 seconds, followed by parsing any downstream data received since the last transmission.
 

 

Example usage of QuickStart API
#include <stdlib.h>
#include "dn_qsl_api.h"

#define NETID           0       // Factory default value used if zero (1229)
#define JOINKEY         NULL    // Factory default value used if NULL (44 55 53 54 4E 45 54 57 4F 52 4B 53 52 4F 43 4B)
#define BANDWIDTH_MS    5000	// Not changed if zero (default base bandwidth given by manager is 9 s)
#define SRC_PORT		0		// Default port used if zero (0xf0b8)
#define DEST_PORT       0		// Default port used if zero (0xf0b8)

int main(void)
{
    my_data_struct_t myData;
    uint8_t bytesRead;
    uint8_t* myBuffer[DN_DEFAULT_PAYLOAD_SIZE_LIMIT];

    if (!dn_qsl_init())
    {
        return; // Initialization failed
    }

    while (TRUE)
	{
		if (dn_qsl_isConnected())
		{
			/*
			Prepare myData
			*/
			
			if (!dn_qsl_send(&myData, sizeof (myData), DEST_PORT))
			{
				// Pushing data to the manager failed
			}

			do
			{
				bytesRead = dn_qsl_read(inboxBuf);
				/*
				Parse received data
				*/
			} while (bytesRead > 0);
			
			/*
			Wait for next transmission (5000 ms)
			*/
		} else
		{
			if (dn_qsl_connect(netID, joinKey, srcPort, service_ms))
			{
				// Connected to network
			} else
			{
				// Failed to connect
			}
		}
	}

	return (EXIT_SUCCESS);
}

 

Further Tips

Base Bandwidth vs Service Request

Every mote is given a base bandwidth (service) upon joining the network (default 9000 ms) that specifies how often the mote can publish data. As noted in the QSL API, you can specify that the mote should request a specific service when connecting. However, this process can add between 20 - 60 seconds for connect to complete. Unless the motes in your network actually need individual bandwidths, you should rather change the base bandwidth granted by the manager: This is easily changed with the set config CLI command.

Change Network ID and Join Key

The default network ID and join key is well known, so unless you change these, anyone can potentially connect to your network. You can easily change both with the set config CLI command on the manager, and then use the same in your application.

Aggregate Data

If your application wants to publish data periodically etc. you should (if possible) aggregate many measurements into each transmission, rather than sending one for each measurement. The SmartMesh IP Network is designed with power consumption in mind, and its motes use very little power, except when transmitting data. Also, since the total bandwidth of a network is limited (36.4 packets/sec for the embedded manager), you will run into trouble if 40 motes requests a bandwidth to transmit messages every second (i.e. a service of 1000 ms).

Back Off Mechanism

Sending can fail if the mote is very busy. The following back off algorithm is recommended such that you only publish at a level that the network can tolerate:

  • If send fails (but you are still connected), double the interval between packets. Upon subsequent failures, increase to 3x, 4x, ..., 255x.
  • When send succeeds after failing, decrease the interval along the same pattern: 5x, 4x, ..., 1x.

Use the Access Control List

The manager maintains an Access Control List (ACL) which associates a mote's MAC address with a mote-specific join key. Once an ACL entry has been set, the manager will not let motes join the network that are not in the ACL. You can add a mote manually to the ACL through the set acl CLI command.

  • No labels