usb_modeswitch problem with Huawei E3372 [EDIT: FOUND BUG, SEE PATCH]

Bug #1593669 reported by Luigi Tarenga
8
This bug affects 1 person
Affects Status Importance Assigned to Milestone
Raspbian
Undecided
Unassigned

Bug Description

Hi,
I'm using raspbian on a raspberry pi 3 and I found a problem with usb_modeswitch udev rules
and the Huawei E3372 LTE usb modem. With default usb_modeswitch udev rules installed the modem
is not recognised and it stay in CD mode:
Bus 001 Device 038: ID 12d1:1f01 Huawei Technologies Co., Ltd.

If I install ModemManager and reinsert the usb modem it get switched into an ethernet device:
Bus 001 Device 039: ID 12d1:14dc Huawei Technologies Co., Ltd.

The problem is that there is nothing in ModemManager that "should" influence the switch of the modem.
I started debugging and found that the udev rules added by ModemManager have some "timing" influence
on the udev flow that make the switch happen. I came up with a simple test case...

ModemManager add some udev rules like:
77-mm-cinterion-port-types.rules 77-mm-nokia-port-types.rules 77-mm-telit-port-types.rules
77-mm-ericsson-mbm.rules 77-mm-pcmcia-device-blacklist.rules 77-mm-usb-device-blacklist.rules
77-mm-huawei-net-port-types.rules 77-mm-platform-serial-whitelist.rules 77-mm-usb-serial-adapters-greylist.rules
77-mm-longcheer-port-types.rules 77-mm-qdl-device-blacklist.rules 77-mm-x22x-port-types.rules
77-mm-mtk-port-types.rules 77-mm-simtech-port-types.rules 77-mm-zte-port-types.rules

to make the switch happen I just need 77-mm-ericsson-mbm.rules in place or 77-mm-qdl-device-blacklist.rules in place. With just one of those two the switch happen correctly.

What happen is that the rules in /lib/udev/rules.d/40-usb_modeswitch.rules have a little different
behavior. The rule:
ATTRS{idVendor}=="12d1", ATTR{bInterfaceNumber}=="00", ATTR{bInterfaceClass}=="08", RUN+="usb_modeswitch '%b/%k'"
is the one responsible of the switch but without ModemManager installed it get fired with %b/%k
having the following value: 1-1.4/1-1.4:1.0
If I install ModemManager (or just put in flace one of the 2 rules files mentioned) this same rules
get fired with %b/%k having the value: /1-1.4:1.0
%b does not hold any value anymore! and the only change is some udev rules that have not effect
on the device just plugged...

the binary usb_modeswitch invoked by udev is /lib/udev/usb_modeswitch, the calling sequence is:
udev fire rule from 40-usb_modeswitch.rules
/lib/udev/usb_modeswitch %b/%k
/bin/systemctl --no-block start usb_modeswitch@$1.service
/usr/sbin/usb_modeswitch_dispatcher --switch-systemd %I

if usb_modeswitch_dispatcher get called from
usb_modeswitch@1-1.4-1-1.4:1.0.service then no switch happen while if systemd get correcly called
than usb_modeswitch_dispatcher get called from usb_modeswitch@1-1.4:1.0.service and the modem
is correclty switched.

there is a bug in usb_modeswitch rules but maybe even in other place because I can't explain why
the id of the device get changed with some rules that have no clue with this modem....

thanks in advance
Luigi

Revision history for this message
Luigi Tarenga (luigi-tarenga) wrote :

I found the bug in usb_modeswitch!
the script /lib/udev/usb_modeswitch call systemctl without escaping and I suspect that it
rely on the unescaping done by systemd and use_modeswitch_dispatcher. I tried to correcly invoke
the dispatcher with the --switch-systemd option but it does not work or I don't know what kind
of escaping it want and support....

So my patch rely on using use_modeswitch_dispatcher with --switch-mode options.
The patch is on 2 distinct files:

--- usb_modeswitch 2016-06-17 13:26:07.449674124 +0200
+++ /lib/udev/usb_modeswitch 2016-06-17 13:25:35.730749887 +0200
@@ -80,7 +80,7 @@
   if [ -x /sbin/initctl ] && /sbin/initctl version 2>/dev/null | /bin/grep -q upstart; then # Test if upstart is running
    exec /sbin/initctl emit --no-wait usb-modeswitch-upstart UMS_PARAM=$1
   elif [ -d "/run/systemd/system/" ]; then # Test if systemd is running
- exec /bin/systemctl --no-block start usb_modeswitch@$1.service
+ exec /bin/systemctl --no-block start $(systemd-escape --template=usb_modeswitch@.service $1)
   else
    export TMPDIR=/run
    exec /usr/sbin/usb_modeswitch_dispatcher --switch-mode $1 &

--- usb_modeswitch@.service 2016-06-17 13:30:51.080058537 +0200
+++ /lib/systemd/system/usb_modeswitch@.service 2016-06-17 13:21:47.668214935 +0200
@@ -3,5 +3,5 @@

 [Service]
 Type=oneshot
-ExecStart=/usr/sbin/usb_modeswitch_dispatcher --switch-systemd %I
+ExecStart=/usr/sbin/usb_modeswitch_dispatcher --switch-mode %I
 Environment="TMPDIR=/run"

With my patch the usb modem switch correctly when use_modeswitch get invoke as:
/lib/udev/usb_modeswitch 1-1.4/1-1.4:1.0

Now I don't need to install ModemManager to have the switch to work. Still I don't know why
the rules contained in ModemManager makes the id change to blank... but at this point I don't care :D

I hope this can help
Luigi

summary: - usb_modeswitch problem with Huawei E3372
+ usb_modeswitch problem with Huawei E3372 [EDIT: FOUND BUG, SEE PATCH]
Revision history for this message
Luigi Tarenga (luigi-tarenga) wrote :

please take care, the patch code get wrapped on some lines.

Luigi

To post a comment you must log in.
This report contains Public information  Edit
Everyone can see this information.

Other bug subscribers