Thursday, January 14, 2010

SMS Server Tools on Mac OS X with Swisscom Unlimited USB Modem E180V

We set up a server to monitor our servers, services and network devices.

Monitoring on Mac OS X


What we started off with is

- a Mac Mini with Mac OS X 10.6 Snow Leopard Client
- Lithium 5 Monitoring Software www.lithium5.com

What I wanted to do is also monitor our internet connection.
For that case we ping www.google.com.
If that service is unavailable, we expect the internet connection to have failed.

The problem now is:
If the internet connection is down, then we cannot alert via email or push notification because we have to assume that there is no connection to the internet.

The idea now is, that in this case, we alert via SMS.

The Device


So I went to our local phone provider and bought a USB HSPA/UMTS/EDGE/GPRS modem.
Thy type I chose is called 'Unlimited USB Modem E180V' which in fact is a Huawei E180V.

As we do not plan to use the Modem to surf the web, we decided to get a prepaid card along with it.
This means we can recharge it by using the credit card.

What's next?

We installed the modem an downloaded and installed the current software to go along with it from the providers web page.
It works.
But: In order for the modem to work, one has to log in and start the application of the provider, in out case:
/Applications/Unlimited Connection Manager.app

Now that is not what I wanted.
The problem is that without having started the app, the modem will not appear as a device in /dev
Which means that the device is not operable. Hmm.
But I do not want a user to have to log in and start the app on this machine.

So here's what did the trick:
I looked at the installer package that came with the modem using Suspicious Package.
It does not install anything other than the application.
So it has to be something inside the application bundle that has to be initiated to make the modem available to the system.
After poking around a bit, I found this folder:
/Applications/Unlimited Connection Manager.app/Contents/Drivers
It contains a kext ba the name of 'HuaweiDataCardDriver.kext'.

So what do I do:
We load the kext:
kextload "/Applications/Unlimited Connection Manager.app/Contents/Drivers/HuaweiDataCardDriver.kext"

And what happens:
We now see the device in /dev:

crw-rw-rw- 1 root wheel 11, 7 Jan 13 15:17 cu.HUAWEIMobile-Diag
crw-rw-rw- 1 root wheel 11, 9 Jan 14 12:35 cu.HUAWEIMobile-Modem
crw-rw-rw- 1 root wheel 11, 5 Jan 13 15:17 cu.HUAWEIMobile-Pcui
crw-rw-rw- 1 root wheel 11, 6 Jan 13 15:17 tty.HUAWEIMobile-Diag
crw-rw-rw- 1 root wheel 11, 8 Jan 13 15:17 tty.HUAWEIMobile-Modem
crw-rw-rw- 1 root wheel 11, 4 Jan 13 15:17 tty.HUAWEIMobile-Pcui


So basically we are now ready to send SMS.
Theoretically.

Sending SMS


When trying to find information on how to send SMS notifications via shell script, found out that there is one big problem.
While sending an SMS the device is blocked so that sending is no longer possible until the first SMS has been sent.
So one would need some kind of queue.

As it turns out, there's an app for that.
The solution is SMS Server Tools 3.

«The SMS Server Tools 3 is a SMS Gateway software which can send and receive short messages through GSM modems and mobile phones.»

And it is open source too!!!
So I downloaded it and compiled it using the apple developer tools.

Now, all we have to do is add the correct device to the config file of the smsd.

device = /dev/cu.HUAWEIMobile-Modem

And we need to start the smsd.

The Script


So we created a script that loads the extension, unmount the volumes provided by the UMTS modem and start the SMS service.

The script looks like this:

#!/bin/sh

# Script that loads the extension, unmount the volumes provided by the UMTS modem and start the SMS service
# Created by kurt hofmann © 2010

diskutil unmount /Volumes/NO\ NAME
diskutil unmount /Volumes/Unlimited\ Connection\ Manager

kextload /Applications/Unlimited\ Connection\ Manager.app/Contents/Drivers/HuaweiDataCardDriver.kext

/usr/local/bin/smsd


This script is then started by a launchd job on startup.

SMS can now be sent using this command from the command line:
sendsms thenumber 'the message'
thenumber is an international phone number without the leading zeros.

Receiving SMS


Now that sending SMS works I wanted to know what it needs to receive SMS.
Then when I send an SMS it might be that someone replies to that message, so it might be useful to receive them.
SMS Server Tools 3 provides a solution for that.

There is an eventhandler that gets called whenever it receives or sent a message or when it was not able to send a message.
So I created a script that sends me an incoming SMS as an email.

The script is here /usr/local/bin/sms2email

It looks like this:

#!/bin/sh
# This is an example how to use an eventhandler with smsd.
# $1 is the type of the event wich can be SENT, RECEIVED, FAILED or REPORT.
# $2 is the filename of the sms.
# $3 is the message id. Only used for SENT messages with status report.

#The next line changes the file attributes so that everybody can read
#received SM
#if [ "$1" = "RECEIVED" ]; then
# chmod a+r $2
#fi

email_receiver="email@provider.com"


#This sends all received SM to an eMail receiver:
if [ "$1" = "RECEIVED" ]; then
/usr/bin/mail -s "Incoming SMS" $email_receiver <$2
fi


Now all we have to do is to is put a reference to the script into the smsd.conf file.

When trying this, I found that there was a problem trying to read the SMS from the device.
So I had to add an additional init string to put the modem in the right mode.

The smsd.conf file


So this is what my config file looks now:

# Example smsd.conf. Read the manual for a description

devices = GSM1
logfile = /var/log/smsd.log
loglevel = 6
smart_logging = yes
eventhandler = /usr/local/bin/sms2email

[GSM1]
init = AT+CPMS="MT","MT","MT"
check_memory_method = 2
device = /dev/cu.HUAWEIMobile-Modem
incoming = yes
#pin = 1111


Conclusion


Now this works perfectly for my needs.
I now have a server that can send SMS per cli and it can even receive SMS and forward them as email.
Cool.

If you have any questions just let me know.