[Tinyos-commits] CVS: tinyos-1.x/tools/src/motelist motelist-linux, 1.1, 1.2 motelist-linux-2.6, 1.1, NONE motelist-linux2, 1.4, NONE

Cory Sharp cssharp at users.sourceforge.net
Wed Jul 27 21:57:20 PDT 2005


Update of /cvsroot/tinyos/tinyos-1.x/tools/src/motelist
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv22025

Modified Files:
	motelist-linux 
Removed Files:
	motelist-linux-2.6 motelist-linux2 
Log Message:
motelist-linux should now work for both Linux kernels 2.4.x and 2.6.x.

The script scans /proc/version to determine the kernel version number.  If the
kernel is 2.4.x, procfs in /proc is used to inspect the usb ssytem.  If the
kernel is 2.6.x, sysfs /in /sys is used to inspect the usb system.  This
behavior can be overridden with command line switches.

Note, the 2.4.x kernels still generally require superuser access to determine
the serial port number.  2.6.x kernels do not.



Index: motelist-linux
===================================================================
RCS file: /cvsroot/tinyos/tinyos-1.x/tools/src/motelist/motelist-linux,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -d -r1.1 -r1.2
*** motelist-linux	25 Jul 2004 02:25:18 -0000	1.1
--- motelist-linux	28 Jul 2005 04:57:17 -0000	1.2
***************
*** 1,317 ****
! #!/usr/bin/perl
! #
! # Reads /proc/bus/usb/devices and selectively lists and/or
! # interprets it with /proc/tty/driver/usb-serial to determine which
! # motes are connected on which virtual comm ports at /dev/ttyUSB*
! #
! # Written by Joe Polastre
! #
  # $Id$
! #
  
! use Getopt::Std;
  
! sub custom {
!   (split /\t/,$a)[1] <=>
!       (split /\t/,$b)[1];
! }
  
! $DEVFILENAME = "/proc/bus/usb/devices";
! $DRIVERFILENAME = "/proc/tty/driver/usb-serial";
! $PROGNAME = $0;
! $debug = 0;
  
! if (@ARGV > 0) {
!   $help = getopts('hclf:');
!   if ($opt_h == 1) {
! 	print "usage: $0 [-l] [-c] [-f <file>]\n\n";
! 	print '  $Revision$ $Date$' . "\n\n";
! 	print "options:\n";
! 	print "  -h  display this help\n";
! 	print "  -l  long format, also display disconnected devices\n";
! 	print "  -c  compact format, not pretty but easier for parsing\n";
!         print "  -f  use file specified for 'usb-serial' instead of /proc/tty/driver\n";
! 	exit(0);
!   }
! }
  
! if (! open (DEVNUM, "<$DEVFILENAME"))
! {
! 	print "$PROGNAME: cannot open '$DEVFILENAME'\n";
! 	exit 1;
  }
! if ($opt_f) {
!   if (! open (DRIVERNUM, "<$opt_f"))
!   {
! 	print "$PROGNAME: cannot open '$DRIVERFILENAME'\n\n";
!         print "make sure that $DRIVERFILENAME is world readable by either\n";
! 	print "running $0 as root or setting up a cron job to copy\n";
! 	print "/proc/tty/driver/usb-serial to /tmp periodically\n\n";
! 	print "use '$0 -h' for help\n";
! 	exit 1;
!   }
  }
! else {
!   if (! open (DRIVERNUM, "<$DRIVERFILENAME"))
!   {
! 	print "$PROGNAME: cannot open '$DRIVERFILENAME'\n\n";
!         print "make sure that $DRIVERFILENAME is world readable by either\n";
! 	print "running $0 as root or setting up a cron job to copy\n";
! 	print "/proc/tty/driver/usb-serial to /tmp periodically\n\n";
! 	print "use '$0 -h' for help\n";
! 	exit 1;
!   }
  }
  
! $showconfig = "yes";
! $currentlevel = 0;
! $portstr = "";
  
  
! while ($line = <DEVNUM>)	# read a text line from DEVNUM
! {
!         $origline = $line;
! 	# skip all lines except those we recognize:
! 	if (($line !~ "^C:")		# Configuration: one is active
! 		    && ($line !~ "^D:")	# Device:
! 		    && ($line !~ "^I:")	# Interface: protocol group
! 		    && ($line !~ "^S:") # String: used with root hub
! 		    && ($line !~ "^T:")	# Topology: starts each device
! 		    && ($line !~ "^P:")	# Product : vendor and prod id
! 		    )
! 	{
! 		next;	# to the next line
! 	}
  
! 	chomp $line;		# remove line endings
  
! 	# First convert '=' signs to spaces.
! 	$line =~ tr/=/ /;
  
! 	# and convert all '(' and ')' to spaces.
! 	$line =~ tr/(/ /;
! 	$line =~ tr/)/ /;
  
! 	# split the line at spaces.
! 	@fields = split / +/, $line;
  
! 	# T:  Bus=01 Lev=01 Prnt=01 Port=03 Cnt=01 Dev#=  3 Spd=1.5 MxCh= 0
! 	if ($line =~ "^T:")
! 	{
! 		# split yields: $bus, $level, $parent, $port, $count, $devnum, $speed, $maxchild.
  
! 		$bus    = @fields [2];
! 		$level  = @fields [4];
! 		$parent = @fields [6];		# parent devnum
! 		$port   = @fields [8] + 1;	# make $port 1-based
! 		$count  = @fields [10];
! 		$devnum = @fields [12];
! 		$speed  = @fields [14];
! 		$maxchild = @fields [16];
  
- 		if (($level == 0) && ($currentlevel == 0)) {
- 		    $portstr = $port;
- 		    $currentlevel = $level;
- 		}
-                 elsif ($level > $currentlevel) {
- 		    $portstr = $portstr . "." . $port;
- 		    $currentlevel = $level;
- 		}
- 		elsif ($level <= $currentlevel) {
- 		    @portsplit = split /\./, $portstr;
-                     $portstr = @portsplit[0];
- 		    for ($i = 1; $i < $level; $i++) {
- 			$portstr = $portstr . "\." . @portsplit[$i];
- 		    }
- 		    $portstr = $portstr . "\." . $port;
- 		    $currentlevel = $level;
- 		}
  
! 		$devclass = "?";
! 		$intclass = "?";
! 		$driver   = "?";
! 		$ifnum    = "?";
! 		$showclass = "?";	# derived from $devclass or $intclass
! 		$lastif = "?";			# show only first altsetting
! 		$HCtype = "?";
!                 $vendor = "?";
!                 $prodid = "?";
! 		$showconfig = "no";
! 		$nconfig = "0";
! 		next;
! 	} # end T: line
  
!         elsif ( $line =~ "^P:" ) {
! 	    $vendor = @fields[2];
!             $prodid = @fields[4];
!             next;
!         }
  
! 	# only show the _active_ configuration
! 	# C:* #Ifs= 1 Cfg#= 1 Atr=a0 MxPwr=100mA
! 	elsif ( $line =~ "^C:" ) {
! 	    if ( $line =~ "^C:\\*" ) {
! 		$showconfig = @fields[4];
! 	    } else {
! 		$showconfig = "no";
! 	    }
! 	    next;
! 	}
  
! 	# D:  Ver= 1.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs=  1
! 	elsif ($line =~ "^D:")
! 	{ # for D: line
! 		$devclass = @fields [5];
! 		$nconfig = @fields [13];
! 		next;
! 	}
  
! 	# in case this is a root hub, look at the device strings.
! 	#  - S:  Manufacturer:Linux 2.6.5 ehci_hcd	[all 2.6]
! 	#  - S:  Product=USB UHCI Root Hub 		[all 2.4, 2.2]
! 	#  - S:  Product=OPTi Inc 82C861		[2.6/PCI_NAMES]
! 	elsif ( $line =~ "^S:" )
! 	{ # for S: line
! 		if ( $level == 00 && $line =~ "hcd" )
! 		{
! 		    $HCtype = @fields [4];
! 		}
! 		elsif ( $level == 00 && $line =~ "HCI" && $HCtype eq "?")
! 		{
! 		    $HCtype = @fields [3];
! 		}
!                 elsif ( ($line =~ "Product") && ($vendor = "0403") ) 
! 		{
! 		    chomp($origline);
! 		    @temparr = split /^S:  Product=/, $origline;
! 		    $product = @temparr[1];
! 		    chomp($product);
!                 }
!                   
!                 elsif ( ($line =~ "SerialNumber") && ( $vendor == "0403" )) 
!                 {
! 		    @temparr = split /\./, $portstr;
! 		    $temparrlen = @temparr;
! 		    $realstr = @temparr[1];
! 		    for ($i = 2; $i < $temparrlen; $i++) {
! 			$realstr = $realstr . "\." . @temparr[$i];
! 		    }
! 		    push ( @serialnums, @fields[2] );
!                     push ( @deviceids, $realstr );
! 		    push ( @productids, $product );
!                 }
! 		next;
! 	}
  
! 	# the rest of this code:
! 	#  - only shows interface descriptors
! 	#  - for the active configuration
! 	#  - for the first (prefer: active!) altsetting
! 	elsif ( ! ( $line =~ "^I:" )
! 		|| "$showconfig" eq "no") {
! 	    next;
! 	}
  
! 	
! 	# I:  If#= 0 Alt= 0 #EPs= 1 Cls=03(HID  ) Sub=01 Prot=02 Driver=hid
! 	$intclass = @fields [9];
! 	$ifnum    = @fields [2];
! 	$driver   = @fields [15];
  
! 	if (($devclass eq ">ifc") || ($devclass eq "unk."))
! 	{	# then use InterfaceClass, not DeviceClass
! 		$showclass = $intclass;
! 	}
! 	else
! 	{	# use DeviceClass
! 		$showclass = $devclass;
! 	}
  
! 	if ($level == 0)
! 	{
! 	    # substitute real driver name
! 	    if ( $HCtype =~ "UHCI-alt" )
! 	    {
! 		$HC = "uhci";
! 	    }
! 	    elsif ( $HCtype =~ "UHCI" )
! 	    {
! 		$HC = "usb-uhci";
! 	    }
! 	    elsif ( $HCtype =~ "OHCI" )
! 	    {
! 		$HC = "usb-ohci";
! 	    }
! 	    else
! 	    {
! 		$HC = $HCtype;
! 	    }
  
- 	    if ($debug != 0) {
- 		print sprintf ("/:  Bus $bus.Port $port: Dev $devnum, Class=root_hub, Driver=%s/%sp, %sM\n",
- 			 $HC, $maxchild, $speed );
- 	    }
- 	}
- 	elsif ($lastif ne $ifnum)
- 	{
- 		$temp = $level;
- 		if ($debug != 0) {
- 		    while ($temp >= 1)
- 		    {
- 			print "    ";
- 			$temp--;
- 		    }
  
! 		    if ($nconfig ne "1") {
! 			$temp = " Cfg $showconfig/$nconfig";
! 		    } else {
! 			$temp = "";
! 		    }
  
- 		    print sprintf ("|__ Port $port: Dev $devnum$temp, If $ifnum, Class=$showclass, Driver=$driver%s, %sM\n",
- 				   ($maxchild == 0) ? "" : ("/" . $maxchild . "p"),
- 				   $speed);
- 		}
- 	   
- 		$lastif = $ifnum;
- 	}
- } # end while DEVNUM
  
! close (DEVNUM);
  
! $count = @serialnums;
! while ($line = <DRIVERNUM>)	# read a text line from DEVNUM
! {
!     for ($i = 0; $i < $count; $i++) {
! 	if ($line =~ $deviceids[$i]) {
! 	    @temparr = split ":", $line;
! 	    @devaddress[$i] = @temparr[0];
! 	}
!     }
! }
  
! close (DRIVERNUM);
  
! for ($i = 0; $i < $count; $i++) {
!     @sortarray[$i] = $serialnums[$i] . "\t" . $devaddress[$i] . "\t" . $productids[$i];
  }
  
- @sorted = sort custom @sortarray;
  
! if ($opt_c != 1) {
!     print "Reference  \tCommPort   \tDescription\n";
!     print "---------- \t---------- \t----------------------------------------\n";
  }
  
! for ($i = 0; $i < $count; $i++) {
!     $temp = @sorted[$i];
!     @fields = split /\t/,$temp;
!     if ($opt_c == 1) {
!       print @fields[0] . ",/dev/ttyUSB" . @fields[1] . ",0," . @fields[2] . "\n";
!     }
!     else {
!       print @fields[0] . "\t/dev/ttyUSB" . @fields[1] . "\t" . @fields[2] . "\n";
!     }
  }
  
- # END.
--- 1,275 ----
! #!/usr/bin/perl -w
! use strict;
  # $Id$
! # @author Cory Sharp <cory at moteiv.com>
! # @author Joe Polastre
  
! my $help = <<'EOF';
! usage: motelist [options]
  
!   $Revision$
  
! options:
!   -h  display this help
!   -c  compact format, not pretty but easier for parsing
!   -f  specify the usb-serial file (for smote.cs)
!   -k  kernel version: 2.4, 2.6, auto (default)
!   -m  method to scan usb: procfs, sysfs, auto (default)
!   -dev_prefix  force the device prefix for the serial device
!   -usb  display extra usb information
! EOF
  
! my %Opt = (
!   compact => 0,
!   usb => 0,
!   method => "auto",
!   kernel => "auto",
!   dev_prefix => [ "/dev/usb/tts/", "/dev/ttyUSB", "/dev/tts/USB" ],
!   usbserial => "sudo cat /proc/tty/driver/usbserial |",
! );
  
! while (@ARGV) {
!   last unless $ARGV[0] =~ /^-/;
!   my $opt = shift @ARGV;
!   if( $opt eq "-h" ) { print "$help\n"; exit 0; }
!   elsif( $opt eq "-c" ) { $Opt{compact} = 1; }
!   elsif( $opt eq "-f" ) { $Opt{usbserial} = shift @ARGV; }
!   elsif( $opt eq "-k" ) { $Opt{kernel} = shift @ARGV; }
!   elsif( $opt eq "-m" ) { $Opt{method} = shift @ARGV; }
!   elsif( $opt eq "-dev_prefix" ) { $Opt{dev_prefix} = shift @ARGV; }
!   elsif( $opt eq "-usb" ) { $Opt{usb} = 1; }
!   else { print STDERR "$help\nerror, unknown command line option $opt\n"; exit 1; }
  }
! 
! if( $Opt{kernel} eq "auto" ) {
!   $Opt{kernel} = "unknown";
!   $Opt{kernel} = $1 if snarf("/proc/version") =~ /\bLinux version (\d+\.\d+)/;
  }
! 
! if( $Opt{method} eq "auto" ) {
!   $Opt{method} = ($Opt{kernel} eq "2.4") ? "procfs" : "sysfs";
  }
  
! my @devs = $Opt{method} eq "procfs" ? scan_procfs() : scan_sysfs();
! print_motelist( sort { cmp_usbdev($a,$b) } @devs );
  
  
! #
! #  SysFS
! #
! sub scan_sysfs {
  
!   #  Scan /sys/bus/usb/drivers/usb for FTDI devices
!   my @ftdidevs =
!     grep { ($_->{UsbVendor}||"") eq "0403" && ($_->{UsbProduct}||"") eq "6001" }
!     map { {
!       SysPath => $_,
!       UsbVendor => snarf("$_/idVendor",1),
!       UsbProduct => snarf("$_/idProduct",1),
!     } }
!     glob("/sys/bus/usb/drivers/usb/*");
  
!   #  Gather information about each FTDI device
!   for my $f (@ftdidevs) {
!     my $syspath = $f->{SysPath};
  
!     $f->{InfoManufacturer} = snarf("$syspath/manufacturer",1);
!     $f->{InfoProduct} = snarf("$syspath/product",1);
!     $f->{InfoSerial} = snarf("$syspath/serial",1);
!     $f->{UsbDevNum} = snarf("$syspath/devnum",1);
  
!     my $devstr = readlink($syspath);
!     if( $devstr =~ m{([^/]+)/usb(\d+)/.*-([^/]+)$} ) {
!       $f->{UsbPath} = "usb-$1-$3";
!       $f->{UsbBusNum} = $2;
!     }
!     ($f->{SysDev} = $syspath) =~ s{^.*/}{};
  
!     my $port = "$syspath/$f->{SysDev}:1.0";
!     ($f->{DriverName} = readlink("$port/driver")) =~ s{^.*/}{} if -l "$port/driver";
!     ($f->{SerialDevName} = (glob("$port/tty*"),undef)[0]) =~ s{^.*/}{};
!     $f->{SerialDevNum} = $1 if $f->{SerialDevName} =~ /(\d+)/;
!     $f->{SerialDevName} = getSerialDevName( $f->{SerialDevNum} ) || "  (none)";
!   }
  
!   return @ftdidevs;
! }
  
  
! #
! #  Scan Procfs
! #
! sub scan_procfs {
  
!   my $text_devs = snarf("< /proc/bus/usb/devices");
!   my $text_serial = snarf($Opt{usbserial});
  
!   my @usbdevs = map { {parse_usb_devices_text($_)} }
!                 grep { !/^\s*$/ } split /\n+(?=T:)/, $text_devs;
!   my %usbtree = build_usb_tree( @usbdevs );
!   my %usbserialtree = build_usbserial_tree( $text_serial );
!   for my $tts ( values %usbserialtree ) {
!     $usbtree{usbkey($tts->{path})}{usbserial} = $tts if defined $tts->{path};
!   }
  
!   my @ftdidevs = map { {
!       UsbVendor => $_->{Vendor},
!       UsbProduct => $_->{ProdID},
!       InfoManufacturer => $_->{Manufacturer},
!       InfoProduct => $_->{Product},
!       InfoSerial => $_->{SerialNumber},
!       UsbBusNum => $_->{nbus},
!       UsbDevNum => $_->{ndev},
!       UsbPath => $_->{usbpath},
!       DriverName => $_->{driver},
!       SerialDevNum => $_->{usbserial}{tts},
!       SerialDevName => getSerialDevName($_->{usbserial}{tts}) || "  (none)",
!     } }
!     grep { ($_->{Vendor}||"") eq "0403" && ($_->{ProdID}||"") eq "6001" }
!     values %usbtree;
  
!   return @ftdidevs;
! }
  
! sub build_usb_tree {
!   my @devs = @_;
!   my %tree = ();
!   for my $dev (sort { $a->{Lev} <=> $b->{Lev} } @devs) {
!     my ($bus,$lev,$prnt) = ( $dev->{Bus}+0, $dev->{Lev}+0, $dev->{Prnt}+0 );
!     my $devnum = $dev->{"Dev#"}+0;
!     $dev->{nbus} = $bus;
!     $dev->{ndev} = $devnum;
!     $tree{"bus$bus"} = {} unless exists $tree{"bus$bus"};
!     $tree{"bus$bus"}{"dev$devnum"} = $dev;
!     if( $lev == 0 ) {
!       $dev->{usbpath} = "usb-$dev->{SerialNumber}";
!     } else {
!       my $sep = ($lev==1) ? "-" : ".";
!       $dev->{parent} = $tree{"bus$bus"}{"dev$prnt"};
!       $dev->{usbpath} = $dev->{parent}{usbpath} . $sep . ($dev->{Port}+1);
!     }
!     $tree{usbkey($dev->{usbpath})} = $dev;
!   }
!   return %tree;
! }
  
! sub parse_usb_devices_text {
!   my $text = shift;
!   $text =~ s/^\S+\s*//gm;
!   return ($text =~ m/([^\s=]+)=\s*(.*?\S)\s*(?=[^\s=]+=|$)/mg);
! }
  
! sub build_usbserial_tree {
!   my $text = shift;
!   my %tree = ();
!   while( $text =~ /^([^:]+):(.*)/mg ) {
!     my ($tts,$params) = ($1,$2);
!     $tree{$tts} = { tts => $tts };
!     while ($params =~ m/\s+([^:]+):(?:"([^"]*)"|(\S+))/g) {
!       $tree{$tts}{$1} = $2||$3;
!     }
!   }
!   return %tree;
! }
  
! sub usbkey {
!   if( $Opt{kernel} eq "2.4" ) {
!     (my $key = $_[0]) =~ s/^.*-//;
!     return $key;
!   }
!   return $_[0];
! }
  
  
! #
! #  getSerialDevName
! #
! #  For each device, force to use dev_prefix if it's not an array.  Otherwise,
! #  assume it's a list of candidate prefixes.  Check them and commit to the
! #  first one that actually exists.
! #
! sub getSerialDevName {
!   my $devnum = shift;
!   my $devname = undef;
!   if( defined $devnum ) {
!     if( ref($Opt{dev_prefix}) eq "ARRAY" ) {
!       $devname = $devnum;
!       for my $prefix (@{$Opt{dev_prefix}}) {
!         my $file = $prefix . $devnum;
!         if( -e $file ) { $devname = $file; last; }
!       }
!     } else {
!       $devname = $Opt{dev_prefix} . $devnum;
!     }
!   }
!   return $devname;
! }
  
  
! #
! #  Print motelist
! #
! sub print_motelist {
!   my @devs = @_;
  
!   #  If none were found, quit
!   if( @devs == 0 ) {
!     print "No devices found.\n";
!     return;
!   }
  
!   #  Print a header
!   if( !$Opt{compact} ) {
!     if( $Opt{usb} ) {
!       print << "EOF" unless $Opt{compact};
! Bus Dev USB Path                 Reference  Device           Description
! --- --- ------------------------ ---------- ---------------- -------------------------------------
! EOF
!     } else {
!       print << "EOF" unless $Opt{compact};
! Reference  Device           Description
! ---------- ---------------- ---------------------------------------------
! EOF
!     }
!   }
  
!   #  Print the usb information
!   for my $dev (sort { cmp_usbdev($a,$b) } @devs) {
!     my $desc = join( " ", $dev->{InfoManufacturer}||"", $dev->{InfoProduct}||"" ) || " (none)";
!     my @output = ( $dev->{InfoSerial}||" (none)", $dev->{SerialDevName}, $desc );
!     @output = ( $dev->{UsbBusNum}, $dev->{UsbDevNum}, $dev->{UsbPath}, @output ) if $Opt{usb};
!     if( $Opt{compact} ) {
!       print join(",", at output) . "\n";
!     } else {
!       printf( ($Opt{usb}?"%3d %3d %-24s ":"")."%-10s %-16s %s\n", @output );
!     }
!   }
  }
  
  
! #
! #  Cmp Usbdev's
! #
! sub cmp_usbdev {
!   my ($a,$b) = @_;
!   if( defined $a->{SerialDevNum} ) {
!     if( defined $b->{SerialDevNum} ) {
!       return $a->{SerialDevNum} <=> $b->{SerialDevNum};
!     }
!     return -1;
!   }
!   return 1 if defined $b->{SerialDevNum};
!   return ($a->{InfoSerial}||"") cmp ($b->{InfoSerial}||"");
  }
  
! #
! #  Read a file in
! #
! sub snarf {
!   open my $fh, $_[0] or return undef;
!   my $text = do{local $/;<$fh>};
!   close $fh;
!   $text =~ s/\s+$// if $_[1];
!   return $text;
  }
  

--- motelist-linux-2.6 DELETED ---

--- motelist-linux2 DELETED ---



More information about the Tinyos-commits mailing list