Activation Codes and Methods, Hardware Details, Sniffing
olia

Post by olia » 13 May 2010, 11:23

Now, that's interesting:
- first device is an ONDA umts-stick, working. online right now.
- second is the olicard100, just plugged in out of curiosity

$ l /dev/gsmmodem*
lrwxrwxrwx 1 root root 7 13 mag 10.46 /dev/gsmmodem -> ttyUSB2
lrwxrwxrwx 1 root root 7 13 mag 11.07 /dev/gsmmodem2 -> ttyUSB7
$ l /dev/gsmmodem*
lrwxrwxrwx 1 root root 7 13 mag 10.46 /dev/gsmmodem -> ttyUSB2
lrwxrwxrwx 1 root root 7 13 mag 11.07 /dev/gsmmodem2 -> ttyUSB3
$ l /dev/gsmmodem*
lrwxrwxrwx 1 root root 7 13 mag 10.46 /dev/gsmmodem -> ttyUSB2
lrwxrwxrwx 1 root root 7 13 mag 11.08 /dev/gsmmodem2 -> ttyUSB7
$ l /dev/gsmmodem*
[..]

wvdialling modem=/dev/gsmmodem2 failed the first try, second worked.

Note: this happens w/o modemmanager installed.

Why does the link switch from usb7 to usb3 (dialup working) and back to usb7 (dialup hanging) again?

Cheers

olia

Post by olia » 13 May 2010, 16:03

Lately it has been gsmmodem -> ttyUSB0, and it dialled up successfully. This is kinda indeterministic to me..

Cheers

Josh
Site Admin
Posts: 6593
Joined: 03 Nov 2007, 00:30

Post by Josh » 13 May 2010, 22:47

A case for the X Files, I'd say ...

Unless there are really two different target modes for the device! In that case you should be able to see a difference between both cases with "lsusb -v".

Very strange, indeed!

olia

Post by olia » 14 May 2010, 15:29

Josh wrote:A case for the X Files, I'd say ...

Unless there are really two different target modes for the device! In that case you should be able to see a difference between both cases with "lsusb -v".

Very strange, indeed!
replug: /dev/gsmmodem -> ttyUSB0
replug: /dev/gsmmodem -> ttyUSB4
replug: /dev/gsmmodem -> ttyUSB4

so far no diffs between lsusb -d 0x0b3c -v

badbadbad: when dialling with ttyUSB4:
--> Modem not responding.

While gsmmodem linking to ttyUSB4 calling wvdial w/ modem=/dev/ttyUSB0 is working. Even after hanging up, a redial works.


Some of the above strange behaviour seemed to be caused by the blacklisting of some ports. I backported the .34-rc7 option driver and added blacklisting for some non-functional ports (1,3,4), leaving intact ports 0 and 2 (which were believed to work). But as we learned the real (hidden) culprit was modemmanager and once this sw was purged, there were no more problem dialling w/ port 0 but only port 0 and only iff any other port got blacklisted. Now, w/ blacklinsting (reason: no_sendsetup) for all ports except port 0 gsmmodem links consistently to USB0 which is working perfectly.

Using minicom on ports 2 and 3 they respond w/

Code: Select all

AT S7=45 S0=0 L1 V1 X4 &c1 E1 Q0                             
OK 
and also a query for AT+CSQ (kinda field strength) they respond w/

Code: Select all

AT S7=45 S0=0 L1 V1 X4 &c1 E1 Q0                             
OK
at+csq                                                       
+CSQ: 9,99

OK
Summary: Using kernel 2.6.33 and option.c from kernel 2.6.34-rc7 (has blacklisting support) and added olivetti option IDs (not necessarily required). The blacklisted ports out of the five ports are: 1,2,3,4. Blacklisting reason: no_sendsetup.

Blacklisting port 0 only or port 4 only doesn't yield to a change.

The above has been verified by a couple of repeatedly run tests. After writing this post, I conducted one more test. And again gsmmodem was pointing to ttyUSB4! This is getting tiresome. Once more after removing the module and replugging, it is pointing to ttyUSB0. Now same procedure again, and again it's ttyUSB4.

And so on.

Doing more tests:
ttyUSB0 is always working. And this even regardless of blacklisting port 0 or not in option.c, also blacklisting on port 4 is of no interest, ttyUSB0 is always the working dial port and never ttyUSB4. But gsmmodem is always pointing to port 4. This has been verified setting debug=1 on modprobing.

Disabling blacklisting for olicard100 results in gsmmodem pointing to ttyUSB0, at least once, now. On subsequent tests, it's ttyUSB4 again.

rmmod option; modprobe option debug=1 and replugging: no different result.
unplugging, rmmod option; modprobe option debug=1: no different result.
rmmod option; modprobe option debug=1 w/o replugging: gsmmodem switches once from ttyUSB4 to ttyUSB0. But only once.
gsmmodem -> ttyUSB4, rmmod option usbserial: ttyUSB0
then replug: ttyUSB4. rmmod option usbserial, modprobe option debug=1: ttyUSB4. then unplug, rmmod option usbserial, modprobe option debug=1: ttyUSB4.

Then:
blacklisting: 1,2,3,4
rmmod option usbserial; modprobe option debug=1: ttyUSB0.
replugging: ttyUSB0.
replugging: ttyUSB4.
rmmod option usbserial; modprobe option debug=1: ttyUSB0.
unplugging, rmmod option usbserial; modprobe option debug=1, plugging: ttyUSB4.
rmmod option usbserial; modprobe option debug=1: ttyUSB4.
unplugging, rmmod option usbserial; waiting 10 secs, modprobe option debug=1, plugging: ttyUSB0.
unplugging, rmmod option usbserial; modprobe option debug=1, waiting 10 secs, plugging: ttyUSB0.
Repeating the last step a couple of times: ttyUSB0.
Doing so, not waiting, no rmmod, switching usb port: ttyUSB0.
Doing so, not waiting: ttyUSB4.
Doing so, not waiting: ttyUSB4.
Doing so, waiting: ttyUSB4.
rmmod, wait, plug: ttyUSB0.
rmmod, wait, plug, switch usb port: ttyUSB0.

yadda yadda

-> only secure, reproducible method is: rmmod, wait. Replugging too fast yields to gsmmodem linking to ttyUSB4. Not rmmoding and
replugging too fast yields to gsmmodem linking to ttyUSB4. This smells like some electronics interfering, maybe in combination with the driver modules usbserial+option.

Ok, so respecting the above rule and retrying w/ option from 2.6.33.3 (to verify whether blacklisting is needed at all, when the above rule is followed): ttyUSB4.

TODAY'S CONCLUSIONS:

CONCLUSION 1: blacklisting is a precondition. ports 1,2,3,4. This also gets rid of wvdial hanging about 15 secs when accessing the device.

CONCLUSION 2: Waiting about 10 secs between replugging/rmmoding is essential. (this might have been obious for historical reasons (personally, I should've known) but w/ other devices there may be no such _strict_ requirement)

PREVIOUS CONCLUSION: If you're having trouble using your device (especially dialling successfully), try purging modemmanager.

UPDATE later the day: the first two conclusions don't seem to hold: It's now working even w/o blacklisting (probably due to removal of DriverModule and DriverIDPath from usb-modeswitch config file). The second conclusion seems still partly true, but not strictly so.

Questions? Alot.

Cheers
Last edited by olia on 14 May 2010, 17:21, edited 1 time in total.

Josh
Site Admin
Posts: 6593
Joined: 03 Nov 2007, 00:30

Post by Josh » 14 May 2010, 15:48

olia wrote:replug: /dev/gsmmodem -> ttyUSB0
replug: /dev/gsmmodem -> ttyUSB4
replug: /dev/gsmmodem -> ttyUSB4

so far no diffs between lsusb -d 0x0b3c -v
The latter can't be right unless it's a bug in usb_modeswitch's wrapper.

The "gsmmodem" symlink is supposed to always point to the first interrupt endpoint port. So either there is a different endpoint setup/order when replugging without the proper delay (note "TransferType Interrupt" in lsusb's output), or my wrapper gets confused.

If you have some energy left after all :? , would you mind checking the correlation between ttyUSB0/4 and lsusb again ?


olia

Post by olia » 14 May 2010, 17:14

Josh wrote:
olia wrote:replug: /dev/gsmmodem -> ttyUSB0
replug: /dev/gsmmodem -> ttyUSB4
replug: /dev/gsmmodem -> ttyUSB4

so far no diffs between lsusb -d 0x0b3c -v
The latter can't be right unless it's a bug in usb_modeswitch's wrapper.

The "gsmmodem" symlink is supposed to always point to the first interrupt endpoint port. So either there is a different endpoint setup/order when replugging without the proper delay (note "TransferType Interrupt" in lsusb's output), or my wrapper gets confused.

If you have some energy left after all :? , would you mind checking the correlation between ttyUSB0/4 and lsusb again ?
Ups, noticed I still had this in the config:
DriverModule="usbserial"
DriverIDPath=/sys/bus/usb-serial/drivers/generic/new_id

Removed it and retried (using blacklisting): couple of times, even w/ waiting ttyUSB4. Then waiting longer, about 4 minutes: ttyUSB0.

Going to re-check whether blacklisting is required w/o the DriverModule/DriverIDPath config: ttyUSB0. Holy cow.
Fast replugging, no waiting: ttyUSB0. No comment.

It works. Again and again. W/o blacklisting.

Hah! ttyUSB4.

I'm relieved. :) Cruel stick..

Having seen this, yes, maybe your wrapper got confused. But if so, then only because of the DriverModule/DriverIDPath config, it seems right now.

Humm.. Do I have to do something special after removing the config options DriverModule/DriverIDPath? I'm asking because the logfile keeps telling me as of the latest entry:
Driver module is "usbserial", ID path is /sys/bus/usb-serial/drivers/generic/new_id

So, right now upon replugging, I always get ttyUSB4.

But probably blacklisting isn't really required.

There seems to be no difference now between blacklisting and plain driver. ttyUSB0 is always the right port but gsmmodem is flickering between ttyUSB0 and ttyUSB4, tendency ttyUSB4 ;)

Back to the lsusb output: lsusb -d b3c: -v > $(mktemp)

Code: Select all

diff -Naur tmp.YrDe75jnNV tmp.7Qwmw8QFS5
--- tmp.YrDe75jnNV      2010-05-14 16:47:15.948475893 +0200
+++ tmp.7Qwmw8QFS5      2010-05-14 16:47:54.780230327 +0200
@@ -1,5 +1,5 @@
 
-Bus 002 Device 068: ID 0b3c:c000 Olivetti Techcenter 
+Bus 002 Device 072: ID 0b3c:c000 Olivetti Techcenter 
 Device Descriptor:
   bLength                18
   bDescriptorType         1
One log was of the previous run, w/ ttyUSB4, the latter w/ ttyUSB0.

Using blacklisting again.

Tendency has changed: out of 10 times, 7 times ttyUSB0.

Code: Select all

--- tmp.txiWSxXfs0      2010-05-14 16:52:08.304452986 +0200
+++ tmp.kieU0p2jJz      2010-05-14 16:54:04.111208257 +0200
@@ -1,6 +1,6 @@
-lrwxrwxrwx 1 root root 7 14 mag 16.51 /dev/gsmmodem -> ttyUSB0
+lrwxrwxrwx 1 root root 7 14 mag 16.53 /dev/gsmmodem -> ttyUSB4
 
-Bus 001 Device 123: ID 0b3c:c000 Olivetti Techcenter 
+Bus 002 Device 080: ID 0b3c:c000 Olivetti Techcenter 
 Device Descriptor:
   bLength                18
   bDescriptorType         1
@@ -213,10 +213,10 @@
   bNumConfigurations      1
 Device Status:     0x0001
   Self Powered
To me it seems that there's no diff. Any idea?

Hah, this is good: stick remained plugged.
w/ blacklisting: ttyUSB0
recompiled option.ko w/o blacklisting, only olicard ids added, rmmod modprobe: ttyUSB4

So, after all, is blacklisting at least helpful? Reducing number of times when ttyUSB4 is showing up? Next try: no change.

Could you please have a look at your wrapper?

Do you have an idea where I could be shooting my foot now?

Cheers,

Nils

Josh
Site Admin
Posts: 6593
Joined: 03 Nov 2007, 00:30

Post by Josh » 14 May 2010, 18:25

Uhmm, I think this time I might have f.. - messed up.

I just realized that your very first "lsusb -v" listing at pastebin is showing two interrupt endpoints ...

The problem is clear: the endpoint directories in sysfs are not always sorted ascending, so the wrapper may find the higher one first !!
(Your's is the very first device with more than one interrupt endpoint.)

This is where I will do some changes. Stand by for a test version ...


olia

Post by olia » 14 May 2010, 19:51

Josh wrote:Uhmm, I think this time I might have f.. - messed up.

I just realized that your very first "lsusb -v" listing at pastebin is showing two interrupt endpoints ...

The problem is clear: the endpoint directories in sysfs are not always sorted ascending, so the wrapper may find the higher one first !!
(Your's is the very first device with more than one interrupt endpoint.)

This is where I will do some changes. Stand by for a test version ...
Hm, I noticed the two INTs but you hinted me at the second one that also had some gibberish in lsusb output, so I believed in 4 being the interesting one and forgot about the first one. But there's always been something that kept bugging me because ttyUSB4 never worked, so there had to be another issue. Pity I didn't connect both thought w/ each other..

But I also could have been looking into the code of usb-modeswitch.. But then, I'm still not loving tcl and there's /lib/udev/usb_modeswitch (which I just noticed _is_ the wrapper) written in tcl so.. :)

Ok , so after all, no blacklisting needed. I'll keep on trying..

olia

fix gsmmodem link for sticks w/ more than one int line

Post by olia » 21 May 2010, 20:33

Ok, since you seemed quite busy recently I hacked some fix fix..

This is far from being elegant but it works for me (tm):

- On every symlink call, check for any interrupt ports and build a list of those
- sort and
- use the lowest numbered port for /dev/gsmmodem

As stated in the comment, there's no consideration taken for more
than one umts stick plugged at the same time.

Code: Select all

--- usb_modeswitch.orig 2010-05-21 20:14:16.000000000 +0200
+++ usb_modeswitch  2010-05-21 20:21:03.000000000 +0200
@@ -559,12 +559,21 @@
 set dev_top [lindex [split $tmpname _] 1]

 set dirList [split $path /]
+set tty [lindex $dirList end]
+regsub {ttyUSB} $tty {} ttyNo
 set idx -1
 set idx [lsearch -regexp $dirList {\d+-\d+:\d+\.\d+}]
 if {$idx == -1} {
  return ""
 }
-set ifDir /sys[join [lrange $dirList 0 $idx] /]
+### Idea is: lower the tty no better it is: ttyUSB0 is working, ttyUSB4 isn't
+###     (holds for devices with more than one interrupt line, tested locally w/
+###       two different devices plugged separately)
+### This doesn't take into account more than one /dev/gsmmodem link/umts dev
+### (ttyUSB? offset) used simultaneously.
+set prefix [lrange $dirList 0 [expr {$idx-1}]]
+set usbPort [lappend prefix $dev_top]
+set ifDir /sys[join $usbPort /]
 set port [lindex $dirList end]

 if {![regexp "/$dev_top/" $path]} {
@@ -572,17 +581,26 @@
 }

 set symlinkName ""
-foreach epDir [glob -nocomplain $ifDir/ep_*] {
+set devNo {}
+foreach epDir [glob -nocomplain $ifDir:\[0-9\].\[0-9\]/ep_*] {
  if [file exists $epDir/type] {
    set rc [open $epDir/type r]
    set type [read $rc]
    close $rc
    if [regexp {Interrupt} $type] {
+      regsub $ifDir:.\.(\[0-9\])/.* $epDir {\1} localId
+      lappend devNo $localId
      set symlinkName "gsmmodem"
      break
    }
  }
 }
+
+set minDevNo [lindex [lsort -decreasing $devNo] end]
+if {$ttyNo > $minDevNo} {
+  return ""
+}
+
 cd /dev
 set idx 2
 set trunkName $symlinkName
First tcl code, so there might very well be chances for optimisation.

Cheers,

Nils

Josh
Site Admin
Posts: 6593
Joined: 03 Nov 2007, 00:30

Post by Josh » 21 May 2010, 22:21

I'm in the process of preparing a new release; unfortunately I got sick (right at the time the weather is finally improving).

So I can't code properly at the moment (not without producing lots of garbage). I'll check the code once I can think more clearly again. I hope for a little patience on your side.

olia

Post by olia » 23 May 2010, 18:13

Hey,

Getting well again is top prio.

Right now I'm investigating an interesting issue:

lsusb -v -d 19d2: |grep -C 13 Interrupt
...
bDescriptorType 4
bInterfaceNumber 3
bAlternateSetting 0
bNumEndpoints 3
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 255 Vendor Specific Subclass
bInterfaceProtocol 255 Vendor Specific Protocol
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x84 EP 4 IN
bmAttributes 3
Transfer Type Interrupt
...

ls -l /dev/gsmmodem /dev/ttyU*
lrwxrwxrwx 1 root root 7 23 mag 11.50 /dev/gsmmodem -> ttyUSB1
crw-rw---- 1 root dialout 188, 0 23 mag 11.50 /dev/ttyUSB0
crw-rw---- 1 root dialout 188, 1 23 mag 11.50 /dev/ttyUSB1
crw-rw---- 1 root dialout 188, 2 23 mag 13.14 /dev/ttyUSB2

So, INT line is port 3, out of three IF.

Then, dialling using gsmmodem works perfectly. Furthermore, dialling
using wvdial inet modem=/dev/ttyUSB2 works perfectly as well but it's printing alot of ctrl char stuff like this:

--> pppd: ��0b] p�0b] [18]�0b]
--> Authentication (PAP) started
--> pppd: ��0b] p�0b] [18]�0b]
--> pppd: ��0b] p�0b] [18]�0b]
--> Authentication (PAP) successful
--> pppd: ��0b] p�0b] [18]�0b]
--> pppd: ��0b] p�0b] [18]�0b]
--> pppd: ��0b] p�0b] [18]�0b]
--> pppd: ��0b] p�0b] [18]�0b]

Note that this isn't the olicard100 stick, though (maybe wrong thread then) but it's occurring right now the first time some days after my changes to usb_modeswitch, so maybe there's some correlation.

I choose ttyUSB2 for the second dial as it's been so far the port used to dial and pointed to by gsmmodem.

My dbg output shows:
symlink call
dirList: {} devices pci0000:00 0000:00:1a.7 usb1 1-3 1-3:1.3 ttyUSB2 tty ttyUSB2
tty: ttyUSB2
ttyNo: 2
ifDir: /sys/devices/pci0000:00/0000:00:1a.7/usb1/1-3/1-3
port: ttyUSB2
dev_top: 1-3
found INT: /sys/devices/pci0000:00/0000:00:1a.7/usb1/1-3/1-3:1.3/ep_84/type

INT-portList: 3

returning symlinkname: gsmmodem

for just every port..

1-3:1.3 means IF 3 but there's only ttyUSB[0,1,2] and then there are dirs /sys/devices/pci0000:00/0000:00:1a.7/usb1/1-3/1-3:1.[0,1,2,3]

Using the original usb_modeswitch script, it's consistent as before.

Using the above patch (plus dbg log) works repeatedly fine w/ the olicard100 stick. Only the onda stick is giving trouble. So there's probably some correlation about the number of INT lines.

Hey, nice:

l /dev/gsmmodem* /dev/ttyUSB*
lrwxrwxrwx 1 root root 7 23 mag 13.40 /dev/gsmmodem -> ttyUSB2
lrwxrwxrwx 1 root root 7 23 mag 13.40 /dev/gsmmodem2 -> ttyUSB1
crw-rw---- 1 root dialout 188, 0 23 mag 13.40 /dev/ttyUSB0
crw-rw---- 1 root dialout 188, 1 23 mag 13.40 /dev/ttyUSB1
crw-rw---- 1 root dialout 188, 2 23 mag 13.40 /dev/ttyUSB2

Onda stick is plugged only..

Wheather is particularly hot today... :-)

I'm using

Linux host 2.6.33.3 #22 SMP PREEMPT Thu May 13 12:52:22 CEST 2010 i686 GNU/Linux

I've been searching the logs for an older lsusb entry, showing INT lines and stuff. Seems like I got none left..

gsmmodem2 doesn't dial.
gsmmodem does dial. w/ and w/o output like the one above..

Intriguing that is, indeed.

Gonna fix that..

The dbg tells that there should be three gsmmodem links. but there're only two of them. Could there be some unresolved bad udev behaviour showing up?

When I'm debugging the original usb_modeswitch, I noticed it seems skipping dir /sys/devices/pci0000:00/0000:00:1a.7/usb1/1-3/1-3:1.2, working w/ ...1-3:1.[0,1,3] though.

Maybe I'm missing something or getting something wrong in my understanding of how things should work out..

olicard: INT on IF number 0 and 4, w/ original script gssmodem points sometimes to ttyUSB0 and other times to ttyUSB4. W/ patch, pointing to ttyUSB0 (first INT line).
onda: INT on IF number 3, w/ original script gssmodem points to ttyUSB2. W/ patch pointing to either ttyUSB1 or ttyUSB2 and sometimes to ttyUSB1 _and_ ttyUSB2.

Note that w/ onda the INT IF no is 3 where contrarily to this gsmmodem points to ttyUSB2, there isn't even a ttyUSB3. How comes?

I noticed during dbg that w/ the orignal script symlink returns gsmmodem for ttyUSB4 first and then ttyUSB0 second, in case olicard is plugged and that time the gsmmodem link really ends up pointing to ttyUSB0 (which is incidentically correct).

Wasn't this also the case w/ the patch and issuing more than one gsmmodem but something going wrong w/ the symlinking process above? Timing problem?

BTW, using this dbg patch against original script from usb-modeswitch pkg version 1.1.2-2:

Code: Select all

--- /lib/udev/usb_modeswitch.orig 2010-05-18 12:01:18.000000000 +0200
+++ /lib/udev/usb_modeswitch.orig.dbg 2010-05-23 14:15:01.000000000 +0200
@@ -531,6 +531,18 @@
 }
 # end of proc {ParseConfigFile}

+proc {pLog} {msg} {
+  
+global wc
+if {![info exists wc]} {
+  set wc [open /tmp/usb_modeswitch_dbg.log a]
+  puts $wc "\n\nUSB_ModeSwitch log from [clock format [clock seconds]]\n"
+}
+puts $wc $msg
+
+}
+# end of proc {Log}
+

 proc {Log} {msg} {

@@ -553,20 +565,37 @@

 proc {SymLinkName} {path} {

+pLog "symlink call"
 # HACK ... /tmp/gsmmodem_* was generated by a switching run before;
 # no way found to signal annother instance in the udev environment
 set tmpname [lindex [glob -nocomplain /tmp/gsmmodem_*] 0]
 set dev_top [lindex [split $tmpname _] 1]

 set dirList [split $path /]
+set tty [lindex $dirList end]
+regsub {ttyUSB} $tty {} ttyNo
+pLog "dirList: $dirList"
+pLog "tty: $tty"
+pLog "ttyNo: $ttyNo"
+#pLog "Path: $path"
 set idx -1
 set idx [lsearch -regexp $dirList {\d+-\d+:\d+\.\d+}]
 if {$idx == -1} {
  return ""
 }
 set ifDir /sys[join [lrange $dirList 0 $idx] /]
+pLog "ifDir:  $ifDir"
+### Idea is: lower the tty no better it is: ttyUSB0 is working, ttyUSB4 isn't
+###     (holds for devices with more than one interrupt line)
+### This doesn't take into account more than one /dev/gsmmodem link.
+set range [lrange $dirList 0 [expr {$idx-1}]]
+set spath [lappend range $dev_top]
+set ifDir2 /sys[join $spath /]
+pLog "ifDir2: $ifDir2"
 set port [lindex $dirList end]

+pLog "port: $port"
+pLog "dev_top: $dev_top"
 if {![regexp "/$dev_top/" $path]} {
  return ""
 }
@@ -583,6 +612,30 @@
    }
  }
 }
+
+set devNo {}
+foreach epDir2 [glob -nocomplain $ifDir2:\[0-9\].\[0-9\]/ep_*] {
+  if [file exists $epDir2/type] {
+    set rc [open $epDir2/type r]
+    set type [read $rc]
+    close $rc
+    if [regexp {Interrupt} $type] {
+      pLog "found INT: $epDir2/type\n"
+      regsub $ifDir2:.\.(\[0-9\])/.* $epDir2 {\1} localId
+      lappend devNo $localId
+      break
+    }
+  }
+ }
+
+set minDevNo [lindex [lsort -decreasing $devNo] end]
+pLog "INT-portList: $minDevNo\n"
+if {$ttyNo > $minDevNo} {
+  pLog "Skipping $ttyNo, larger than $minDevNo\n"
+#  return ""
+}
+pLog "INFO: $ttyNo smaller than or equal to $minDevNo\n"
+
 cd /dev
 set idx 2
 set trunkName $symlinkName
@@ -594,6 +647,7 @@
  incr idx
 }

+pLog "returning symlinkname: $symlinkName\n"
 return $symlinkName

 }
I then noticed that this "break" in the dbg loop isn't correct. Removed it and the original script w/ dbg patch is working better (showing all INT lines in list). Backported this change to the fix. Now, orig script patched to support the olicard (now w/ dbg enabled) tells, that all ports are lower than 3 (correct) and therefore issues for every port a gsmmodem link name. The actual order of appearance was in the latest run: ports 1, 0, 2. The gsmmodem ended up pointing to ttyUSB1. Maybe because it was the first one issued.. Correct would have been ttyUSB2. ttyUSB1 isn't working. ttyUSB2 does work.

Deductions to verify:
1) Iff count(INT lines) is larger than max(ports) (onda: INT line no 3, port no max 2) then set gsmmodem to max(ports).
2) Iff count(INT lines) is larger than max(ports) (onda: INT line no 3, port no max 2) then set gsmmodem to count(INT lines) - 1: 3 - 1 = 2.

(ttyUSB_2_ is working)

But then, does this hold:
max(ports) == count(INT lines) - 1?
In this case deductions 1 and 2 coincide.

No clue so far. Neither can I verify whether I am going to break the script for all sticks in the wild out there w/ one of those assumptions..
Additionally, it seems that the deductions only apply to sticks w/ only one single INT line (like onda mf363 here), whereas olicard w/ 2 INT lines do already work w/ the fix.

ONDA: w/ fix patch: symlinks issued for all ports, in order: 0,2,1 and gsmmodem points to ttyUSB2. This looks quite like a timing problem.

I once tried some code w/ timing mods like "after 1000".. to no avail.. It's also not that deterministic to just wait. OTOH, how does udev work when there's already a link? I'd think it's skipping it's new link. At least it looks like this to me when ttyUSB1 is showing up but no ttyUSB[0,2] after that in the second last example above (order 1,0,2). Another point this is the case when there are gsmmodem[,2].. That means the timing problem didn't catch us and the script detected the first gsmmodem link. But isn't this rather udev missing to set some link instead of a race condition?

w/ fix patch: (reminder: the "break" removed from the loop)
onda:
cat /sys/devices/pci0000:00/0000:00:1a.7/usb1/1-3/bNumInterfaces
4

Interesting thing:
olicard:
1-3:1.*/bInterfaceClass
ff
ff
ff
ff
ff

onda: whether gsmmodem is pointing ttyUSB0 or ttyUSB2.
cat 1-3:1.*/bInterfaceClass
ff
ff
08
ff

So, can we use bInterfaceClass content for devs w/ count(INT lines) == 1? Obviously we need more info when handling devs w/ count(INT lines) >= 2 (bInterfaceClass always ff). Or are those bInterfaceClass values dev dependent (and maybe more than one is different from ff, or more than one is 08 or those different from ff aren't the same (as 08 here))?

Just noticed that udev calls us w/ path /devices/pci0000:00/0000:00:1a.7/usb1/1-3/1-3:1.3/ttyUSB2/tty/ttyUSB2 for ttyUSB2! Hm. That's a hint regarding the deductions above.

Latest dbg output: (onda)

USB_ModeSwitch log from Sun May 23 16:02:19 CEST 2010
symlink call
dirList: {} devices pci0000:00 0000:00:1a.7 usb1 1-3 1-3:1.1 ttyUSB1 tty ttyUSB1
tty: ttyUSB1
ttyNo: 1
Path: /devices/pci0000:00/0000:00:1a.7/usb1/1-3/1-3:1.1/ttyUSB1/tty/ttyUSB1
ifDir: /sys/devices/pci0000:00/0000:00:1a.7/usb1/1-3/1-3
port: ttyUSB1
dev_top: 1-3
className: /sys/devices/pci0000:00/0000:00:1a.7/usb1/1-3/1-3:1.1/bInterfaceClass
classType: ff
found INT: /sys/devices/pci0000:00/0000:00:1a.7/usb1/1-3/1-3:1.3/ep_84/type
INT-portList: 3
INFO: 1 smaller than or equal to 3
returning symlinkname: gsmmodem

USB_ModeSwitch log from Sun May 23 16:02:19 CEST 2010
symlink call
dirList: {} devices pci0000:00 0000:00:1a.7 usb1 1-3 1-3:1.0 ttyUSB0 tty ttyUSB0
tty: ttyUSB0
ttyNo: 0
Path: /devices/pci0000:00/0000:00:1a.7/usb1/1-3/1-3:1.0/ttyUSB0/tty/ttyUSB0
ifDir: /sys/devices/pci0000:00/0000:00:1a.7/usb1/1-3/1-3
port: ttyUSB0
dev_top: 1-3
className: /sys/devices/pci0000:00/0000:00:1a.7/usb1/1-3/1-3:1.0/bInterfaceClass
classType: ff
found INT: /sys/devices/pci0000:00/0000:00:1a.7/usb1/1-3/1-3:1.3/ep_84/type
INT-portList: 3
INFO: 0 smaller than or equal to 3
returning symlinkname: gsmmodem


USB_ModeSwitch log from Sun May 23 16:02:19 CEST 2010
symlink call
dirList: {} devices pci0000:00 0000:00:1a.7 usb1 1-3 1-3:1.3 ttyUSB2 tty ttyUSB2
tty: ttyUSB2
ttyNo: 2
Path: /devices/pci0000:00/0000:00:1a.7/usb1/1-3/1-3:1.3/ttyUSB2/tty/ttyUSB2
ifDir: /sys/devices/pci0000:00/0000:00:1a.7/usb1/1-3/1-3
port: ttyUSB2
dev_top: 1-3
className: /sys/devices/pci0000:00/0000:00:1a.7/usb1/1-3/1-3:1.3/bInterfaceClass
classType: ff
found INT: /sys/devices/pci0000:00/0000:00:1a.7/usb1/1-3/1-3:1.3/ep_84/type
INT-portList: 3
INFO: 2 smaller than or equal to 3
returning symlinkname: gsmmodem2

In the last call (the one for ttyUSB2) here's the correlation between path element __1.3__/ttyUSB2 and "found INT: /sys/devices/pci0000:00/0000:00:1a.7/usb1/1-3/1-3:__1.3__/ep_84/type"
That could be it.


dbg log for the olicard: only the relevant port

USB_ModeSwitch log from Sun May 23 16:14:54 CEST 2010
symlink call
dirList: {} devices pci0000:00 0000:00:1a.7 usb1 1-3 1-3:1.0 ttyUSB0 tty ttyUSB0
tty: ttyUSB0
ttyNo: 0
Path: /devices/pci0000:00/0000:00:1a.7/usb1/1-3/1-3:1.0/ttyUSB0/tty/ttyUSB0
ifDir: /sys/devices/pci0000:00/0000:00:1a.7/usb1/1-3/1-3
port: ttyUSB0
dev_top: 1-3
className: /sys/devices/pci0000:00/0000:00:1a.7/usb1/1-3/1-3:1.0/bInterfaceClass
classType: ff
found INT: /sys/devices/pci0000:00/0000:00:1a.7/usb1/1-3/1-3:1.0/ep_81/type
found INT: /sys/devices/pci0000:00/0000:00:1a.7/usb1/1-3/1-3:1.4/ep_86/type
INT-portList: 0
INFO: 0 smaller than or equal to 0
returning symlinkname: gsmmodem

I think that was it. The id in the path name from udev and the one from the lowest found interrupt must be identical, then it works harmoniously (for me again)tm.

Josh, please give this patch a look and try. Forget about the above, I consider the first one a first shot that didn't go far enough.

I already did some minor cleanup and even did some language usage improvement. But there's probably more potential.

Again, this isn't multi-device-reentrant yet..

Everything regarding "pLog" can be safely removed, it's kind of "privateLog" used for local debugging as the "Log" fct isn't available within the "SymlinkName" fct.

Code: Select all

--- /lib/udev/usb_modeswitch.orig 2010-05-18 12:01:18.000000000 +0200
+++ /lib/udev/usb_modeswitch.dbg  2010-05-23 18:03:57.000000000 +0200
@@ -531,6 +531,17 @@
 }
 # end of proc {ParseConfigFile}

+proc {pLog} {msg} {
+  
+global wc
+if {![info exists wc]} {
+  set wc [open /tmp/usb_modeswitch_dbg.log a]
+  puts $wc "\n\nUSB_ModeSwitch log from [clock format [clock seconds]]\n"
+}
+puts $wc $msg
+
+}
+# end of proc {Log}

 proc {Log} {msg} {

@@ -553,36 +564,100 @@

 proc {SymLinkName} {path} {

+pLog "symlink call"
 # HACK ... /tmp/gsmmodem_* was generated by a switching run before;
 # no way found to signal annother instance in the udev environment
 set tmpname [lindex [glob -nocomplain /tmp/gsmmodem_*] 0]
 set dev_top [lindex [split $tmpname _] 1]

 set dirList [split $path /]
+set tty [lindex $dirList end]
+regsub {ttyUSB} $tty {} ttyNo
+pLog "dirList: $dirList"
+pLog "tty: $tty"
+pLog "ttyNo: $ttyNo"
+pLog "Path: $path"
 set idx -1
 set idx [lsearch -regexp $dirList {\d+-\d+:\d+\.\d+}]
 if {$idx == -1} {
  return ""
 }
-set ifDir /sys[join [lrange $dirList 0 $idx] /]
+### Idea is: lower the tty no better it is: ttyUSB0 is working, 
+###   ttyUSB4 isn't (holds for devices with more than one 
+###   interrupt line like olicard100) This doesn't take into 
+###   account more than one /dev/gsmmodem link.
+set devDirBricks [lrange $dirList 0 [expr {$idx-1}]]
+set devDir /sys[join $devDirBricks /]
+lappend devDirBricks $dev_top
+set ifDirPrefixed /sys[join $devDirBricks /]
+pLog "ifDirPrefixed: $ifDirPrefixed"
+set vendorF "idVendor"
+set productF "idProduct"
+set idVendor ""
+set idProduct ""
+if [file exists $devDir/$vendorF] {
+  set fh [open $devDir/$vendorF r]
+  set idVendor [read $fh]
+  close $fh
+}
+if [file exists $devDir/$productF] {
+  set fh [open $devDir/$productF r]
+  set idProduct [read $fh]
+  close $fh
+}
+set idVendor [lindex [split $idVendor \n] 0]
+set idProduct [lindex [split $idProduct \n] 0]
+pLog "device: $idVendor:$idProduct"
+
 set port [lindex $dirList end]
+pLog "port: $port"

+pLog "dev_top: $dev_top"
 if {![regexp "/$dev_top/" $path]} {
  return ""
 }

+set usbPathId [lindex $dirList 6]
+set subPaths [split $usbPathId :]
+set pathId [lindex $subPaths end]
+set className $ifDirPrefixed:$pathId/bInterfaceClass
+pLog "className: $className"
+if [file exists $className] {
+  set classFh [open $className r]
+  set classType [read $classFh]
+  close $classFh
+  set classType [lindex [split $classType \n] 0]
+  pLog "classType: $classType"
+}
+
 set symlinkName ""
-foreach epDir [glob -nocomplain $ifDir/ep_*] {
+set usbIds {}
+foreach epDir [glob -nocomplain $ifDirPrefixed:\[0-9\].\[0-9\]/ep_*] {
  if [file exists $epDir/type] {
    set rc [open $epDir/type r]
    set type [read $rc]
    close $rc
    if [regexp {Interrupt} $type] {
-     set symlinkName "gsmmodem"
-     break
+      pLog "INTERRUPT: $epDir/type"
+      regsub $ifDirPrefixed:.\.(\[0-9\])/.* $epDir {\1} localUsbId
+      lappend usbIds $localUsbId
    }
  }
 }
+
+set minUsbId [lindex [lsort -decreasing $usbIds] end]
+pLog "minUsbId(INTERRUPT): $minUsbId"
+
+set lastCharUsbPathId [lindex [split $usbPathId .] end]
+### The id from the device on the given usb port (path from udev)
+### and the lowest found interrupt line path id must be identical.
+### This works for 1-interrupt devs like the Onda ZTE MF636 and 
+### multi-interrupt devices like the Olivetti Olicard100 sticks.
+pLog "INFO: lastCharUsbPathId: $lastCharUsbPathId, minUsbId: $minUsbId"
+if {$lastCharUsbPathId == $minUsbId} {
+  set symlinkName "gsmmodem"
+}
+
 cd /dev
 set idx 2
 set trunkName $symlinkName
@@ -594,6 +669,7 @@
  incr idx
 }

+pLog "returning symlinkname: $symlinkName"
 return $symlinkName

 }

Cheers,

Nils

PS: sorry 4 the monster post! :-D

olia

above patch cleaned up

Post by olia » 23 May 2010, 22:36

The above patch w/o debugging and logging stuff, unused code paths removed, code structure reordered to reflect logical coherence, thus alot cleaner:

Code: Select all

--- /lib/udev/usb_modeswitch.orig 2010-05-18 12:01:18.000000000 +0200
+++ /lib/udev/usb_modeswitch  2010-05-23 22:29:44.000000000 +0200
@@ -553,36 +553,52 @@

 proc {SymLinkName} {path} {

-# HACK ... /tmp/gsmmodem_* was generated by a switching run before;
-# no way found to signal annother instance in the udev environment
-set tmpname [lindex [glob -nocomplain /tmp/gsmmodem_*] 0]
-set dev_top [lindex [split $tmpname _] 1]
-
 set dirList [split $path /]
 set idx -1
 set idx [lsearch -regexp $dirList {\d+-\d+:\d+\.\d+}]
 if {$idx == -1} {
  return ""
 }
-set ifDir /sys[join [lrange $dirList 0 $idx] /]
-set port [lindex $dirList end]

+# HACK ... /tmp/gsmmodem_* was generated by a switching run before;
+# no way found to signal annother instance in the udev environment
+set tmpname [lindex [glob -nocomplain /tmp/gsmmodem_*] 0]
+set dev_top [lindex [split $tmpname _] 1]
 if {![regexp "/$dev_top/" $path]} {
  return ""
 }

+### Idea is: the lower the tty the better it is: ttyUSB0 is 
+###   working, ttyUSB4 isn't (holds for devices with more 
+###   than one interrupt line like olicard100) This doesn't 
+###   take into account more than one /dev/gsmmodem link.
 set symlinkName ""
-foreach epDir [glob -nocomplain $ifDir/ep_*] {
+set usbIds {}
+set devDirBricks [lrange $dirList 0 [expr {$idx-1}]]
+lappend devDirBricks $dev_top
+set ifDirPrefixed /sys[join $devDirBricks /]
+foreach epDir [glob -nocomplain $ifDirPrefixed:\[0-9\].\[0-9\]/ep_*] {
  if [file exists $epDir/type] {
    set rc [open $epDir/type r]
    set type [read $rc]
    close $rc
    if [regexp {Interrupt} $type] {
-     set symlinkName "gsmmodem"
-     break
+      lappend usbIds [regsub $ifDirPrefixed:.\.(\[0-9\])/.* $epDir {\1}]
    }
  }
 }
+set minUsbId [lindex [lsort -decreasing $usbIds] end]
+
+### The id from the device on the given usb port (path from udev)
+### and the lowest found interrupt line path id must be identical.
+### This works for 1-interrupt devs like the Onda ZTE MF636 and 
+### multi-interrupt devices like the Olivetti Olicard100 sticks.
+set usbPathId [lindex $dirList 6]
+set lastCharUsbPathId [lindex [split $usbPathId .] end]
+if {$lastCharUsbPathId == $minUsbId} {
+  set symlinkName "gsmmodem"
+}
+
 cd /dev
 set idx 2
 set trunkName $symlinkName
Still working like a charm here :-D
This time I'm quite confident that it'll continue working after a week, too.. ;-) Seems just more robust this way (w/ respect to the very first patch of course).

Cheers,

Nils

olia

Re: above patch cleaned up

Post by olia » 31 May 2010, 11:33

olia wrote: Still working like a charm here :-D
This time I'm quite confident that it'll continue working after a week, too.. ;-) Seems just more robust this way (w/ respect to the very first patch of course).

Cheers,

Nils
Running wildly on a couple of machines here :D


Josh, could you please comment on the above patch? Does is make sense to you? Do you intend to merge it in for the next release?

I've got calls for help from a couple of local users here. Doing all the steps manually each time is a) tedious, b) prone to errors. Furthermore, they're mostly rather basic users interested in Linux but appalled by the "difficult" linux, that "doesn't work" as they see fit.


Cheers

olia

Re: above patch cleaned up

Post by olia » 24 Jun 2010, 13:59

Hi Josh,

noticed your release and the update of the interesting part of usb-modeswitch.tcl.

I would have approved a note of yours shortly upon the above request for comment. Only now there's a new release and a month later still no feedback/comment. This is rather discouraging for contributors.

Again, as stated above, for the olicard to work _reliably_ the condition
has to be that the IDs correlate:
dbg log for the olicard: only the relevant port

USB_ModeSwitch log from Sun May 23 16:14:54 CEST 2010
symlink call
dirList: {} devices pci0000:00 0000:00:1a.7 usb1 1-3 1-3:1.0 ttyUSB0 tty ttyUSB0
tty: ttyUSB0
ttyNo: 0
Path: /devices/pci0000:00/0000:00:1a.7/usb1/1-3/1-3:1.0/ttyUSB0/tty/ttyUSB0
ifDir: /sys/devices/pci0000:00/0000:00:1a.7/usb1/1-3/1-3
port: ttyUSB0
dev_top: 1-3
className: /sys/devices/pci0000:00/0000:00:1a.7/usb1/1-3/1-3:1.0/bInterfaceClass
classType: ff
found INT: /sys/devices/pci0000:00/0000:00:1a.7/usb1/1-3/1-3:1.0/ep_81/type
found INT: /sys/devices/pci0000:00/0000:00:1a.7/usb1/1-3/1-3:1.4/ep_86/type
INT-portList: 0
INFO: 0 smaller than or equal to 0
returning symlinkname: gsmmodem

I think that was it. The id in the path name from udev and the one from the lowest found interrupt must be identical, then it works harmoniously (for me again)tm.
Only this made it work once and for all. If only the lowest one is chosen, then every now and then - and sometimes even always - the wrong ports get linked.

I'm ignorant as of why this observation/condition didn't make it into the release as it is critical for correct behaviour.

Cheers

Josh
Site Admin
Posts: 6593
Joined: 03 Nov 2007, 00:30

Post by Josh » 24 Jun 2010, 18:53

Let me state one thing very clear: I don't like feeling pushed.
Or - to quote Greg Kroah-Hartman in his reply to you - "you need to be a bit more patient".

Regarding your code proposal, I decided to rewrite the function myself. I guess I should have contacted you before the release; I did indeed miss the bit about the interface numbers. That said, it is probably system dependent if interfaces are assigned to a driver in an increasing order. I never had annother outcome on my machines and systems, but I have reports from others about differences between kernel device numbering order and interface order.

I'm not sure if that is a bug or just the state of things; I'll try to get information or dig into the source code.


Post Reply