June 30, 2013

An RPi SMS Gateway



After the implementation of my email account sign up system on my Raspberry Pi hotspot system, I decided to go out and get a Huawei 3G USB dongle and together with my 2nd SIM card (on the multisim plan), I built the SMS gateway right onto the Pi itself. I’ll be the first to admit, I can get a little bogged down doing research before I buy anything, but this time I did it on a whim and ended up with the Huawei E303 – purchased for a reasonable price of S$55 at 4am from everybody’s favorite Mustafa Center. There were other 3g modems there, primarily from Prolink and Vodafone, but they cost twice as much as the Huawei one did.

In anycase, this E303 is a multipurpose USB device, meaning that it has 2 functions – firstly its a 3G modem and secondly, its a storage device (it has an internal storage by itself and an expandable storage via a microSD slot). So depending on how your system scans the device, it may or may not allocate the 3G functionality to it. With the newer devices, it detects the 3G rather effortlessly, but if life wants to throw you lemons, it will detect the device as a USB storage device. Thats where things get a little painful.

You essentially have to change the USB mode from storage device to 3G modem using usb_modeswitch. Simple enough one would think. Not in the slightest. The usb_modeswitch requires you to provide the vendor and product id of the device in the storage mode and the vendor and product id you want it to change to (as the 3G modem). The lsusb command can give you the ids at the storage mode quite easily, but you’ve got to go to Google to find out the ids at the 3G modem mode.

And this isn’t the end of it – the power to the device seems to also play a part. When I connected the Huawei directly to the Pi, no matter what I did with the usb_modeswitch, it refused to change. A bit of reading confirmed what I was beginning to realise, that the modem function actually required more power than the Pi’s USB ports could muster. A typical ‘B’ device (512MB Ram 700MHz) Pi puts out 100mA per port, while the 3G modem needs considerably more. That being the case, without sufficient power, the system would never detect the 3G modem and create the device nodes for it.

Solving the power issue was simple enough – I connected a powered USB 2.0 hub to the Pi and powered the Pi via another power adapter dishing out 1A of current. So I basically had 2 power supplies – one for the Pi and one for the hub. With this setup, the 3G modem was detected easily over the storage and I was a happy camper, even though it took me well over 8 hours to figure things out – trial and error takes time. By the way, if you keep getting switched back to storage mode because you plug the dongle into different ports of the USB hub, just unplug and replug the dongle into that same port of  the USB hub. That should have it switch back to modem mode. After which it should always detect the dongle in modem mode. I’m still looking for a software way to do this, since the usbreset codes I found don’t help, at least for the Pi – they seem to work fine on my standard Ubuntu and Slackware though.

With the device detected properly, it was a matter of installing a 3G controlling software. There are 2 to choose from – gnokii and gammu. By far, gammu is the superior of the two and it doesn’t install a lot of junk that I don’t need the way gnokii does. Its a whopping difference of 156MB for gnokii (on my system) compared to 759KB for gammu (there are a lot of gnome dependencies and stuff that gnokii needs).

The gammu software also comes with a handy curses based configuration tool gammu-config which creates and allows you to setup the most pertinent options in the gammu config file. Install gammu via apt-get:

root@raspberrypi:~# apt-get install gammu
Reading package lists... Done
Building dependency tree
Reading state information... Done
Suggested packages:
  wammu gammu-doc
The following NEW packages will be installed:
0 upgraded, 1 newly installed, 0 to remove and 95 not upgraded.
Need to get 0 B/322 kB of archives.
After this operation, 759 kB of additional disk space will be used.
Selecting previously unselected package gammu.
(Reading database ... 39205 files and directories currently installed.)
Unpacking gammu (from .../gammu_1.31.90-1_armhf.deb) ...
Processing triggers for man-db ...
Setting up gammu (1.31.90-1) ...

Get the port your modem is connected to by checking dmesg:

root@raspberrypi:~# dmesg |grep tty
[    0.000000] Kernel command line: dma.dmachans=0x7f35 bcm2708_fb.fbwidth=1680 
bcm2708_fb.fbheight=1050 bcm2708.boardrev=0xf bcm2708.serial=0xb2a882a3 
smsc95xx.macaddr=B8:27:EB:A8:82:A3 sdhci-bcm2708.emmc_clock_freq=100000000 
vc_mem.mem_base=0x1c000000 vc_mem.mem_size=0x20000000  dwc_otg.lpm_enable=0 
console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 console=tty1 root=/dev/mmcblk0p2 
rootfstype=ext4 elevator=deadline rootwait
[    0.000000] console [tty1] enabled
[    0.576921] dev:f1: ttyAMA0 at MMIO 0x20201000 (irq = 83) is a PL011 rev3
[    0.887032] console [ttyAMA0] enabled
[    8.236054] usb 1-1.2.4: GSM modem (1-port) converter now attached to ttyUSB0
[    8.432593] usb 1-1.2.4: GSM modem (1-port) converter now attached to ttyUSB1
[    8.625152] usb 1-1.2.4: GSM modem (1-port) converter now attached to ttyUSB2
[ 4182.867673] option1 ttyUSB0: GSM modem (1-port) converter now disconnected from ttyUSB0
[ 4182.875577] option1 ttyUSB1: GSM modem (1-port) converter now disconnected from ttyUSB1
[ 4182.878408] option1 ttyUSB2: GSM modem (1-port) converter now disconnected from ttyUSB2

In this case you can see there are 3 options ttyUSB0, ttyUSB1 and ttyUSB2.

Run gammu-config and setup the configuration file using any of the ttyUSB* values (you can take the defaults for the rest):


Then run gammu –identify to see if you can pick up the device’s IMEI number (values have been masked out for obvious reasons):

root@raspberrypi:~# gammu --identify
Device               : /dev/ttyUSB2
Manufacturer         : Huawei
Model                : unknown (E303)
Firmware             :
IMEI                 : xxxxxxxxxxxxxxx
SIM IMSI             : xxxxxxxxxxxxxxx

If you get a message along the lines of “phone not connected”, then fire up gammu-config again and try the other ttyUSB* values shown in the dmesg till gammu identifies your device.

After that its a matter of sending off the SMS as follows:

root@raspberrypi:~# echo "Test SMS from RPi SMS Gateway" | gammu --sendsms TEXT +65xxxxxxxx
If you want break, press Ctrl+C...
Sending SMS 1/1....waiting for network answer..OK, message reference=67

Now sit back and wait for the SMS to arrive.


From here it was basically a modification of my hotspot signup scripts to have the user key in their mobile number (local numbers only) and remove the ‘desired password’ section completely.


Now when the user signs up, the system will:

  • Send me an email to ask me to authorize adding the user (via a URL link in the mail)
  • If I authorize the user’s request by clicking on the link in the email, the system will automatically add the user’s mobile number (without the country code) as the username to the radcheck table of the radius database and generate a random password which will be encrypted and also added to the radcheck table of the radius database
  • The random password will then be SMS-ed to the users mobile number and the expiry counter gets started
  • Once the expiry counter is over, the system will send the disconnection packet to the wireless router to disconnect the user and then remove the username (mobile number) and password from the radcheck table

If theres any abuse, I’ll have the users mobile number to follow up with. Pretty good way to make use of my many free SMSes, left over every month from my mobile plan because, seriously – who uses SMS anymore?

If you’re trying this out yourself and run into any problems, drop me a line and I’ll see what I can do to help. Setting up a hotspot is a brilliant learning exercise, so despite the frustrations that may occur from time to time, try and have fun – Cheers!


With regards to using software to ‘unplug and replug’ the modem, I got the usbreset working. My own lack of common sense – I was trying to reset the individual port the modem was on when I should have been resetting the hub.

root@raspberrypi:~# lsusb
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 002: ID 0424:9512 Standard Microsystems Corp.
Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp.
Bus 001 Device 004: ID 05e3:0608 Genesys Logic, Inc. USB-2.0 4-Port HUB
Bus 001 Device 005: ID 12d1:1446 Huawei Technologies Co., Ltd. E1552/E1800/E173 (HSPA modem)
root@raspberrypi:~# gammu --identify
Error opening device, it doesn't exist.
root@raspberrypi:~# ./usbreset /dev/usbdev1.4
Resetting USB device /dev/usbdev1.4
Reset successful
root@raspberrypi:~# lsusb
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 002: ID 0424:9512 Standard Microsystems Corp.
Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp.
Bus 001 Device 004: ID 05e3:0608 Genesys Logic, Inc. USB-2.0 4-Port HUB
Bus 001 Device 007: ID 12d1:1436 Huawei Technologies Co., Ltd.
root@raspberrypi:~# gammu --identify
Device               : /dev/ttyUSB2
Manufacturer         : Huawei
Model                : unknown (E303)
Firmware             :
IMEI                 : xxxxxxxxxxxxxxx
SIM IMSI             : xxxxxxxxxxxxxxx

Instead of resetting Bus 001 Device 005 (the modem port), I needed to reset Bus 001 Device 004 (the hub). The reason it worked on my Slackware and Ubuntu setups, was because the modem was connected directly to the laptop’s usb ports and not through a hub. Another lesson learnt!

Comments (2)

  1. March 18, 2014
    Gal Bar-or said...

    Great article, thank you. I followed this all the way, but I’m not sure if there’s an easy way to receive SMS messages on the rPI. I’ve tried smsd, but it’s not obvious – any pointers?

Leave a comment...

To leave a comment on this post, please login by clicking one of the following.