view · edit · history · print


The code you can find here exists of 2 C++ shared libraries. The first one is used for Serial Port communication, the second one is for encoding and decoding SMS PDU format strings. By combining both you can write code to send SMS messages to your cell phone device.

BEFORE YOU CONTINUE... This code is written for an assignment and purely for fun, if you are looking for a more complete, tested and established solution then consider using the gnokii!

For communication we use BT (Bluetooth); below you find a guide on how to setup your BT on Linux, we also provided code documentation (using Doxygen), notes, references etc...

SMS format and PDU message

SMS (Short Message Service) is specified by the ETSI (standards GSM 03.40 and 03.38 ). It can contain up to 160 (debatable 255char?) characters, when each character is written according the 7-bits GSM default alphabet.

Next to a message the SMS contains also some meta-data, for example

  • Info about the senders ( Service center number, sender number)
  • Protocol information (Protocol identifier, Data coding scheme)
  • Time stamp

There are two ways to receive and send SMS messages, PDU (protocol description unit) and Text mode. In this document we focus on PDU mode which is known by all cell phones. The PDU messages itself is encoded with 8-bit octets representing 7-bit data.

  • PDU message
The PDU is only a part of the entire SMS-message which is added to the end. The encoded message "How are you?" would look something like this (witout the spaces) "C8 F7 1D 14 96 97 41 F9 77 FD 07" (using the GSM default alphabet with 8-bit octets representing 7-bit data)!

Explanation of some PDU fields for submitting messages:

field 6 (the phone number)
Phone numbers can be national or international, in your code we only use international type-of-adress=91(HEX). For international phone numbers the "+"-sign is suppressed and [for Belgium] 12 characters long. For these 12 characters you should use the length 0B(HEX), the rest [1 character] is filled up with F(HEX). The wierd thing is that every 2 characters should be switched! Example:
number +31641600986
becomes 1346610089F6 (remove +, add F to the end, transpose)
field 11
The body. "How are you?" becomes "C8F71D14969741F977FD07", see above description.

Explanation of some PDU fields for recieving messages:

field 3 (service center number)
The number of your GSM operator service center. This enables you to see which operator is used by the sender of the message (eg. Proximus, BASE, etc).
field 10 (time stamp)
Time the message is send, if the message cannot be delivered after 4 days it will expire. This enables you to see the delay in delivery (eg. hours or even a couple of days).

The software

The compiled code will provide you 2 shared objects and 1 dynamically linked executable. The shared objects (.so) provide the necessary API for Serial Communication and encoding PDU-style SMS messages.

Enables you to set: baud rate, character size, parity stopbits and flow control for any serial device and eventually start sending and receiving data.
Encodes (and decodes) PDU style text and builds up an SMS-message that can be send using basic AT commands over a serial connection.
  • sendsms
sample code that makes use of the 2 shared objects and provides a method to send SMS messages via a serial attached cell-phone using AT commands from the command line by typing something like this "sendsms +32478123123 'Hello there!'"

Note: If you want to write your own code using one or both library's then you will also need to include and carry the library header files with you. These header files carry the same name as the shared objects (SerialPort.h, pdu.h).

Compiling the code

Compiling is done by running the make command. No automake is used, we created a clean and simple Makefile to give you full flexibility and understanding. Lets go over the options...

The compilation flow

Creating shared objects

For the creation of shared objects (.so files) we will take a look at the Makefile of this project:

SerialPort.o: SerialPort.cpp SerialPort.h
        g++ -I. -fPIC -g -Wall -c SerialPort.cpp SerialPort.o
        g++ -shared -Wl,-soname, -o SerialPort.o

Note: The first paragraph will only compile, the second on will create the dynamic shared library. In the complation part I did not add the optional "-o" parameter because during compilation ("-c") it wil default to a binary file with identical name and the ".o" extension.

States that this is a shared binary.
Internal name for the shared library; this is not always set the same as the filename.
Create Position Independent Code; highly recommended for shared libraries. The "position independent" part means that in the first memory segment of the loaded binary does not contain a hard coded memory segment address but rather relative ones. Example: function XYZ is at the "current memory segment address +200" vs. "the memory segment address 0x55607".

optional linker parameters

Include extra library searchpath.
include an archive-type or shared-type library (without .a or .so extension).

Code snippets

The string to char[] cast

char *buf2 = strdup(resultingPDU.c_str());

include C code into C++ code

The inclusion was tested because we wanted to use the pduconv code from Nerdlabs. The idea was abandoned and a full C++ alternative is chosen (considering the course).

The pduconv source files are :

Enclosed guide on howto use the pduconv functions.
Tables with 7bit GSM alphabet and pdu generation functions.
Header file with function definitions for use in your code.
Sample of pduconv usage provided by Nerdlabs (Not used).

The idea was to use the pduconv functions (ascii_to_pdu and pdu_to_ascii) in C++ code to write a command line interface, write a more easy to use interface for the conversion functions and maybe even create a threaded server.

To do this you need to change the pduconv header file and include something like this:

#ifdef __cplusplus
extern "C" {
  int ascii_to_pdu(char *ascii, unsigned char **pdu);
  int pdu_to_ascii(unsigned char *pdu, int pdulength, char **ascii);
#ifdef __cplusplus

For the rest you can pretty much ignore the fact your binary is written using C code and include the pduconv header file in your C++ code.

Here is a Makefile snippet that shows the usage:

CC = gcc
C+ = g++
FLAGS = -Wall -O2
OBJ = pduconv.o wrapper.o

all: $(OBJ)
        $(C+) $(OBJ) -o wrapper

wrapper.o: wrapper.cpp pduconv.h
        $(C+) $(FLAGS) -c -o wrapper.o wrapper.cpp

pduconv.o: pduconv.c pduconv.h
        $(CC) $(FLAGS) -c -o pduconv.o pduconv.c


Sources of inspiration

PDU format conversion (and C code linking with C++)

Code: pduconv
License: PD
Source: Mats Engstrom from Nerdlabs Consulting (
Version: 0.1
Test: (test2 on laptop) shows the usage of C code in C++ by linking them.

Shared library creation

Code: CmoTime
License: ?
Source: Syntra Waasland
Version: 7.10
Test: port Miscrosoft VC++ code to GNU/Linux and re-use Makefile parameterization.

SMS message creation

Code: Javascript in
License: ?
Source: Swan-Peter Ekkebus (and others) from the University of Twente NL 
Version: 1.5 r2aja
Test: convert parts to C++.

POSIX serial communication

Code: snippets from the book
License: GNU Free Documentation License
Source: Michael R. Sweet ( 
Version: 5th Edition, 4th Revision
Test: set properties, send and recieve data.


Release notes

Copyright (c) 2004-2005 S. Lapers, W. Van Hooste and Syntra Waasland (Belgium)

License: Probably MIT (or even PD)

Version: 0.2

admin · attr · attach · edit · history · print
Page last modified on March 30, 2006, at 01:55 PM