Tiliman’s Weblog

October 21, 2011

Sending Unicode SMS via Kannel

Filed under: GSM — Tags: , , , — tiliman @ 3:36 pm

Kannel is always a delight to work with. It is solid piece of software that would win over any commercial SMS GW.

Standard GSM characters are usually enough for English and most European languages but when it comes to sending SMS in other languages you have to rely on UNICODE. Here is character sheet of GSM characterset http://www.csoft.co.uk/sms/character_sets/gsm.htm
It might seem tricky at first to send Unicode SMS via Kannel and usually requires trial and error.

Sending unicode SMS involves following
1– Converting your SMS body string from whatever character set to into UNICODE (UTF-16).
2– URL Encoding (Percent Encoding) the SMS body.

HTTP GET example for sending Unicode SMS

<?php
$in_msg = "你好朋友Michael";
print urlencode(iconv('utf-8', 'ucs-2', $in_msg));
?>

My text here is stored in UTF-8 so I have to first convert it to UNICODE and then convert to URLencoded format.
The result comes out to be something like this
%60O%7DY%0Bg%CBSM%00i%00c%00h%00a%00e%00l%00
Now in Kannel send URL I have to specify that I am sending it UNICODE and for that I used charset=UCS-2
and to tell Kannel to send SMS as UNICODE as well (not as GSM characters)&nbsp;coding=2
I use HTTP GET URL for testing and this is how my final URL looks like
lynx –dump “http://KANNEL_SERVER:13003/cgi-bin/sendsms?username=USERNAME&password=PASSWORD&from=YOURFROMID&to=MOBILE_NUMBER&text=%60O%7DY%0Bg%CBSM%00i%00c%00h%00a%00e%00l%00&coding=2&charset=UCS-2&#8221;

HTTP XML POST example for sending Unicode SMS

XML POST is a little different indeed. The charcterset is actually identified in encoding param of xml namespace tag. You need to provide it the body in UNICODE (UTF-16/UTF-16BE) in URLEncoded form.


<?php
$SERVER = 'KANNEL_SERVER';
$PORT = '13003';

$out_msg = "你好朋友Michael怎么了";

# convert from UTF-8 to UTF-16.
$out_msg = mb_convert_encoding($out_msg,"UTF-16","UTF-8");

# Don't forget to URLEncode or else you might get unwanted string termination
$out_msg =  urlencode($out_msg);

print $out_msg."\n";
print "len ". strlen($out_msg)."\n";

$fp = fsockopen ($SERVER, $PORT, $errno, $errstr, 30);
    $res = "";
    $header = "POST /cgi-bin/sendsms HTTP/1.1\r\nHost: $SERVER\r\nContent-Type: text/xml; charset=utf-8\r\nContent-Length: __LENGTH__\r\n\r\n";
    $re1 = "";
    $req = "
<message>
    <submit>
        <da>
            <number>YOUR_NUMBER</number>
        </da>
        <oa>
            <number>FROM_ID</number>
        </oa>
        <ud>$out_msg</ud>
        <udh/>
        <dcs>
            <coding>2</coding>
        </dcs>
        <from>
            <username>USERNAME</username>
            <password>PASSWORD</password>
        </from>
    </submit>
</message>"; 

    $header = str_replace("__LENGTH__",strlen($req),$header);
    if (!$fp) {
            // HTTP ERROR
            print("Error in service.\nPlease try again later..");
            exit;
    } else {
            print "Sending\n$req\n";
            fputs ($fp, $header . $req);
            // read the body data
            $res = '';
            $headerdone = false;
            if (!feof($fp)) {
                $line = fread ($fp, 4096);
                print "Read:\n$line\n";
                fclose($fp);
            }

    }
?>

This is how your XML should look like

<?xml version="1.0" encoding="utf-16"?>
<message>
    <submit>
        <da>
            <number>MOBILE_NUMBER</number>
        </da>
        <oa>
            <number>YOURFROMID</number>
        </oa>
        <ud>O%60Y%7Dg%0BS%CB%00M%00i%00c%00h%00a%00e%00l%60%0ENHN%86</ud>
        <udh/>
        <dcs>
            <coding>2</coding>
        </dcs>
        <from>
            <username>USERNAME</username>
            <password>PASSWORD</password>
        </from>
    </submit>
</message>

This is all. Sending Unicode SMS is not that hard with Kannel after all.

Bringing back Adler32 to SCTP for Kernel 2.6

Filed under: GSM — Tags: , , , , , , , — tiliman @ 9:55 am

I had a situation a few days ago where I wanted to connect to our STP to test MAP applications built on Mobicents. Our STP was configured to only support Adler32 checksum. Adler32 is deprecated and CRC32 is considered a standard checksum to be used for SCTP. Keeping up with standards the Linux 2.6 kernel stopped supporting Adler32 and implemented CRC32 using libcrc32c.

I couldn’t reconfigure STP to use CRC32 and it was not possible to use different checksums for different SCTP peers as it is a Transport Layer Protocol. There was no solution I could find on internet, so I decided to patch my kernel and replace CRC32 with Adler32. I could see that a lot of other have had this problem and they couldn’t find any solution. I hope my solution would work for them as well.

  • Download kernel-headers for your kernel. Command like this would work on Debian apt-get install linux-headers-$(uname -r). Note: you don’t need sources for kernel. Just header files.
  • Take a backup of your original sctp.ko file. It would be somewhere /lib/modules/$(uname -r)/kernel/net/sctp/sctp.ko
  • Download the sctp module code from here to a clean directory somewhere away from usual linux sources. You don’t need it to be in linux sources directory.
  • Do make and make install in the new SCTP code at src/sctp/.
  • Check if new module is installed using modinfo sctp. It should say in description:    Support for the SCTP protocol (RFC2960) – with Adler32.
  • Do rmmod sctp and then modprobe sctp to load this new module. If you can’t do rmmod as module is busy and you can’t free it then you might have to reboot the system.
  • On load the module prints a message in /var/log/messages Initialising Adler32 patched SCTP module for 2.6 kernel

Now you have SCTP using Adler32 instead of CRC32. If you need to ever go back to CRC32, you can replace sctp.ko with your backedup module or you could download kernel sources and remake module.
May be in future I would add a load param to module to tell it to use CRC32 or Adler32 checksum.


Update October 24, 2011
The initial code was able to use checksum for outbound packets but was still using CRC32 for inbound packets. Updated the link to fix that.

December 20, 2008

Replacing SMS on a Phone using Kannel SMS Gateway

Filed under: GSM — Tags: , , , , , — tiliman @ 11:35 am

What is Replace Message?

The 3GPP (ETSI) standard for GSM communication specifies a way to replace an existing message on a mobile phone by sending another message. I had a requirement to use this functionality with Kannel connected to an SMS GW that communicates over SS7/MAP.

Using Kannel to Replace Message

Sending a self destruct or replaceable message is pretty easy with Kannel as long as your SMSC supports it.

Send first SMS with pid=65
http://SERVER:PORT/cgi-bin/sendsms?from=55512345&username=me&password=mypass&amp;
to=5551233&text=original+msg&pid=65

Send second SMS with pid=65

http://SERVER:PORT/cgi-bin/sendsms?from=55512345&username=me&password=mypass&amp;
to=5551233&text=msg+replaced&pid=65

 

Quest for correct PID value

The documentation of Kannel doesn’t provide any information about the method at all. It however mentions the field PID that can be set while sending SMS. Looking at some forums related to NowSMS gateway, it appeared that PID can be used to send such SMS.

The next issue was to find out what exact value to provide as NowSMS GW allows a value of between 41--47 in decimal. This doesn’t work with Kannel.

3G TS 23.040 V3.2.0 (1999-10) on page 52-53 states this:

9.2.3.9 TP-Protocol-Identifier (TP-PID)
The TP-Protocol-Identifier parameter serves the purposes indicated in subclause 3.2.3. It consists of one octet, and the
bits in the octet are used as follows:
.
.
.
In the case where bit 7 = 0, bit 6 = 1, bits 5..0 are used as defined below
5 .. . .0
000000 Short Message Type 0
000001 Replace Short Message Type 1
000010 Replace Short Message Type 2
000011 Replace Short Message Type 3
000100 Replace Short Message Type 4
000101 Replace Short Message Type 5
000110 Replace Short Message Type 6
000111 Replace Short Message Type 7

Here is explanation of Replace Short Message from standard

The Replace Short Message feature is optional for the ME and the SIM but if implemented it shall be performed as
described here.
For MT short messages, on receipt of a short message from the SC, the MS shall check to see if the associated Protocol
Identifier contains a Replace Short Message Type code.
If such a code is present, then the MS will check the originating address and replace any existing stored message having
the same Protocol Identifier code and originating address with the new short message and other parameter values. If
there is no message to be replaced, the MS shall store the message in the normal way. The MS may also check the SC
address as well as the Originating Address. However, in a network which has multiple SCs, it is possible for a Replace
Message type for a SM to be sent via different SCs and so it is recommended that the SC address should not be checked
by the MS unless the application specifically requires such a check.

According to this 01000001 or in decimal 65 would give me Replace Short Message Type 1 and it can go upto 71.
I have tested this on Samsung, Nokia, HTC and iPhone. Seems to work fine on all of these.

Blog at WordPress.com.