[Android General] duckygo:
3G USB dongle no longer working after upgrade to v2.3.38

I'd like to share something that may be useful for the community here.

After I upgraded my Asteroid Tablet to the newest 2.3.38.16 version of the firmware, my 3G USB dongle (a Vodafone Huawei K4510) was no longer recognized. Grrrr...

It took me a couple of hours/days and in the end I solved the problem! The problem lies in/around the usb_modeswitch tool (draisberghof.de/usb_modeswitch) . Asteroid firmware 2.3.38.16 uses usb_modeswitch version 1.2.5 whereas firmware 2.1.5 (and 2.1.1) use usb_modeswitch version 1.2.2 .

It appears either:

- The guys at Parrot have made a mistake while compiling the usb_modeswitch tool, or

- usb_modeswitch v1.2.5 has a bug compared to v1.2.2 .

(or both)

Anyway, in either case, there is a workaround, which I will explain here.

Instructions

** BEWARE! Proceed at your own risk. I am not responsible for damage or inoperability to your unit after you follow these instructions. **

What you'll need to do:

1.) Download and install Framaroot 1.4.1 from framaroot.org/388-parrot-asteroid-smart . (see Note 1 below for explanation how to install a .apk file)

2.) Download and install Terminal Emulator from jackpal.github.io/Android-Terminal-Emulator.

3.) Make sure your 3G USB dongle is not (yet) plugged in to your Asteroid.

4.) Run Framaroot, select install SuperSU and choose the Gimli exploit. Reboot the Asteroid. Check if you have the SuperSU icon on the home screen: the diamond-shaped icon with a '#' sign in it. (It's just there; no need to launch that.)

5.) Run Terminal Emulator and at the prompt, enter the 'su' command (you can use the on-screen keyboard but I prefer real typing, so I plugged in a real keyboard in one of the USB ports; it works):

$ su
#

A popup appears asking for confirmation to give the terminal emulator root access. Respond by pressing 'Grant'.

Check if you are indeed user 'root':

# id
uid=0(root) gid=0(root)

Enter the 'lsusb' command in the terminal emulator:

# lsusb
...

(ignore the message about not being able to read "/usr/share/usb.ids" .)

6.) Plug your 3G USB dongle in one of the USB ports. Wait a few seconds then type in the terminal emulator:

# lsusb
...
Bus 001 Device 005: ID 12d1:14cb

Note the added line. It contains the vendor ID and the product ID of your USB dongle. In my case, 12d1:14cb

7.) Now go to the place where the usb_modeswitch configuration files are stored, and search for the correct configuration file:

# cd /system/usr/share/usb_modeswitch
# grep 14cb *
12d1:14c5:TargetProduct= 0x14cb

8.) Show the contents of this file, in my case:

# cat 12d1:14c5
# Vodafone (Huawei) K4510

TargetVendor= 0x12d1
TargetProduct= 0x14cb

MessageContent="55534243123456780000000000000011062000000100000000000000000000"

9.) Append a line to this file. To do this, you'll first need to remount the (read-only) file system to make it writeable:

# mount -o remount,rw -t ubifs ubi0:system /system

Then:

# echo "CheckSuccess=9" >> /system/usr/share/usb_modeswitch/12d1.14c5

10.)Unplug and plug back the USB dongle. Wait for a couple of seconds, and hey presto, it works!!

Explanation

Time for some explanation here. When the 3G USB dongle is plugged in, it presents itself as a (virtual) "CD-ROM" drive to the system. The usb_modeswitch tool is there to take care of sending an "eject" command to the "CD-ROM" drive, which then disappears and the (serial) USB "modem" device will appear. usb_modeswitch then proceeds by loading the appropriate kernel module. As a result, a number of USB tty devices should appear, e.g.:

# ls /dev/ttyU*
/dev/ttyUSB0
/dev/ttyUSB1
/dev/ttyUSB2
/dev/ttyUSB3
/dev/ttyUSB4

In my case, the product ID is 0x14c5 as long as the USB dongle is in "CD-ROM" mode, and will be 0x14cb when it is in "modem" mode.

From the output of the 'lsusb' command, it is clear that the mode was switched; the product ID is 0x14cb. But the stick is not recognized as modem! What is wrong here?

After having spent hours of debugging and looking into verbose logs, it appeared that usb_modeswitch is doing something wrong. After (correctly) switching the mode of the USB dongle, it should proceed to load the necessary kernel driver. But that did not happen. Why?

To find out, i changed the following line in /system/usr/share/usb_modeswitch.conf :

EnableLogging=0

to:

EnableLogging=1

Now, whenever a 3G USB dongle is plugged in, a couple of files will appear under /tmp/usb_modeswitch . In my case:

# cat /tmp/usb_modeswitch/log_1-1.1

USB_ModeSwitch log from Tue Mar 01 08:38:43 GMT 2016

Raw args from udev: /1-1.1
[...]
Device is gone, skipping any further commands
Bus/dev search active, referring success check to wrapper. Bye.

ok:busdev
--------------------------------
(end of usb_modeswitch output)

Checking success of mode switch for max. 20 seconds ...
Waiting for device file system (1 sec.) ...
Waiting for device file system (2 sec.) ...
Waiting for device file system (3 sec.) ...
Reading attributes ...
Reading attributes ...
Reading attributes ...
Reading attributes ...
Reading attributes ...
Reading attributes ...
Reading attributes ...
Reading attributes ...
Reading attributes ...
Reading attributes ...
Reading attributes ...
Reading attributes ...
Reading attributes ...
Reading attributes ...
Reading attributes ...
Reading attributes ...
Reading attributes ...

Target config not matching - current values are
1-1.1:1.0/bInterfaceClass: ff
bConfigurationValue: 1
bNumConfigurations: 1
busnum: 1
devnum: 5
idProduct: 14cb
idVendor: 12d1
manufacturer: Vodafone Group (Huawei)
product: Vodafone Mobile Broadband (Huawei)
serial:

Mode switching may have failed. Exiting

# ls /dev/ttyU*
/dev/ttyU*: No such file or directory

Hmmm, so the switch worked, the product ID is updated, but usb_modeswitch thinks that the "Target config" is "not matching"

To force the driver loading, I did:

# cd /sys/bus/usb-serial/drivers/option1
# echo "12d1 14cb" > new_id

And it worked! The 3G modem was suddenly recognized and the Asteroid started its dial-up procedure.

But only once (of course). After a power cycle it did not work any more.

To make it working permanently, I analysed the code of usb_modeswitch v1.2.5, which can be found at:

pkgs.fedoraproject.org/repo/pkgs/usb_modeswitch/usb-modeswitch-1.2.5.tar.bz2/c393603908eceab95444c5bde790f6f0

Look for the file 'usb_modeswitch.tcl'. The "proc {CheckSuccess} {devdir}" at line 985 seems to be broken. I could not find out exactly, but apparently it returns 0 (not OK).

Now, in line 1022, there is a somewhat strange statement. If you get out of the for-loop with $i being 20 or smaller, you always get 1 (OK) as result! Now we can use that :) After having run the for-loop, $i will be equal to $config(checkSuccess) . So if i force $config(checkSuccess) to be lower than 20, the result of 'CheckSuccess' will always be 1 (OK) and usb_modeswitch might proceed as it should.

So I tried my luck and wrote "CheckSuccess=10" in the /system/usr/share/usb_modeswitch/12d1.14c5 file. But then the log shows:

[...]
! matched. Reading config data
config: CheckSuccess set to 0
[...]

and that didn't work. Apparently usb_modeswitch.tcl is making a mistake in parsing the value '10'.

But when I wrote "CheckSuccess=9" in the /system/usr/share/usb_modeswitch/12d1.14c5 file, the log shows:

[...]
! matched. Reading config data
config: CheckSuccess set to 9
[...]
Device is gone, skipping any further commands
Bus/dev search active, referring success check to wrapper. Bye.

ok:busdev
--------------------------------
(end of usb_modeswitch output)

Checking success of mode switch for max. 9 seconds ...
Waiting for device file system (1 sec.) ...
Waiting for device file system (2 sec.) ...
Waiting for device file system (3 sec.) ...
Reading attributes ...
Reading attributes ...
Reading attributes ...
Reading attributes ...
Reading attributes ...
Reading attributes ...
Mode switching was successful, found 12d1:14cb (Vodafone Group (Huawei): Vodafone Mobile Broadband (Huawei))
Logger is
Can't add system message, no syslog helper found
Now checking for bound driver ...
no driver has bound to interface 0 yet
No 12d1:14cb in bind_list
Device is not in "bind_list" yet, bind it now
Module loader is /system/xbin/modprobe
Module is active already
Trying to add ID to driver "option"
Can't add system message, no syslog helper found
Can't add system message, no syslog helper found
ID added to driver; check for new devices in /dev
driver was bound to the device
Checking for AVOID_RESET_QUIRK kernel attribute
AVOID_RESET_QUIRK activated

All done, exiting

Yeah!!!

The tty's appeared:

# ls /dev/ttyU*
/dev/ttyUSB0
/dev/ttyUSB1
/dev/ttyUSB2
/dev/ttyUSB3
/dev/ttyUSB4

and the dial-up procedure is started.

Notes

1.) How to 'install' a .apk file on your Asteroid?

- Power off the Asteroid.

- Remove the SD card.

- Put the SD card into a card reader on your laptop/PC.

- Copy the .apk file into the top-level directory of the SD card.

- Unmount/eject the SD card from your laptop/PC.

- Slide the SD card into the Asteroid.

- Power up the Asteroid.

- Go to the Settings app (gray gear icon), select 'Application Settings', check the box 'Unknown Sources',

scroll down this same menu and choose 'Development', choose 'Applications installer'.

- From there, you will see the list of .apk files on your SD card. Choose the app(s) you wish to install

and follow the prompts.

2.) Older 3G dongles (like the Huawei E220) were working without problem after the firmware upgrade. Looking at the verbose log of usb_modeswitch, it appears that *no* mode switching is involved for the Huawei E220. It seems that the E220 is natively supported by the kernel (module 'option' as found in /system/lib/modules/2.6.35.13-03063-g0557d18/kernel/drivers/usb/serial/option.ko ).

That explains why only the newer USB dongles are having a problem.

3.) The solution as indicated above makes only a specific modem work again. Maybe there are more generic solutions; i didn't dig into that. One could think along the lines of replacing the /system/xbin/usb_modeswitch and /system/xbin/usb_modeswitch_dispatcher tools by the versions in the 2.1.1/5 firmware.

What strikes me is that /system/xbin/usb_modeswitch_dispatcher in firmware 2.3.38 is a tclsh script (29518 bytes), while in 2.1.1/5 it is a self-contained (compiled) binary (866084 bytes). Firmware 2.3.38 contains a /system/xbin/jimsh file, and a symlink tclsh pointing to that. It seems the guys at Parrot built ('make') the usb_modeswitch package differenly for 2.3.38. The 'Makefile' in the usb_modeswitch package defines the make targets 'install-static' and 'install-shared'; the former seems to have been used in 2.1.1/5 while the latter seems to have been used for 2.3.38 . It seems there is something wrong with the tcl regex parsing done by jimsh in 2.3.38 .

BTW: as said above, the usb_modeswitch package can be downloaded from: pkgs.fedoraproject.org/repo/pkgs/usb_modeswitch/usb-modeswitch-1.2.5.tar.bz2/c393603908eceab95444c5bde790f6f0

4.) Maybe some-one else has come up with the same issue and solution, i didn't fancy looking through all 277 pages in this forum. Googling around for a solution didn't give any results.

5.) This is my first post, so i'm not allowed to write URLs yet. You must copy and paste the mentioned links in your browser address bar yourself.