I am likely experiencing the same issue, yet on other hardware: Ubuntu
20.04 with a ZTE MF100 modem but only on Raspberry Pi. The good news: I
have triaged the issue.

The bug is in "usb_modeswitch_dispatcher.c", a C rewrite of the upstream
Tcl script. The C dispatcher receives the modem's kernel_name. If it
contains the characters dot ('.') and dash ('-') but no colon (':'), the
device is marked for some extended "interface validation" (see lines
343ff of "usb_modeswitch_dispatcher.c"). A bit further down at lines
388ff, the "iface" is initialized to 0, but the interface validation
updates it to 8. The value 8 stems from an atoi() invocation on the
contents of "bInterfaceClass". For this updated iface value, the C
dispatcher tries to find the corresponding (sub) interface directory and
this fails because my modem does not have 8 sub devices. Until here,
18.04 and 20.04 behavior is identical. However, the following new code
was introduced in 20.04 right after the directory lookup attempt is
made:

----------8<----------
if (ifdir == NULL) {
  modeswitch_log(" No access to interface %d. Exit\n", iface);
  return 1;
}
----------8<----------

This is causing the early exit for Mariusz and me. If I remove this
code, the rest of the C dispatcher works fine (even with a wrong iface
value of 8 - this is the same behavior as it was on 18.04). In a
scenario where no interface validation takes place (e.g. because of a
colon in the kernel_name or the absence of a dot - such as Ubuntu 20.04
on x86_64 VM), the iface value of 0 remains unchanged and the interface
directory is looked up successfully.

I have tried to match the C dispatcher code with the upstream Tcl
script. The Tcl script initializes iface to 0 and eventually updates it
to "1.0" when doing the interface validation branch.

Another thing that I noticed is that the C dispatcher erroneously uses
atoi() on the contents of bInterfaceClass. The content is a hexadecimal
string such as "00", "08" or "ff" while atoi() expects a decimal string.
If bInterfaceClass contains "ff", atoi() would return 0.

I have solved this problem by replacing "usb_modeswitch_dispatcher" with the 
upstream Tcl script, pointing its interpreter to jimsh and installing jimsh. I 
think it would be a wise choice to ditch the C dispatcher, use the upstream Tcl 
script and make the package depend on jimsh. Reasons:
- The C dispatcher does not implement the same functionality as the Tcl script 
in 2.5.2.
- Implementing changes from the Tcl script in 2.6.0 would be even more painful.
- The usb_modeswitch author provides flavors that eliminate the Tcl dependency.
- I fail to see how the "binary size" argument still applies in 2020 to 
machines that are capable of running Ubuntu.

-- 
You received this bug notification because you are a member of Ubuntu
Bugs, which is subscribed to Ubuntu.
https://bugs.launchpad.net/bugs/1866926

Title:
  usb_modeswitch does not switch modems (remain visible as mass storage)

To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu/+source/usb-modeswitch/+bug/1866926/+subscriptions

-- 
ubuntu-bugs mailing list
ubuntu-bugs@lists.ubuntu.com
https://lists.ubuntu.com/mailman/listinfo/ubuntu-bugs

Reply via email to