Embedded Freaks..

October 9, 2008

Encoding GSM SMS Septets

Filed under: java — Tags: — kunilkuda @ 1:01 pm

One part of the annoying thing in SMS is that you need to send the data in GSM septets (you may want to read it more in here and here).

There’s a lot of approach to encode your message to 7-bits GSM septets, but this is my approach to encode it without relying on java utils too much (which means that it’s quite portable for MCUs, like AVR).

First of all, let’s create two tables from the original data, like this:

GSM Septet Encoding Tables

GSM Septet Encoding Tables

Once the tables are created, the next step to get the encoding is easy.

  1. Shift the adder table 1-column to the left (the table, not the bytes inside the table)
  2. Add ‘0’ (0x00) at the right-est column
  3. Sum the adder and base table row, except for the column where the shifter is 8 (on adder) or 7 (on base).

Here’s the illustration:

And here’s the java code for the thing:


/**
* brief Encode the message into GSM octets
* param data The user data in ASCII (ISO-8859-1 / Latin 1) charset
* return The GSM 03.40 compressed data
*/
public byte[] encode(String data) {
    // rawData refers to 8-bit uncompressed byte
    byte[] rawData = data.getBytes();
    // compressedData refers to compressed septets list
    ArrayList compressedData = new ArrayList();

    byte shiftValue = 0;
    int iRawData = 0;
    while (iRawData > shiftValue) {
        byte adderByte = 0;
        if ((iRawData + 1) < rawData.length) {
            adderByte = (byte) (rawData[iRawData + 1] << (7 - shiftValue));
        } else {
            // adderByte = 0; //< Not needed, since adderByte is initialized with 0
        }

        byte resultByte = (byte) (baseByte + adderByte);

        if (shiftValue < 7) {
            shiftValue++;
            compressedData.add(new Byte(resultByte));
        } else {
            shiftValue = 0;
            // Don't add the resultByte to the result.
        }

        iRawData++;
    }

    byte[] retVal =
    translateToByte((Byte[]) compressedData.toArray(new Byte[0]));

    return retVal;
}

/**
* brief Tranverse Bytes[] array into byte[] array
* param data Bytes[] array
* return byte[] array
*/
private byte[] translateToByte(Byte[] data) {
    byte[] retVal = new byte[data.length];

    for (int i = 0; i < data.length; i++) {
        retVal[i] = data[i].byteValue();
    }

    return retVal;
}

Here’s some example of how to use it:


public static void main(String[] args) {
    if (args.length != 1) {
        System.out.println("Usage: java PduData ");
        System.exit(1);
    }

    byte[] result = new PduData().encode(args[0]);
    for (int i = 0; i < result.length; i++) {
        System.out.print(Integer.toHexString(result[i] & 0xFF) + "");
    }
    System.out.println();
}

If you read the AVR323 application note, you’ll find out that the procedure to encode the septet is similar, except that the application sample has one-off bug in its while loop.

Advertisements

4 Comments »

  1. […] 2008. Filed under: java, programming tips | Tags: java, java-sms | Once encoding is done (refer to this post), decoding is […]

    Pingback by Decoding GSM SMS Septets « Embedded Freaks.. — October 9, 2008 @ 5:18 pm

  2. Errors in the code:

    baseByte is not defined !

    This condition is illogical and
    will not work:

    12 byte shiftValue = 0;
    13 int iRawData = 0;
    14 while (iRawData > shiftValue);

    Parenthesis missing at some places

    Comment by Mohsin — February 12, 2010 @ 9:00 pm

  3. This code is not working. I have the working code on here. You can use site <a href="http://www.smartposition.nl/resources/sms_pdu.html” to verify the out put of my code. Also ask me if you need more explanationhere.

    Comment by mlusincuba — December 2, 2011 @ 3:47 pm

  4. Forget about the Java code, the idea works. I have implemented it in C.

    Thank you for such an elegant – and accurate solution !

    T h a n k y o u k u n i k u d a !
    Dumping 19 (0x13) bytes:
    5468616E6B20796F75206B756E696B75646121
    Dumping 17 (0x11) bytes:
    5474D8BD06E5DF75D0BAEE4EAFEBE47008
    Dumping 19 (0x13) bytes:
    5468616E6B20796F75206B756E696B75646121
    T h a n k y o u k u n i k u d a !

    Comment by Guillaume — January 28, 2012 @ 12:26 pm


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: