A.7. Dealing With Received SMS

A.7.1. Receiving SMS

There are two ways to handle incoming SMS messages, and each method has advantages and disadvantages.

The AT+ command set supports online notification of received SMS messages. In the same way as a Hayes AT compatible modem sends the client program a RING to indicate that there is an incoming phone call, an AT+ modem sends the client an AT+CNMI when a new SMS message is received.

The advantage of using this online notification is that the client becomes aware as soon as a new message is received. This eliminates any delay between the receipt of an SMS message and its being handled by the service. Unfortunately, such a system requires that either a daemon constantly poll the serial line for this notification, or we listen for a serial port interrupt. Either way, this daemon would have to handle both incoming and outgoing SMS messages. Such an approach requires that we implemented some method of inter-process communication between the serial daemon and the SOAP service, greatly increasing the complexity of the system as a whole.

The simpler approach is to periodically poll the modem for new SMS messages. This can be done using any system scheduling application such as cron(8) [11]. The disadvantage of this approach is that there may be a delay between the receipt of an SMS message and when it is processed.

In the case of the web-service that is the subject of this paper, the second approach was implemented. It was felt that the advantages brought by simplicity of implementation outweighed the disadvantage of a delay in the handling of new messages. This is because the SOAP does not provide for the service to initiate connections to a client. Thus the client itself must initiate any connection that results in notification.

Since we have no way of forcing a client to establish this connection, the known time delay between the receiving of a message by the modem and its processing within the service, is inconsequential compared to the delay between the service and the client.

A.7.2. Storing it in the database

The GSM modem is polled by cron(8) once a minute for new SMS messages. When a new message is received, it is stored in the database described in the previous section. As soon as it has been successfully stored in the database, it is removed from the GSM SIM card to free up room for new messages.

Incoming SMS messages require that the same sort of information be stored as is done for outgoing messages, with a couple of differences. In the incoming SMS table, it is essential that the full text of the SMS message is stored — otherwise there is no way for the client to ever retrieve it.

Rather than store information on whether a message was successfully received, the status field for incoming messages contains information on whether the stored SMS message has been read or not.

The username field contains information on the intended recipient of the message. This is worked out using a threading scheme, which is described below.

A.7.3. Threading

One of the most complex problems in receiving an SMS message is getting it back to the right client. This is compounded by the fact that all messages are sent and received from one cell phone number, meaning we have to somehow turn a many-to-one transport method into a many-to-many service. Thus, the basis for any threading or distribution method must be contained within the received messages themselves.

The mechanism this service uses to thread messages was based on an idea used in eXcell Technologies' SMS ↔ e-mail gateway, in which the user enters the desired e-mail address as the first word of an SMS message [12]. Both major networks in South Africa have subsequently used this idea to implement a similar service for their customers.

When a new message is received, the first word is extracted from the message and used as a tag. The first character of this tag is used to determine what sort of threading is to be done.

If an "S" is the first character of the tag, the service assumes that the rest of the tag contains the message identifier of a previously sent SMS message. It will then try and find the original sent message in the database, and if it is successful will route the newly received message to the sender of the original message.

In the same way, an "R" as the first character refers to the message identifier of a previously received message. This is useful, for example, to continue a previous message past the 160-character limit imposed by the SMS standard.

Sometimes the remote user may want to initiate a thread themselves. This is catered for by the "!" prefix. Any word prefixed with an exclamation mark is considered to be a service username, and messages are routed to that user.

It is possible that a message is received that has no valid tag on it. This could happen either when the user forgets to tag the message, or mistypes the tag. If the service cannot work out who "owns" the message, it marks it as a special broadcast type. Any authenticated user of the service can read broadcast messages.

A.7.4. Client notification

Once we know who the message is intended for, we face the next challenge; letting that client know they we have a message for them. As has been mentioned already, SOAP does not allow for server-initiated connections. For this reason, clients can only be notified of pending messages when they connect to the service.

The XML schema makes provision for this with a newsms flag. This flag can be set in any client response (an example of it is given in Figure A-3, and contains a list of message identifiers for unread messages. The client can then use these message identifiers to retrieve the waiting messages.

A.7.5. Client retrieval

Clients can retrieve any message from the database using a SOAP request containing the message identifier of the message they are after. An example of such a request is given in Figure A-4.

Figure A-4. Typical client request to retrieve SMS

    <?xml version="1.0" encoding="iso-8859-1" ?>
    <soap:Envelope xmlns:soap="…">
        <sms:sms xmlns:sms="]>…">

The readsms field can contain a list of one or more SMS messages to retrieve. In addition, it can contain one of four pseudo-message identifiers; "ALL", "UNREAD", "BCAST" or "SENT". These identify groups of messages, and except for "BCAST", their meaning is fairly straightforward. The "BCAST" identifier retrieves any of the broadcast messages (messages without specified recipients) described in Section A.7.3.