Let’s make SMS Gateway using Itegno GSM Modem, Kannel, & Playsms

To make our own SMS Gateway has a tough challenge. Actually there are many documentations about this on the internet, but few are really suitable for newbie. After 2 weeks of sleepless nights, I manage to set it up. What's so different if we send sms using program from our cell phone? Well using Kannel and Playsms we can make it multiuser and can be accessed from the internet.


First of all, I want to thank all the people who have been so helpful, especially:
1. Itegno Modem Developer who has provided the AT command.
2. Anton Rahardja and team who has made Playsms and willing to be asked at 2 am in the morning 🙂
3. Mr. Adi Prasaja who has provided key setting of GSM modem.
4. All colleaques who have been so kind in discussing, Mas Dave Muhammad, Mas Rist. Andy Nugroho, Arief Suherlan, etc.
5. Uncle Google and Aunt Mailing Lists 🙂

Ok, let's start. We will need these:
1. GSM Modem. I use Itegno 3000 with USB connection (http://www.dsc.co.id/?page=category&catid=5&pid=120).
2. Kannel (http://www.kannel.org) as sms engine.
3. Playsms (http://playsms.sourceforge.net) as web-based Mobile Portal System.
4. Linux OS with MySQL, I use FC4 with the latest kernel 2.6.15-1.1830.
5. Very black coffee, toasts, and your favourite instant noodle to keep us awake in the sleepless nights 🙂

This is very important, this are the steps to setup a sms gateway:
1. Setting GSM Modem.
2. Install and setup Kannel.
3. Install and setup Playsms.
4. Testing up.

A. Setting up GSM Modem
Put in the GSM card into the modem, and don't forget to put the hatch back. Because if not the modem won't work correctly.

Fire up Linux and plug the modem into the usb port. Open a terminal and do tail -f /var/log/messages. We will see this when Linux recognises the modem:

Feb  18 19:36:01 fc4 kernel: usb 2-2: new full speed USB device using uhci_hcd and address 3
Feb  18 19:36:01 fc4 kernel: usbcore: registered new driver usbserial
Feb  18 19:36:01 fc4 kernel: drivers/usb/serial/usb-serial.c: USB Serial support registered for generic
Feb  18 19:36:01 fc4 kernel: usbcore: registered new driver usbserial_generic
Feb  18 19:36:01 fc4 kernel: drivers/usb/serial/usb-serial.c: USB Serial Driver core
Feb  18 19:36:02 fc4 kernel: drivers/usb/serial/usb-serial.c: USB Serial support registered for pl2303
Feb  18 19:36:02 fc4 kernel: pl2303 2-2:1.0: pl2303 converter detected
Feb  18 19:36:02 fc4 kernel: usb 2-2: pl2303 converter now attached to ttyUSB0
Feb  18 19:36:02 fc4 kernel: usbcore: registered new driver pl2303
Feb  18 19:36:02 fc4 kernel: drivers/usb/serial/pl2303.c: Prolific PL2303 USB to serial adaptor driver

Physically we can see if the modem was recognized by it's blinking light.

B1. Installing Kannel.
We can install either from source or binary. No problem. With FC4 we can install it with:

yum install kannel kannel-devel

It is located in the extras repository.

B2. Setting up Kannel.
Setting up Kannel is pretty difficult for the first time. It's very helpful to download and read the Kannel userguide from kannel.org. Playsms has provided a starter guide for us.

This is my /etc/kannel.conf:
# CORE
group = core
admin-port = 13000
admin-password = pwd
status-password = pwd
log-file = "/var/log/kannel/kannel.log"
log-level = 0
access-log = "/var/log/kannel/access.log"
smsbox-port = 13001
store-file = "/var/log/kannel/kannel.store"

# SMSC Fake
#group = smsc
#smsc = fake
#host = localhost
#port = 13013

#SMSC modem gsm
group = smsc
smsc = at
host = localhost
port = 13013
smsc-id = linuxku
modemtype = wavecom
device = /dev/ttyUSB0
speed = 115200
sms-center = 0816124

group = modems
id = WAVECOM
name = wavecom
detect-string = WAVECOM
init-string = "AT+CNMI=1,2,0,1,0;+CMEE=1"

# SMSBOX SETUP
group = smsbox
bearerbox-host = localhost
sendsms-port = 13131
sendsms-chars = "0123456789+"
log-file = "/var/log/kannel/smsbox.log"
log-level = 0
access-log = "/var/log/kannel/access.log"

# SEND-SMS USERS
group = sendsms-user
username = playsms
password = pwd

# SMS SERVICE 'Default'
# there should be default always
group = sms-service
keyword = default
max-messages = 0
exec = /usr/local/bin/kannel_incoming %t %q %a
#get-url = "http://localhost/~playsms/plugin/gateway/kannel/geturl.php?t=%t&q=%q&a=%a"

Short explanation:
The SMSC Fake part is commented out, because it's for testing only. We cannot send real sms with it. Since we are using a real modem, we must define the modem part. The important part here is the init-string, that is: "AT+CNMI=1,2,0,1,0;+CMEE=1", CMEE=1 means we instruct the modem to be verbosed with any error. If we don't set it verbose, the modem will say an error occured without any error code. Without the error code Kannel cannot say what it the error is:

2006-02-18 10:20:46 [8984] [7] ERROR: AT2[/dev/ttyUSB0]: Error occurs: ERROR (error number not known to us. ask google and add it.)

With verbose setting, we can see the error :

2006-02-18 10:25:20 [8984] [7]  CMS ERROR: +CMS ERROR: 38 (Network out of order)

Next what is also important is the max-messages = 0 in sms-service group. Option max-message = 0. That option is to prevent kannel from sending reply when receiving any sms. Because if it does, it can be lost in send and receive loop, for example if we send a sms to ourselves. It will reply the sms to itself then the reply gets reply, so on.

How does kannel work?
Kannel is more than a sms engine, it can also function as a wap gateway. There are 3 main components in kannel: bearerbox, smsbox, and wapbox. Bearerbox is the heart of kannel, it manages the other 2 components.

C. Installing and setting up Playsms

Playsms has provided a quite comprehensive howto. This is a part of it:
1.  It is important to meet all minimum requiments above (Its a must!)
2.  Setup a system user named 'playsms' to manage PlaySMS
    # adduser playsms
    # passwd playsms
    Note: on some Linux distributions adduser and passwd combined
3.  On most Linux distributions actions (2) will create system user and group named playsms
    with home directory /home/playsms, there you will install all PlaySMS files
4.  Create public_html on user's home directory, if its not already exists
    # mkdir /home/playsms/public_html
5.  Extract PlaySMS package somewhere (Place in /usr/local/src if you want to)
    # tar -zxvf playsms-x.x.x.tar.gz -C /usr/local/src
    # cd /usr/local/src/playsms-x.x.x
6.  Copy 'web' directory to public_html directory and set owner back to user playsms again
    (for security reason)
    # cp -rR web/* /home/playsms/public_html
    # chown -R playsms /home/playsms/public_html
    # chmod 701 /home/playsms
7.  Setup database (import database)
    # mysqladmin -u root -p create playsms
    # mysql -u root -p playsms < /usr/local/src/playsms-x.x.x/db/playsms.sql
    Note: you dont need to use MySQL root access nor this method to setup PlaySMS
    database, but this is beyond our scope, you should read MySQL manual's for custom
    installation method
8.  Edit config.php on playsms web directory (/home/playsms/public_html/config.php)
    Please read and fill all required fields carefully
9.  Enter bin directory and copy playsmsd and playsmsd_start to /usr/local/bin
    # cd /usr/local/src/playsms-x.x.x
    # cd bin
    # cp playsmsd playsmsd_start /usr/local/bin/
10. Enter /etc/init.d or /etc/rc.d/init.d and look for file rc.local, im sure you'll
    found it. Edit that file and put "/usr/local/bin/playsmsd_start" (without quotes) on the
    bottom of the file (before exit if theres exit). This way playsmsd_start will be run
    everytime the system startup. You need 'root' access for this purpose.
11  Browse http://localhost/~playsms and login using default administrator user
    username: admin
    password: admin
12. At this point you should be able to logon PlaySMS webbased interface.
    Lets move on to gateway module part, the hard one 🙂

If you decide to use kannel gateway module, then you must install kannel on the same
server where PlaySMS installed. There are discussion on hoto install Kannel on separate machine
with PlaySMS.
Due to complexity of installation process for kannel, we decide to leave this module for experts.
Well experts, there's something you should see on this package contrib/kannel/kannel.conf,
sms service 'Default' part.

Dont forget to:
1.  Create kannel cache directory and make it writable to the web servers user
    # mkdir /usr/local/cache
    # mkdir /usr/local/cache/smsd
    # chmod -R 777 /usr/local/cache
    Note:
    – make it writable to the world (chmod -R 777) just to simplify installation
    – it is better if you know what is the web server's user (eg: 'nobody')
      and instead chmod -R 777 you use:
      # chown -R nobody /usr/local/cache
2.  Create log directory
    # mkdir /var/log/kannel
3.  Enter bin directory in this package, and copy kannel_incoming to /usr/local/bin

If you decide to use kannel gateway module, but you dont want to use 'exec' method in sms service,
just replace you kannel.conf near to sms service 'Default' part, with sms service 'Default' part in
this package contrib/kannel/kannel-geturl.conf
After copying sample configuration, dont forget to change 'CHANGE_THIS_TO_YOUR_PLAYSMS_URL'
in your kannel.conf near to sms service 'Default' part, to your working PlaySMS URL

Note:
FC4 on default doesn't permit user home directory to be accessed from the web. So, to make it accessible, we must edit /etc/httpd/conf/httpd.conf, and commented out UserDir disable:
# UserDir: The name of the directory that is appended onto a user's home
    # UserDir is disabled by default since it can confirm the presence
#    UserDir disable

Ok, let's restart apache, and then we open playsms website. In localhost we the address is:

http://localhost/~playsms

You can logon with username: admin, password: admin

D. Testing
After all is ready, let's start testing:
– Start bearerbox
bearerbox /etc/kannel.conf

2006-02-16 09:11:48 [6196] [0] INFO: Kannel bearerbox II version 1.4.0 starting
2006-02-16 09:11:48 [6196] [0] INFO: Loading store file `/var/log/kannel/kannel.store'
2006-02-16 09:11:48 [6196] [0] INFO: Store-file size 0, starting to unpack
2006-02-16 09:11:48 [6196] [0] INFO: Retrieved 0 messages, non-acknowledged messages: 0
2006-02-16 09:11:48 [6196] [7] DEBUG: Thread 7 (gw/smsc/smsc_at.c:at2_device_thread) maps to pid 6196.
2006-02-16 09:11:48 [6196] [0] INFO: MAIN: Start-up done, entering mainloop
2006-02-16 09:11:48 [6196] [0] DEBUG: AT2[linuxku]: start called
2006-02-16 09:11:48 [6196] [8] DEBUG: Thread 8 (gw/bb_smscconn.c:sms_router) maps to pid 6196.
2006-02-16 09:11:48 [6196] [8] DEBUG: sms_router: time to sleep
2006-02-16 09:11:48 [6196] [8] DEBUG: sms_router: list_len = 0
2006-02-16 09:11:48 [6196] [7] DEBUG: AT2[linuxku]: detecting modem type
2006-02-16 09:11:48 [6196] [7] INFO: AT2[linuxku]: opening device
2006-02-16 09:11:48 [6196] [7] DEBUG: AT2[linuxku]: device opened
2006-02-16 09:11:49 [6196] [7] DEBUG: AT2[linuxku]: device opened
2006-02-16 09:11:49 [6196] [7] INFO: AT2[linuxku]: speed set to 115200
2006-02-16 09:11:49 [6196] [7] DEBUG: AT2[linuxku]: –> ^M
2006-02-16 09:11:51 [6196] [7] DEBUG: AT2[linuxku]: –> AT^M
2006-02-16 09:11:51 [6196] [7] DEBUG: AT2[linuxku]: <– AT
2006-02-16 09:11:51 [6196] [7] DEBUG: AT2[linuxku]: <– OK
2006-02-16 09:11:51 [6196] [7] DEBUG: AT2[linuxku]: –> AT&F^M
2006-02-16 09:11:51 [6196] [7] DEBUG: AT2[linuxku]: <– AT&F
2006-02-16 09:11:51 [6196] [7] DEBUG: AT2[linuxku]: <– OK
2006-02-16 09:11:51 [6196] [7] DEBUG: AT2[linuxku]: –> ATE0^M
2006-02-16 09:11:51 [6196] [7] DEBUG: AT2[linuxku]: <– ATE0
2006-02-16 09:11:51 [6196] [7] DEBUG: AT2[linuxku]: <– OK
2006-02-16 09:11:51 [6196] [7] DEBUG: AT2[linuxku]: –> ATI^M
2006-02-16 09:11:51 [6196] [7] DEBUG: AT2[linuxku]: <– WAVECOM MODEM
2006-02-16 09:11:51 [6196] [7] DEBUG: AT2[linuxku]: <– MULTIBAND  900E  1800
2006-02-16 09:11:51 [6196] [7] DEBUG: AT2[linuxku]: <– OK
2006-02-16 09:11:51 [6196] [7] DEBUG: AT2[linuxku]: found string <WAVECOM>, using modem definition <wavecom>
2006-02-16 09:11:51 [6196] [7] DEBUG: AT2[linuxku]: –> AT+CSMS=?^M
2006-02-16 09:11:51 [6196] [7] DEBUG: AT2[linuxku]: <– +CSMS: (0,1)
2006-02-16 09:11:51 [6196] [7] DEBUG: AT2[linuxku]: <– OK
2006-02-16 09:11:51 [6196] [7] INFO: AT2[linuxku]: Phase 2+ is supported
2006-02-16 09:11:51 [6196] [7] INFO: AT2[linuxku]: closing device
2006-02-16 09:11:52 [6196] [7] INFO: AT2[linuxku]: opening device
2006-02-16 09:11:52 [6196] [7] DEBUG: AT2[linuxku]: device opened
2006-02-16 09:11:52 [6196] [7] DEBUG: AT2[linuxku]: device opened
2006-02-16 09:11:52 [6196] [7] INFO: AT2[linuxku]: init device
2006-02-16 09:11:52 [6196] [7] INFO: AT2[linuxku]: speed set to 115200
2006-02-16 09:11:52 [6196] [7] DEBUG: AT2[linuxku]: –> ATZ^M
2006-02-16 09:11:52 [6196] [7] DEBUG: AT2[linuxku]: <– OK
2006-02-16 09:11:52 [6196] [7] DEBUG: AT2[linuxku]: –> AT^M
2006-02-16 09:11:52 [6196] [7] DEBUG: AT2[linuxku]: <– AT
2006-02-16 09:11:52 [6196] [7] DEBUG: AT2[linuxku]: <– OK
2006-02-16 09:11:52 [6196] [7] DEBUG: AT2[linuxku]: –> AT&F^M
2006-02-16 09:11:52 [6196] [7] DEBUG: AT2[linuxku]: <– AT&F
2006-02-16 09:11:52 [6196] [7] DEBUG: AT2[linuxku]: <– OK
2006-02-16 09:11:52 [6196] [7] DEBUG: AT2[linuxku]: –> ATE0^M
2006-02-16 09:11:52 [6196] [7] DEBUG: AT2[linuxku]: <– ATE0
2006-02-16 09:11:52 [6196] [7] DEBUG: AT2[linuxku]: <– OK
2006-02-16 09:11:52 [6196] [7] DEBUG: AT2[linuxku]: –> AT+IFC=2,2^M
2006-02-16 09:11:52 [6196] [7] DEBUG: AT2[linuxku]: <– OK
2006-02-16 09:11:52 [6196] [7] DEBUG: AT2[linuxku]: –> AT+CPIN?^M
2006-02-16 09:11:52 [6196] [7] DEBUG: AT2[linuxku]: <– +CPIN: READY
2006-02-16 09:12:03 [6196] [7] DEBUG: AT2[linuxku]: –> AT+CSCA="0816124"^M
2006-02-16 09:12:03 [6196] [7] DEBUG: AT2[linuxku]: <– OK
2006-02-16 09:12:03 [6196] [7] DEBUG: AT2[linuxku]: –> AT+CMGF=0^M
2006-02-16 09:12:03 [6196] [7] DEBUG: AT2[linuxku]: <– OK
2006-02-16 09:12:03 [6196] [7] DEBUG: AT2[linuxku]: –> AT+CSMS=?^M
2006-02-16 09:12:03 [6196] [7] DEBUG: AT2[linuxku]: <– +CSMS: (0,1)
2006-02-16 09:12:03 [6196] [7] DEBUG: AT2[linuxku]: <– OK
2006-02-16 09:12:03 [6196] [7] INFO: AT2[linuxku]: Phase 2+ is supported
2006-02-16 09:12:03 [6196] [7] DEBUG: AT2[linuxku]: –> AT+CSMS=1^M
2006-02-16 09:12:03 [6196] [7] DEBUG: AT2[linuxku]: <– +CSMS: 1,1,1
2006-02-16 09:12:03 [6196] [7] DEBUG: AT2[linuxku]: <– OK
2006-02-16 09:12:03 [6196] [7] DEBUG: AT2[linuxku]: –> AT+CNMI=1,2,0,1,0;+CMEE=1^M
2006-02-16 09:12:03 [6196] [7] DEBUG: AT2[linuxku]: <– OK
2006-02-16 09:12:03 [6196] [7] INFO: AT2[linuxku]: AT SMSC successfully opened.

– Next start smsbox:
smsbox /etc/kannel.conf

2006-02-12 13:36:20 [7002] [0] DEBUG: Kannel smsbox version 1.4.0 starting
2006-02-12 13:36:20 [7002] [0] DEBUG: Started thread 4 (gw/smsbox.c:obey_request_thread)
2006-02-12 13:36:20 [7002] [0] DEBUG: Started thread 5 (gw/smsbox.c:url_result_thread)
2006-02-12 13:36:20 [7002] [0] DEBUG: Started thread 6 (gw/smsbox.c:http_queue_thread)
2006-02-12 13:36:20 [7002] [0] INFO: Connected to bearerbox at localhost port 13001.
2006-02-12 13:36:20 [7002] [0] DEBUG: Started thread 7 (gw/heartbeat.c:heartbeat_thread)
2006-02-12 13:36:20 [7002] [2] DEBUG: Thread 2 (gwlib/http.c:server_thread) maps to pid 7002.
2006-02-12 13:36:20 [7002] [3] DEBUG: Thread 3 (gw/smsbox.c:sendsms_thread) maps to pid 7002.
2006-02-12 13:36:20 [7002] [1] DEBUG: Thread 1 (gwlib/fdset.c:poller) maps to pid 7002.
2006-02-12 13:36:20 [7002] [4] DEBUG: Thread 4 (gw/smsbox.c:obey_request_thread) maps to pid 7002.
2006-02-12 13:36:20 [7002] [5] DEBUG: Thread 5 (gw/smsbox.c:url_result_thread) maps to pid 7002.
2006-02-12 13:36:20 [7002] [6] DEBUG: Thread 6 (gw/smsbox.c:http_queue_thread) maps to pid 7002.
2006-02-12 13:36:20 [7002] [7] DEBUG: Thread 7 (gw/heartbeat.c:heartbeat_thread) maps to pid 7002.

– Open playsms and try sending a sms to someone:

In /var/log/kannel/kannel.log we will see:

2006-02-16 09:12:16 [6196] [6] DEBUG: Started thread 9 (gw/bb_boxc.c:function)
2006-02-16 09:12:16 [6196] [9] DEBUG: Thread 9 (gw/bb_boxc.c:function) maps to pid 6196.
2006-02-16 09:12:16 [6196] [9] INFO: Client connected from <127.0.0.1>
2006-02-16 09:12:16 [6196] [9] DEBUG: Started thread 10 (gw/bb_boxc.c:boxc_sender)
2006-02-16 09:12:16 [6196] [10] DEBUG: Thread 10 (gw/bb_boxc.c:boxc_sender) maps to pid 6196.
2006-02-16 09:15:06 [6196] [7] DEBUG: AT2[linuxku]: <– +CMT: ,35
2006-02-16 09:15:06 [6196] [7] DEBUG: AT2[linuxku]: <– 059126181642040C9126189519497500006020619041628212502B284C6EA7DDA0B03C0D5297D9E535
2006-02-16 09:15:06 [6196] [7] DEBUG: AT2[linuxku]: Numeric sender (international) <+628153314433>
2006-02-16 09:15:06 [6196] [7] DEBUG: AT2[linuxku]: User data length read as (18)
2006-02-16 09:15:06 [6196] [7] DEBUG: AT2[linuxku]: Udh decoding done len=18 udhi=0 udhlen=0 udh=''
2006-02-16 09:15:06 [6196] [7] DEBUG: AT2[linuxku]: –> AT+CNMA^M
2006-02-16 09:15:06 [6196] [10] DEBUG: send_msg: sending msg to box: <127.0.0.1>
2006-02-16 09:15:06 [6196] [10] DEBUG: boxc_sender: sent message to <127.0.0.1>
2006-02-16 09:15:06 [6196] [7] DEBUG: AT2[linuxku]: <– OK
2006-02-16 09:15:07 [6196] [9] DEBUG: boxc_receiver: got ack
2006-02-16 09:15:07 [6196] [1] DEBUG: Dumping 0 messages and 0 acks to store
2006-02-16 09:15:16 [6196] [9] DEBUG: boxc_receiver: heartbeat with load value 0 received

In /var/log/kannel/smsbox.log we will see:

2006-02-17 11:08:30 [9423] [3] INFO: smsbox: Got HTTP request </cgi-bin/sendsms> from <127.0.0.1>
2006-02-17 11:08:30 [9423] [3] INFO: sendsms used by <playsms>
2006-02-17 11:08:30 [9423] [3] INFO: sendsms sender:<playsms:+62816195566> (127.0.0.1) to:<+628153314433> msg:<Test kirim sms – fajar>
2006-02-17 11:08:30 [9423] [3] DEBUG: message length 56, sending 1 messages
2006-02-17 11:08:30 [9423] [3] DEBUG: Status: 202 Answer: <Sent.>
2006-02-17 11:08:30 [9423] [3] DEBUG: HTTP: Destroying HTTPClient area 0x91794e0.
2006-02-17 11:08:30 [9423] [3] DEBUG: HTTP: Destroying HTTPClient for `127.0.0.1'.
2006-02-17 11:08:35 [9423] [4] INFO: Starting delivery report <playsms> from <+628161922701>
2006-02-17 11:08:35 [9423] [4] DEBUG: Started thread 8 (gwlib/fdset.c:poller)
2006-02-17 11:08:35 [9423] [4] DEBUG: Started thread 9 (gwlib/http.c:write_request_thread)
2006-02-17 11:08:35 [9423] [8] DEBUG: Thread 8 (gwlib/fdset.c:poller) maps to pid 9423.
2006-02-17 11:08:35 [9423] [9] DEBUG: Thread 9 (gwlib/http.c:write_request_thread) maps to pid 9423.
2006-02-17 11:08:35 [9423] [9] DEBUG: Parsing URL `http://localhost/~playsms/plugin/gateway/kannel/dlr.php?type=8&slid=93&uid=1':
2006-02-17 11:08:35 [9423] [9] DEBUG:   Scheme: http://
2006-02-17 11:08:35 [9423] [9] DEBUG:   Host: localhost
2006-02-17 11:08:35 [9423] [9] DEBUG:   Port: 80
2006-02-17 11:08:35 [9423] [9] DEBUG:   Username: (null)
2006-02-17 11:08:35 [9423] [9] DEBUG:   Password: (null)
2006-02-17 11:08:35 [9423] [9] DEBUG:   Path: /~playsms/plugin/gateway/kannel/dlr.php
2006-02-17 11:08:35 [9423] [9] DEBUG:   Query: type=8&slid=93&uid=1
2006-02-17 11:08:35 [9423] [9] DEBUG:   Fragment: (null)

We can see the status of the sms in Playsms outbox:

Conclusion
This tutorial is so not perfect, but hopefully it can give a starting point for any of us who wants to setup a sms gateway. Any critics, suggestions are welcome, please let me know.

v.1.0 by ari_stress a.k.a tiger74 a.k.a Fajar Priyanto

Bukit Sentul, 19 February 2006. Email: fajarpri at arinet dot org

He is a Microsoft Certified Professional who falls in love with Linux. Working at a automotive dealer in Jakarta

 

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *