summaryrefslogtreecommitdiff
path: root/scripts/setconfig.pl
blob: 0421f9cc22f79fce58385e667a8d680cbe4d0eb2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#!/usr/bin/perl
# Copyright 2012 Bjørn Mork <bjorn@mork.no>
# License: GPLv2

use strict;
use warnings;
use Getopt::Long;
use Device::USB;
use Data::Dumper;

# defaults
my %opt = (
    'debug' => 0, 
    'cfg' => 1,
);

GetOptions(\%opt,
	   'device=s',
	   'debug|d+',
	   'cfg=i',
	   'help|h|?',
    );

&usage if ($opt{'help'} || !$opt{'device'});

my $usb = Device::USB->new();
$usb->debug_mode($opt{'debug'});

my ($vid, $pid) = map { hex } split(/:/, $opt{'device'});

my $dev = $usb->find_device($vid, $pid);
die "Cannot find any such device: $opt{'device'} - $!\n" unless $dev;

warn "Device: ", sprintf("%04x:%04x", $dev->idVendor(), $dev->idProduct()), "\n";

$dev->open();

# unbind all drivers
foreach my $cfg (@{$dev->config()}) {
foreach (@{$cfg->interfaces()}) {
    my $ifnum = $_->[0]->bInterfaceNumber;
    
    my $driver = $dev->get_driver_np($ifnum);
    if ($driver) {
	warn "unbinding interface $ifnum from kernel driver \"$driver\"\n";
	if ($dev->detach_kernel_driver_np($ifnum) < 0) {
	    warn "unbinding FAILED\n";
	    return undef;
	}
    }
}
}
my $ret = $dev->set_configuration($opt{cfg});

#my ($ret, $descr) = &set_config($dev, $opt{cfg});
warn "ret=$ret\n";

sub set_config {
    my ($dev, $cfg) = @_;
    my $reqtype = 0x00;   # USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE
    my $req = 0x09;       # USB_REQ_SET_CONFIGURATION
    my $wValue = 0x0;
    
    return (-1, undef) unless defined($cfg);

    my $buf = 0 x 512; # pre-allocate buffer - libusb is not perl!
    my $ret = $dev->control_msg($reqtype,
				$req,
				$cfg, # bConfigurationValue
				0, # wIndex
				$buf,
				0, # wLength
				1000);  # timeout in ms

    printf "usb_control_msg(0x%02x, 0x%02x, 0x%02x, 0x%04x, 0x%04x) returned $ret\n", $reqtype, $req, $cfg, 0, 0;
    return ($ret, $buf);
}


sub usage {
    warn <<EOT
      Usage:
	$0 [--debug] --device=<idVendor:idProduct> --cfg=<num>

      Options:
	--debug
	    debug output
	--device
	    USB device ID to test - required
        --cfg
            new configuration value

      Example:
	$0 --device=1199:68a2 --cfg=2

EOT
;
    exit 0;
}