Sunday, July 5, 2009

Home SMS Gateway using Perl, Ubuntu and Nokia

Thinking what would be good for the start. SMS gateway sounds quite interesting.

On a large scale one is inclined to look at Kannel as a starting point. There are a few traps with Kannel. While being open source (bearerbox and smsbox), the most interesting parts like smppbox are not open source, so be prepared to spit out about 4000 Euros for it when the volume becomes critical. Also, Kannel doesn't like SuSE Linux Enterprise Server very much, and for some reason that one is used here by the government and big companies. Apparently, Novell sells support cheaper than Red Hat and it is friendlier with MS. So, if you like Kannel-based solution - use Red Hat or Debian. That is stated in Kannel's documentation and they know what they are talking about.

What else may one use to roll out SMS gateway?

Java and its enormous wealth of open source libraries, application servers and development tools. Assembling SMS gateway with SMPP API should be quite easy.

How about deploying SMS gateway on Windows?

You cannot be serious.

Now we may leave alone make-millions-from-spamming enterprise projects and check something more appropriate for common people. How do you create your own SMS gateway? Not so long ago I wrote a small article about sending SMS using Nokia S60 phone as a modem from Ubuntu and Device::Gsm Pearl module. Now lot of people will ask why Perl? If you want to do something simple and effective on Ubuntu (or any other kind of Linux), Pearl is the way to go. If you want to do some massive development with tens of thousands of line of code, do not use Perl.

I tried this using Nokia N81 as a modem. There is no need to go that high, any phone which can act as a modem will do. USB wireless modems, like Huawei E220 should do as well. Operating system is Ubuntu 8.04, but you can try that using any OS where Perl can be installed.

For the start we need to install Device::Gms.

$ sudo perl -MCPAN -e shell

Super user is required to do that, now from CPAN shell we update our CPAN

cpan[1]> install Bundle::CPAN

That may take some time.

cpan[2]> reload cpan

And finally why we started all this:

cpan[3]> install Device::Gsm

It may be needed to install dependencies, like Device::Modem, CPAN will suggest that it downloads and installs dependencies. Home page of Device::Gsm is here, I suggest visiting it and reading it - carefully.

Now we can grab the USB cable and connect Nokia (or whatever you are using) and PC, from phone menu we select PC Suite. On Ubuntu we activate terminal and execute dmesg, only the last few lines are interesting.

[11869.492522] usb 2-5: new full speed USB device using ohci_hcd and address 2

[11869.727885] usb 2-5: configuration #1 chosen from 1 choice

[11870.010452] cdc_acm 2-5:1.8: ttyACM0: USB ACM device

[11870.015377] usbcore: registered new interface driver cdc_acm

[11870.015387] /build/buildd/linux-2.6.24/drivers/usb/class/cdc-acm.c: v0.25:USB Abstract Control Model driver for USB modems and ISDN adapters

[11870.053566] usbcore: registered new interface driver cdc_ether

[11870.056287] usb 2-5: bad CDC descriptors

[11870.056308] usbcore: registered new interface driver rndis_host

We now locate the following line of code on Device::Gsm home page

my $gsm = new Device::Gsm( port => '/dev/ttyS1', pin => 'xxxx' );

From dmesg otput we find out where the phone is and also we enter appropriate PIN

my $gsm = new Device::Gsm( port => '/dev/ttyACM0', pin => 'here comes your PIN' );

We are now ready to go:

#!/usr/bin/perl -w

use Device::Gsm;

my $gsm = new Device::Gsm( port => '/dev/ttyACM0', pin => 'XXXX' );

if( $gsm->connect() ) {

print "connected!\n";

} else {

print "sorry, no connection with gsm phone on serial port!\n";


my $imei = $gsm->imei();

print "$imei\n";

my $model = $gsm->model();

print "$model\n";

Copy and paste this into new file, name it and execute from terminal perl That will print IMEI and phone model.

By further modification of initial example from Device::Gsm home page we have

#!/usr/bin/perl -w

use Device::Gsm;

my $gsm = new Device::Gsm( port => '/dev/ttyACM0', pin => 'XXXX' , log => 'file,network.log', loglevel => 'debug');

if( $gsm->connect() ) {

print "connected!\n";

} else {

print "sorry, no connection with gsm phone on serial port!\n";




recipient => '+2774XXXXXXX',

content => 'Here is your Ubuntu talking',

class => 'normal'


Naturally, replace XXXX with what is your pin number. Start of recipient is +27 for South Africa and 74 for network, it may need adjustment as well. Reusing is a good idea. To send an SMS takes a while. In network.log we will find the story, if everything went well do not even look at it - 160 Kb of log per SMS. Now typically one would like to combine this with some kind of HTTP or maybe TCP access, but that is quite easy and well explained all over the web so I will not bother you with it.

If you happen to be in Italy, Cosimo Streppone may be happy to know that you are using his library, look for in examples folder.

No comments:

Post a Comment