Writing udev rules to create symbolic link for Huawei E220 USB GSM/UMTS Modem

On an Ubuntu 8.04 server, I connected a Huawei USB modem to send SMS using SMSLib. Normally, the modem interface can be found under /dev/ttyUSB0. For some reason, the system decided to mount the modem interface using /dev/ttyUSB1. To avoid to always reconfigure SMSLib, if such a change occurs, I decided to use udev rules to create a specific symlink for the modem interface.

1. Check with lsusb if the device is connected:

prompt> lsusb
Bus 005 Device 005: ID 12d1:1003 Huawei Technologies Co., Ltd. E220 HSDPA Modem
....

2. Somewhere in /var/log/messages you should find an information, to which devices the different ports of the modem have been mapped to. In my case, it is:

Jul  9 08:50:07 server kernel: [4378805.151459] usb 5-5.1: airprime converter now attached to ttyUSB1
Jul  9 08:50:07 server kernel: [4378805.151488] usb 5-5.1: airprime converter now attached to ttyUSB2
Jul  9 08:50:07 server kernel: [4378805.151513] usb 5-5.1: airprime converter now attached to ttyUSB3

3. After checking with minicom that ttyUSB1 is the correct port, I used

udevinfo -a -p $(udevinfo -q path -n /dev/ttyUSB1) > ttyUSB1.info
udevinfo -a -p $(udevinfo -q path -n /dev/ttyUSB3) > ttyUSB3.info

to retrieve information about the different device information stored in the udev database.  Simply running diff on the information shows you some hints, how to differentiate the devices and only create a symbolic link for one of those ports. In my case, the diff showed following results:

8,9c8,9
<   looking at device '/devices/pci0000:00/0000:00:1d.7/usb5/5-5/5-5.1/5-5.1:1.0/ttyUSB1/tty/ttyUSB1':
<     KERNEL=="ttyUSB1"
---
>   looking at device '/devices/pci0000:00/0000:00:1d.7/usb5/5-5/5-5.1/5-5.1:1.0/ttyUSB3/tty/ttyUSB3':
>     KERNEL=="ttyUSB3"
12c12
<     ATTR{dev}=="188:1"
---
>     ATTR{dev}=="188:3"

4. Using the information ATTR{dev}==”188:1″ and ATTRS{product}==”HUAWEI Mobile” in a parent device, I came up with the following udev rule that I put into /etc/udev/rules.d/98-modem.rules:

KERNEL=="ttyUSB*", ATTR{dev}=="188:1", ATTRS{product}=="HUAWEI Mobile", SYMLINK+="ttyS20"

According to the great tutorial Writing udev rules by Daniel Drake, it is not possible to mix attributes from different parent devices. This is why I used the ATTR{dev}==”188:1″ and not ATTRS{port_number}==”0″ as I already used ATTRS{product}==”HUAWEI Mobile” in a different parent device. (You could also ATTRS{idVendor}==”12d1″ and ATTRS{idProduct}==”1003″ to specify the modem instead of the product attribute.)

5. Simply let udev know about your newly created rule and check, if the system created the correct link:

promtp> sudo udevtrigger
prompt> ll /dev/ttyS20
lrwxrwxrwx 1 root root 7 2009-07-10 08:12 /dev/ttyS20 -> ttyUSB1

Now you can use the device /dev/ttyS20 in your SMSLib configuration. To be used in SMSLib, the symbolic link should be named to something resembling a standard serial port, like /dev/ttyS*. If you do not so, it is possible that SMSLib (or the used RXTX lib) does not correctly recognise the serial port. It my first try, I named the symbolic link /dev/huawei_modem. Minicom was fine with that, but SMSLib did not like it.