Thingstream Client Library  BLD4131-v2.13
Implementing a custom Modem transport

Custom modem implementation

Why implement a custom modem?

The standard Thingstream modem implementation assumes that the target platform has

  • Hayes compatible modem hardware accessible via a serial UART
  • the modem supports sending USSD messages via AT+CUSD=1,"..."
  • the modem returns unsolicited USSD messages as serial "+CUSD: ..." lines

If the target platform modem hardware does not correspond to that model then a custom modem implementation may be the best solution.

What must a custom modem provide?

Starting point

We suggest that you use the supplied skeleton files sdk/src/custom_modem_transport.c and sdk/inc/custom_modem_transport.h as starting points.
You will need to add your own appropriate code at the places labelled with a "/* TODO: ... */" comment.

Overview

The modem transport is needed to send USSD messages to the Thingstream server and to accept and buffer incoming USSD messages from the Thingstream server.

When the transport stack calls the modem ThingstreamTransport::run() function the modem transport must call the previously registered callback if there are any buffered USSD messages. If errors have occurred then the modem ThingstreamTransport::run() should return the appropriate error code when it returns.

If the modem transport can obtain the <cell-identifier> and <location-area-code> from the network then it should store this in a global structure for use by the Thingstream stack. This is optional but does provide extra information to the Thingstream servers that is useful for diagnosing problems. The <stat> indicating whether the registered network is 'roaming' or 'home' should also be set to 0x05 or 0x01 respectively when these globals are updated.

The modem ThingstreamTransport::send() function is called to send the USSD payload to the Thingstream server.

A Hayes compatible modem would do this by the command AT+CUSD=1,"#<shortcode><payload>#" where the <shortcode> is usually "469".

Some of the requests to ThingstreamTransport::send() are done with the flags parameter containing the TSEND_USSD_SESSION_END bit, and these must end the USSD session before returning.

A Hayes compatible modem would do this by the command AT+CUSD=2.

The Thingstream stack will register a callback function that must be called by the custom modem transport to pass inbound messages from the USSD server up the stack.

A Hayes compatible modem would see an inbound message as AT+CUSD=1,"#<shortcode><payload>#" and the modem transport must pass the <payload> without quotation marks as the payload when calling the callback function.

The callback function must only be called from inside a call to the modem ThingstreamTransport::run(), if a target's modem hardware generates incoming USSD messages asynchronously then the modem transport must buffer at least one of these incoming messages until the modem ThingstreamTransport::run() is called. It should not be necessary to buffer more than one message at a time in the modem transport.