Activation Codes and Methods, Hardware Details, Sniffing
Post Reply
joke_dst
Posts: 19
Joined: 04 Mar 2008, 12:21

Novatel MC990D

Post by joke_dst » 16 Oct 2008, 15:21

Ok, I've tried out the Novatel MC990D and managed to make it switch.

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);

Josh
Site Admin
Posts: 6593
Joined: 03 Nov 2007, 00:30

Post by Josh » 18 Oct 2008, 00:38

Sure thing. I'll play around to make the program look for the first available interface as a default and optionally set it on the command line. Cool. Could come handy at times.

karmak
Posts: 1
Joined: 21 May 2010, 00:48

Post by karmak » 21 May 2010, 00:55

Configuration for Novatel Ovation MC990D is now in /etc/usb_modeswitch.d/1410:5020

Code: Select all

# cat /etc/usb_modeswitch.d/1410\:5020 
########################################################
# Novatel MC990D

DefaultVendor= 0x1410
DefaultProduct=0x5020

TargetClass=0xff

CheckSuccess=20

Interface=      5
MessageContent="5553424312345678000000000000061b000000020000000000000000000000"

but it doesn't switch automatically on Ubuntu 10.04 with usb-modeswitch 1.1.0 from repositories. I thought the problem was caused by gnome trying to mount the virtual CD (who came up with that?), turning automount off didn't help though.

How to make it switch automatically?

Josh
Site Admin
Posts: 6593
Joined: 03 Nov 2007, 00:30

Post by Josh » 22 May 2010, 13:35

There may be a deadlock between wrapper and configuration ...

Could you try the following?
Edit the rules file /lib/udev/rules.d/40-usb_modeswitch.rules

Change line 7 to this:

Code: Select all

ATTRS{bInterfaceNumber}!="0[05]", GOTO="modeswitch_rules_end"
Then edit /lib/udev/usb_modeswitch and change line 58:

Code: Select all

if {![string match {*[05]} $device]} {
To confirm that the rules line works switch on logging in /etc/usb_modeswitch.conf


Post Reply