Script to translate cryptic USB device reporting into human-relatable description

Trying to analyze this other reported issue prompted me to experiment and create this little ad-hoc tool, just for the hell of it! It makes use of the usb-devices command.

What better way to spend your retirement! :slight_smile:

Entering the command

Devices__ReportUsbDetails.sh --idVendor 046d --idProduct c077

will report as

COMPONENT:  Logitech, USB Optical Mouse
T:  Bus=03 Lev=01 Prnt=01 Port=01 Cnt=01 Dev#=  2 Spd=1.5 MxCh= 0
D:  Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs=  1
P:  Vendor=046d ProdID=c077 Rev=72.00
S:  Manufacturer=Logitech
S:  Product=USB Optical Mouse
C:  #Ifs= 1 Cfg#= 1 Atr=a0 MxPwr=100mA
I:  If#= 0 Alt= 0 #EPs= 1 Cls=03(HID  ) Sub=01 Prot=02 Driver=usbhid
E:  Ad=81(I) Atr=03(Int.) MxPS=   4 Ivl=10ms

As you can see, it gives the full detail reported by the "usb-devices" tool, but it adds the corresponding "COMPONENT" description as the first line for every device reported, for quick recognition.

Devices__ReportUsbDetails.sh :

#!/bin/bash

###	Script to translate "cryptic" USB device reporting into human-relatable description

### Typical log entry when trying to debug
#[ 439.463843] usb 1-1: New USB device found, idVendor=0634, idProduct=5600, bcdDevice= 1.00

idVendor="-1"
idProduct="-1"

while [ $# -gt 0 ]
do
	case "${1}" in
		"--all" ) usb-devices ; exit ;;
		"--idVendor" ) idVendor="${2}" ; shift ; shift ;;
		"--idProduct" ) idProduct="${2}" ; shift ; shift ;;
		"--debug" ) dbg=1 ; shift ;;
		"--test1" )
			### Hardcoded local test case #1 - Single component (USB Mouse)
			idVendor="046d" ;
			idProduct="c077" ;
			shift ;
			;;
		"--test2" )
			### Hardcoded local test case #2 - Multiple component (USB ports)
			idVendor="1d6b" ;
			idProduct="0001" ;
			shift ;
			;;
	esac
done

if [ "${idVendor}" = "-1" ] || [ "${idProduct}" = "-1" ]
then
	printf "\n\t Script requires reported values for both --idVendor {} and --idProduct {} \n\n" ; exit 1
fi

usb-devices |
awk -v dbg=${dbg} -v idvendor="${idVendor}" -v idproduct="${idProduct}" 'BEGIN{
	captureON=0 ;
	split( "", details) ;
	split( "", size) ;
	split( "", descr) ;
	indx=0 ;
	lastgood=0 ;
	keep=0 ;
}{
	if( NF == 0 ){
		if( keep == 1 ){
			size[indx]=attrib ;	### save number of attribute lines
			if( dbg == 1 ){
				printf("\n\t attrib = %d\n", attrib ) | "cat 1>&2" ;
			} ;
			lastgood=indx ;
		}else{
			indx=lastgood ;		### reset index to discard any details captured for last item
		} ;
		keep=0 ;
		captureON=0 ;
	} ;

	if( index( $0, "T:" ) == 1 ){		### First line of every BUS item
		captureON=1 ;
		indx++ ;
		if( dbg == 1 ){
			printf("\n\t indx = %d\n", indx ) | "cat 1>&2" ;
		} ;
		attrib=0 ;
		size[indx]=0 ;
	};

	if( captureON == 1 ){
		attrib++ ;
		if( dbg == 1 ){
			printf("\t\t attrib = %d\n", attrib ) | "cat 1>&2" ;
		} ;
		details[indx,attrib]=$0 ;		### capture raw line for reporting

		#P:  Vendor=046d ProdID=c077 Rev=72.00
		if( index( $0, "P:" ) == 1 ){
			split( $2, vend, "=" ) ;
			vendor=vend[2] ;
			split( $3, prod, "=" ) ;
			product=prod[2] ;

			if( dbg == 1 ){
				printf("\t\t  vendor = %s      idvendor = %s \n", vendor, idvendor ) | "cat 1>&2" ;
				printf("\t\t product = %s     idproduct = %s \n", product, idproduct ) | "cat 1>&2" ;
			} ;

			if( vendor == idvendor && product == idproduct ){
				keep=1 ;
			} ;
		} ;

		#S:  Manufacturer=Logitech
		if( $2 ~ /Manufacturer/ ){
			split( $0, mfg, "=" ) ;
			manufacturer=mfg[2] ;
			descr[indx]=sprintf("COMPONENT:  %s", manufacturer ) ;
		} ;

		#S:  Product=USB Optical Mouse
		if( $2 ~ /Product/ ){
			split( $0, prod, "=" ) ;
			product=prod[2] ;
			descr[indx]=sprintf("%s, %s", descr[indx], product ) ;
		} ;
	} ;
}END{
	if( keep == 0 ){
		indx-- ;
	} ;
	for( i=1 ; i <= indx ; i++ ){
		if( size[i] > 0 ){
			if( indx > 1 ){
				printf("\n==========================================================================\n" ) ;
			} ;
			print descr[i] ;
			for( j=1 ; j <= size[i] ; j++ ){
				print details[i,j] ;
			} ;
		} ;
	} ;
}'


exit