It's a bit messy though, I had to patch usb_modeswitch so I could set which interface to use, since the default (0) didn't work (i had to use 5).
My patch is pretty simple, it adds a parameter "interface" (or "-i"), but since this was the only interface available on the card it should be possible to detect the interface and then use it... Future thing I guess, when the need arrives.
Command line:
usb_modeswitch -v 0x1410 -p 0x5020 -m 1 -M 5553424312345678000000000000061b000000020000000000000000000000 -i 5
Patch for usb_modeswitch:
Code: Select all
Index: usb_modeswitch.c
===================================================================
--- usb_modeswitch.c (.../trunk/NAS-GPL/AP/usb_modeswitch-0.9.4/usb_modeswitch.c) (revision 149)
+++ usb_modeswitch.c (.../1.3/NAS-GPL/AP/usb_modeswitch-0.9.4/usb_modeswitch.c) (working copy)
@@ -66,8 +66,10 @@
int DefaultVendor=0, DefaultProduct=0, TargetVendor=0, TargetProduct=0, TargetClass=0;
int MessageEndpoint=0, ResponseEndpoint=0;
-char DetachStorageOnly=0, NeedResponse=0, HuaweiMode=0, verbose=0, show_progress=1;
+char DetachStorageOnly=0, NeedResponse=0, HuaweiMode=0, verbose=0, show_progress=1, ResetUSB=0;
char MessageContent[LINE_DIM];
+//Settable interface and config (for debugging mostly) (jmw)
+int interface = 0, configuration = -1, altsetting = -1;
static struct option long_options[] =
{
@@ -83,9 +85,13 @@
{"DetachStorageOnly", required_argument, 0, 'd'},
{"HuaweiMode", required_argument, 0, 'H'},
{"NeedResponse", required_argument, 0, 'n'},
+ {"ResetUSB", required_argument, 0, 'R'},
{"config", required_argument, 0, 'c'},
{"verbose", no_argument, 0, 'W'},
{"quiet", no_argument, 0, 'Q'},
+ {"interface", required_argument, 0, 'i'},
+ {"configuration", required_argument, 0, 'u'},
+ {"altsetting", required_argument, 0, 'a'},
{0, 0, 0, 0}
};
@@ -102,6 +108,7 @@
ParseParamString(configFilename, MessageContent);
ParseParamHex(configFilename, NeedResponse);
ParseParamHex(configFilename, ResponseEndpoint);
+ ParseParamHex(configFilename, ResetUSB);
}
void printConfig()
@@ -127,7 +134,7 @@
while (1)
{
- c = getopt_long (argc, argv, "hWQv:p:V:P:C:m:M:r:d:H:n:c:",
+ c = getopt_long (argc, argv, "hWQv:p:V:P:C:m:M:r:d:H:n:c:R:i:u:a:",
long_options, &option_index);
/* Detect the end of the options. */
@@ -136,11 +143,12 @@
count++;
switch (c)
{
+ case 'R': ResetUSB = strtol(optarg, NULL, 16); break;
case 'v': DefaultVendor = strtol(optarg, NULL, 16); break;
case 'p': DefaultProduct = strtol(optarg, NULL, 16); break;
case 'V': TargetVendor = strtol(optarg, NULL, 16); break;
case 'P': TargetProduct = strtol(optarg, NULL, 16); break;
- case 'C': TargetClass = strtol(optarg, NULL, 16); break;
+ case 'C': TargetClass = strtol(optarg, NULL, 16); break;
case 'm': MessageEndpoint = strtol(optarg, NULL, 16); break;
case 'M': strcpy(MessageContent, optarg); break;
case 'r': ResponseEndpoint = strtol(optarg, NULL, 16); break;
@@ -150,6 +158,10 @@
case 'c': readConfigFile(optarg); break;
case 'W': verbose=1; count--; break;
case 'Q': show_progress=0; count--; break;
+
+ case 'i': interface = strtol(optarg, NULL, 16); break;
+ case 'u': configuration = strtol(optarg, NULL, 16); break;
+ case 'a': altsetting = strtol(optarg, NULL, 16); break;
case 'h':
printf ("Usage: usb_modeswitch [-hvpVPmMrdHn] [-c config-file]\n\n");
@@ -168,6 +180,9 @@
printf (" -c, --config [config-file] load named config file\n");
printf (" -Q, --quiet don't show progress or error messages\n");
printf (" -W, --verbose print all settings before running\n\n");
+ printf (" -i, --interface select usb interface to use (default 0)\n\n");
+ printf (" -u, --configuration select usb configuration\n\n");
+ printf (" -a, --altsetting selects alternative usb interface setting\n\n");
exit(0);
break;
@@ -182,7 +197,7 @@
int main(int argc, char **argv) {
- int ret, message_length, devclass;
+ int ret, message_length;
int numTargets = 0;
int numDefaults = 0;
char buf[65535];
@@ -190,11 +205,12 @@
struct usb_device *dev;
char ByteString[LINE_DIM/2];
+
printf("\n * usb_modeswitch: tool for controlling \"flip flop\" mode USB devices\n");
printf(" * Version 0.9.4 (C) Josua Dietze 2008\n");
printf(" * Works with libusb 0.1.12 and probably other versions\n\n");
- // Check command arguments, use them instead of config file if possible
+ // Check command arguments, use them instead of config file altsettingif possible
switch (readArguments(argc, argv)) {
case 1:
if (!verbose && show_progress)
@@ -211,6 +227,7 @@
if(verbose) printConfig();
usb_init();
+ if (verbose) usb_set_debug(15);
usb_find_busses();
usb_find_devices();
@@ -259,12 +276,12 @@
#ifdef LIBUSB_HAS_GET_DRIVER_NP
if ( !HuaweiMode ) {
if (show_progress) printf("Looking for active default driver to detach it\n");
- ret = usb_get_driver_np(devh, 0, buf, sizeof(buf));
+ ret = usb_get_driver_np(devh, interface, buf, sizeof(buf));
if (ret == 0) {
if (show_progress) printf(" OK, driver found (\"%s\")\n", buf);
if ( (DetachStorageOnly && !strcmp(buf,"usb-storage")) || !DetachStorageOnly ) {
#ifdef LIBUSB_HAS_DETACH_KERNEL_DRIVER_NP
- ret = usb_detach_kernel_driver_np(devh, 0);
+ ret = usb_detach_kernel_driver_np(devh, interface);
if (ret == 0) {
if (show_progress) printf(" OK, Driver \"%s\" successfully detached\n", buf);
} else {
@@ -295,17 +312,25 @@
if (!DetachStorageOnly && !HuaweiMode ) {
if (show_progress) printf("Setting up communication with device\n");
- ret = usb_claim_interface(devh, 0);
+
+ if (configuration != -1) {
+ ret = usb_set_configuration(devh, configuration);
+ printf("Set configuration %i return: %i (%x)\n", configuration, ret, ret);
+ }
+ ret = usb_claim_interface(devh, interface);
if (ret != 0) {
if (show_progress) fprintf(stderr, "Error: could not claim interface (error %d). Can't communicate. Aborting\n\n", ret);
exit(1);
}
+ if (altsetting != -1) {
+ usb_set_altinterface(devh, altsetting);
+ }
ret = usb_clear_halt(devh, MessageEndpoint);
/* If you still have problems try with the following line uncommented */
// ret = usb_clear_halt(devh, ResponseEndpoint);
- ret = usb_set_altinterface(devh, 0);
+ ret = usb_set_altinterface(devh, interface);
if (ret != 0) {
if (show_progress) fprintf(stderr, "Error: could not set alt interface (error %d). Aborting\n\n", ret);
exit(1);
@@ -323,7 +348,7 @@
message_length = strlen(MessageContent) / 2;
if (!message_length) {
- if (show_progress) fprintf(stderr, "Error: no MessageContent given. Can't send message. Aborting\n\n", MessageContent);
+ if (show_progress) fprintf(stderr, "Error: no MessageContent given. Can't send message. Aborting\n\n");
exit(1);
}
@@ -350,7 +375,21 @@
/* or one of these: */
- usb_reset(devh); /* ignore following error messages */
+ if ( ResetUSB ) {
+ printf("Resetting usb device");
+ int success;
+ int bpoint;
+ bpoint = 0;
+ do
+ {
+ printf(".");
+ success = usb_reset(devh);
+ bpoint++;
+ if (bpoint>100) {
+ success = 1;
+ }
+ } while (success<0);
+ }
// usb_resetep(devh, MessageEndpoint); /* marked as deprecated in libusb docs */
}
@@ -367,7 +406,7 @@
if (show_progress) printf("-> See /proc/bus/usb/devices (or call lsusb) for changes. Bye\n\n");
if (!DetachStorageOnly && !HuaweiMode) {
- ret = usb_release_interface(devh, 0);
+ ret = usb_release_interface(devh, interface);
if (ret != 0)
if (show_progress) fprintf(stderr, "Error: releasing interface failed (error %d). Trying to continue\n", ret);
}
@@ -406,7 +445,7 @@
void release_usb_device(int dummy) {
int ret;
if (show_progress) printf("Program cancelled by system. Bye\n\n");
- ret = usb_release_interface(devh, 0);
+ ret = usb_release_interface(devh, interface);
if (!ret)
if (show_progress) fprintf(stderr, "Error: failed to release interface: %d\n", ret);
usb_close(devh);