
For mobile UMTS/GSM, I have been using an Option 3G Data Card for two and a half years now. I blogged about getting the
card to work (in German, sorry) on Linux in
July 2005. I never found the time - until now - to automate the card initialization so that I had been
using a horrible chat script for card initialization when the PPP connection was built.
I recently took the time to automate this, so that the PIN is transmitted to the card automatically when the card is
plugged in. This article documents what I did.
On a side note: Unfortunately, the vendors’ attitude towards Linux hasn’t changed since 2005. Their
Hotlines still deny that their products can be used with Linux at all, and they surely do not publish any documentation
that can be of help. Otoh, Vodafone has published a software that supposedly aids usage of their products under Linux. I
haven’t tried it yet since it is not packaged yet for Debian. Additionally, Vodafone support media and sales do
not seem to know about this effort, they still deny that their products work with Linux. Windows users happily install
proprietary software products that do little more than sending a handful of AT commands to the emulated USB modem and
hand over the connection to Windows’ PPP Stack. A very unsatisfying situation.
Just for the record: Dear Vodafone DE, a week ago you missed the sale of a new USB UMTS interface because you
don’t even document it on Linux. This motivated me to look into the drawer that holds the old, non-HSDPA PC cards
that have been decommissioned at the customers’ site and use an old, used device. Your fault.
But now back on topic: For a data center monitoring system, I want to send out alerts as text message (for German
speakers: SMS - we have a rather strange vocabulary for mobile communications), and am reluctant to do so via IP: IP is
one of the things that can fail, so it is preferred to directly inject the text messages into the network of the
operator that provides service to the recipients of the text messages. Fortunately, most of the recipients are in the
same network.
After evaluating current hardware solutions that could be plugged directly into the “real” server doing the
monitoring and running into the wall of non-support provided by the network operators and hardware vendors, I decided on
taking things a little further and to build an Ethernet-Connected text message device. An old hp compaq nc8000 (no, not
mine, mine still works fine and is in daily use) and an old, first generation Option Datacard 3G will be mounted near
the datacenter’s windows and equipped with Debian and Nagios. That way, the text message device can itself monitor
the monitoring system and even send out a warning message when the data center goes out of power: It has a built-in
UPS.
But now back on topic: For the text messages to go out reliably, it is necessary that the UMTS card is initialized
automatically when the system comes up. A great opportunity to finally address this issue for Linux, on customers’
expense **grins**.
UMTS card initialization is done in two steps: First, when the card is plugged in, the virtual OHCI host port appears.
Initialization of the virtual OHCI happens automatically. Most documentation on the web says that you now need to load
an appropriately parametrized usbserial module, and I did it this way for years, but that’s not necessary any
more. CONFIG_USB_SERIAL_OPTION is a dedicated kernel module for the Option 3G data card, which gets automatically loaded
if it is available.
If you don’t have the Option module for some reason, you still need the following udev rule to automatically load
the generic USB serial module. I figured that out yesterday before I learned about the Option module in a comment made
to the original version of this article.
SUBSYSTEM==“usb”, \
SYSFS idProduct ==“5000”, SYSFS idVendor ==“0af0”, \
ACTION==“add”, \
RUN+=“/sbin/modprobe usbserial vendor=0x$attr idVendor product=0x$attr idProduct ”
SUBSYSTEM==“usb”, \
SYSFS idProduct ==“5000”, SYSFS idVendor ==“0af0”, \
ACTION==“remove”, \
RUN+=“/sbin/modprobe -r usbserial”
Unfortunately, the usbserial and option modules stay around after the card is pulled. This doesn’t hurt though.
Next, we see three virtual serial interfaces, which we can detect via udev, and assign “speaking” device
names and transmit the PIN. This goes into /etc/udev/rules.d/50-option3g.rules:
SUBSYSTEM==“tty”, SUBSYSTEMS==“usb”, DRIVERS==“option”, \
ATTRS bInterfaceNumber ==“00”, \
ATTRS modalias ==“usb:v0AF0p5000d0000dc00dsc00dp00icFFiscFFipFF”, \
SYMLINK=“UMTS-DATA”
SUBSYSTEM==“tty”, SUBSYSTEMS==“usb”, DRIVERS==“option”, \
ATTRS bInterfaceNumber ==“02”, \
ATTRS modalias ==“usb:v0AF0p5000d0000dc00dsc00dp00icFFiscFFipFF”, \
SYMLINK=“UMTS-CONTROL”, RUN+=“/usr/local/sbin/umts-pin --device %k”
I am not sure what the modalias attribute identifies, but it looks like it identifies the hardware model: An identical
Option Datacard 3G, plugged into the other PC Card Slot gets properly initialized as well.
These two udev stanzas do two different things: First, they make sure that the new devices are symlinked to
/dev/UMTS-DATA and /dev/UMTS-CONTROL, suggesting the intended use of the interface. The second virtual interface of the
3G Data Card does not seem to be useable at all, and you cannot build an actual data connection over the third. So, we
baptize the first interface /dev/UMTS-DATA and ignore the second. The third gets called /dev/UMTS-CONTROL.
Now to the real magic:
/usr/local/sbin/umts-pin is a perl script that sends the PIN to the Card. %k gets expanded to the device
name of the device that has just been detected, so umts-pin gets called with “--device ttyUSB2”.
It makes use of Cosimo Streppone’s Device::Modem module (Device::Gsm is not yet packaged for Debian and might be
of better use here) to talk to the UMTS device. Unfortunately, I have not yet fully understood the logging and answer
processing features of Device::Modem, so the implementation might look a little clumsy. I hope that it can be clearly
understood anyway.
The actual PIN is read from a configuration file in an apache-like format, which is by default looked for in
/etc/umts/pin.conf:
<pin>
<default>
pin xyzw
</default>
</pin>
The reason I settled for this rather complex configuration file format is that the ultimate goal is to automatically
detect which of my SIMs is currently inserted in the UMTS card and to automatically send the correct PIN. I
haven’t been successful in doing so since I didn’t find an AT command yet to get the UMTS card to divulge
the SIM serial number or the IMSI
before the PIN is transmitted to the SIM. So currently, the only things that
are supported are the “default” stanza and an identically formatted “override” stanza which
takes precedence over the default stanza if present.
If the first attempt to send the PIN fails, the script tries again ten seconds later. On my test system, this happens
about once in twenty times. That must be some weird timing issue. So, if you have the wrong PIN configured, you’ll
need the PUK after plugging in the card for the second time, since the first try will eat two of your three attempts.
Beware.
If you feel uncomfortable with all this scripting and the “quality” of my code, you can also use
gammu’s entersecuritycode function. I discovered this after my PIN script was already written, and gammu currently
forces you to expose the PIN on the command line (see
#484102), and of course my script’s PIN handling is vastly superior **grins**.
And one end note: More current hardware, most notably the Huawei series of cards, are reported to show themselves as
virtual USB storage first to allow identification and installation of Windows drivers, and need an explicit command to
show their virtual USB serial side. I have read web pages where people have managed to do this in Linux, but since I use
an older card and do not have a current card available (again, Vodafone, your fault!) I cannot comment about this. But
there are reports that this can be done, so don’t panic if you have more recent hardware.