(This post is the 3rd part of my Ubuntu Linux Router Upgrade Project.)
Note that all Linux commands here assume use of Ubuntu Linux 8.04 ("Hardy Heron"), with all updates installed as of 2008-09-30.
The device I purchased for Alltel's Wireless Internet service (3G 1xEV-DO) was a UTStarcom UM175, purchased for $100 before a $100 mail-in rebate on a 2-year contract.
Some specs as printed on the box and from Alltel's website:
- USB modem with swivel connector
- Compatible with Windows XP, Vista, Mac OS X
- 1xRTT/EVDO Rev 0 and Rev A Ready
- CDMA 800/1900MHz
Also Known As
The "Alltel Part#" listed on the box label is "UM175ALA". The P/N on the device label is "UM175AL". (I'm assuming the "AL"/"ALA" suffixes are specific to Alltel?) The FCC ID is PP4PX-700. Also listed on the device label: "Distributed by UTStarcom Personal Communications. Made in Korea by PANTECH. QUALCOMM 3G CDMA."
When connected to Windows before installing the drivers, the following "Hardware Ids" are listed in Device Manager where it is recognized as a "USB Mass Storage Device", with a vendor ID of 0x106c and a product ID of 0x3b03:
USB\Vid_106c&Pid_3b03&Rev_0100 USB\Vid_106c&Pid_3b03
And here is the output of "/usr/sbin/lsusb -l" under Linux:
Bus 001 Device 006: ID 106c:3b03 Curitel Communications, Inc.
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 1.10
bDeviceClass 0 (Defined at Interface level)
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 64
idVendor 0x106c Curitel Communications, Inc.
idProduct 0x3b03
bcdDevice 1.00
iManufacturer 1 PANTECH
iProduct 2 USB MMC Storage
iSerial 3 000000000002
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 32
bNumInterfaces 1
bConfigurationValue 1
iConfiguration 0
bmAttributes 0xc0
Self Powered
MaxPower 100mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 2
bInterfaceClass 8 Mass Storage
bInterfaceSubClass 6 SCSI
bInterfaceProtocol 80 Bulk (Zip)
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x83 EP 3 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x05 EP 5 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 0
Device Status: 0x0001
Self Powered
Note that the above shows a vendor ID of 0x106c ("Curitel Communications, Inc.") and a product ID of 0x3b03.
Should be Easy (or not)
Even before I made the purchase, I ran across a blog post by Jason Costomiris, "HOWTO: Verizon UM175 USB EVDO Card under Ubuntu Hardy". Reading it gave me a good vote of confidence that my plan should work. He had success using the "same" device under the same distribution of Linux that I was planning on. Verizon and Alltel use the same CDMA technology (and Verizon is buying Alltel). The instructions made it almost appear as simple as "plug & play".
Unfortunately, this is where things got tricky. The device is not even shipped with drivers, at least not on a CD. Instead, the device doubles as a USB mass storage device (USB MCS / UMS), and is recognized as an Autorun-enabled CD-Rom with drivers for Windows and Mac OS. Under Windows, after the drivers are installed, the device is listed as a "PANTECH UM175AL Composite Device", a "UM175AL CD-ROM USB Device", a "PANTECH UM175AL Diagnostic Port", and a "PANTECH UM175AL" modem.
By default, Linux only sees this device as a USB CD-Rom. As such, no serial port (e.g. /dev/ttyACM0) is ever created, leaving PPP nothing to connect to.
I need to thank Jason for responding to the comment I left on his post asking for help. Unfortunately, it appears that my "UM175AL" is a slightly different revision than what Jason used with so few issues.
lsusb Note
Many pages I found while researching this issue referenced the output of "/proc/bus/usb/devices". This does not exist under recent versions of Ubuntu Linux. lsusb appears to be one of the preferred replacements. Some details are available in Ubuntu bug #156085 on launchpad.
USB_ModeSwitch
The closest I found to anyone having a similar issue was a post by "theosib" on the Ubuntu Forums with a post less than a month old, "Total disaster trying to set up Verizon EVDO device". I replied with some details of my issue, after which "theosib" replied with what would turn out to be my solution - USB_ModeSwitch.
Be sure to read the main content on USB_ModeSwitch's main page at http://www.draisberghof.de/usb_modeswitch/, as it is a pretty good summary of the issue.
Note that in my response on the UbuntuForums, I stated that when the device is properly recognized by Windows, the Vendor ID was 0x3715, compared to the current 0x3b03. So the goal is getting this to "switch" to 0x3715, at which point it should be (and is) properly recognized as a USB modem by Linux.
The download of USB_ModeSwitch comes with a precompiled executable, but I'm guessing it was compiled for 32-bit, as it wasn't recognized on my system. I recompiled it from the included source without any issues. Just make sure the "build-essential" and "libusb-dev" packages are installed, as this isn't mentioned on the page. Following the notes on the USB_ModeSwitch page, I placed a copy of the output in "/sbin" as "/sbin/usb_modeswitch" using sudo.
Given the about output from "lsusb", I already had the "DefaultVendor" and "DefaultProduct" values needed to configure USB_ModeSwitch. Using these successfully detached the storage driver, but didn't have any effect on the Vendor ID or any apparent change on the output listed by lsusb. Following the documentation, this most likely meant that I still needed to send an additional special command to make the device "switch", using the "MessageEndpoint" and "MessageContent" parameters.
The preferred tool to use to find these parameters mentioned in the USB_ModeSwitch documentation is "SniffUSB". The link is for version 1.8. For me, it would constantly and uncontrollably refresh the screen, making it impossible to scroll the device list and pretty much making it unusable. Fortunately, I found an updated version 2.0, based on the same source, at http://www.pcausa.com/Utilities/UsbSnoop/default.htm. (Source code is readily available for both versions.)
To sniff the necessary commands from this device, I found the VID/PID with the "unswitched" ID's. Specifically, "USB\Vid_106c&Pid_3b03&Rev_0100" ("PANTECH UM175AL Composite Device"). I then installed the filter, then removed and reinserted the device. The following is my captured "UsbSnoop.log", with the necessary message portions highlighted:
[3 ms] UsbSnoop - FilterAddDevice(9a47f748) : DriverObject 89773a48, pdo 8992a9d8
[3 ms] UsbSnoop - FilterDispatchPnp(9a47f45c) : IRP_MJ_PNP (IRP_MN_QUERY_LEGACY_BUS_INFORMATION)
[3 ms] UsbSnoop - FdoHookDispatchPnp(9a47f45c) : IRP_MJ_PNP (IRP_MN_QUERY_LEGACY_BUS_INFORMATION)
[4 ms] UsbSnoop - FilterDispatchPnp(9a47f45c) : IRP_MJ_PNP (IRP_MN_QUERY_RESOURCE_REQUIREMENTS)
[4 ms] UsbSnoop - FdoHookDispatchPnp(9a47f45c) : IRP_MJ_PNP (IRP_MN_QUERY_RESOURCE_REQUIREMENTS)
[4 ms] UsbSnoop - FilterDispatchPnp(9a47f45c) : IRP_MJ_PNP (IRP_MN_FILTER_RESOURCE_REQUIREMENTS)
[4 ms] UsbSnoop - FdoHookDispatchPnp(9a47f45c) : IRP_MJ_PNP (IRP_MN_FILTER_RESOURCE_REQUIREMENTS)
[4 ms] UsbSnoop - FilterDispatchPnp(9a47f45c) : IRP_MJ_PNP (IRP_MN_START_DEVICE)
[4 ms] UsbSnoop - FdoHookDispatchPnp(9a47f45c) : IRP_MJ_PNP (IRP_MN_START_DEVICE)
[5 ms] UsbSnoop - FilterDispatchAny(9a47afd2) : IRP_MJ_SYSTEM_CONTROL
[8 ms] UsbSnoop - FilterDispatchPnp(9a47f45c) : IRP_MJ_PNP (IRP_MN_QUERY_CAPABILITIES)
[8 ms] UsbSnoop - FdoHookDispatchPnp(9a47f45c) : IRP_MJ_PNP (IRP_MN_QUERY_CAPABILITIES)
[8 ms] UsbSnoop - FilterDispatchAny(9a47afd2) : IRP_MJ_INTERNAL_DEVICE_CONTROL
[8 ms] UsbSnoop - FdoHookDispatchInternalIoctl(9a47b1ea) : fdo=8992a9d8, Irp=888c49d0, IRQL=0
[8 ms] >>> URB 1 going down >>>
-- URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE:
TransferBufferLength = 00000012
TransferBuffer = 89a098f8
TransferBufferMDL = 00000000
Index = 00000000
DescriptorType = 00000001 (USB_DEVICE_DESCRIPTOR_TYPE)
LanguageId = 00000000
[11 ms] UsbSnoop - MyInternalIOCTLCompletion(9a47b126) : fido=00000000, Irp=888c49d0, Context=89951008, IRQL=2
[11 ms] <<< URB 1 coming back <<<
-- URB_FUNCTION_CONTROL_TRANSFER:
PipeHandle = 89673020
TransferFlags = 0000000b (USBD_TRANSFER_DIRECTION_IN, USBD_SHORT_TRANSFER_OK)
TransferBufferLength = 00000012
TransferBuffer = 89a098f8
TransferBufferMDL = 8979e558
00000000: 12 01 10 01 00 00 00 40 6c 10 03 3b 00 01 01 02
00000010: 03 01
UrbLink = 00000000
SetupPacket =
00000000: 80 06 00 01 00 00 12 00
[11 ms] UsbSnoop - FilterDispatchAny(9a47afd2) : IRP_MJ_INTERNAL_DEVICE_CONTROL
[11 ms] UsbSnoop - FdoHookDispatchInternalIoctl(9a47b1ea) : fdo=8992a9d8, Irp=888c49d0, IRQL=0
[11 ms] >>> URB 2 going down >>>
-- URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE:
TransferBufferLength = 00000009
TransferBuffer = 896cab78
TransferBufferMDL = 00000000
Index = 00000000
DescriptorType = 00000002 (USB_CONFIGURATION_DESCRIPTOR_TYPE)
LanguageId = 00000000
[15 ms] UsbSnoop - MyInternalIOCTLCompletion(9a47b126) : fido=00000000, Irp=888c49d0, Context=89951008, IRQL=2
[15 ms] <<< URB 2 coming back <<<
-- URB_FUNCTION_CONTROL_TRANSFER:
PipeHandle = 89673020
TransferFlags = 74f06e2f (USBD_TRANSFER_DIRECTION_IN, USBD_SHORT_TRANSFER_OK)
TransferBufferLength = 00000009
TransferBuffer = 896cab78
TransferBufferMDL = 8898c160
00000000: 09 02 20 00 01 01 00 c0 32
UrbLink = 00000000
SetupPacket =
00000000: 80 06 00 02 00 00 09 00
[15 ms] UsbSnoop - FilterDispatchAny(9a47afd2) : IRP_MJ_INTERNAL_DEVICE_CONTROL
[15 ms] UsbSnoop - FdoHookDispatchInternalIoctl(9a47b1ea) : fdo=8992a9d8, Irp=888c49d0, IRQL=0
[15 ms] >>> URB 3 going down >>>
-- URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE:
TransferBufferLength = 00000020
TransferBuffer = 89873cc8
TransferBufferMDL = 00000000
Index = 00000000
DescriptorType = 00000002 (USB_CONFIGURATION_DESCRIPTOR_TYPE)
LanguageId = 00000000
[19 ms] UsbSnoop - MyInternalIOCTLCompletion(9a47b126) : fido=00000000, Irp=888c49d0, Context=89951008, IRQL=2
[19 ms] <<< URB 3 coming back <<<
-- URB_FUNCTION_CONTROL_TRANSFER:
PipeHandle = 89673020
TransferFlags = 74f06e2f (USBD_TRANSFER_DIRECTION_IN, USBD_SHORT_TRANSFER_OK)
TransferBufferLength = 00000020
TransferBuffer = 89873cc8
TransferBufferMDL = 8898c160
00000000: 09 02 20 00 01 01 00 c0 32 09 04 00 00 02 08 06
00000010: 50 00 07 05 83 02 40 00 00 07 05 05 02 40 00 00
UrbLink = 00000000
SetupPacket =
00000000: 80 06 00 02 00 00 20 00
[19 ms] UsbSnoop - FilterDispatchAny(9a47afd2) : IRP_MJ_INTERNAL_DEVICE_CONTROL
[19 ms] UsbSnoop - FdoHookDispatchInternalIoctl(9a47b1ea) : fdo=8992a9d8, Irp=888c49d0, IRQL=0
[19 ms] >>> URB 4 going down >>>
-- URB_FUNCTION_SELECT_CONFIGURATION:
ConfigurationDescriptor = 0x89873cc8 (configure)
ConfigurationDescriptor : bLength = 9
ConfigurationDescriptor : bDescriptorType = 0x00000002
ConfigurationDescriptor : wTotalLength = 0x00000020
ConfigurationDescriptor : bNumInterfaces = 0x00000001
ConfigurationDescriptor : bConfigurationValue = 0x00000001
ConfigurationDescriptor : iConfiguration = 0x00000000
ConfigurationDescriptor : bmAttributes = 0x000000c0
ConfigurationDescriptor : MaxPower = 0x00000032
ConfigurationHandle = 0x00000000
Interface[0]: Length = 56
Interface[0]: InterfaceNumber = 0
Interface[0]: AlternateSetting = 0
[57 ms] UsbSnoop - MyInternalIOCTLCompletion(9a47b126) : fido=00000000, Irp=888c49d0, Context=89951008, IRQL=0
[57 ms] <<< URB 4 coming back <<<
-- URB_FUNCTION_SELECT_CONFIGURATION:
ConfigurationDescriptor = 0x89873cc8 (configure)
ConfigurationDescriptor : bLength = 9
ConfigurationDescriptor : bDescriptorType = 0x00000002
ConfigurationDescriptor : wTotalLength = 0x00000020
ConfigurationDescriptor : bNumInterfaces = 0x00000001
ConfigurationDescriptor : bConfigurationValue = 0x00000001
ConfigurationDescriptor : iConfiguration = 0x00000000
ConfigurationDescriptor : bmAttributes = 0x000000c0
ConfigurationDescriptor : MaxPower = 0x00000032
ConfigurationHandle = 0x888d14d0
Interface[0]: Length = 56
Interface[0]: InterfaceNumber = 0
Interface[0]: AlternateSetting = 0
Interface[0]: Class = 0x00000008
Interface[0]: SubClass = 0x00000006
Interface[0]: Protocol = 0x00000050
Interface[0]: InterfaceHandle = 0x88bcece0
Interface[0]: NumberOfPipes = 2
Interface[0]: Pipes[0] : MaximumPacketSize = 0x00000040
Interface[0]: Pipes[0] : EndpointAddress = 0x00000083
Interface[0]: Pipes[0] : Interval = 0x00000000
Interface[0]: Pipes[0] : PipeType = 0x00000002 (UsbdPipeTypeBulk)
Interface[0]: Pipes[0] : PipeHandle = 0x88bcecfc
Interface[0]: Pipes[0] : MaxTransferSize = 0x00001000
Interface[0]: Pipes[0] : PipeFlags = 0x00000000
Interface[0]: Pipes[1] : MaximumPacketSize = 0x00000040
Interface[0]: Pipes[1] : EndpointAddress = 0x00000005
Interface[0]: Pipes[1] : Interval = 0x00000000
Interface[0]: Pipes[1] : PipeType = 0x00000002 (UsbdPipeTypeBulk)
Interface[0]: Pipes[1] : PipeHandle = 0x88bced1c
Interface[0]: Pipes[1] : MaxTransferSize = 0x00001000
Interface[0]: Pipes[1] : PipeFlags = 0x00000000
[57 ms] UsbSnoop - FilterDispatchAny(9a47afd2) : IRP_MJ_INTERNAL_DEVICE_CONTROL
[57 ms] UsbSnoop - FdoHookDispatchInternalIoctl(9a47b1ea) : fdo=8992a9d8, Irp=88da7770, IRQL=0
[57 ms] >>> URB 5 going down >>>
-- URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER:
PipeHandle = 88bced1c [endpoint 0x00000005]
TransferFlags = 00000000 (USBD_TRANSFER_DIRECTION_OUT, ~USBD_SHORT_TRANSFER_OK)
TransferBufferLength = 0000001f
TransferBuffer = 88c4b790
TransferBufferMDL = 00000000
00000000: 55 53 42 43 90 4e d6 8a 24 00 00 00 80 00 08 ff
00000010: 02 44 45 56 43 48 47 00 00 00 00 00 00 00 00
UrbLink = 00000000
[57 ms] UsbSnoop - FilterDispatchPnp(9a47f45c) : IRP_MJ_PNP (IRP_MN_QUERY_CAPABILITIES)
[57 ms] UsbSnoop - FdoHookDispatchPnp(9a47f45c) : IRP_MJ_PNP (IRP_MN_QUERY_CAPABILITIES)
[58 ms] UsbSnoop - FilterDispatchPnp(9a47f45c) : IRP_MJ_PNP (IRP_MN_QUERY_PNP_DEVICE_STATE)
[58 ms] UsbSnoop - FdoHookDispatchPnp(9a47f45c) : IRP_MJ_PNP (IRP_MN_QUERY_PNP_DEVICE_STATE)
[58 ms] UsbSnoop - FilterDispatchPnp(9a47f45c) : IRP_MJ_PNP (IRP_MN_QUERY_DEVICE_RELATIONS)
[58 ms] UsbSnoop - FdoHookDispatchPnp(9a47f45c) : IRP_MJ_PNP (IRP_MN_QUERY_DEVICE_RELATIONS)
[58 ms] UsbSnoop - MyInternalIOCTLCompletion(9a47b126) : fido=00000000, Irp=88da7770, Context=89951008, IRQL=2
[58 ms] <<< URB 5 coming back <<<
-- URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER:
PipeHandle = 88bced1c [endpoint 0x00000005]
TransferFlags = 00000000 (USBD_TRANSFER_DIRECTION_OUT, ~USBD_SHORT_TRANSFER_OK)
TransferBufferLength = 0000001f
TransferBuffer = 88c4b790
TransferBufferMDL = 8979e558
UrbLink = 00000000
[165 ms] UsbSnoop - FilterDispatchPnp(9a47f45c) : IRP_MJ_PNP (IRP_MN_QUERY_DEVICE_RELATIONS)
[165 ms] UsbSnoop - FdoHookDispatchPnp(9a47f45c) : IRP_MJ_PNP (IRP_MN_QUERY_DEVICE_RELATIONS)
[165 ms] UsbSnoop - FilterDispatchPnp(9a47f45c) : IRP_MJ_PNP (IRP_MN_QUERY_DEVICE_RELATIONS)
[165 ms] UsbSnoop - FdoHookDispatchPnp(9a47f45c) : IRP_MJ_PNP (IRP_MN_QUERY_DEVICE_RELATIONS)
[166 ms] UsbSnoop - FilterDispatchPnp(9a47f45c) : IRP_MJ_PNP (IRP_MN_SURPRISE_REMOVAL)
[166 ms] UsbSnoop - FdoHookDispatchPnp(9a47f45c) : IRP_MJ_PNP (IRP_MN_SURPRISE_REMOVAL)
[240 ms] UsbSnoop - FilterDispatchPnp(9a47f45c) : IRP_MJ_PNP (IRP_MN_REMOVE_DEVICE)
Given the above information, I then saved the following as "/etc/usb_modeswitch.conf":
DefaultVendor = 0x106c DefaultProduct = 0x3b03 MessageEndpoint = 0x05 MessageContent = "55534243904ed68a24000000800008ff024445564348470000000000000000"
The following command can then be used to "switch" the mode of the device so that it is recognized as a USB modem. Note that as documented on the USB_ModeSwitch page, most programs using libusb need to be run as root:
sudo /sbin/usb_modeswitch -c /etc/usb_modeswitch.conf
Here is the updated output of "/usr/sbin/lsusb -l":
Bus 001 Device 006: ID 106c:3715 Curitel Communications, Inc.
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 1.10
bDeviceClass 2 Communications
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 64
idVendor 0x106c Curitel Communications, Inc.
idProduct 0x3715
bcdDevice 1.00
iManufacturer 1 PANTECH
iProduct 2 PANTECH USB MODEM
iSerial 0
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 113
bNumInterfaces 4
bConfigurationValue 1
iConfiguration 0
bmAttributes 0x80
(Bus Powered)
MaxPower 500mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 1
bInterfaceClass 2 Communications
bInterfaceSubClass 2 Abstract (modem)
bInterfaceProtocol 1 AT-commands (v.25ter)
iInterface 0
CDC Header:
bcdCDC 1.09
CDC Call Management:
bmCapabilities 0x03
call management
use DataInterface
bDataInterface 1
CDC ACM:
bmCapabilities 0x0f
connection notifications
sends break
line coding and serial state
get/set/clear comm features
CDC Union:
bMasterInterface 0
bSlaveInterface 1
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0010 1x 16 bytes
bInterval 32
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 0
bNumEndpoints 2
bInterfaceClass 10 CDC Data
bInterfaceSubClass 0 Unused
bInterfaceProtocol 0
iInterface 3 Data Interface
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x82 EP 2 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x02 EP 2 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 0
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 2
bAlternateSetting 0
bNumEndpoints 2
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 0
bInterfaceProtocol 0
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x84 EP 4 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x04 EP 4 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 0
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 3
bAlternateSetting 0
bNumEndpoints 2
bInterfaceClass 8 Mass Storage
bInterfaceSubClass 6 SCSI
bInterfaceProtocol 80 Bulk (Zip)
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x83 EP 3 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x05 EP 5 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 0
Device Status: 0x0001
Self Powered
At this point, I was finally able to establish a connection using PPP. This setting appears to even persist across reboots, as long as the USB device doesn't loose power. Following the examples on the USB_ModeSwitch page, I saved the following as "/etc/udev/rules.d/99-usb_modeswitch.rules" which will automatically run the above command whenever the device is detected:
SUBSYSTEM=="usb", ATTR{idProduct}="3b03", ATTR{idVendor}=="106c", \
RUN+="/sbin/usb_modeswitch -c /etc/usb_modeswitch.conf"
Note that there is a "README" file in the "/etc/udev/rules.d" directory. Additional information can be found in the man page for udev ("man udev").
Accessing the Modem
The "cdc_acm" kernel module should now detect a connected device, and connect it to "/dev/ttyACM0".
Before making the Internet connection with PPP, the modem can be communicated with as a serial device. I'm not sure what the preferred method is for doing this under Linux, but the "screen" command (located in "/usr/bin") worked for me:
/usr/bin/screen /dev/ttyACM0
AT OK AT+GMM UM175AL OK ATI Manufacturer: UTStarcom communication Inc. Model: UM175AL Revision: D0700ALM01_5.226 1 [Mar 21 2008 06:00:00] [Jul 29 2008 15:10:28] ESN: 0x83AF77E +GCAP: +CIS707-A, CIS-856, CIS-856-A OK AT+CSQ 31, 0 OK
(If you don't recognize the above, the Hayes command set on Wikipedia may be a good starting reference.)
Signal Strength
The "AT+CSQ" returns the current signal strength as a value between 0-31, with higher being better. According to Ken Kinder, this number indicates the signal strength above -109 dBm in 2 dBm increments.
I know the Windows client software displays a regularly updated signal strength indicator, even while the connection is active. It would be nice to have this functionality available under Linux, too, but it doesn't look easy, if even possible.
I found one forum thread with one response on the topic: http://fixunix.com/ppp/62263-commad-mode-gprs-same-time.html. Pretty much, it seems that the data stream would have to be paused, the modem dropped to command mode, the "AT+CSQ" command issued and the value retrieved, then sending "ATO" to go back online. The forum response suggested that a modified pppd would be needed. I'm wondering if a "wrapper" tty couldn't be written that would be passed to pppd, and query the signal strength whenever the connection is idle. Alternatively, I'd be curious if the "diagnostic port" as shown in Windows would provide similar functionality without having to interrupt the data line? Maybe this is available by one of the other interface descriptors shown in the lsusb output (above)? Maybe "bInterfaceClass 10 CDC Data"?
Update 2008-10-08: Sysinternal's Portmon shows that under Windows, the The Alltel Wireless Connection Manager communicates with the "diagnostic port". Unfortunately, unlike the text-based "AT" commands used above, this communication looks completely binary. I will include some of the logging output here shortly. It also doesn't look to be easily decipherable, or to use any known standard. I've sent an email to UTStarcom, and can only hope for an unlikely helpful response.
To be continued...
Next up: Configuring PPP.