Flyport GPRS SMS Management

From openPicus Wiki
Jump to: navigation, search

Contents

What you are going to learn

Managing the SMSes with GPRS modules is not straightforward. This guide is intended to guide you through understanding how the GSM module works, and how you can effectively obtain the functionality you want.


Introduction - Asynchronous Modems

The point of this introduction is to give the reader an idea of what is continuously going on even when he entered no code in the Flyport besides the default template the IDE presents.

To obtain the GPRS functionalities the Flyport GPRS houses a GSM module interfacing the microcontroller with the wireless network via sim-card identification. These modules are controlled via a serial interface and a series of textual commands universally known as AT commands originating from the first Hayes smartmodem in the long forgotten 1981. Just like an old 56k modem.

A modem is called DTE (Data Terminal Equipement), while the host is called DCE (Data Circuit-terminating Equipement). The DCE in our case is the Flyport.

The fact that there is a serial communication via AT commands between DCE and DTE means the DCE doesn't have direct access to the DTE internal status and variables. Everything is asynchronous and the DCE has to continually poll the DTE to be sure it has the most up to date information about it. This also means that, also given the asynchronous nature of the data-link itself, events may interrupt the execution of a command, or a command may interrupt an ongoing data flow.

For example the user may wish to establish a TCP socket while being totally oblivious to the fact that the network operator is delivering an SMS, at least until the SmsReceived event is raised by the framework. This is exactly the case for most of the operations: the framework is designed to be asynchronous, in order to be resilient to unforeseeable interruptions. This in turn means that it's the programmer that has to check the real status of the operations he/she has queued up.

More pertinent to the SMS let us make an example: the SMSRead function has a void return type because it can't return anything directly, the function just starts the reading process, the termination of which depends on other parameters. So to know when the process has ended, the programmer must monitor the status of the operation.

Memory

The GSM module works with two memories: its own internal one, and the SIM's memory.

The module's internal memory is able to hold 40 SMS. While the number the SIM can hold depends on the size of the SIM itself.

Moreover the module dynamically changes the memory if either one is full: it will switch to the next free memory without errors or notifications.

There is no event or error in this case, because the GSM protocol doesn't see this as a failure situation: the network operator asks the device to send an SMS, the device polls its memories seeing it has no space and tells the network operator to delay the sending.

This means the programmer has always to check the amount of messages in both memories.

Functions and Status

The available operations are

SMSRead Asynchronous
SMSDelete Asynchronous
SMSSend Asynchronous
LastSmsIndex Synchronous
LastSmsMemType Synchronous
LastSmsMsgRef Synchronous
LastSmsRepValue Synchronous
LastSmsSender Synchronous
LastSmsText Synchronous
LastSmsTime Synchronous

The asynchronous operations are those that interact with the GSM module, thus requiring checking the internal status. The synchronous operations on the contrary do not require any checking: they directly return the result.

So it's true you could call LastSmsText() even by itself, but for it to return meaningful data, it must be preceded by a successful SMSRead().

Each GSM operation returns with at least one generic error code, if this is valid (not success) a second specific error code is available.

LastExecStat Generic Error Code
LastErrorCode Specific Error Code

Here is the list of possible generic error codes returned by LastExecStat

0 OP_SUCCESS Last function executed correctly
-1 OP_EXECUTION Last function still executing
-2 OP_LL Low Level mode is activate
1 OP_TIMEOUT Timeout error: GPRS module has not answered within the required timeout for the operation
2 OP_SYNTAX_ERR GPRS module reported a “syntax error” message
3 OP_CMS_ERR GPRS module reported a CMS error
4 OP_CME_ERR GPRS module reported a CME error
5 OP_NO_CARR_ERR GPRS module reported NO CARRIER message
6 OP_SMTP_ERR Error in sending the email
7 OP_FTP_ERR Error message received in FTP operation
8 OP_HIB_ERR GPRS module is turned off and cannot reply to commands


For a complete list of error codes, check Sierra Wireless documentation.

Operation

Now that all the necessary pieces have been laid out, it's time to follow some examples.

Send an SMS

SMSSend("99912345678","Flyport test!",FALSE);
while(LastExecStat() == OP_EXECUTION);
if(LastExecStat() == OP_SUCCESS)
    UARTWrite(1,"SMS Sent!\n");
else
    UARTWrite(1,"Error sending SMS\n");

As is shown in the above code, after the send instruction terminates, the operation is not itself completed. It becomes completed when the internal status becomes OP_SUCCESS. So to check for this there is a while loop that just waits until the internal status becomes different from OP_EXECUTION.

Read an SMS

SMSRead(1,SM_MEM);
while(LastExecStat() == OP_EXECUTION);
if(LastExecStat() == OP_SUCCESS)
{
    sprintf(msg,"SMS %d text:\n%s",1,LastSmsText());
    UARTWrite(1,msg);
}
else
    UARTWrite(1,"Error retrieving SMS\n");

Just like in the other example, there is while loop to wait until the operation has completed. Once we are sure that is the case, we check the result of the operation and proceed accordingly.

Final Notes

The synchronous functions all report the last valid data. So if you execute multiple SMSRead but just a few are valid, you could get misleading results if you do not prevent executing the synchronous functions with a prepended if(LastExecStat == OP_SUCCESS).

A code like the following

for(i=0; i<10; i++)
{
    SMSRead(i,SM_MEM);
    while(LastExecStat() == OP_EXECUTION);
    sprintf(msg,"SMS %d text:\n%s",i,LastSmsText());
    UARTWrite(1,msg);
}

Could even return all valid data, save for the fact that only a few of the 10 SMSes may be valid, and the rest are data lingering in memory. So remember to always check the status of the GSM library.

Personal tools
Namespaces

Variants
Actions
START HERE
DEVELOPMENT
HARDWARE INFO
RESOURCES
PHASED OUT
Toolbox