Blog Archives

SMS goodies in ModemManager

(C) josullivan.59 @ Flickr – CC by-nc-sa

Lots of new SMS-related features have landed in ModemManager this week, and as I have as much memory as a fish used to have, I need to write down all the commands I’ve used to test all this; hence this post.

Note that all the stuff I talk about here applies to both AT and QMI based modems.

 

Multiple storages

The current stable 0.5/0.6 releases will only use the core/plugin defined ‘default’ storages for reading and sending short messages. This means that if you happen to have stored SMS in another non-default storage ModemManager won’t show them to you.

In the new 0.7 codebase, ModemManager reads the messages from all the available storages. It is able to read not only DELIVER-type PDUs from received SMS, but also SUBMIT-type PDUs from user-created SMS which got stored. The “Sms.Store()” method in the interface now allows (optionally) specifying in which storage the SMS should be kept.

The following commands allow to create a new SMS and store it in the “sm” (SIM) storage:

$> sudo mmcli -m 0 \
              --messaging-create-sms="text='Hello world',number='+1234567890'

Successfully created new SMS:
    /org/freedesktop/ModemManager1/SMS/21 (unknown)
 
$> sudo mmcli -s 21 --store-in-storage="sm"
successfully stored the SMS
 
$> sudo mmcli -s 21
SMS '/org/freedesktop/ModemManager1/SMS/21'
  -----------------------------------
  Content    |              number: '+1234567890'
             |                text: 'Hello world'
  -----------------------------------
  Properties |            PDU type: 'submit'
             |               state: 'stored'
             |                smsc: 'unknown'
             |            validity: '0'
             |               class: '0'
             |             storage: 'sm'
             |     delivery report: 'not requested'
             |   message reference: '0'

Note that you can create, store and send SMS objects regardless of what storage you’re using for each, ModemManager will take care of properly synchronizing the access to each of them.

The Messaging interface also defines new properties to list all the supported storages and to specify which is the default storage being used for received messages (and for stored ones when no specific one given in “Sms.Store()“):


$> sudo mmcli -m 0 --messaging-status
/org/freedesktop/ModemManager1/Modem/0
  ----------------------------
  Messaging | supported storages: 'sm, me'
            |    default storage: 'me'

 

Text multipart SMS

We support receiving text multipart messages in ModemManager since some stable releases ago; but support for sending multipart messages was still missing. Not any more! Roberto Majadas of OpenShine started this work some months ago with a patch for MM 0.6, which I took over and ported to git master and the new 0.7 codebase.

Of course, we support both the default GSM 7-bit alphabet, as well as UCS-2:

  • GSM 7 encoded multipart messages: If the message is less or equal than 160 septets a singlepart SMS will be used; otherwise the input text will be split into chunks of 153 septets and sent as a multipart message.
  • UCS-2 encoded multipart messages: The GSM 7 alphabet and its extensions are not enough to cover all scripts available out there. Luckily, we can send PDUs with UCS-2 encoded text (UCS-2 covers all the basic plane of Unicode, and is equivalent to UTF-16 in that range). When using this encoding, if the input text is less or equal than 70 UCS-2 characters (140 bytes) a singlepart SMS will be used; otherwise the input text will be split into chunks of 67 UCS-2 characters (134 bytes) and sent as a multipart message. Note anyway that this doesn’t mean that we only allow 70-byte long input strings to fit into a singlepart message; as the conversion from the input UTF-8 text to UCS-2 isn’t always increasing the required number of bytes. As an example, we can now send 210 bytes of UTF-8 encoded chinese text into a single SMS with 140-bytes of UCS-2.

Note that from the API user’s point of view, the SMS objects are not considered multipart or singlepart; that is taken as internal information only required for the PDU-based implementation.

Multipart messages can be created by writing a long enough ‘text‘ value passed in the ‘--messaging-create-sms‘ command, as shown before.

 

Raw data multipart SMS

In addition to text short messages we now also properly support raw binary data singlepart and multipart messages (reported as 8bit encoded). This means that both the sender and receiver can agree in any text encoding to be used between them, or even send in one or more SMS whatever raw binary stream you have.

The ‘mmcli’ command line utility was improved with several commands to test this feature. For example, you can now send using just SMS messages whatever file you have in your system, just doing:

$> sudo mmcli -m 0 \
       --messaging-create-sms="number='+1234567890'" \
       --messaging-create-sms-with-data=/path/to/your/file

Successfully created new SMS:
    /org/freedesktop/ModemManager1/SMS/22 (unknown)
 
$> sudo mmcli -s 22 --send
successfully sent the SMS

When the receiver gets all the parts of the message, she can now recover the sent file with another ‘mmcli’ command in her ModemManager setup:

$> sudo mmcli -m 0 \
              --messaging-list-sms

Found 1 SMS messages:
    /org/freedesktop/ModemManager1/SMS/0 (received)
 
$> sudo mmcli -s 0 \
              --create-file-with-data=/path/to/the/output/file

But beware! The file is sent in chunks of 134 bytes, and there is a maximum of 255 parts in a given multipart SMS, so this leaves you with a maximum size of around 33 Kbytes :-) And not only that, if you’re paying e.g. 0.10€ for each SMS sent, you would be paying more than 25€ for those 33 Kbytes. Yes, needless to say, this is therefore the most useless use case ever. But still, works as a proof of concept.

 

Delivery reports

Last and least, you can now also request delivery reports when sending an SMS, by passing the ‘delivery-report-request=yes‘ key/value pair in the ‘--messaging-create-sms‘ command.


$> sudo mmcli -m 0 \
           --messaging-create-sms="text='你好',\
                                   number='+1234567890',\
                                   delivery-report-request=yes"

Successfully created new SMS:
  /org/freedesktop/ModemManager1/SMS/0 (unknown)
 
$> sudo mmcli -s 0 --send
successfully sent the SMS
 
$> sudo mmcli -m 0 --messaging-list-sms
Found 21 SMS messages:
  /org/freedesktop/ModemManager1/SMS/0 (sent)
  /org/freedesktop/ModemManager1/SMS/1 (received)
 
$> sudo mmcli -s 1
SMS '/org/freedesktop/ModemManager1/SMS/1'
  -----------------------------------
  Content    |              number: '+1234567890'
  -----------------------------------
  Properties |            PDU type: 'status-report'
             |               state: 'received'
             |                smsc: '+9876543210'
             |            validity: '0'
             |               class: '0'
             |             storage: 'unknown'
             |   message reference: '137'
             |           timestamp: '120914120619+02'
             |      delivery state: 'temporary-error-sc-specific-reason' (0x30)
             | discharge timestamp: '120914120619+02'

You can then match the delivery report with the message sent by using the ‘message reference‘ value, which should be the same in both. This also applies to multipart messages, where the ‘message reference’ of our SMS object is the one reported when sending the last part, and therefore we only request the delivery report in the last part sent.

Enjoy!

Follow

Get every new post delivered to your Inbox.

Join 36 other followers