[sane-devel] USB recordings MD6190 available

Lauri Pirttiaho lauri.pirttiaho at luukku.com
Sat Sep 24 20:06:13 UTC 2005


Martin Haag on Fri Sep 23 23:20:38 UTC 2005
>Hi,
>
>I've recorded some USB traffic with SniffUSB from the Medion MD6190
>scanner tonight. I am going to analyse them in the near future, but if
>one can't wait the scans are available on
>http://mibix.de/wiki/index.php/MD6190_USB_Recording .

Great recordings! Very similar to the ones from CanoScan 3200F.
The most important to me was scan5 that contained the firmware
upload. The code is similar to the CanoScan code, but not
identical. Interestingly enough, the code contains string descriptors
that say it is Canon/CanoScan :).

>By the way, maybe someone can give me some hints how to analyse such a
>huge amount of data :) I thought about comparing always two of the
>files with a block orientated compare tool such as beyond compare on
>wind-ws.  ( hm I can't belive that I sayed this. Ok let's use diff *g*
>)

A good start is a text log filter that reduces the data to more manageable
form, like one here:
---- snip ---- snip ---- snip ---
#!perl

$newimage = 1;
$image = 0;
$imagect = 0;
%pipe2ep = ();

while ( <> ) {
    if ( /UsbSnoop/ ) {
        next;
    }
    if ( /Driver/ ) {
        next;
    }
    if ( /Pipes\[(.)\] : PipeHandle\s+= 0x(........)/ ) {
        if ( $pipe_number == $1 ) {
            $pipe2ep{ $2 } = $endpoint_address;
#            print( "handle $2 endpoint $endpoint_address\n" );
        }
        next;
    }
    if ( /Pipes\[(.)\] : EndpointAddress\s+= 0x(..)/ ) {
        $pipe_number = $1;
        $endpoint_address = $2;
        next;
    }
    if ( /^[0-9]{8}\s+([0-9]+\.[0-9]{8})\s+([<>]).*URB *([0-9]+)/ ) {
        $t = $1;
        $d = $2;
        $u = $3;
        $type = <>;
        $type =~ /([A-Z_]+)/;
        $type = $1;
        
#        print "$d $type\n";

        if ( $type eq "URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER" ) {
            $endp = <>;
            $endp =~ /= (........)/;
            $endp = $pipe2ep{$1};
            $tbuflen = <>; #read one line off
            $tbuflen = <>;
            $tbuflen =~ /TransferBufferLength = (........)/;
            $tbuflen = $1;
            $dir = ( ( hex($endp) & 0x80 ) == 0 ) ? "o" : "i";
            $dd = ( ( hex($endp) & 0x80 ) == 0 ) ? ">" : "<";
            if ( $d ne $dd ) {
                next;
            }
            if ( $newimage == 1 && $image == 1 ) {
                $imagect++;
                $newimage = 0;
            }
            if ( $image == 0 ) {
                $fname = sprintf "%04d$dir.bin", $u;
            }
            else {
                $fname = sprintf "image%02d.bin", $imagect;
            }
            printf "%012.8f/%012.8f:%04d B$dd ep=$endp tl=$tbuflen fn=\"$fname\"\n",
                   $t,0,$u;
            open DF, ">>$fname";
            binmode DF;
            while ( <> ) {
                if ( /TransferBufferMDL/ ) {
                    last;
                }
            }
            while ( <> ) {
                next if ( /^[0-9]{8}\s+[0-9]+\.[0-9]{8}\s+$/ );
                next if ( /^[0-9]{8}\s+[0-9]+\.[0-9]{8}\s+[[:xdigit:]]{4}:\s$/ );
                last if ( /UrbLink/ );
                /^[0-9]{8}\s+[0-9]+\.[0-9]{8}\s+([[:xdigit:]]{2})\s$/;
                print DF pack "C", hex $1;
            }
            close DF;
            next;
        }


        if ( $d eq ">" ) {
            $td = $t;
            $urb = $u;
            $tyd = $type;
            if ( $type eq "URB_FUNCTION_ABORT_PIPE" ) {
                $endp = <>;
                $endp =~ /endpoint 0x000000(..)/;
                $endp = $1;
            }
            elsif ( $type eq "URB_FUNCTION_RESET_PIPE" ) {
                $endp = <>;
                $endp =~ /endpoint 0x000000(..)/;
                $endp = $1;
            }
            elsif ( $type eq "URB_FUNCTION_SELECT_CONFIGURATION" ) {
                while ( <> ) {
                    if ( /iConfiguration *= 0x(..)/ ) {
                        $conf = $1;
                        last;
                    }
                }
            }
            elsif ( $type eq "URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE" ) {
                while ( <> ) {
                    if ( /DescriptorType *= (..) \(([^)]+)\)/ ) {
                        $dtype = $1;
                        $dname = $2;
                        last;
                    }
                }
            }
            elsif ( $type eq "URB_FUNCTION_VENDOR_DEVICE" ) {
                $vdata = "";
                while ( <> ) {
                    if ( /TransferFlags *= 000000(..)/ ) {
                        $tf = $1;
                    }
                    elsif ( /TransferBufferLength = 0000(....)/ ) {
                        $tbl = $1;
                    }
                    elsif ( /RequestTypeReservedBits = (..)/ ) {
                        $rt = $1
                    }
                    elsif ( /Request *= (..)/ ) {
                        $rq = $1
                    }
                    elsif ( /Value *= (....)/ ) {
                        $vl = $1;
                    }
                    elsif ( /Index *= (....)/ ) {
                        $ix = $1;
                        last;
                    }
                    elsif ( /^[0-9]{8}\s+[0-9]+\.[0-9]{8}\s+( [[:xdigit:]]{2})\s$/ ) {
                        $vdata .= $1;
                    }
                }
            }
        }
        elsif ( $d eq "<" ) {
            $tb = $t;
            $tyu = $type;
            if ( $type eq "URB_FUNCTION_ABORT_PIPE" ) {
                printf "%012.8f/%012.8f:%04d AP ep=%s\n",$td,$tb,$urb,$endp; 
            }
            elsif ( $type eq "URB_FUNCTION_RESET_PIPE" ) {
                printf "%012.8f/%012.8f:%04d RP ep=%s\n",$td,$tb,$urb,$endp; 
            }
            elsif ( $type eq "URB_FUNCTION_SELECT_CONFIGURATION" ) {
                printf "%012.8f/%012.8f:%04d SC cf=%s\n",$td,$tb,$urb,$conf; 
            }
            elsif ( $tyd eq "URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE" ) {
                $ddata = "";
                while ( <> ) {
                    if ( /TransferBufferLength *= 0000(....)/ ) {
                        $tbl = $1;
                    }
                    elsif ( /^[0-9]{8}\s+[0-9]+\.[0-9]{8}\s+( [[:xdigit:]]{2})\s$/ ) {
                        $ddata .= $1;
                    }
                    elsif( /SetupPacket/ ) {
                        printf "%012.8f/%012.8f:%04d ", $td,$tb,$urb;
                        # print "GD $dtype ($dname) bl=$tbl ";
                        print "GD ty=$dtype bl=$tbl ";
                        print "dt=$ddata\n";
                        last;
                    }
                }
            }
            elsif ( $tyd eq "URB_FUNCTION_VENDOR_DEVICE" ) {
                while ( <> ) {
                    if ( /^[0-9]{8}\s+[0-9]+\.[0-9]{8}\s+( [[:xdigit:]]{2})\s$/ ) {
                        $vdata .= $1;
                    }
                    elsif( /SetupPacket/ ) {
                        printf "%012.8f/%012.8f:%04d ",$td,$tb,$urb;
                        if ( $tf == 0 ) {
                            print "> ";
                        }
                        else {
                            print "< ";
                        }
                        print "rt=$rt rq=$rq vl=$vl ix=$ix bl=$tbl ";
                        print "dt=$vdata\n";

                        $image = ( $vl eq '0030' ) ? 1 : 0;
                        $newimage = 1;

                        last;
                    }
                }
            }
        }
    }
}
---- snip ---- snip ---- snip ---
(I have a different version of the snooper so I quickly modified my earlier
script. This looks like it works OK but there may be problems with
some logs. Let me know and I will make a fix.)

It eats the text logs and outputs a reduced info about the USB transfers
one info per line, like from scan5.txt:
---
000.00297971/000.00818260:0001 GD ty=01 bl=0012 dt= 12 01 10 01 ff ff ff 40 61 04 7b 03 01 01 00 01 00 01
000.00862316/000.01213450:0002 GD ty=02 bl=0009 dt= 09 02 27 00 01 01 00 c0 00
000.01244879/000.01812912:0003 GD ty=02 bl=0027 dt= 09 02 27 00 01 01 00 c0 00 09 04 00 00 03 ff ff ff 00 07 05 81 02 40 00 00 07 05 02 02 40 00 00 07 05 83 03 08 00 10
000.01872640/000.08083681:0004 SC cf=00
000.64165837/000.64507890:0005 < rt=c0 rq=04 vl=0040 ix=0000 bl=0004 dt= 00 00 00 0c
000.64541441/000.64903808:0006 > rt=40 rq=0c vl=0040 ix=0000 bl=0001 dt= 00
000.64928669/000.65303522:0007 < rt=c0 rq=0c vl=00e1 ix=ffe2 bl=0001 dt= 00
000.65331542/000.65703434:0008 < rt=c0 rq=0c vl=00e1 ix=ffed bl=0001 dt= 03
000.65731204/000.66103399:0009 > rt=40 rq=04 vl=00e0 ix=ffed bl=0002 dt= 03 00
000.66208053/000.66605645:0010 < rt=c0 rq=04 vl=0040 ix=0000 bl=0004 dt= 00 00 00 0c
000.66637242/000.67003375:0011 > rt=40 rq=04 vl=00f0 ix=0000 bl=0005 dt= 00 00 00 00 00
000.67027485/000.67403316:0012 < rt=c0 rq=04 vl=0040 ix=0000 bl=0004 dt= 00 00 00 0c
000.67433429/000.67802721:0013 > rt=40 rq=04 vl=00f3 ix=0000 bl=0004 dt= 00 41 00 00
000.67828929/000.00000000:0014 B> ep=02 tl=00008200 fn="0014o.bin"
001.20546997/001.20900762:0015 < rt=c0 rq=04 vl=0040 ix=0000 bl=0004 dt= 00 00 00 0c
...
---
GD is get descriptor, SC is select configuration,
< indicates control read, > a control write B> a bulk write ect.
In addition it extracts the bulk transfers to files in binary form
so the images can be extracted there. None of the files contained
any image data, though, so I could not test that.
The bulk transfers to the scanner are mostly some kind of configuration
parameters and curves (gamma, mask etc.) which I call mystery files
and try to figure out from the firmware. I am not that far yet, though.

With best regards,

Lauri Pirttiaho
Oulu
Finland


...................................................................
Luukku Plus paketilla pääset eroon tila- ja turvallisuusongelmista.
Hanki Luukku Plus ja helpotat elämääsi. http://www.mtv3.fi/luukku


More information about the sane-devel mailing list