~ubuntu-branches/ubuntu/utopic/usb-modeswitch/utopic

« back to all changes in this revision

Viewing changes to usb_modeswitch.c

  • Committer: Package Import Robot
  • Author(s): Mathieu Trudel-Lapierre
  • Date: 2014-04-07 11:39:41 UTC
  • mfrom: (17.1.11 sid)
  • Revision ID: package-import@ubuntu.com-20140407113941-b4dwfneyd07pgijf
Tags: 2.1.1+repack0-1ubuntu1
* Merge with Debian unstable; remaining changes: (LP: #1280546)
  - patch to rewrite dispatcher to C.
  - debian/patches/redirect_dispatcher_output.patch: redirect all dispatcher
    output when called from udev to /dev/null.
  - Replace libjim depends with libpipeline-dev, libudev-dev.
* Fixed some bugs in dispatcher rewrite. (LP: #1155975)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
  Mode switching tool for controlling flip flop (multiple device) USB gear
3
 
  Version 1.2.3, 2012/01/28
 
2
  Mode switching tool for controlling mode of 'multi-state' USB devices
 
3
  Version 2.1.1, 2014/03/27
4
4
 
5
 
  Copyright (C) 2007 - 2012 Josua Dietze (mail to "usb_admin" at the domain
 
5
  Copyright (C) 2007 - 2014 Josua Dietze (mail to "usb_admin" at the domain
6
6
  of the home page; or write a personal message through the forum to "Josh".
7
7
  NO SUPPORT VIA E-MAIL - please use the forum for that)
8
8
 
45
45
 
46
46
/* Recommended tab size: 4 */
47
47
 
48
 
#define VERSION "1.2.3"
 
48
#define VERSION "2.1.1"
49
49
 
50
50
#include <stdio.h>
51
51
#include <stdlib.h>
54
54
#include <ctype.h>
55
55
#include <getopt.h>
56
56
#include <syslog.h>
 
57
#include <unistd.h>
57
58
 
58
 
#include <usb.h>
59
59
#include "usb_modeswitch.h"
60
60
 
 
61
 
 
62
/* libusb 1.0 wrappers, lazy leftover */
 
63
 
 
64
int usb_bulk_io(struct libusb_device_handle *handle, int ep, char *bytes,
 
65
        int size, int timeout)
 
66
{
 
67
        int actual_length;
 
68
        int r;
 
69
//      usbi_dbg("endpoint %x size %d timeout %d", ep, size, timeout);
 
70
        r = libusb_bulk_transfer(handle, ep & 0xff, (unsigned char *)bytes, size,
 
71
                &actual_length, timeout);
 
72
        
 
73
        /* if we timed out but did transfer some data, report as successful short
 
74
         * read. FIXME: is this how libusb-0.1 works? */
 
75
        if (r == 0 || (r == LIBUSB_ERROR_TIMEOUT && actual_length > 0))
 
76
                return actual_length;
 
77
 
 
78
        return r;
 
79
}
 
80
 
 
81
static int usb_interrupt_io(libusb_device_handle *handle, int ep, char *bytes,
 
82
        int size, int timeout)
 
83
{
 
84
        int actual_length;
 
85
        int r;
 
86
//      usbi_dbg("endpoint %x size %d timeout %d", ep, size, timeout);
 
87
        r = libusb_interrupt_transfer(handle, ep & 0xff, (unsigned char *)bytes, size,
 
88
                &actual_length, timeout);
 
89
        
 
90
        /* if we timed out but did transfer some data, report as successful short
 
91
         * read. FIXME: is this how libusb-0.1 works? */
 
92
        if (r == 0 || (r == LIBUSB_ERROR_TIMEOUT && actual_length > 0))
 
93
                return actual_length;
 
94
 
 
95
        return (r);
 
96
}
 
97
 
 
98
 
61
99
#define LINE_DIM 1024
62
100
#define MAXLINES 50
63
101
#define BUF_SIZE 4096
73
111
 
74
112
char *TempPP=NULL;
75
113
 
76
 
struct usb_device *dev;
77
 
struct usb_dev_handle *devh;
 
114
static struct libusb_context *ctx = NULL;
 
115
static struct libusb_device *dev;
 
116
static struct libusb_device_handle *devh;
 
117
static struct libusb_config_descriptor *active_config = NULL;
78
118
 
79
119
int DefaultVendor=0, DefaultProduct=0, TargetVendor=0, TargetProduct=-1, TargetClass=0;
80
120
int MessageEndpoint=0, ResponseEndpoint=0, ReleaseDelay=0;
82
122
int devnum=-1, busnum=-1;
83
123
int ret;
84
124
 
85
 
char DetachStorageOnly=0, HuaweiMode=0, SierraMode=0, SonyMode=0, GCTMode=0, KobilMode=0;
86
 
char SequansMode=0, MobileActionMode=0, CiscoMode=0, QisdaMode=0;
 
125
unsigned int ModeMap = 0;
 
126
#define DETACHONLY_MODE         0x00000001
 
127
#define HUAWEI_MODE                     0x00000002
 
128
#define SIERRA_MODE                     0x00000004
 
129
#define SONY_MODE                       0x00000008
 
130
#define GCT_MODE                        0x00000010
 
131
#define KOBIL_MODE                      0x00000020
 
132
#define SEQUANS_MODE            0x00000040
 
133
#define MOBILEACTION_MODE       0x00000080
 
134
#define CISCO_MODE                      0x00000100
 
135
#define QISDA_MODE                      0x00000200
 
136
#define QUANTA_MODE                     0x00000400
 
137
#define BLACKBERRY_MODE         0x00000800
 
138
#define PANTECH_MODE            0x00001000
 
139
 
87
140
char verbose=0, show_progress=1, ResetUSB=0, CheckSuccess=0, config_read=0;
88
 
char NeedResponse=0, NoDriverLoading=0, InquireDevice=1, sysmode=0;
 
141
char NeedResponse=0, NoDriverLoading=0, InquireDevice=0, sysmode=0, mbim=0;
 
142
char StandardEject=0;
89
143
 
90
144
char imanufact[DESCR_MAX], iproduct[DESCR_MAX], iserial[DESCR_MAX];
91
145
 
93
147
char MessageContent2[LINE_DIM];
94
148
char MessageContent3[LINE_DIM];
95
149
char TargetProductList[LINE_DIM];
 
150
char DefaultProductList[5];
96
151
char ByteString[LINE_DIM/2];
97
152
char buffer[BUF_SIZE];
98
153
 
124
179
        {"sierra-mode",                 no_argument, 0, 'S'},
125
180
        {"sony-mode",                   no_argument, 0, 'O'},
126
181
        {"qisda-mode",                  no_argument, 0, 'B'},
 
182
        {"quanta-mode",                 no_argument, 0, 'E'},
127
183
        {"kobil-mode",                  no_argument, 0, 'T'},
128
184
        {"gct-mode",                    no_argument, 0, 'G'},
129
185
        {"sequans-mode",                no_argument, 0, 'N'},
130
186
        {"mobileaction-mode",   no_argument, 0, 'A'},
131
187
        {"cisco-mode",          no_argument, 0, 'L'},
 
188
        {"blackberry-mode",             no_argument, 0, 'Z'},
 
189
        {"pantech-mode",                no_argument, 0, 'F'},
 
190
        {"std-eject",                   no_argument, 0, 'K'},
132
191
        {"need-response",               no_argument, 0, 'n'},
133
192
        {"reset-usb",                   no_argument, 0, 'R'},
134
193
        {"config-file",                 required_argument, 0, 'c'},
135
194
        {"verbose",                             no_argument, 0, 'W'},
136
195
        {"quiet",                               no_argument, 0, 'Q'},
137
196
        {"sysmode",                             no_argument, 0, 'D'},
138
 
        {"no-inquire",                  no_argument, 0, 'I'},
 
197
        {"inquire",                             no_argument, 0, 'I'},
139
198
        {"stdinput",                    no_argument, 0, 't'},
 
199
        {"find-mbim",                   no_argument, 0, 'j'},
140
200
        {"long-config",                 required_argument, 0, 'f'},
141
201
        {"check-success",               required_argument, 0, 's'},
142
202
        {"interface",                   required_argument, 0, 'i'},
154
214
        ParseParamHex(configFilename, TargetClass);
155
215
        ParseParamHex(configFilename, DefaultVendor);
156
216
        ParseParamHex(configFilename, DefaultProduct);
157
 
        ParseParamBool(configFilename, DetachStorageOnly);
158
 
        ParseParamBool(configFilename, HuaweiMode);
159
 
        ParseParamBool(configFilename, SierraMode);
160
 
        ParseParamBool(configFilename, SonyMode);
161
 
        ParseParamBool(configFilename, QisdaMode);
162
 
        ParseParamBool(configFilename, GCTMode);
163
 
        ParseParamBool(configFilename, KobilMode);
164
 
        ParseParamBool(configFilename, SequansMode);
165
 
        ParseParamBool(configFilename, MobileActionMode);
166
 
        ParseParamBool(configFilename, CiscoMode);
 
217
        ParseParamBoolMap(configFilename, DetachStorageOnly, ModeMap, DETACHONLY_MODE);
 
218
        ParseParamBoolMap(configFilename, HuaweiMode, ModeMap, HUAWEI_MODE);
 
219
        ParseParamBoolMap(configFilename, SierraMode, ModeMap, SIERRA_MODE);
 
220
        ParseParamBoolMap(configFilename, SonyMode, ModeMap, SONY_MODE);
 
221
        ParseParamBoolMap(configFilename, GCTMode, ModeMap, GCT_MODE);
 
222
        ParseParamBoolMap(configFilename, KobilMode, ModeMap, KOBIL_MODE);
 
223
        ParseParamBoolMap(configFilename, SequansMode, ModeMap, SEQUANS_MODE);
 
224
        ParseParamBoolMap(configFilename, MobileActionMode, ModeMap, MOBILEACTION_MODE);
 
225
        ParseParamBoolMap(configFilename, CiscoMode, ModeMap, CISCO_MODE);
 
226
        ParseParamBoolMap(configFilename, QisdaMode, ModeMap, QISDA_MODE);
 
227
        ParseParamBoolMap(configFilename, QuantaMode, ModeMap, QUANTA_MODE);
 
228
        ParseParamBoolMap(configFilename, BlackberryMode, ModeMap, BLACKBERRY_MODE);
 
229
        ParseParamBoolMap(configFilename, PantechMode, ModeMap, PANTECH_MODE);
 
230
        ParseParamBool(configFilename, StandardEject);
167
231
        ParseParamBool(configFilename, NoDriverLoading);
168
232
        ParseParamHex(configFilename, MessageEndpoint);
169
233
        ParseParamString(configFilename, MessageContent);
192
256
void printConfig()
193
257
{
194
258
        if ( DefaultVendor )
195
 
                printf ("DefaultVendor=  0x%04x\n",                     DefaultVendor);
196
 
        else
197
 
                fprintf (output,"DefaultVendor=  not set\n");
 
259
                fprintf (output,"DefaultVendor=  0x%04x\n",                     DefaultVendor);
198
260
        if ( DefaultProduct )
199
261
                fprintf (output,"DefaultProduct= 0x%04x\n",                     DefaultProduct);
200
 
        else
201
 
                fprintf (output,"DefaultProduct= not set\n");
202
262
        if ( TargetVendor )
203
263
                fprintf (output,"TargetVendor=   0x%04x\n",             TargetVendor);
204
 
        else
205
 
                fprintf (output,"TargetVendor=   not set\n");
206
264
        if ( TargetProduct > -1 )
207
265
                fprintf (output,"TargetProduct=  0x%04x\n",             TargetProduct);
208
 
        else
209
 
                fprintf (output,"TargetProduct=  not set\n");
210
266
        if ( TargetClass )
211
267
                fprintf (output,"TargetClass=    0x%02x\n",             TargetClass);
212
 
        else
213
 
                fprintf (output,"TargetClass=    not set\n");
214
 
        fprintf (output,"TargetProductList=\"%s\"\n",           TargetProductList);
215
 
        fprintf (output,"\nDetachStorageOnly=%i\n",     (int)DetachStorageOnly);
216
 
        fprintf (output,"HuaweiMode=%i\n",                      (int)HuaweiMode);
217
 
        fprintf (output,"SierraMode=%i\n",                      (int)SierraMode);
218
 
        fprintf (output,"SonyMode=%i\n",                        (int)SonyMode);
219
 
        fprintf (output,"QisdaMode=%i\n",               (int)QisdaMode);
220
 
        fprintf (output,"GCTMode=%i\n",                 (int)GCTMode);
221
 
        fprintf (output,"KobilMode=%i\n",               (int)KobilMode);
222
 
        fprintf (output,"SequansMode=%i\n",             (int)SequansMode);
223
 
        fprintf (output,"MobileActionMode=%i\n",        (int)MobileActionMode);
224
 
        fprintf (output,"CiscoMode=%i\n",                       (int)CiscoMode);
 
268
        if ( strlen(TargetProductList) )
 
269
                fprintf (output,"TargetProductList=\"%s\"\n",           TargetProductList);
 
270
        if (StandardEject)
 
271
                fprintf (output,"\nStandardEject=1\n");
 
272
        if (ModeMap & DETACHONLY_MODE)
 
273
                fprintf (output,"\nDetachStorageOnly=1\n");
 
274
        if (ModeMap & HUAWEI_MODE)
 
275
                fprintf (output,"HuaweiMode=1\n");
 
276
        if (ModeMap & SIERRA_MODE)
 
277
                fprintf (output,"SierraMode=1\n");
 
278
        if (ModeMap & SONY_MODE)
 
279
                fprintf (output,"SonyMode=1\n");
 
280
        if (ModeMap & QISDA_MODE)
 
281
                fprintf (output,"QisdaMode=1\n");
 
282
        if (ModeMap & QUANTA_MODE)
 
283
                fprintf (output,"QuantaMode=1\n");
 
284
        if (ModeMap & GCT_MODE)
 
285
                fprintf (output,"GCTMode=1\n");
 
286
        if (ModeMap & KOBIL_MODE)
 
287
                fprintf (output,"KobilMode=1\n");
 
288
        if (ModeMap & SEQUANS_MODE)
 
289
                fprintf (output,"SequansMode=1\n");
 
290
        if (ModeMap & MOBILEACTION_MODE)
 
291
                fprintf (output,"MobileActionMode=1\n");
 
292
        if (ModeMap & CISCO_MODE)
 
293
                fprintf (output,"CiscoMode=1\n");
 
294
        if (ModeMap & BLACKBERRY_MODE)
 
295
                fprintf (output,"BlackberryMode=1\n");
 
296
        if (ModeMap & PANTECH_MODE)
 
297
                fprintf (output,"PantechMode=1\n");
225
298
        if ( MessageEndpoint )
226
299
                fprintf (output,"MessageEndpoint=0x%02x\n",     MessageEndpoint);
227
 
        else
228
 
                fprintf (output,"MessageEndpoint=  not set\n");
229
 
        fprintf (output,"MessageContent=\"%s\"\n",      MessageContent);
 
300
        if ( strlen(MessageContent) )
 
301
                fprintf (output,"MessageContent=\"%s\"\n",      MessageContent);
230
302
        if ( strlen(MessageContent2) )
231
303
                fprintf (output,"MessageContent2=\"%s\"\n",     MessageContent2);
232
304
        if ( strlen(MessageContent3) )
234
306
        fprintf (output,"NeedResponse=%i\n",            (int)NeedResponse);
235
307
        if ( ResponseEndpoint )
236
308
                fprintf (output,"ResponseEndpoint=0x%02x\n",    ResponseEndpoint);
237
 
        else
238
 
                fprintf (output,"ResponseEndpoint= not set\n");
239
309
        if ( Interface > -1 )
240
310
                fprintf (output,"Interface=0x%02x\n",                   Interface);
241
311
        if ( Configuration > 0 )
243
313
        if ( AltSetting > -1 )
244
314
                fprintf (output,"AltSetting=0x%02x\n",  AltSetting);
245
315
        if ( InquireDevice )
246
 
                fprintf (output,"\nInquireDevice enabled (default)\n");
247
 
        else
248
 
                fprintf (output,"\nInquireDevice disabled\n");
 
316
                fprintf (output,"\nInquireDevice=1\n");
249
317
        if ( CheckSuccess )
250
318
                fprintf (output,"Success check enabled, max. wait time %d seconds\n", CheckSuccess);
251
 
        else
252
 
                fprintf (output,"Success check disabled\n");
253
319
        if ( sysmode )
254
320
                fprintf (output,"System integration mode enabled\n");
255
 
        else
256
 
                fprintf (output,"System integration mode disabled\n");
257
 
        fprintf (output,"\n");
258
321
}
259
322
 
260
323
 
271
334
 
272
335
        while (1)
273
336
        {
274
 
                c = getopt_long (argc, argv, "heWQDndHSOBGTNALRItv:p:V:P:C:m:M:2:3:w:r:c:i:u:a:s:f:b:g:",
 
337
                c = getopt_long (argc, argv, "hejWQDndKHSOBEGTNALZFRItv:p:V:P:C:m:M:2:3:w:r:c:i:u:a:s:f:b:g:",
275
338
                                                long_options, &option_index);
276
339
 
277
340
                /* Detect the end of the options. */
293
356
                        case 'w': ReleaseDelay = strtol(optarg, NULL, 10); break;
294
357
                        case 'n': NeedResponse = 1; break;
295
358
                        case 'r': ResponseEndpoint = strtol(optarg, NULL, 16); break;
296
 
                        case 'd': DetachStorageOnly = 1; break;
297
 
                        case 'H': HuaweiMode = 1; break;
298
 
                        case 'S': SierraMode = 1; break;
299
 
                        case 'O': SonyMode = 1; break;
300
 
                        case 'B': QisdaMode = 1; break;
301
 
                        case 'G': GCTMode = 1; break;
302
 
                        case 'T': KobilMode = 1; break;
303
 
                        case 'N': SequansMode = 1; break;
304
 
                        case 'A': MobileActionMode = 1; break;
305
 
                        case 'L': CiscoMode = 1; break;
 
359
                        case 'K': StandardEject = 1; break;
 
360
                        case 'd': ModeMap = ModeMap + DETACHONLY_MODE; break;
 
361
                        case 'H': ModeMap = ModeMap + HUAWEI_MODE; break;
 
362
                        case 'S': ModeMap = ModeMap + SIERRA_MODE; break;
 
363
                        case 'O': ModeMap = ModeMap + SONY_MODE; break;; break;
 
364
                        case 'B': ModeMap = ModeMap + QISDA_MODE; break;
 
365
                        case 'E': ModeMap = ModeMap + QUANTA_MODE; break;
 
366
                        case 'G': ModeMap = ModeMap + GCT_MODE; break;
 
367
                        case 'T': ModeMap = ModeMap + KOBIL_MODE; break;
 
368
                        case 'N': ModeMap = ModeMap + SEQUANS_MODE; break;
 
369
                        case 'A': ModeMap = ModeMap + MOBILEACTION_MODE; break;
 
370
                        case 'L': ModeMap = ModeMap + CISCO_MODE; break;
 
371
                        case 'Z': ModeMap = ModeMap + BLACKBERRY_MODE; break;
 
372
                        case 'F': ModeMap = ModeMap + PANTECH_MODE; break;
306
373
                        case 'c': readConfigFile(optarg); break;
307
374
                        case 't': readConfigFile("stdin"); break;
308
375
                        case 'W': verbose = 1; show_progress = 1; count--; break;
309
376
                        case 'Q': show_progress = 0; verbose = 0; count--; break;
310
377
                        case 'D': sysmode = 1; count--; break;
311
378
                        case 's': CheckSuccess = strtol(optarg, NULL, 10); count--; break;
312
 
                        case 'I': InquireDevice = 0; break;
 
379
                        case 'I': InquireDevice = 1; break;
313
380
                        case 'b': busnum = strtol(optarg, NULL, 10); break;
314
381
                        case 'g': devnum = strtol(optarg, NULL, 10); break;
315
382
 
316
383
                        case 'i': Interface = strtol(optarg, NULL, 16); break;
317
384
                        case 'u': Configuration = strtol(optarg, NULL, 16); break;
318
385
                        case 'a': AltSetting = strtol(optarg, NULL, 16); break;
 
386
                        case 'j': mbim = 1; break;
319
387
 
320
388
                        case 'f':
321
389
                                longConfig = malloc(strlen(optarg)+5);
349
417
 
350
418
int main(int argc, char **argv)
351
419
{
352
 
        int numDefaults=0, specialMode=0, sonySuccess=0;
 
420
        int numDefaults=0, sonySuccess=0;
353
421
        int currentConfig=0, defaultClass=0, interfaceClass=0;
354
 
 
 
422
        struct libusb_device_descriptor descriptor;
355
423
 
356
424
        /* Make sure we have empty strings even if not set by config */
357
425
        TargetProductList[0] = '\0';
358
426
        MessageContent[0] = '\0';
359
427
        MessageContent2[0] = '\0';
360
428
        MessageContent3[0] = '\0';
 
429
        DefaultProductList[0] = '\0';
361
430
 
362
431
        /* Useful for debugging during boot */
363
432
//      output=fopen("/dev/console", "w");
375
444
                        break;
376
445
                default:                                        /* one or more arguments except -W, -q or -s */
377
446
                        if (!config_read)               /* if arguments contain -c, the config file was already processed */
378
 
                                if (verbose) fprintf(output,"Taking all parameters from the command line\n\n");
 
447
                                if (verbose) fprintf(output,"Take all parameters from the command line\n\n");
379
448
        }
380
449
 
381
 
        if (verbose)
 
450
        if (verbose) {
382
451
                printVersion();
383
 
 
384
 
        if (verbose)
385
452
                printConfig();
 
453
                fprintf(output,"\n");
 
454
        }
386
455
 
387
 
        /* Plausibility checks. The default IDs are mandatory */
 
456
        /* Some sanity checks. The default IDs are mandatory */
388
457
        if (!(DefaultVendor && DefaultProduct)) {
389
 
                SHOW_PROGRESS(output,"No default vendor/product ID given. Aborting.\n\n");
 
458
                SHOW_PROGRESS(output,"No default vendor/product ID given. Abort\n\n");
390
459
                exit(1);
391
460
        }
 
461
 
392
462
        if (strlen(MessageContent)) {
393
463
                if (strlen(MessageContent) % 2 != 0) {
394
 
                        fprintf(stderr, "Error: MessageContent hex string has uneven length. Aborting.\n\n");
 
464
                        fprintf(stderr, "Error: MessageContent hex string has uneven length. Abort\n\n");
395
465
                        exit(1);
396
466
                }
397
467
                if ( hexstr2bin(MessageContent, ByteString, strlen(MessageContent)/2) == -1) {
398
 
                        fprintf(stderr, "Error: MessageContent %s\n is not a hex string. Aborting.\n\n", MessageContent);
 
468
                        fprintf(stderr, "Error: MessageContent %s\n is not a hex string. Abort\n\n", MessageContent);
399
469
                        exit(1);
400
470
                }
401
471
        }
402
 
        SHOW_PROGRESS(output,"\n");
403
472
 
404
473
        if (devnum == -1) {
405
474
                searchMode = SEARCH_DEFAULT;
410
479
 
411
480
        if (show_progress)
412
481
                if (CheckSuccess && !(TargetVendor || TargetProduct > -1 || TargetProductList[0] != '\0') && !TargetClass)
413
 
                        printf("Note: target parameter missing; success check limited\n");
 
482
                        fprintf(output,"Note: No target parameter given; success check limited\n");
 
483
 
 
484
        if (TargetProduct > -1 && TargetProductList[0] == '\0') {
 
485
                sprintf(TargetProductList,"%04x",TargetProduct);
 
486
                TargetProduct = -1;
 
487
        }
414
488
 
415
489
        /* libusb initialization */
416
 
        usb_init();
 
490
        libusb_init(&ctx);
417
491
 
418
492
        if (verbose)
419
 
                usb_set_debug(15);
 
493
                libusb_set_debug(ctx, 3);
420
494
 
421
 
        usb_find_busses();
422
 
        usb_find_devices();
 
495
        if (mbim) {
 
496
                printf("%d\n", findMBIMConfig(DefaultVendor, DefaultProduct, searchMode) );
 
497
                exit(0);
 
498
        }
423
499
 
424
500
        /* Count existing target devices, remember for success check */
425
 
        if ((TargetVendor || TargetClass) && searchMode != SEARCH_BUSDEV) {
426
 
                SHOW_PROGRESS(output,"Looking for target devices ...\n");
427
 
                search_devices(&targetDeviceCount, TargetVendor, TargetProduct, TargetProductList, TargetClass, 0, SEARCH_TARGET);
 
501
        if (searchMode != SEARCH_BUSDEV && (TargetVendor || TargetClass)) {
 
502
                SHOW_PROGRESS(output,"Look for target devices ...\n");
 
503
                search_devices(&targetDeviceCount, TargetVendor, TargetProductList, TargetClass, 0, SEARCH_TARGET);
428
504
                if (targetDeviceCount) {
429
505
                        SHOW_PROGRESS(output," Found devices in target mode or class (%d)\n", targetDeviceCount);
430
506
                } else
432
508
        }
433
509
 
434
510
        /* Count default devices, get the last one found */
435
 
        SHOW_PROGRESS(output,"Looking for default devices ...\n");
436
 
        dev = search_devices(&numDefaults, DefaultVendor, DefaultProduct, "\0", TargetClass, Configuration, searchMode);
 
511
        SHOW_PROGRESS(output,"Look for default devices ...\n");
 
512
 
 
513
        sprintf(DefaultProductList,"%04x",DefaultProduct);
 
514
        dev = search_devices(&numDefaults, DefaultVendor, DefaultProductList, TargetClass, Configuration, searchMode);
437
515
        if (numDefaults) {
438
 
                SHOW_PROGRESS(output," Found device in default mode, class or configuration (%d)\n", numDefaults);
 
516
                SHOW_PROGRESS(output," Found devices in default mode (%d)\n", numDefaults);
439
517
        } else {
440
 
                SHOW_PROGRESS(output," No devices in default mode found. Nothing to do. Bye.\n\n");
 
518
                SHOW_PROGRESS(output," No devices in default mode found. Nothing to do. Bye!\n\n");
441
519
                exit(0);
442
520
        }
443
521
        if (dev == NULL) {
444
 
                SHOW_PROGRESS(output," No bus/device match. Is device connected? Bye.\n\n");
 
522
                SHOW_PROGRESS(output," No bus/device match. Is device connected? Abort\n\n");
445
523
                exit(0);
446
524
        } else {
447
525
                if (devnum == -1) {
448
 
                        devnum = dev->devnum;
449
 
                        busnum = (int)strtol(dev->bus->dirname,NULL,10);
450
 
                        SHOW_PROGRESS(output,"Accessing device %03d on bus %03d ...\n", devnum, busnum);
 
526
                        devnum = libusb_get_device_address(dev);
 
527
                        busnum = libusb_get_bus_number(dev);
 
528
                        SHOW_PROGRESS(output,"Access device %03d on bus %03d\n", devnum, busnum);
451
529
                }
452
 
                devh = usb_open(dev);
 
530
                libusb_open(dev, &devh);
453
531
                if (devh == NULL) {
454
 
                        SHOW_PROGRESS(output,"Error opening the device. Aborting.\n\n");
 
532
                        SHOW_PROGRESS(output,"Error opening the device. Abort\n\n");
455
533
                        exit(1);
456
534
                }
457
535
        }
 
536
        libusb_get_active_config_descriptor(dev, &active_config);
458
537
 
459
 
        /* Get current configuration of default device
460
 
         * A configuration value of -1 denotes a quirky device which has
461
 
         * trouble determining the current configuration. Just use the first
462
 
         * branch (which may be incorrect)
463
 
         */
464
 
        if (Configuration > -1)
465
 
                currentConfig = get_current_configuration(devh);
466
 
        else {
467
 
                SHOW_PROGRESS(output,"Skipping the check for the current configuration\n");
 
538
        /* Get current configuration of default device if parameter is set */
 
539
        if (Configuration > -1) {
 
540
                currentConfig = active_config->bConfigurationValue;
 
541
                SHOW_PROGRESS(output,"Current configuration number is %d\n", currentConfig);
 
542
        } else
468
543
                currentConfig = 0;
469
 
        }
 
544
 
 
545
        libusb_get_device_descriptor(dev, &descriptor);
 
546
        defaultClass = descriptor.bDeviceClass;
 
547
        if (Interface == -1)
 
548
                Interface = active_config->interface[0].altsetting[0].bInterfaceNumber;
 
549
        SHOW_PROGRESS(output,"Use interface number %d\n", Interface);
470
550
 
471
551
        /* Get class of default device/interface */
472
 
        defaultClass = dev->descriptor.bDeviceClass;
473
 
        interfaceClass = get_interface0_class(dev, currentConfig);
 
552
        interfaceClass = get_interface_class();
 
553
 
 
554
        /* Check or get endpoints */
 
555
        if (strlen(MessageContent) || StandardEject || InquireDevice || ModeMap & CISCO_MODE) {
 
556
                if (!MessageEndpoint)
 
557
                        MessageEndpoint = find_first_bulk_endpoint(LIBUSB_ENDPOINT_OUT);
 
558
                if (!ResponseEndpoint)
 
559
                        ResponseEndpoint = find_first_bulk_endpoint(LIBUSB_ENDPOINT_IN);
 
560
                libusb_free_config_descriptor(active_config);
 
561
                if (!MessageEndpoint) {
 
562
                        fprintf(stderr,"Error: message endpoint not given or found. Abort\n\n");
 
563
                        exit(1);
 
564
                }
 
565
                if (!ResponseEndpoint) {
 
566
                        fprintf(stderr,"Error: response endpoint not given or found. Abort\n\n");
 
567
                        exit(1);
 
568
                }
 
569
                SHOW_PROGRESS(output,"Use endpoints 0x%02x (out) and 0x%02x (in)\n", MessageEndpoint, ResponseEndpoint);
 
570
        } else
 
571
                libusb_free_config_descriptor(active_config);
 
572
 
474
573
        if (interfaceClass == -1) {
475
 
                fprintf(stderr, "Error: getting the interface class failed. Aborting.\n\n");
 
574
                fprintf(stderr, "Error: Could not get class of interface %d. Does it exist? Abort\n\n",Interface);
476
575
                exit(1);
477
576
        }
478
577
 
485
584
                        defaultClass = 8;
486
585
                }
487
586
 
488
 
        if (Interface == -1)
489
 
                Interface = dev->config[0].interface[0].altsetting[0].bInterfaceNumber;
490
 
        SHOW_PROGRESS(output,"Using first interface: 0x%02x\n", Interface);
491
 
 
492
 
        /* Check or get endpoints */
493
 
        if (strlen(MessageContent) || InquireDevice || CiscoMode) {
494
 
                if (!MessageEndpoint)
495
 
                        MessageEndpoint = find_first_bulk_output_endpoint(dev);
496
 
                if (!MessageEndpoint) {
497
 
                        fprintf(stderr,"Error: message endpoint not given or found. Aborting.\n\n");
498
 
                        exit(1);
499
 
                }
500
 
                if (!ResponseEndpoint)
501
 
                        ResponseEndpoint = find_first_bulk_input_endpoint(dev);
502
 
                if (!ResponseEndpoint) {
503
 
                        fprintf(stderr,"Error: response endpoint not given or found. Aborting.\n\n");
504
 
                        exit(1);
505
 
                }
506
 
                SHOW_PROGRESS(output,"Using endpoints 0x%02x (out) and 0x%02x (in)\n", MessageEndpoint, ResponseEndpoint);
507
 
        }
508
 
 
509
 
        if (!MessageEndpoint || !ResponseEndpoint)
510
 
                if (InquireDevice && defaultClass == 0x08) {
511
 
                        SHOW_PROGRESS(output,"Endpoints not found, skipping SCSI inquiry\n");
512
 
                        InquireDevice = 0;
 
587
        if (strlen(MessageContent) && strncmp("55534243",MessageContent,8) == 0)
 
588
                if (defaultClass != 8) {
 
589
                        fprintf(stderr, "Error: can't use storage command in MessageContent with interface %d;\n"
 
590
                                "       interface class is %d, expected 8. Abort\n\n", Interface, defaultClass);
 
591
                        exit(1);
513
592
                }
514
593
 
515
594
        if (InquireDevice && show_progress) {
516
595
                if (defaultClass == 0x08) {
517
 
                        SHOW_PROGRESS(output,"Inquiring device details; driver will be detached ...\n");
 
596
                        SHOW_PROGRESS(output,"Inquire device details; driver will be detached ...\n");
518
597
                        detachDriver();
519
598
                        if (deviceInquire() >= 0)
520
599
                                InquireDevice = 2;
521
600
                } else
522
 
                        SHOW_PROGRESS(output,"Not a storage device, skipping SCSI inquiry\n");
 
601
                        SHOW_PROGRESS(output,"Not a storage device, skip SCSI inquiry\n");
523
602
        }
524
603
 
525
604
        deviceDescription();
526
605
        if (show_progress) {
527
 
                printf("\nUSB description data (for identification)\n");
528
 
                printf("-------------------------\n");
529
 
                printf("Manufacturer: %s\n", imanufact);
530
 
                printf("     Product: %s\n", iproduct);
531
 
                printf("  Serial No.: %s\n", iserial);
532
 
                printf("-------------------------\n");
 
606
                fprintf(output,"\nUSB description data (for identification)\n");
 
607
                fprintf(output,"-------------------------\n");
 
608
                fprintf(output,"Manufacturer: %s\n", imanufact);
 
609
                fprintf(output,"     Product: %s\n", iproduct);
 
610
                fprintf(output,"  Serial No.: %s\n", iserial);
 
611
                fprintf(output,"-------------------------\n");
533
612
        }
534
613
 
535
 
        /* Some scenarios are exclusive, so check for unwanted combinations */
536
 
        specialMode = DetachStorageOnly + HuaweiMode + SierraMode + SonyMode + QisdaMode + KobilMode
537
 
                + SequansMode + MobileActionMode + CiscoMode;
538
 
        if ( specialMode > 1 ) {
539
 
                SHOW_PROGRESS(output,"Invalid mode combination. Check your configuration. Aborting.\n\n");
 
614
        /* Special modes are exclusive, so check for illegal combinations.
 
615
         * More than one bit set?
 
616
         */
 
617
        if ( ModeMap & (ModeMap-1) ) {
 
618
                fprintf(output,"Multiple special modes selected; check configuration. Abort\n\n");
540
619
                exit(1);
541
620
        }
542
621
 
543
 
        if ( !specialMode && !strlen(MessageContent) && AltSetting == -1 && Configuration == 0 )
544
 
                SHOW_PROGRESS(output,"Warning: no switching method given.\n");
 
622
        if ((strlen(MessageContent) || StandardEject) && ModeMap ) {
 
623
                MessageContent[0] = '\0';
 
624
                StandardEject = 0;
 
625
                fprintf(output,"Warning: MessageContent/StandardEject ignored; can't combine with special mode\n");
 
626
        }
 
627
 
 
628
        if (StandardEject && (strlen(MessageContent2) || strlen(MessageContent3))) {
 
629
                fprintf(output,"Warning: MessageContent2/3 ignored; only one allowed with StandardEject\n");
 
630
        }
 
631
 
 
632
        if ( !ModeMap && !strlen(MessageContent) && AltSetting == -1 && !Configuration && !StandardEject )
 
633
                SHOW_PROGRESS(output,"Warning: no switching method given. See documentation\n");
545
634
 
546
635
        /*
547
636
         * The switching actions
549
638
 
550
639
        if (sysmode) {
551
640
                openlog("usb_modeswitch", 0, LOG_SYSLOG);
552
 
                syslog(LOG_NOTICE, "switching device %04x:%04x on %03d/%03d", DefaultVendor, DefaultProduct, busnum, devnum);
 
641
                syslog(LOG_NOTICE, "switch device %04x:%04x on %03d/%03d", DefaultVendor, DefaultProduct, busnum, devnum);
553
642
        }
554
643
 
555
 
        if (DetachStorageOnly) {
556
 
                SHOW_PROGRESS(output,"Only detaching storage driver for switching ...\n");
 
644
        if (ModeMap & DETACHONLY_MODE) {
 
645
                SHOW_PROGRESS(output,"Detach storage driver as switching method ...\n");
557
646
                if (InquireDevice == 2) {
558
 
                        SHOW_PROGRESS(output," Any driver was already detached for inquiry\n");
 
647
                        SHOW_PROGRESS(output," Any driver was already detached for inquiry. Do nothing\n");
559
648
                } else {
560
649
                        ret = detachDriver();
561
650
                        if (ret == 2)
563
652
                }
564
653
        }
565
654
 
566
 
        if (HuaweiMode) {
 
655
        if(ModeMap & HUAWEI_MODE) {
567
656
                switchHuaweiMode();
568
657
        }
569
 
        if (SierraMode) {
 
658
        if(ModeMap & SIERRA_MODE) {
570
659
                switchSierraMode();
571
660
        }
572
 
        if (GCTMode) {
 
661
        if(ModeMap & GCT_MODE) {
573
662
                detachDriver();
574
663
                switchGCTMode();
575
664
        }
576
 
        if (QisdaMode) {
 
665
        if(ModeMap & QISDA_MODE) {
577
666
                switchQisdaMode();
578
667
        }
579
 
        if(KobilMode) {
 
668
        if(ModeMap & KOBIL_MODE) {
580
669
                detachDriver();
581
670
                switchKobilMode();
582
671
        }
583
 
        if (SequansMode) {
 
672
        if(ModeMap & QUANTA_MODE) {
 
673
                switchQuantaMode();
 
674
        }
 
675
        if(ModeMap & SEQUANS_MODE) {
584
676
                switchSequansMode();
585
677
        }
586
 
        if(MobileActionMode) {
 
678
        if(ModeMap & MOBILEACTION_MODE) {
587
679
                switchActionMode();
588
680
        }
589
 
        if(CiscoMode) {
 
681
        if(ModeMap & CISCO_MODE) {
590
682
                detachDriver();
591
683
                switchCiscoMode();
592
684
        }
593
 
        if (SonyMode) {
 
685
        if(ModeMap & BLACKBERRY_MODE) {
 
686
                detachDriver();
 
687
            switchBlackberryMode();
 
688
        }
 
689
        if(ModeMap & PANTECH_MODE) {
 
690
                detachDriver();
 
691
                switchPantechMode();
 
692
        }
 
693
        if(ModeMap & SONY_MODE) {
594
694
                if (CheckSuccess)
595
 
                        SHOW_PROGRESS(output,"Note: ignoring CheckSuccess. Separate checks for Sony mode\n");
 
695
                        SHOW_PROGRESS(output,"Note: CheckSuccess ignored; Sony mode does separate checks\n");
596
696
                CheckSuccess = 0; /* separate and implied success control */
597
697
                sonySuccess = switchSonyMode();
598
698
        }
599
699
 
600
 
        if (strlen(MessageContent) && MessageEndpoint) {
601
 
                if (specialMode == 0) {
602
 
                        if (InquireDevice != 2)
603
 
                                detachDriver();
604
 
                        switchSendMessage();
605
 
                } else
606
 
                        SHOW_PROGRESS(output,"Warning: ignoring MessageContent. Can't combine with special mode\n");
 
700
        if (StandardEject) {
 
701
                SHOW_PROGRESS(output,"Sending standard EJECT sequence\n");
 
702
                detachDriver();
 
703
                if (MessageContent[0] != '\0')
 
704
                        strcpy(MessageContent3, MessageContent);
 
705
                else
 
706
                        MessageContent3[0] = '\0';
 
707
 
 
708
                strcpy(MessageContent,"5553424312345678000000000000061e000000000000000000000000000000");
 
709
                strcpy(MessageContent2,"5553424312345679000000000000061b000000020000000000000000000000");
 
710
                NeedResponse = 1;
 
711
                switchSendMessage();
 
712
        } else if (strlen(MessageContent)) {
 
713
                if (InquireDevice != 2)
 
714
                        detachDriver();
 
715
                switchSendMessage();
607
716
        }
608
717
 
609
718
        if (Configuration > 0) {
610
719
                if (currentConfig != Configuration) {
611
720
                        if (switchConfiguration()) {
612
 
                                currentConfig = get_current_configuration(devh);
 
721
                                currentConfig = get_current_configuration(dev);
613
722
                                if (currentConfig == Configuration) {
614
723
                                        SHOW_PROGRESS(output,"The configuration was set successfully\n");
615
724
                                } else {
617
726
                                }
618
727
                        }
619
728
                } else {
620
 
                        SHOW_PROGRESS(output,"Target configuration %d already active. Doing nothing\n", currentConfig);
 
729
                        SHOW_PROGRESS(output,"Target configuration %d found. Do nothing\n", currentConfig);
621
730
                }
622
731
        }
623
732
 
627
736
 
628
737
        /* No "removal" check if these are set */
629
738
        if ((Configuration > 0 || AltSetting > -1) && !ResetUSB) {
630
 
                usb_close(devh);
 
739
                libusb_close(devh);
631
740
                devh = 0;
632
741
        }
633
742
 
634
743
        if (ResetUSB) {
635
744
                resetUSB();
636
 
                usb_close(devh);
637
745
                devh = 0;
638
746
        }
639
747
 
640
748
        if (CheckSuccess) {
641
749
                if (searchMode == SEARCH_BUSDEV && sysmode) {
642
 
                        SHOW_PROGRESS(output,"Bus/dev search active, referring success check to wrapper. Bye.\n\n");
 
750
                        SHOW_PROGRESS(output,"Bus/dev search active, refer success check to wrapper. Bye!\n\n");
643
751
                        printf("ok:busdev\n");
644
752
                        goto CLOSING;
645
753
                }
657
765
                        if (sysmode)
658
766
                                printf("fail:\n");
659
767
        } else {
660
 
                if (SonyMode)
 
768
                if (ModeMap & SONY_MODE)
661
769
                        if (sonySuccess) {
662
770
                                if (sysmode) {
663
771
                                        syslog(LOG_NOTICE, "switched S.E. MD400 to modem mode");
664
772
                                        printf("ok:\n"); /* ACM device, no driver action */
665
773
                                }
666
 
                                SHOW_PROGRESS(output,"-> device should be stable now. Bye.\n\n");
 
774
                                SHOW_PROGRESS(output,"-> device should be stable now. Bye!\n\n");
667
775
                        } else {
668
776
                                if (sysmode)
669
777
                                        printf("fail:\n");
670
 
                                SHOW_PROGRESS(output,"-> switching was probably not completed. Bye.\n\n");
 
778
                                SHOW_PROGRESS(output,"-> switching was probably not completed. Bye!\n\n");
671
779
                        }
672
780
                else
673
 
                        SHOW_PROGRESS(output,"-> Run lsusb to note any changes. Bye.\n\n");
 
781
                        SHOW_PROGRESS(output,"-> Run lsusb to note any changes. Bye!\n\n");
674
782
        }
675
783
CLOSING:
676
784
        if (sysmode)
677
785
                closelog();
678
786
        if (devh)
679
 
                usb_close(devh);
 
787
                libusb_close(devh);
680
788
        exit(0);
681
789
}
682
790
 
684
792
/* Get descriptor strings if available (identification details) */
685
793
void deviceDescription ()
686
794
{
687
 
        int ret;
688
795
        char* c;
689
796
        memset (imanufact, ' ', DESCR_MAX);
690
797
        memset (iproduct, ' ', DESCR_MAX);
691
798
        memset (iserial, ' ', DESCR_MAX);
692
799
 
693
 
        if (dev->descriptor.iManufacturer) {
694
 
                ret = usb_get_string_simple(devh, dev->descriptor.iManufacturer, imanufact, DESCR_MAX);
 
800
        struct libusb_device_descriptor descriptor;
 
801
        libusb_get_device_descriptor(dev, &descriptor);
 
802
 
 
803
        int iManufacturer = descriptor.iManufacturer;
 
804
        int iProduct = descriptor.iProduct;
 
805
        int iSerialNumber = descriptor.iSerialNumber;
 
806
 
 
807
        if (iManufacturer) {
 
808
                ret = libusb_get_string_descriptor_ascii(devh, iManufacturer, (unsigned char *)imanufact, DESCR_MAX);
695
809
                if (ret < 0)
696
810
                        fprintf(stderr, "Error: could not get description string \"manufacturer\"\n");
697
811
        } else
700
814
        if (c)
701
815
                memset((void*)c, '\0', 1);
702
816
 
703
 
        if (dev->descriptor.iProduct) {
704
 
                ret = usb_get_string_simple(devh, dev->descriptor.iProduct, iproduct, DESCR_MAX);
 
817
        if (iProduct) {
 
818
                ret = libusb_get_string_descriptor_ascii(devh, iProduct, (unsigned char *)iproduct, DESCR_MAX);
705
819
                if (ret < 0)
706
820
                        fprintf(stderr, "Error: could not get description string \"product\"\n");
707
821
        } else
710
824
        if (c)
711
825
                memset((void*)c, '\0', 1);
712
826
 
713
 
        if (dev->descriptor.iSerialNumber) {
714
 
                ret = usb_get_string_simple(devh, dev->descriptor.iSerialNumber, iserial, DESCR_MAX);
 
827
        if (iSerialNumber) {
 
828
                ret = libusb_get_string_descriptor_ascii(devh, iSerialNumber, (unsigned char *)iserial, DESCR_MAX);
715
829
                if (ret < 0)
716
830
                        fprintf(stderr, "Error: could not get description string \"serial number\"\n");
717
831
        } else
733
847
        };
734
848
        char *command;
735
849
        char data[36];
736
 
        int i, ret;
 
850
        int i;
737
851
 
738
852
        command = malloc(31);
739
853
        if (command == NULL) {
743
857
 
744
858
        memcpy(command, inquire_msg, sizeof (inquire_msg));
745
859
 
746
 
        ret = usb_claim_interface(devh, Interface);
 
860
        ret = libusb_claim_interface(devh, Interface);
747
861
        if (ret != 0) {
748
 
                SHOW_PROGRESS(output," Could not claim interface (error %d). Skipping device inquiry\n", ret);
749
 
                goto out;
750
 
        }
751
 
        usb_clear_halt(devh, MessageEndpoint);
752
 
 
753
 
        ret = usb_bulk_write(devh, MessageEndpoint, (char *)command, 31, 0);
754
 
        if (ret < 0) {
755
 
                SHOW_PROGRESS(output," Could not send INQUIRY message (error %d)\n", ret);
756
 
                goto out;
757
 
        }
758
 
 
759
 
        ret = usb_bulk_read(devh, ResponseEndpoint, data, 36, 0);
760
 
        if (ret < 0) {
761
 
                SHOW_PROGRESS(output," Could not get INQUIRY response (error %d)\n", ret);
762
 
                goto out;
763
 
        }
764
 
 
765
 
        i = usb_bulk_read(devh, ResponseEndpoint, command, 13, 0);
766
 
 
767
 
        printf("\nSCSI inquiry data (for identification)\n");
768
 
        printf("-------------------------\n");
769
 
 
770
 
        printf("  Vendor String: ");
 
862
                SHOW_PROGRESS(output," Could not claim interface (error %d). Skip device inquiry\n", ret);
 
863
                goto out;
 
864
        }
 
865
        libusb_clear_halt(devh, MessageEndpoint);
 
866
 
 
867
        ret = usb_bulk_io(devh, MessageEndpoint, (char *)command, 31, 0);
 
868
        if (ret < 0) {
 
869
                SHOW_PROGRESS(output," INQUIRY message failed (error %d)\n", ret);
 
870
                goto out;
 
871
        }
 
872
 
 
873
        ret = usb_bulk_io(devh, ResponseEndpoint, data, 36, 0);
 
874
        if (ret < 0) {
 
875
                SHOW_PROGRESS(output," INQUIRY response failed (error %d)\n", ret);
 
876
                goto out;
 
877
        }
 
878
 
 
879
        i = usb_bulk_io(devh, ResponseEndpoint, command, 13, 0);
 
880
 
 
881
        fprintf(output,"\nSCSI inquiry data (for identification)\n");
 
882
        fprintf(output,"-------------------------\n");
 
883
 
 
884
        fprintf(output,"  Vendor String: ");
771
885
        for (i = 8; i < 16; i++) printf("%c",data[i]);
772
 
        printf("\n");
 
886
        fprintf(output,"\n");
773
887
 
774
 
        printf("   Model String: ");
 
888
        fprintf(output,"   Model String: ");
775
889
        for (i = 16; i < 32; i++) printf("%c",data[i]);
776
 
        printf("\n");
 
890
        fprintf(output,"\n");
777
891
 
778
 
        printf("Revision String: ");
 
892
        fprintf(output,"Revision String: ");
779
893
        for (i = 32; i < 36; i++) printf("%c",data[i]);
780
894
 
781
 
        printf("\n-------------------------\n");
 
895
        fprintf(output,"\n-------------------------\n");
782
896
 
783
897
out:
784
 
        if (strlen(MessageContent) == 0)
785
 
                usb_clear_halt(devh, MessageEndpoint);
786
 
                usb_release_interface(devh, Interface);
 
898
        if (strlen(MessageContent) == 0) {
 
899
                libusb_clear_halt(devh, MessageEndpoint);
 
900
                libusb_release_interface(devh, Interface);
 
901
        }
787
902
        free(command);
788
903
        return ret;
789
904
}
790
905
 
791
906
 
 
907
/* Auxiliary function used by the wrapper */
 
908
int findMBIMConfig(int vendor, int product, int mode)
 
909
{
 
910
        struct libusb_device **devs;
 
911
        int resultConfig=0;
 
912
        int i=0, j;
 
913
 
 
914
        if (libusb_get_device_list(ctx, &devs) < 0) {
 
915
                perror("Libusb could not access USB. Abort");
 
916
                return 0;
 
917
        }
 
918
 
 
919
        SHOW_PROGRESS(output,"Search USB devices ...\n");
 
920
        while ((dev = devs[i++]) != NULL) {
 
921
                struct libusb_device_descriptor descriptor;
 
922
                libusb_get_device_descriptor(dev, &descriptor);
 
923
 
 
924
                if (mode == SEARCH_BUSDEV) {
 
925
                        if ((libusb_get_bus_number(dev) != busnum) ||
 
926
                                (libusb_get_device_address(dev) != devnum)) {
 
927
                                continue;
 
928
                        } else {
 
929
                                if (descriptor.idVendor != vendor)
 
930
                                        continue;
 
931
                                if (product != descriptor.idProduct)
 
932
                                        continue;
 
933
                        }
 
934
                }
 
935
                SHOW_PROGRESS(output,"Found device, search for MBIM configuration...\n");
 
936
 
 
937
                // No check if there is only one configuration
 
938
                if (descriptor.bNumConfigurations < 2)
 
939
                        return -1;
 
940
 
 
941
                // Checking all interfaces of all configurations
 
942
                for (j=0; j<descriptor.bNumConfigurations; j++) {
 
943
                        struct libusb_config_descriptor *config;
 
944
 
 
945
                        libusb_get_config_descriptor(dev, j, &config);
 
946
                        resultConfig = config->bConfigurationValue;
 
947
                        for (i=0; i<config->bNumInterfaces; i++) {
 
948
                                if ( config->interface[i].altsetting[0].bInterfaceClass == 2 )
 
949
                                        if ( config->interface[i].altsetting[0].bInterfaceSubClass == 0x0e ) {
 
950
                                                // found MBIM interface in this configuration
 
951
                                                libusb_free_config_descriptor(config);
 
952
                                                return resultConfig;
 
953
                                        }
 
954
                        }
 
955
                        libusb_free_config_descriptor(config);
 
956
                }
 
957
                return -1;
 
958
        }
 
959
        return 0;
 
960
}
 
961
 
792
962
void resetUSB ()
793
963
{
794
964
        int success;
795
965
        int bpoint = 0;
796
966
 
 
967
        if (!devh) {
 
968
                fprintf(output,"Device handle empty, skip USB reset\n");
 
969
                return;
 
970
        }
797
971
        if (show_progress) {
798
 
                printf("Resetting usb device ");
799
 
                fflush(stdout);
 
972
                fprintf(output,"Reset USB device ");
 
973
                fflush(output);
800
974
        }
801
 
 
802
975
        sleep( 1 );
803
976
        do {
804
 
                success = usb_reset(devh);
 
977
                success = libusb_reset_device(devh);
805
978
                if ( ((bpoint % 10) == 0) && show_progress ) {
806
 
                        printf(".");
807
 
                        fflush(stdout);
 
979
                        fprintf(output,".");
 
980
                        fflush(output);
808
981
                }
809
982
                bpoint++;
810
983
                if (bpoint > 100)
812
985
        } while (success < 0);
813
986
 
814
987
        if ( success ) {
815
 
                SHOW_PROGRESS(output,"\n Reset failed. Can be ignored if device switched OK.\n");
 
988
                SHOW_PROGRESS(output,"\n Device reset failed.\n");
816
989
        } else
817
 
                SHOW_PROGRESS(output,"\n OK, device was reset\n");
 
990
                SHOW_PROGRESS(output,"\n Device was reset\n");
818
991
}
819
992
 
820
993
 
831
1004
//      if (MessageContent2[0] != '\0' || MessageContent3[0] != '\0')
832
1005
//              NeedResponse = 1;
833
1006
 
834
 
        SHOW_PROGRESS(output,"Setting up communication with interface %d\n", Interface);
 
1007
        SHOW_PROGRESS(output,"Set up interface %d\n", Interface);
835
1008
        if (InquireDevice != 2) {
836
 
                ret = usb_claim_interface(devh, Interface);
 
1009
                ret = libusb_claim_interface(devh, Interface);
837
1010
                if (ret != 0) {
838
 
                        SHOW_PROGRESS(output," Could not claim interface (error %d). Skipping message sending\n", ret);
 
1011
                        SHOW_PROGRESS(output," Could not claim interface (error %d). Skip message sending\n", ret);
839
1012
                        return 0;
840
1013
                }
841
1014
        }
842
 
        usb_clear_halt(devh, MessageEndpoint);
843
 
        SHOW_PROGRESS(output,"Using endpoint 0x%02x for message sending ...\n", MessageEndpoint);
 
1015
        libusb_clear_halt(devh, MessageEndpoint);
 
1016
        SHOW_PROGRESS(output,"Use endpoint 0x%02x for message sending ...\n", MessageEndpoint);
844
1017
        if (show_progress)
845
1018
                fflush(stdout);
846
1019
 
854
1027
                if (NeedResponse) {
855
1028
                        if ( strstr(msg[i],cmdHead) != NULL ) {
856
1029
                                // UFI command
857
 
                                SHOW_PROGRESS(output,"Reading the response to message %d (CSW) ...\n", i+1);
 
1030
                                SHOW_PROGRESS(output,"Read the response to message %d (CSW) ...\n", i+1);
858
1031
                                ret = read_bulk(ResponseEndpoint, ByteString, 13);
859
1032
                        } else {
860
1033
                                // Other bulk transfer
861
 
                                SHOW_PROGRESS(output,"Reading the response to message %d ...\n", i+1);
 
1034
                                SHOW_PROGRESS(output,"Read the response to message %d ...\n", i+1);
862
1035
                                ret = read_bulk(ResponseEndpoint, ByteString, strlen(msg[i])/2 );
863
1036
                        }
864
1037
                        if (ret < 0)
866
1039
                }
867
1040
        }
868
1041
 
869
 
        SHOW_PROGRESS(output,"Resetting response endpoint 0x%02x\n", ResponseEndpoint);
870
 
        ret = usb_clear_halt(devh, ResponseEndpoint);
871
 
        if (ret)
872
 
                SHOW_PROGRESS(output," Could not reset endpoint (probably harmless): %d\n", ret);
873
 
        SHOW_PROGRESS(output,"Resetting message endpoint 0x%02x\n", MessageEndpoint);
874
 
        ret = usb_clear_halt(devh, MessageEndpoint);
875
 
        if (ret)
876
 
                SHOW_PROGRESS(output," Could not reset endpoint (probably harmless): %d\n", ret);
877
 
        usleep(200000);
 
1042
        SHOW_PROGRESS(output,"Reset response endpoint 0x%02x\n", ResponseEndpoint);
 
1043
        ret = libusb_clear_halt(devh, ResponseEndpoint);
 
1044
        if (ret)
 
1045
                SHOW_PROGRESS(output," Could not reset endpoint (probably harmless): %d\n", ret);
 
1046
        SHOW_PROGRESS(output,"Reset message endpoint 0x%02x\n", MessageEndpoint);
 
1047
        ret = libusb_clear_halt(devh, MessageEndpoint);
 
1048
        if (ret)
 
1049
                SHOW_PROGRESS(output," Could not reset endpoint (probably harmless): %d\n", ret);
 
1050
        usleep(50000);
 
1051
 
878
1052
        if (ReleaseDelay) {
879
 
                SHOW_PROGRESS(output,"Blocking the interface for %d ms before releasing ...\n", ReleaseDelay);
 
1053
                SHOW_PROGRESS(output,"Wait for %d ms before releasing interface ...\n", ReleaseDelay);
880
1054
                usleep(ReleaseDelay*1000);
881
1055
        }
882
 
        ret = usb_release_interface(devh, Interface);
 
1056
        ret = libusb_release_interface(devh, Interface);
883
1057
        if (ret)
884
1058
                goto skip;
885
1059
        return 1;
886
1060
 
887
1061
skip:
888
 
        SHOW_PROGRESS(output," Device is gone, skipping any further commands\n");
889
 
        usb_close(devh);
 
1062
        SHOW_PROGRESS(output," Device is gone, skip any further commands\n");
 
1063
        libusb_close(devh);
890
1064
        devh = 0;
891
1065
        return 2;
892
1066
}
893
1067
 
 
1068
 
894
1069
int switchConfiguration ()
895
1070
{
896
1071
        int count = SWITCH_CONFIG_MAXTRIES; 
897
 
        int ret;
898
1072
 
899
 
        SHOW_PROGRESS(output,"Changing configuration to %i ...\n", Configuration);
900
 
        while (((ret = usb_set_configuration(devh, Configuration)) < 0) && --count) {
901
 
                SHOW_PROGRESS(output," Device is busy, trying to detach kernel driver\n");
 
1073
        SHOW_PROGRESS(output,"Change configuration to %i ...\n", Configuration);
 
1074
        while (((ret = libusb_set_configuration(devh, Configuration)) < 0) && --count) {
 
1075
                SHOW_PROGRESS(output," Device is busy, try to detach kernel driver\n");
902
1076
                detachDriver();
903
1077
        }
904
 
        if (ret == 0 ) {
 
1078
        if (ret < 0 ) {
 
1079
                SHOW_PROGRESS(output," Changing the configuration failed (error %d). Try to continue\n", ret);
 
1080
                return 0;
 
1081
        } else {
905
1082
                SHOW_PROGRESS(output," OK, configuration set\n");
906
1083
                return 1;
907
1084
        }
908
 
        SHOW_PROGRESS(output," Setting the configuration returned error %d. Trying to continue\n", ret);
909
 
        return 0;
910
1085
}
911
1086
 
912
 
 
913
1087
int switchAltSetting ()
914
1088
{
915
 
        int ret;
916
1089
 
917
 
        SHOW_PROGRESS(output,"Changing to alt setting %i ...\n", AltSetting);
918
 
        ret = usb_claim_interface(devh, Interface);
919
 
        ret = usb_set_altinterface(devh, AltSetting);
920
 
        usb_release_interface(devh, Interface);
921
 
        if (ret != 0) {
922
 
                SHOW_PROGRESS(output," Changing to alt setting returned error %d. Trying to continue\n", ret);
 
1090
        SHOW_PROGRESS(output,"Change to alt setting %i ...\n", AltSetting);
 
1091
        ret = libusb_claim_interface(devh, Interface);
 
1092
        ret = libusb_set_interface_alt_setting(devh, Interface, AltSetting);
 
1093
        libusb_release_interface(devh, Interface);
 
1094
        if (ret < 0) {
 
1095
                SHOW_PROGRESS(output," Change to alt setting returned error %d. Try to continue\n", ret);
923
1096
                return 0;
924
 
        } else {
925
 
                SHOW_PROGRESS(output," OK, changed to alt setting\n");
 
1097
        } else
926
1098
                return 1;
927
 
        }
928
1099
}
929
1100
 
930
1101
 
931
1102
void switchHuaweiMode ()
932
1103
{
933
 
        int ret;
934
1104
 
935
 
        SHOW_PROGRESS(output,"Sending Huawei control message ...\n");
936
 
        ret = usb_control_msg(devh, USB_TYPE_STANDARD + USB_RECIP_DEVICE, USB_REQ_SET_FEATURE, 00000001, 0, buffer, 0, 1000);
 
1105
        SHOW_PROGRESS(output,"Send old Huawei control message ...\n");
 
1106
        ret = libusb_control_transfer(devh, LIBUSB_REQUEST_TYPE_STANDARD | LIBUSB_RECIPIENT_DEVICE, \
 
1107
                LIBUSB_REQUEST_SET_FEATURE, 00000001, 0, (unsigned char *)buffer, 0, 1000);
937
1108
        if (ret != 0) {
938
 
                fprintf(stderr, "Error: sending Huawei control message failed (error %d). Aborting.\n\n", ret);
 
1109
                fprintf(stderr, "Error: Huawei control message failed (error %d). Abort\n\n", ret);
939
1110
                exit(1);
940
 
        } else
941
 
                SHOW_PROGRESS(output," OK, Huawei control message sent\n");
 
1111
        }
942
1112
}
943
1113
 
944
1114
 
945
1115
void switchSierraMode ()
946
1116
{
947
 
        int ret;
948
 
 
949
 
        SHOW_PROGRESS(output,"Trying to send Sierra control message\n");
950
 
        ret = usb_control_msg(devh, 0x40, 0x0b, 00000001, 0, buffer, 0, 1000);
951
 
        if (ret != 0) {
952
 
                fprintf(stderr, "Error: sending Sierra control message failed (error %d). Aborting.\n\n", ret);
 
1117
        SHOW_PROGRESS(output,"Send Sierra control message\n");
 
1118
        ret = libusb_control_transfer(devh, LIBUSB_REQUEST_TYPE_VENDOR, 0x0b, 00000001, 0, (unsigned char *)buffer, 0, 1000);
 
1119
        if (ret == LIBUSB_ERROR_PIPE) {
 
1120
                SHOW_PROGRESS(output," communication with device stopped. May have switched modes anyway\n");
 
1121
            return;
 
1122
        }
 
1123
        if (ret < 0) {
 
1124
                fprintf(stderr, "Error: Sierra control message failed (error %d). Abort\n\n", ret);
953
1125
            exit(1);
954
 
        } else
955
 
                SHOW_PROGRESS(output," OK, Sierra control message sent\n");
 
1126
        }
956
1127
}
957
1128
 
958
1129
 
959
1130
void switchGCTMode ()
960
1131
{
961
 
        int ret;
962
 
 
963
 
        ret = usb_claim_interface(devh, Interface);
 
1132
        ret = libusb_claim_interface(devh, Interface);
964
1133
        if (ret != 0) {
965
 
                SHOW_PROGRESS(output," Could not claim interface (error %d). Skipping GCT sequence \n", ret);
 
1134
                SHOW_PROGRESS(output," Could not claim interface (error %d). Skip GCT sequence\n", ret);
966
1135
                return;
967
1136
        }
968
 
 
969
 
        SHOW_PROGRESS(output,"Sending GCT control message 1 ...\n");
970
 
        ret = usb_control_msg(devh, 0xa1, 0xa0, 0, Interface, buffer, 1, 1000);
971
 
        SHOW_PROGRESS(output,"Sending GCT control message 2 ...\n");
972
 
        ret = usb_control_msg(devh, 0xa1, 0xfe, 0, Interface, buffer, 1, 1000);
973
 
        SHOW_PROGRESS(output," OK, GCT control messages sent\n");
974
 
        usb_release_interface(devh, Interface);
975
 
}
976
 
 
977
 
 
978
 
int switchKobilMode() {
979
 
        int ret;
980
 
 
981
 
        SHOW_PROGRESS(output,"Sending Kobil control message ...\n");
982
 
        ret = usb_control_msg(devh, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN, 0x88, 0, 0, buffer, 8, 1000);
983
 
        if (ret != 0) {
984
 
                fprintf(stderr, "Error: sending Kobil control message failed (error %d). Aborting.\n\n", ret);
985
 
                exit(1);
986
 
        } else
987
 
                SHOW_PROGRESS(output," OK, Kobil control message sent\n");
988
 
        return 1;
989
 
}
990
 
 
991
 
 
992
 
int switchQisdaMode () {
993
 
        int ret;
994
 
 
 
1137
        SHOW_PROGRESS(output,"Send GCT control message 1 ...\n");
 
1138
        ret = libusb_control_transfer(devh, 0xa1, 0xa0, 0, Interface, (unsigned char *)buffer, 1, 1000);
 
1139
        if (ret < 0) {
 
1140
                SHOW_PROGRESS(output," GCT control message 1 failed (error %d), continue anyway ...\n", ret);
 
1141
        }
 
1142
        SHOW_PROGRESS(output,"Send GCT control message 2 ...\n");
 
1143
        ret = libusb_control_transfer(devh, 0xa1, 0xfe, 0, Interface, (unsigned char *)buffer, 1, 1000);
 
1144
        if (ret < 0) {
 
1145
                SHOW_PROGRESS(output," GCT control message 2 failed (error %d). Abort\n\n", ret);
 
1146
        }
 
1147
        libusb_release_interface(devh, Interface);
 
1148
        if (ret < 0)
 
1149
                exit(1);
 
1150
}
 
1151
 
 
1152
 
 
1153
void switchKobilMode() {
 
1154
        SHOW_PROGRESS(output,"Send Kobil control message ...\n");
 
1155
        ret = libusb_control_transfer(devh, LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE | LIBUSB_ENDPOINT_IN,
 
1156
                        0x88, 0, 0, (unsigned char *)buffer, 8, 1000);
 
1157
        if (ret < 0) {
 
1158
                fprintf(stderr, "Error: Kobil control message failed (error %d). Abort\n\n", ret);
 
1159
                exit(1);
 
1160
        }
 
1161
}
 
1162
 
 
1163
 
 
1164
void switchQisdaMode () {
995
1165
        SHOW_PROGRESS(output,"Sending Qisda control message ...\n");
996
1166
        memcpy(buffer, "\x05\x8c\x04\x08\xa0\xee\x20\x00\x5c\x01\x04\x08\x98\xcd\xea\xbf", 16);
997
 
        ret = usb_control_msg(devh, 0x40, 0x04, 00000000, 0, buffer, 16, 1000);
998
 
        if (ret != 0) {
999
 
                fprintf(stderr, "Error: sending Qisda control message failed (error %d). Aborting.\n\n", ret);
1000
 
                exit(1);
1001
 
        } else
1002
 
                SHOW_PROGRESS(output," OK, Qisda control message sent\n");
1003
 
        return 1;
1004
 
}
1005
 
 
1006
 
 
1007
 
int switchSonyMode ()
1008
 
{
1009
 
        int i, found, ret;
1010
 
        detachDriver();
1011
 
 
1012
 
        if (CheckSuccess) {
1013
 
                printf("Note: CheckSuccess pointless with Sony mode, disabling\n");
1014
 
                CheckSuccess = 0;
1015
 
        }
1016
 
 
1017
 
        SHOW_PROGRESS(output,"Trying to send Sony control message\n");
1018
 
        ret = usb_control_msg(devh, 0xc0, 0x11, 2, 0, buffer, 3, 100);
1019
 
        if (ret < 0) {
1020
 
                fprintf(stderr, "Error: sending Sony control message failed (error %d). Aborting.\n\n", ret);
1021
 
                exit(1);
1022
 
        } else
1023
 
                SHOW_PROGRESS(output," OK, control message sent, waiting for device to return ...\n");
1024
 
 
1025
 
        usb_close(devh);
1026
 
        devh = 0;
1027
 
 
1028
 
        /* Now waiting for the device to reappear */
1029
 
        devnum=-1;
1030
 
        busnum=-1;
1031
 
        i=0;
1032
 
        dev = 0;
1033
 
        while ( dev == 0 && i < 30 ) {
1034
 
                if ( i > 5 ) {
1035
 
                        usb_find_busses();
1036
 
                        usb_find_devices();
1037
 
                        dev = search_devices(&found, DefaultVendor, DefaultProduct, "\0", TargetClass, 0, SEARCH_TARGET);
1038
 
                }
1039
 
                if ( dev != 0 )
1040
 
                        break;
1041
 
                sleep(1);
1042
 
                if (show_progress) {
1043
 
                        printf("#");
1044
 
                        fflush(stdout);
1045
 
                }
1046
 
                i++;
1047
 
        }
1048
 
        SHOW_PROGRESS(output,"\n After %d seconds:",i);
1049
 
        if ( dev ) {
1050
 
                SHOW_PROGRESS(output," device came back, proceeding\n");
1051
 
                devh = usb_open( dev );
1052
 
                if (devh == 0) {
1053
 
                        fprintf(stderr, "Error: could not get handle on device\n");
1054
 
                        return 0;
1055
 
                }
1056
 
        } else {
1057
 
                SHOW_PROGRESS(output," device still gone, cancelling\n");
1058
 
                return 0;
1059
 
        }
1060
 
        sleep(1);
1061
 
 
1062
 
        SHOW_PROGRESS(output,"Sending Sony control message again ...\n");
1063
 
        ret = usb_control_msg(devh, 0xc0, 0x11, 2, 0, buffer, 3, 100);
1064
 
        if (ret < 0) {
1065
 
                fprintf(stderr, "Error: sending Sony control message (2) failed (error %d)\n", ret);
1066
 
                return 0;
1067
 
        }
1068
 
        SHOW_PROGRESS(output," OK, control message sent\n");
1069
 
        return 1;
 
1167
        ret = libusb_control_transfer(devh, 0x40, 0x04, 0, 0, (unsigned char *)buffer, 16, 1000);
 
1168
        if (ret < 0) {
 
1169
                fprintf(stderr, "Error: Qisda control message failed (error %d). Abort\n\n", ret);
 
1170
                exit(1);
 
1171
        }
 
1172
}
 
1173
 
 
1174
 
 
1175
void switchQuantaMode() {
 
1176
        SHOW_PROGRESS(output,"Send Quanta control message ...\n");
 
1177
        ret = libusb_control_transfer(devh, LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE | LIBUSB_ENDPOINT_IN,
 
1178
                        0xff, 0, 0, (unsigned char *)buffer, 0, 1000);
 
1179
        if (ret < 0) {
 
1180
                SHOW_PROGRESS(output,"Error: Quanta control message failed (error %d). Abort\n\n", ret);
 
1181
                exit(1);
 
1182
        }
 
1183
}
 
1184
 
 
1185
 
 
1186
void switchBlackberryMode ()
 
1187
{
 
1188
        SHOW_PROGRESS(output,"Send Blackberry control message 1 ...\n");
 
1189
        ret = libusb_control_transfer(devh, LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE | LIBUSB_ENDPOINT_IN,
 
1190
                        0xb1, 0x0000, 0, (unsigned char *)buffer, 8, 1000);
 
1191
        if (ret != 8) {
 
1192
                fprintf(stderr, "Error: Blackberry control message 1 failed (result %d)\n", ret);
 
1193
        }
 
1194
        SHOW_PROGRESS(output,"Send Blackberry control message 2 ...\n");
 
1195
        ret = libusb_control_transfer(devh, LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE | LIBUSB_ENDPOINT_IN,
 
1196
                        0xa9, 0x000e, 0, (unsigned char *)buffer, 2, 1000);
 
1197
        if (ret != 2) {
 
1198
                fprintf(stderr, "Error: Blackberry control message 2 failed (result %d). Abort\n\n", ret);
 
1199
                exit(1);
 
1200
        }
 
1201
}
 
1202
 
 
1203
 
 
1204
void switchPantechMode()
 
1205
{
 
1206
        SHOW_PROGRESS(output,"Send Pantech control message ...\n");
 
1207
        ret = libusb_control_transfer(devh, LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE, 0x70, 2, 0, (unsigned char *)buffer, 0, 1000);
 
1208
        if (ret < 0) {
 
1209
                SHOW_PROGRESS(output," Error: Pantech control message failed (error %d). Abort\n\n", ret);
 
1210
                exit(1);
 
1211
        }
1070
1212
}
1071
1213
 
1072
1214
 
1077
1219
#define MOBILE_ACTION_READLOOP1 63
1078
1220
#define MOBILE_ACTION_READLOOP2 73
1079
1221
 
1080
 
int switchActionMode ()
 
1222
/* If anyone can test the MobileAction cable - I bet this
 
1223
 * function (which is confirmed working) can be greatly
 
1224
 * simplified ...
 
1225
 */
 
1226
 
 
1227
void switchActionMode ()
1081
1228
{
1082
1229
        int i;
1083
 
        SHOW_PROGRESS(output,"Sending MobileAction control sequence ...\n");
1084
 
        memcpy(buffer, "\xb0\x04\x00\x00\x02\x90\x26\x86", SIZE);
1085
 
        usb_control_msg(devh, USB_TYPE_CLASS + USB_RECIP_INTERFACE, 0x09, 0x0300, 0, buffer, SIZE, 1000);
1086
 
        memcpy(buffer, "\xb0\x04\x00\x00\x02\x90\x26\x86", SIZE);
1087
 
        usb_control_msg(devh, USB_TYPE_CLASS + USB_RECIP_INTERFACE, 0x09, 0x0300, 0, buffer, SIZE, 1000);
1088
 
        usb_interrupt_read(devh, EP_IN, buffer, SIZE, 1000);
1089
 
        usb_interrupt_read(devh, EP_IN, buffer, SIZE, 1000);
 
1230
        SHOW_PROGRESS(output,"Send MobileAction control sequence ...\n");
 
1231
        memcpy(buffer, "\xb0\x04\x00\x00\x02\x90\x26\x86", SIZE);
 
1232
        libusb_control_transfer(devh, LIBUSB_REQUEST_TYPE_CLASS + LIBUSB_RECIPIENT_INTERFACE, 0x09, 0x0300, 0, (unsigned char *)buffer, SIZE, 1000);
 
1233
        memcpy(buffer, "\xb0\x04\x00\x00\x02\x90\x26\x86", SIZE);
 
1234
        libusb_control_transfer(devh, LIBUSB_REQUEST_TYPE_CLASS + LIBUSB_RECIPIENT_INTERFACE, 0x09, 0x0300, 0, (unsigned char *)buffer, SIZE, 1000);
 
1235
        usb_interrupt_io(devh, EP_IN, buffer, SIZE, 1000);
 
1236
        usb_interrupt_io(devh, EP_IN, buffer, SIZE, 1000);
1090
1237
        memcpy(buffer, "\x37\x01\xfe\xdb\xc1\x33\x1f\x83", SIZE);
1091
 
        usb_interrupt_write(devh, EP_OUT, buffer, SIZE, 1000);
1092
 
        usb_interrupt_read(devh, EP_IN, buffer, SIZE, 1000);
 
1238
        usb_interrupt_io(devh, EP_OUT, buffer, SIZE, 1000);
 
1239
        usb_interrupt_io(devh, EP_IN, buffer, SIZE, 1000);
1093
1240
        memcpy(buffer, "\x37\x0e\xb5\x9d\x3b\x8a\x91\x51", SIZE);
1094
 
        usb_interrupt_write(devh, EP_OUT, buffer, SIZE, 1000);
1095
 
        usb_interrupt_read(devh, EP_IN, buffer, SIZE, 1000);
 
1241
        usb_interrupt_io(devh, EP_OUT, buffer, SIZE, 1000);
 
1242
        usb_interrupt_io(devh, EP_IN, buffer, SIZE, 1000);
1096
1243
        memcpy(buffer, "\x34\x87\xba\x0d\xfc\x8a\x91\x51", SIZE);
1097
 
        usb_interrupt_write(devh, EP_OUT, buffer, SIZE, 1000);
 
1244
        usb_interrupt_io(devh, EP_OUT, buffer, SIZE, 1000);
1098
1245
        for (i=0; i < MOBILE_ACTION_READLOOP1; i++) {
1099
 
                usb_interrupt_read(devh, EP_IN, buffer, SIZE, 1000);
 
1246
                usb_interrupt_io(devh, EP_IN, buffer, SIZE, 1000);
1100
1247
        }
1101
1248
        memcpy(buffer, "\x37\x01\xfe\xdb\xc1\x33\x1f\x83", SIZE);
1102
 
        usb_interrupt_write(devh, EP_OUT, buffer, SIZE, 1000);
1103
 
        usb_interrupt_read(devh, EP_IN, buffer, SIZE, 1000);
 
1249
        usb_interrupt_io(devh, EP_OUT, buffer, SIZE, 1000);
 
1250
        usb_interrupt_io(devh, EP_IN, buffer, SIZE, 1000);
1104
1251
        memcpy(buffer, "\x37\x0e\xb5\x9d\x3b\x8a\x91\x51", SIZE);
1105
 
        usb_interrupt_write(devh, EP_OUT, buffer, SIZE, 1000);
1106
 
        usb_interrupt_read(devh, EP_IN, buffer, SIZE, 1000);
 
1252
        usb_interrupt_io(devh, EP_OUT, buffer, SIZE, 1000);
 
1253
        usb_interrupt_io(devh, EP_IN, buffer, SIZE, 1000);
1107
1254
        memcpy(buffer, "\x34\x87\xba\x0d\xfc\x8a\x91\x51", SIZE);
1108
 
        usb_interrupt_write(devh, EP_OUT, buffer, SIZE, 1000);
 
1255
        usb_interrupt_io(devh, EP_OUT, buffer, SIZE, 1000);
1109
1256
        for (i=0; i < MOBILE_ACTION_READLOOP2; i++) {
1110
 
                usb_interrupt_read(devh, EP_IN, buffer, SIZE, 1000);
 
1257
                usb_interrupt_io(devh, EP_IN, buffer, SIZE, 1000);
1111
1258
        }
1112
1259
        memcpy(buffer, "\x33\x04\xfe\x00\xf4\x6c\x1f\xf0", SIZE);
1113
 
        usb_interrupt_write(devh, EP_OUT, buffer, SIZE, 1000);
1114
 
        usb_interrupt_read(devh, EP_IN, buffer, SIZE, 1000);
 
1260
        usb_interrupt_io(devh, EP_OUT, buffer, SIZE, 1000);
 
1261
        usb_interrupt_io(devh, EP_IN, buffer, SIZE, 1000);
1115
1262
        memcpy(buffer, "\x32\x07\xfe\xf0\x29\xb9\x3a\xf0", SIZE);
1116
 
        ret = usb_interrupt_write(devh, EP_OUT, buffer, SIZE, 1000);
1117
 
        usb_interrupt_read(devh, EP_IN, buffer, SIZE, 1000);
 
1263
        ret = usb_interrupt_io(devh, EP_OUT, buffer, SIZE, 1000);
 
1264
        usb_interrupt_io(devh, EP_IN, buffer, SIZE, 1000);
1118
1265
        if (ret < 0) {
1119
1266
                SHOW_PROGRESS(output," MobileAction control sequence did not complete\n Last error was %d\n",ret);
1120
 
                return 1;
1121
1267
        } else {
1122
1268
                SHOW_PROGRESS(output," MobileAction control sequence complete\n");
1123
 
                return 0;
1124
1269
        }
1125
1270
}
1126
1271
 
1132
1277
#define SQN_MASS_STORAGE_MODE                   0x01
1133
1278
#define SQN_CUSTOM_DEVICE_MODE                  0x02
1134
1279
 
1135
 
int switchSequansMode() {
1136
 
        int ret;
 
1280
void switchSequansMode() {
1137
1281
 
1138
 
        SHOW_PROGRESS(output,"Sending Sequans vendor request\n");
1139
 
        ret = usb_control_msg(devh, USB_TYPE_VENDOR | USB_RECIP_DEVICE, SQN_SET_DEVICE_MODE_REQUEST, SQN_CUSTOM_DEVICE_MODE, 0, buffer, 0, 1000);
1140
 
        if (ret != 0) {
1141
 
                fprintf(stderr, "Error: sending Sequans request failed (error %d). Aborting.\n\n", ret);
 
1282
        SHOW_PROGRESS(output,"Send Sequans control message\n");
 
1283
        ret = libusb_control_transfer(devh, LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE, SQN_SET_DEVICE_MODE_REQUEST, SQN_CUSTOM_DEVICE_MODE, 0, (unsigned char *)buffer, 0, 1000);
 
1284
        if (ret < 0) {
 
1285
                fprintf(stderr, "Error: Sequans request failed (error %d). Abort\n\n", ret);
1142
1286
            exit(1);
1143
 
        } else
1144
 
                SHOW_PROGRESS(output," OK, Sequans request was sent\n");
1145
 
 
1146
 
        return 1;
 
1287
        }
1147
1288
}
1148
1289
 
1149
 
int switchCiscoMode() {
1150
 
        int ret, i;
 
1290
void switchCiscoMode() {
 
1291
        int i;
1151
1292
        char* msg[11];
1152
1293
 
1153
 
        SHOW_PROGRESS(output,"Preparing for sending Cisco message sequence\n");
1154
 
 
1155
1294
        msg[0] = "55534243f83bcd810002000080000afd000000030000000100000000000000";
1156
1295
        msg[1] = "55534243984300820002000080000afd000000070000000100000000000000";
1157
1296
        msg[2] = "55534243984300820000000000000afd000100071000000000000000000000";
1164
1303
        msg[9] = "55534243d84c04820000000000000afd000300241300000000000000000000";
1165
1304
        msg[10] = "55534243d84c04820000000000000afd000110732400000000000000000000";
1166
1305
 
1167
 
        SHOW_PROGRESS(output,"Setting up communication with interface %d\n", Interface);
1168
 
        ret = usb_claim_interface(devh, Interface);
1169
 
        if (ret != 0) {
1170
 
                SHOW_PROGRESS(output," Could not claim interface (error %d). Skipping message sending\n", ret);
1171
 
                return 0;
 
1306
        SHOW_PROGRESS(output,"Set up Cisco interface %d\n", Interface);
 
1307
        ret = libusb_claim_interface(devh, Interface);
 
1308
        if (ret < 0) {
 
1309
                SHOW_PROGRESS(output," Could not claim interface (error %d). Abort\n", ret);
 
1310
                exit(1);
1172
1311
        }
1173
 
//      usb_clear_halt(devh, MessageEndpoint);
 
1312
//      libusb_clear_halt(devh, MessageEndpoint);
1174
1313
        if (show_progress)
1175
1314
                fflush(output);
1176
1315
 
1178
1317
                if ( sendMessage(msg[i], i+1) )
1179
1318
                        goto skip;
1180
1319
 
1181
 
                SHOW_PROGRESS(output,"Reading the response (CSW) to bulk message %d ...\n",i+1);
 
1320
                SHOW_PROGRESS(output," Read the response (CSW) to bulk message %d ...\n",i+1);
1182
1321
                ret = read_bulk(ResponseEndpoint, ByteString, 13);
1183
1322
                if (ret < 0)
1184
1323
                        goto skip;
1185
1324
        }
1186
1325
 
1187
1326
        if (ReleaseDelay) {
1188
 
                SHOW_PROGRESS(output,"Blocking the interface for %d ms before releasing ...\n", ReleaseDelay);
 
1327
                SHOW_PROGRESS(output,"Wait for %d ms before releasing interface ...\n", ReleaseDelay);
1189
1328
                usleep(ReleaseDelay*1000);
1190
1329
        }
1191
 
        ret = usb_release_interface(devh, Interface);
1192
 
        if (ret)
 
1330
        ret = libusb_release_interface(devh, Interface);
 
1331
        if (ret < 0)
1193
1332
                goto skip;
 
1333
        return;
 
1334
 
 
1335
skip:
 
1336
        SHOW_PROGRESS(output,"Device returned error %d, skip further commands\n", ret);
 
1337
        libusb_close(devh);
 
1338
        devh = 0;
 
1339
}
 
1340
 
 
1341
 
 
1342
int switchSonyMode ()
 
1343
{
 
1344
        int i, found;
 
1345
        detachDriver();
 
1346
 
 
1347
        if (CheckSuccess) {
 
1348
                CheckSuccess = 0;
 
1349
        }
 
1350
 
 
1351
        SHOW_PROGRESS(output,"Send Sony control message\n");
 
1352
        ret = libusb_control_transfer(devh, 0xc0, 0x11, 2, 0, (unsigned char *)buffer, 3, 100);
 
1353
        if (ret < 0) {
 
1354
                fprintf(stderr, "Error: Sony control message failed (error %d). Abort\n\n", ret);
 
1355
                exit(1);
 
1356
        } else
 
1357
                SHOW_PROGRESS(output," OK, control message sent, wait for device to return ...\n");
 
1358
 
 
1359
        libusb_close(devh);
 
1360
        devh = 0;
 
1361
 
 
1362
        /* Now waiting for the device to reappear */
 
1363
        devnum=-1;
 
1364
        busnum=-1;
 
1365
        i=0;
 
1366
        dev = 0;
 
1367
        while ( dev == 0 && i < 30 ) {
 
1368
                if ( i > 5 ) {
 
1369
                        dev = search_devices(&found, DefaultVendor, DefaultProductList, TargetClass, 0, SEARCH_TARGET);
 
1370
                }
 
1371
                if ( dev != 0 )
 
1372
                        break;
 
1373
                sleep(1);
 
1374
                if (show_progress) {
 
1375
                        fprintf(output,"#");
 
1376
                        fflush(stdout);
 
1377
                }
 
1378
                i++;
 
1379
        }
 
1380
        SHOW_PROGRESS(output,"\n After %d seconds:",i);
 
1381
        if ( dev ) {
 
1382
                SHOW_PROGRESS(output," device came back, proceed\n");
 
1383
                libusb_open(dev, &devh);
 
1384
                if (devh == 0) {
 
1385
                        fprintf(stderr, "Error: could not get handle on device\n");
 
1386
                        return 0;
 
1387
                }
 
1388
        } else {
 
1389
                SHOW_PROGRESS(output," device still gone, abort\n");
 
1390
                return 0;
 
1391
        }
 
1392
        sleep(1);
 
1393
 
 
1394
        SHOW_PROGRESS(output,"Send Sony control message again ...\n");
 
1395
        ret = libusb_control_transfer(devh, 0xc0, 0x11, 2, 0, (unsigned char *)buffer, 3, 100);
 
1396
        if (ret < 0) {
 
1397
                fprintf(stderr, "Error: Sony control message (2) failed (error %d)\n", ret);
 
1398
                return 0;
 
1399
        }
 
1400
        SHOW_PROGRESS(output," OK, control message sent\n");
1194
1401
        return 1;
1195
 
 
1196
 
skip:
1197
 
        SHOW_PROGRESS(output,"Device returned error, skipping any further commands\n");
1198
 
        usb_close(devh);
1199
 
        devh = 0;
1200
 
        return 2;
1201
1402
}
1202
1403
 
 
1404
 
1203
1405
/* Detach driver
1204
1406
 */
1205
1407
int detachDriver()
1206
1408
{
1207
 
        int ret;
1208
 
 
1209
 
#ifndef LIBUSB_HAS_GET_DRIVER_NP
1210
 
        printf(" Cant't do driver detection and detaching on this platform.\n");
1211
 
        return 2;
1212
 
#endif
1213
 
 
 
1409
 
 
1410
        // Driver already detached during SCSI inquiry ?
 
1411
        if (InquireDevice == 2)
 
1412
                return 1;
1214
1413
        SHOW_PROGRESS(output,"Looking for active driver ...\n");
1215
 
        ret = usb_get_driver_np(devh, Interface, buffer, BUF_SIZE);
1216
 
        if (ret != 0) {
1217
 
                SHOW_PROGRESS(output," No driver found. Either detached before or never attached\n");
 
1414
        ret = libusb_kernel_driver_active(devh, 0);
 
1415
        if (ret == LIBUSB_ERROR_NOT_SUPPORTED) {
 
1416
                fprintf(output," Can't do driver detection on this platform.\n");
 
1417
                return 2;
 
1418
        }
 
1419
        if (ret < 0) {
 
1420
                fprintf(output," Driver check failed with error %d. Try to continue\n", ret);
 
1421
                return 2;
 
1422
        }
 
1423
        if (ret == 0) {
 
1424
                SHOW_PROGRESS(output," No active driver found. Detached before or never attached\n");
1218
1425
                return 1;
1219
1426
        }
1220
 
        if (strncmp("dummy",buffer,5) == 0) {
1221
 
                SHOW_PROGRESS(output," OK, driver found; name unknown, limitation of libusb1\n");
1222
 
                strcpy(buffer,"unkown");
1223
 
        } else {
1224
 
                SHOW_PROGRESS(output," OK, driver found (\"%s\")\n", buffer);
 
1427
 
 
1428
        ret = libusb_detach_kernel_driver(devh, Interface);
 
1429
        if (ret == LIBUSB_ERROR_NOT_SUPPORTED) {
 
1430
                fprintf(output," Can't do driver detaching on this platform.\n");
 
1431
                return 2;
1225
1432
        }
1226
 
 
1227
 
#ifndef LIBUSB_HAS_DETACH_KERNEL_DRIVER_NP
1228
 
        SHOW_PROGRESS(output," Can't do driver detaching on this platform\n");
1229
 
        return 2;
1230
 
#endif
1231
 
 
1232
 
 
1233
 
        ret = usb_detach_kernel_driver_np(devh, Interface);
1234
1433
        if (ret == 0) {
1235
 
                SHOW_PROGRESS(output," OK, driver \"%s\" detached\n", buffer);
 
1434
                SHOW_PROGRESS(output," OK, driver detached\n");
1236
1435
        } else
1237
 
                SHOW_PROGRESS(output," Driver \"%s\" detach failed with error %d. Trying to continue\n", buffer, ret);
 
1436
                SHOW_PROGRESS(output," Driver detach failed (error %d). Try to continue\n", ret);
1238
1437
        return 1;
1239
1438
}
1240
1439
 
1241
1440
 
1242
1441
int sendMessage(char* message, int count)
1243
1442
{
1244
 
        int message_length, ret;
 
1443
        int message_length;
1245
1444
 
1246
1445
        if (strlen(message) % 2 != 0) {
1247
1446
                fprintf(stderr, "Error: MessageContent %d hex string has uneven length. Skipping ...\n", count);
1255
1454
        SHOW_PROGRESS(output,"Trying to send message %d to endpoint 0x%02x ...\n", count, MessageEndpoint);
1256
1455
        fflush(output);
1257
1456
        ret = write_bulk(MessageEndpoint, ByteString, message_length);
1258
 
        if (ret == -19)
 
1457
        if (ret == LIBUSB_ERROR_NO_DEVICE)
1259
1458
                return 1;
1260
1459
 
1261
1460
        return 0;
1264
1463
 
1265
1464
int checkSuccess()
1266
1465
{
1267
 
        int i=0, ret;
 
1466
        int i=0;
1268
1467
        int newTargetCount, success=0;
1269
1468
 
1270
 
        SHOW_PROGRESS(output,"\nChecking for mode switch (max. %d times, once per second) ...\n", CheckSuccess);
 
1469
        SHOW_PROGRESS(output,"\nCheck for mode switch (max. %d times, once per second) ...\n", CheckSuccess);
1271
1470
        sleep(1);
1272
1471
 
1273
1472
        /* If target parameters are given, don't check for vanished device
1275
1474
         * storage device stays active
1276
1475
         */
1277
1476
        if ((TargetVendor || TargetClass) && devh) {
1278
 
                usb_close(devh);
 
1477
                libusb_close(devh);
1279
1478
                devh = 0;
1280
1479
        }
1281
1480
 
1295
1494
                        /* Test if default device still can be accessed; positive result does
1296
1495
                         * not necessarily mean failure
1297
1496
                         */
1298
 
                        SHOW_PROGRESS(output," Waiting for original device to vanish ...\n");
 
1497
                        SHOW_PROGRESS(output," Wait for original device to vanish ...\n");
1299
1498
 
1300
 
                        ret = usb_claim_interface(devh, Interface);
1301
 
                        usb_release_interface(devh, Interface);
 
1499
                        ret = libusb_claim_interface(devh, Interface);
 
1500
                        libusb_release_interface(devh, Interface);
1302
1501
                        if (ret < 0) {
1303
1502
                                SHOW_PROGRESS(output," Original device can't be accessed anymore. Good.\n");
1304
 
                                usb_close(devh);
 
1503
                                libusb_close(devh);
1305
1504
                                devh = 0;
1306
1505
                                break;
1307
1506
                        }
1308
1507
                        if (i == CheckSuccess-1) {
1309
 
                                SHOW_PROGRESS(output," Original device still present after the timeout\n\nMode switch most likely failed. Bye.\n\n");
 
1508
                                SHOW_PROGRESS(output," Original device still present after the timeout\n\nMode switch most likely failed. Bye!\n\n");
1310
1509
                        } else
1311
1510
                                sleep(1);
1312
1511
                }
1318
1517
                 * description is read for syslog message
1319
1518
                 */
1320
1519
                for (i=i; i < CheckSuccess; i++) {
1321
 
                        SHOW_PROGRESS(output," Searching for target devices ...\n");
1322
 
                        ret = usb_find_busses();
1323
 
                        if (ret >= 0)
1324
 
                                ret = usb_find_devices();
1325
 
                        if (ret < 0) {
1326
 
                                SHOW_PROGRESS(output,"Error: libusb1 bug, no more searching, try to work around\n");
1327
 
                                success = 3;
1328
 
                                break;
1329
 
                        }
1330
 
                        dev = search_devices(&newTargetCount, TargetVendor, TargetProduct, TargetProductList, TargetClass, 0, SEARCH_TARGET);
 
1520
                        SHOW_PROGRESS(output," Search for target devices ...\n");
 
1521
                        dev = search_devices(&newTargetCount, TargetVendor, TargetProductList, TargetClass, 0, SEARCH_TARGET);
1331
1522
                        if (dev && (newTargetCount > targetDeviceCount)) {
1332
 
                                printf("\nFound target device, now opening\n");
1333
 
                                devh = usb_open(dev);
 
1523
                                fprintf(output,"\nFound target device, open it\n");
 
1524
                                libusb_open(dev, &devh);
1334
1525
                                deviceDescription();
1335
 
                                usb_close(devh);
 
1526
                                libusb_close(devh);
1336
1527
                                devh = 0;
1337
1528
                                if (verbose) {
1338
 
                                        printf("\nFound target device %03d on bus %03d\n", \
1339
 
                                        dev->devnum, (int)strtol(dev->bus->dirname,NULL,10));
1340
 
                                        printf("\nTarget device description data\n");
1341
 
                                        printf("-------------------------\n");
1342
 
                                        printf("Manufacturer: %s\n", imanufact);
1343
 
                                        printf("     Product: %s\n", iproduct);
1344
 
                                        printf("  Serial No.: %s\n", iserial);
1345
 
                                        printf("-------------------------\n");
 
1529
                                        fprintf(output,"\nFound target device %03d on bus %03d\n", \
 
1530
                                        libusb_get_device_address(dev), libusb_get_bus_number(dev));
 
1531
                                        fprintf(output,"\nTarget device description data\n");
 
1532
                                        fprintf(output,"-------------------------\n");
 
1533
                                        fprintf(output,"Manufacturer: %s\n", imanufact);
 
1534
                                        fprintf(output,"     Product: %s\n", iproduct);
 
1535
                                        fprintf(output,"  Serial No.: %s\n", iserial);
 
1536
                                        fprintf(output,"-------------------------\n");
1346
1537
                                }
1347
 
                                SHOW_PROGRESS(output," Found correct target device\n\nMode switch succeeded. Bye.\n\n");
 
1538
                                SHOW_PROGRESS(output," Found correct target device\n\nMode switch succeeded. Bye!\n\n");
1348
1539
                                success = 2;
1349
1540
                                break;
1350
1541
                        }
1351
1542
                        if (i == CheckSuccess-1) {
1352
 
                                SHOW_PROGRESS(output," No new devices in target mode or class found\n\nMode switch has failed. Bye.\n\n");
 
1543
                                SHOW_PROGRESS(output," No new devices in target mode or class found\n\nMode switch has failed. Bye!\n\n");
1353
1544
                        } else
1354
1545
                                sleep(1);
1355
1546
                }
1357
1548
                /* No target data given, rely on the vanished device */
1358
1549
                if (!devh) {
1359
1550
                        SHOW_PROGRESS(output," (For a better success check provide target IDs or class)\n");
1360
 
                        SHOW_PROGRESS(output," Original device vanished after switching\n\nMode switch most likely succeeded. Bye.\n\n");
 
1551
                        SHOW_PROGRESS(output," Original device vanished after switching\n\nMode switch most likely succeeded. Bye!\n\n");
1361
1552
                        success = 1;
1362
1553
                }
1363
1554
 
1389
1580
 
1390
1581
int write_bulk(int endpoint, char *message, int length)
1391
1582
{
1392
 
        int ret;
1393
 
        ret = usb_bulk_write(devh, endpoint, message, length, 3000);
 
1583
        ret = usb_bulk_io(devh, endpoint, message, length, 3000);
1394
1584
        if (ret >= 0 ) {
1395
1585
                SHOW_PROGRESS(output," OK, message successfully sent\n");
1396
1586
        } else
1397
 
                if (ret == -19) {
 
1587
                if (ret == LIBUSB_ERROR_NO_DEVICE) {
1398
1588
                        SHOW_PROGRESS(output," Device seems to have vanished right after sending. Good.\n");
1399
1589
                } else
1400
 
                        SHOW_PROGRESS(output," Sending the message returned error %d. Trying to continue\n", ret);
 
1590
                        SHOW_PROGRESS(output," Sending the message returned error %d. Try to continue\n", ret);
1401
1591
        return ret;
1402
1592
 
1403
1593
}
1404
1594
 
1405
1595
int read_bulk(int endpoint, char *buffer, int length)
1406
1596
{
1407
 
        int ret;
1408
 
        ret = usb_bulk_read(devh, endpoint, buffer, length, 3000);
1409
 
        usb_bulk_read(devh, endpoint, buffer, 13, 100);
 
1597
        ret = usb_bulk_io(devh, endpoint, buffer, length, 3000);
1410
1598
        if (ret >= 0 ) {
1411
 
                SHOW_PROGRESS(output," OK, response successfully read (%d bytes).\n", ret);
 
1599
                SHOW_PROGRESS(output," Response successfully read (%d bytes).\n", ret);
1412
1600
        } else
1413
 
                if (ret == -19) {
 
1601
                if (ret == LIBUSB_ERROR_NO_DEVICE) {
1414
1602
                        SHOW_PROGRESS(output," Device seems to have vanished after reading. Good.\n");
1415
1603
                } else
1416
 
                        SHOW_PROGRESS(output," Response reading got error %d\n", ret);
 
1604
                        SHOW_PROGRESS(output," Response reading failed (error %d)\n", ret);
1417
1605
        return ret;
1418
1606
 
1419
1607
}
1420
1608
 
1421
 
void release_usb_device(int dummy) {
1422
 
        SHOW_PROGRESS(output,"Program cancelled by system. Bye.\n\n");
 
1609
void release_usb_device(int __attribute__((unused)) dummy) {
 
1610
        SHOW_PROGRESS(output,"Program cancelled by system. Bye!\n\n");
1423
1611
        if (devh) {
1424
 
                usb_release_interface(devh, Interface);
1425
 
                usb_close(devh);
 
1612
                libusb_release_interface(devh, Interface);
 
1613
                libusb_close(devh);
1426
1614
        }
1427
1615
        if (sysmode)
1428
1616
                closelog();
1434
1622
/* Iterates over busses and devices, counts the ones which match the given
1435
1623
 * parameters and returns the last one of them
1436
1624
*/
1437
 
struct usb_device* search_devices( int *numFound, int vendor, int product, char* productList, int targetClass, int configuration, int mode)
 
1625
struct libusb_device* search_devices( int *numFound, int vendor, char* productList, int targetClass, int configuration, int mode)
1438
1626
{
1439
 
        struct usb_bus *bus;
1440
1627
        char *listcopy=NULL, *token, buffer[2];
1441
 
        int devClass;
1442
 
        struct usb_device* right_dev = NULL;
1443
 
        struct usb_dev_handle *testdevh;
 
1628
        int devClass, product;
 
1629
        struct libusb_device* right_dev = NULL;
 
1630
//      struct libusb_device_handle *testdevh;
 
1631
        struct libusb_device **devs;
 
1632
        int i=0;
1444
1633
 
1445
1634
        /* only target class given, target vendor and product assumed unchanged */
1446
 
        if ( targetClass && !(vendor || product) ) {
 
1635
        if ( targetClass && !(vendor || strlen(productList)) ) {
1447
1636
                vendor = DefaultVendor;
1448
 
                product = DefaultProduct;
 
1637
                productList = DefaultProductList;
1449
1638
        }
1450
1639
        *numFound = 0;
1451
1640
 
1452
1641
        /* Sanity check */
1453
 
        if (!vendor || (!product && productList == '\0') )
 
1642
        if (!vendor || productList == '\0')
1454
1643
                return NULL;
1455
1644
 
1456
 
        if (productList != '\0')
1457
 
                listcopy = malloc(strlen(productList)+1);
1458
 
 
1459
 
        for (bus = usb_get_busses(); bus; bus = bus->next) {
1460
 
                if (mode == SEARCH_BUSDEV)
1461
 
                        if (busnum != (int)strtol(bus->dirname,NULL,10))
1462
 
                                continue;
1463
 
                struct usb_device *dev;
1464
 
                for (dev = bus->devices; dev; dev = dev->next) {
1465
 
                        if (mode == SEARCH_BUSDEV) {
1466
 
                                if (dev->devnum != devnum)
1467
 
                                        continue;
1468
 
                                else
1469
 
                                        SHOW_PROGRESS(output," bus/device number matched\n");
1470
 
                        }
1471
 
                        if (verbose)
1472
 
                                fprintf (output,"  searching devices, found USB ID %04x:%04x\n", dev->descriptor.idVendor, dev->descriptor.idProduct);
1473
 
                        if (dev->descriptor.idVendor != vendor)
1474
 
                                continue;
1475
 
                        if (verbose)
1476
 
                                fprintf (output,"   found matching vendor ID\n");
1477
 
                        // product list given
1478
 
                        if ( strlen(productList) ) {
1479
 
                                strcpy(listcopy, productList);
1480
 
                                token = strtok(listcopy, ",");
1481
 
                                while (token != NULL) {
1482
 
                                        if (strlen(token) != 4) {
1483
 
                                                SHOW_PROGRESS(output,"Error: entry in product ID list has wrong length: %s. Ignoring\n", token);
1484
 
                                                goto NextToken;
1485
 
                                        }
1486
 
                                        if ( hexstr2bin(token, buffer, strlen(token)/2) == -1) {
1487
 
                                                SHOW_PROGRESS(output,"Error: entry in product ID list is not a hex string: %s. Ignoring\n", token);
1488
 
                                                goto NextToken;
1489
 
                                        }
1490
 
                                        product = 0;
1491
 
                                        product += (unsigned char)buffer[0];
1492
 
                                        product <<= 8;
1493
 
                                        product += (unsigned char)buffer[1];
1494
 
                                        if (product == dev->descriptor.idProduct) {
 
1645
        listcopy = malloc(strlen(productList)+1);
 
1646
 
 
1647
        if (libusb_get_device_list(ctx, &devs) < 0) {
 
1648
                perror("Libusb failed to get USB access!");
 
1649
                return 0;
 
1650
        }
 
1651
 
 
1652
        while ((dev = devs[i++]) != NULL) {
 
1653
                struct libusb_device_descriptor descriptor;
 
1654
                libusb_get_device_descriptor(dev, &descriptor);
 
1655
 
 
1656
                if (mode == SEARCH_BUSDEV) {
 
1657
                        if ((libusb_get_bus_number(dev) != busnum) ||
 
1658
                                (libusb_get_device_address(dev) != devnum))
 
1659
                                continue;
 
1660
                        else
 
1661
                                SHOW_PROGRESS(output," bus/device number matched\n");
 
1662
                }
 
1663
 
 
1664
                if (verbose)
 
1665
                        fprintf (output,"  found USB ID %04x:%04x\n",
 
1666
                                        descriptor.idVendor, descriptor.idProduct);
 
1667
                if (descriptor.idVendor != vendor)
 
1668
                        continue;
 
1669
                if (verbose)
 
1670
                        fprintf (output,"   vendor ID matched\n");
 
1671
 
 
1672
                strcpy(listcopy, productList);
 
1673
                token = strtok(listcopy, ",");
 
1674
                while (token != NULL) {
 
1675
                        if (strlen(token) != 4) {
 
1676
                                SHOW_PROGRESS(output,"Error: entry in product ID list has wrong length: %s. Ignored\n", token);
 
1677
                                goto NextToken;
 
1678
                        }
 
1679
                        if ( hexstr2bin(token, buffer, strlen(token)/2) == -1) {
 
1680
                                SHOW_PROGRESS(output,"Error: entry in product ID list is not a hex string: %s. Ignored\n", token);
 
1681
                                goto NextToken;
 
1682
                        }
 
1683
                        product = 0;
 
1684
                        product += (unsigned char)buffer[0];
 
1685
                        product <<= 8;
 
1686
                        product += (unsigned char)buffer[1];
 
1687
                        if (product == descriptor.idProduct) {
 
1688
                                SHOW_PROGRESS(output,"   product ID matched\n");
 
1689
 
 
1690
                                if (targetClass != 0) {
 
1691
                                        // TargetClass is set, check class of first interface
 
1692
                                        struct libusb_device_descriptor descriptor;
 
1693
                                        libusb_get_device_descriptor(dev, &descriptor);
 
1694
                                        devClass = descriptor.bDeviceClass;
 
1695
                                        struct libusb_config_descriptor *config;
 
1696
                                        libusb_get_config_descriptor(dev, 0, &config);
 
1697
                                        int ifaceClass = config->interface[0].altsetting[0].bInterfaceClass;
 
1698
                                        libusb_free_config_descriptor(config);
 
1699
                                        if (devClass == 0)
 
1700
                                                devClass = ifaceClass;
 
1701
                                        else
 
1702
                                                /* Check for some quirky devices */
 
1703
                                                if (devClass != ifaceClass)
 
1704
                                                        devClass = ifaceClass;
 
1705
                                        if (devClass == targetClass) {
1495
1706
                                                if (verbose)
1496
 
                                                        fprintf (output,"   found matching product ID from list\n");
1497
 
                                                (*numFound)++;
1498
 
                                                if (busnum == -1)
 
1707
                                                        fprintf (output,"   target class %02x matches\n", targetClass);
 
1708
                                                if (mode == SEARCH_TARGET) {
 
1709
                                                        (*numFound)++;
1499
1710
                                                        right_dev = dev;
1500
 
                                                else
1501
 
                                                        if (dev->devnum >= devnum && (int)strtol(dev->bus->dirname,NULL,10) == busnum) {
1502
 
                                                                right_dev = dev;
1503
 
                                                                TargetProduct = dev->descriptor.idProduct;
1504
 
                                                                break;
1505
 
                                                        }
1506
 
                                        }
1507
 
                                        NextToken:
1508
 
                                        token = strtok(NULL, ",");
1509
 
                                }
1510
 
                        /* Product ID is given */
1511
 
                        } else
1512
 
                                if (product == dev->descriptor.idProduct) {
1513
 
                                        SHOW_PROGRESS(output,"   found matching product ID\n");
1514
 
                                        if (targetClass == 0 && configuration < 1) {
1515
 
                                                (*numFound)++;
1516
 
                                                SHOW_PROGRESS(output,"   adding device\n");
1517
 
                                                right_dev = dev;
 
1711
                                                        if (verbose)
 
1712
                                                                fprintf (output,"   count device\n");
 
1713
                                                } else
 
1714
                                                        if (verbose)
 
1715
                                                                fprintf (output,"   device not counted, target class reached\n");
1518
1716
                                        } else {
1519
 
                                                if (targetClass != 0) {
1520
 
                                                        devClass = dev->descriptor.bDeviceClass;
1521
 
                                                        if (devClass == 0)
1522
 
                                                                devClass = dev->config[0].interface[0].altsetting[0].bInterfaceClass;
1523
 
                                                        else
1524
 
                                                                /* Check for some quirky devices */
1525
 
                                                                if (devClass != dev->config[0].interface[0].altsetting[0].bInterfaceClass)
1526
 
                                                                        devClass = dev->config[0].interface[0].altsetting[0].bInterfaceClass;
1527
 
                                                        if (devClass == targetClass) {
1528
 
                                                                if (verbose)
1529
 
                                                                        fprintf (output,"   target class %02x matching\n", targetClass);
1530
 
                                                                if (mode == SEARCH_TARGET) {
1531
 
                                                                        (*numFound)++;
1532
 
                                                                        right_dev = dev;
1533
 
                                                                        if (verbose)
1534
 
                                                                                fprintf (output,"   adding device\n");
1535
 
                                                                } else
1536
 
                                                                        if (verbose)
1537
 
                                                                                fprintf (output,"   not adding device\n");
1538
 
                                                        } else {
1539
 
                                                                if (verbose)
1540
 
                                                                        fprintf (output,"   target class %02x not matching\n", targetClass);
1541
 
                                                                if (mode == SEARCH_DEFAULT || mode == SEARCH_BUSDEV) {
1542
 
                                                                        (*numFound)++;
1543
 
                                                                        right_dev = dev;
1544
 
                                                                        if (verbose)
1545
 
                                                                                fprintf (output,"   adding device\n");
1546
 
                                                                }
1547
 
                                                        }
1548
 
                                                } else {
1549
 
                                                        // check configuration (only if no target class given)
1550
 
                                                        testdevh = usb_open(dev);
1551
 
                                                        int testconfig = get_current_configuration(testdevh);
1552
 
                                                        if (testconfig != configuration) {
1553
 
                                                                if (verbose)
1554
 
                                                                        fprintf (output,"   device configuration %d not matching parameter\n", testconfig);
1555
 
                                                                (*numFound)++;
1556
 
                                                                right_dev = dev;
1557
 
                                                                if (verbose)
1558
 
                                                                        fprintf (output,"   adding device\n");
1559
 
                                                        } else
1560
 
                                                                if (verbose)
1561
 
                                                                        fprintf (output,"   not adding device, target configuration already set\n");
 
1717
                                                if (verbose)
 
1718
                                                        fprintf (output,"   device class %02x not matching target\n", devClass);
 
1719
                                                if (mode == SEARCH_DEFAULT || mode == SEARCH_BUSDEV) {
 
1720
                                                        (*numFound)++;
 
1721
                                                        right_dev = dev;
 
1722
                                                        if (verbose)
 
1723
                                                                fprintf (output,"   count device\n");
1562
1724
                                                }
1563
1725
                                        }
 
1726
                                } else if (configuration > 0) {
 
1727
                                        // Configuration parameter is set, check device configuration
 
1728
                                        int testconfig = get_current_configuration(dev);
 
1729
                                        if (testconfig != configuration) {
 
1730
                                                if (verbose)
 
1731
                                                        fprintf (output,"   device configuration %d not matching target\n", testconfig);
 
1732
                                                (*numFound)++;
 
1733
                                                right_dev = dev;
 
1734
                                                if (verbose)
 
1735
                                                        fprintf (output,"   count device\n");
 
1736
                                        } else
 
1737
                                                if (verbose)
 
1738
                                                        fprintf (output,"   device not counted, target configuration reached\n");
 
1739
                                } else {
 
1740
                                        // Neither TargetClass nor Configuration are set
 
1741
                                        (*numFound)++;
 
1742
                                        right_dev = dev;
 
1743
                                        if (mode == SEARCH_BUSDEV)
 
1744
                                                break;
1564
1745
                                }
 
1746
                        }
 
1747
 
 
1748
                        NextToken:
 
1749
                        token = strtok(NULL, ",");
1565
1750
                }
1566
1751
        }
1567
1752
        if (listcopy != NULL)
1575
1760
 
1576
1761
/* Autodetect bulk endpoints (ab) */
1577
1762
 
1578
 
int find_first_bulk_output_endpoint(struct usb_device *dev)
1579
 
{
1580
 
        int i;
1581
 
        struct usb_interface_descriptor *alt = &(dev->config[0].interface[0].altsetting[0]);
1582
 
        struct usb_endpoint_descriptor *ep;
1583
 
 
1584
 
        for(i=0;i < alt->bNumEndpoints;i++) {
1585
 
                ep=&(alt->endpoint[i]);
1586
 
                if( ( (ep->bmAttributes & USB_ENDPOINT_TYPE_MASK) == USB_ENDPOINT_TYPE_BULK) &&
1587
 
                    ( (ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT ) ) {
1588
 
                        return ep->bEndpointAddress;
1589
 
                }
1590
 
        }
1591
 
 
1592
 
        return 0;
1593
 
}
1594
 
 
1595
 
 
1596
 
int find_first_bulk_input_endpoint(struct usb_device *dev)
1597
 
{
1598
 
        int i;
1599
 
        struct usb_interface_descriptor *alt = &(dev->config[0].interface[0].altsetting[0]);
1600
 
        struct usb_endpoint_descriptor *ep;
1601
 
 
1602
 
        for(i=0;i < alt->bNumEndpoints;i++) {
1603
 
                ep=&(alt->endpoint[i]);
1604
 
                if( ( (ep->bmAttributes & USB_ENDPOINT_TYPE_MASK) == USB_ENDPOINT_TYPE_BULK) &&
1605
 
                    ( (ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN ) ) {
1606
 
                        return ep->bEndpointAddress;
1607
 
                }
1608
 
        }
1609
 
 
1610
 
        return 0;
1611
 
}
1612
 
 
1613
 
int get_current_configuration(struct usb_dev_handle* devh)
1614
 
{
1615
 
        int ret;
1616
 
 
1617
 
        SHOW_PROGRESS(output,"Getting the current device configuration ...\n");
1618
 
        ret = usb_control_msg(devh, USB_DIR_IN + USB_TYPE_STANDARD + USB_RECIP_DEVICE, USB_REQ_GET_CONFIGURATION, 0, 0, buffer, 1, 1000);
1619
 
        if (ret < 0) {
1620
 
                // There are quirky devices which fail to respond properly to this command
1621
 
                fprintf(stderr, "Error getting the current configuration (error %d). Assuming configuration 1.\n", ret);
1622
 
                if (Configuration) {
1623
 
                        fprintf(stderr, " No configuration setting possible for this device.\n");
1624
 
                        Configuration = 0;
1625
 
                }
1626
 
                return 1;
1627
 
        } else {
1628
 
                SHOW_PROGRESS(output," OK, got current device configuration (%d)\n", buffer[0]);
1629
 
                return buffer[0];
1630
 
        }
1631
 
}
1632
 
 
1633
 
 
1634
 
int get_interface0_class(struct usb_device *dev, int devconfig)
1635
 
{
1636
 
        /* Hack for quirky devices */
1637
 
        if (devconfig == 0)
1638
 
                return dev->config[0].interface[0].altsetting[0].bInterfaceClass;
1639
 
 
1640
 
        int i;
1641
 
        for (i=0; i<dev->descriptor.bNumConfigurations; i++)
1642
 
                if (dev->config[i].bConfigurationValue == devconfig)
1643
 
                        return dev->config[i].interface[0].altsetting[0].bInterfaceClass;
 
1763
int find_first_bulk_endpoint(int direction)
 
1764
{
 
1765
        int i, j;
 
1766
        const struct libusb_interface_descriptor *alt;
 
1767
        const struct libusb_endpoint_descriptor *ep;
 
1768
 
 
1769
        for (j=0; j < active_config->bNumInterfaces; j++) {
 
1770
                alt = &(active_config->interface[j].altsetting[0]);
 
1771
                if (alt->bInterfaceNumber == Interface) {
 
1772
                        for(i=0; i < alt->bNumEndpoints; i++) {
 
1773
                                ep=&(alt->endpoint[i]);
 
1774
                                if( ( (ep->bmAttributes & LIBUSB_ENDPOINT_ADDRESS_MASK) == LIBUSB_TRANSFER_TYPE_BULK) &&
 
1775
                                    ( (ep->bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK) == direction ) ) {
 
1776
                                        return ep->bEndpointAddress;
 
1777
                                }
 
1778
                        }
 
1779
                }
 
1780
        }
 
1781
        return 0;
 
1782
}
 
1783
 
 
1784
int get_current_configuration()
 
1785
{
 
1786
        int cfg;
 
1787
        SHOW_PROGRESS(output,"Get the current device configuration ...\n");
 
1788
        if (active_config == NULL)
 
1789
                libusb_get_active_config_descriptor(dev, &active_config);
 
1790
 
 
1791
        cfg = active_config->bConfigurationValue;
 
1792
        libusb_free_config_descriptor(active_config);
 
1793
        if (ret < 0)
 
1794
                exit(1);
 
1795
        else
 
1796
                return cfg;
 
1797
}
 
1798
 
 
1799
int get_interface_class()
 
1800
{
 
1801
        int i;
 
1802
        for (i=0; i < active_config->bNumInterfaces; i++) {
 
1803
                if (active_config->interface[i].altsetting[0].bInterfaceNumber == Interface)
 
1804
                        return active_config->interface[i].altsetting[0].bInterfaceClass;
 
1805
        }
1644
1806
        return -1;
1645
1807
}
1646
1808
 
1647
 
 
1648
1809
/* Parameter parsing */
1649
1810
 
1650
1811
char* ReadParseParam(const char* FileName, char *VariableName)
1651
1812
{
1652
1813
        static int numLines = 0;
1653
1814
        static char* ConfigBuffer[MAXLINES];
1654
 
 
1655
1815
        char *VarName, *Comment=NULL, *Equal=NULL;
1656
1816
        char *FirstQuote, *LastQuote, *P1, *P2;
1657
 
        int Line=0, Len=0, Pos=0;
 
1817
        int Line=0;
 
1818
        unsigned Len=0, Pos=0;
1658
1819
        char Str[LINE_DIM], *token, *configPos;
1659
1820
        FILE *file = NULL;
1660
1821
 
1661
1822
        // Reading and storing input during the first call
1662
1823
        if (numLines==0) {
1663
1824
                if (strncmp(FileName,"##",2) == 0) {
1664
 
                        if (verbose) fprintf(output,"\nReading long config from command line\n");
 
1825
                        if (verbose) fprintf(output,"\nRead long config from command line\n");
1665
1826
                        // "Embedded" configuration data
1666
1827
                        configPos = (char*)FileName;
1667
1828
                        token = strtok(configPos, "\n");
1668
1829
                        strncpy(Str,token,LINE_DIM-1);
1669
1830
                } else {
1670
1831
                        if (strcmp(FileName, "stdin")==0) {
1671
 
                                if (verbose) fprintf(output,"\nReading long config from stdin\n");
 
1832
                                if (verbose) fprintf(output,"\nRead long config from stdin\n");
1672
1833
                                file = stdin;
1673
1834
                        } else {
1674
 
                                if (verbose) fprintf(output,"\nReading config file: %s\n", FileName);
 
1835
                                if (verbose) fprintf(output,"\nRead config file: %s\n", FileName);
1675
1836
                                file=fopen(FileName, "r");
1676
1837
                        }
1677
1838
                        if (file==NULL) {
1678
 
                                fprintf(stderr, "Error: Could not find file %s\n\n", FileName);
 
1839
                                fprintf(stderr, "Error: Could not find file %s. Abort\n\n", FileName);
1679
1840
                                exit(1);
1680
1841
                        } else {
1681
1842
                                token = fgets(Str, LINE_DIM-1, file);
1732
1893
                Pos=strspn (Str, " \t");
1733
1894
                if (Pos==strlen(Str)) {
1734
1895
                        fprintf(stderr, "Error reading parameters from file %s - Missing variable name:\n%s\n", FileName, Str);
1735
 
                        goto Next;              // No function name
 
1896
                        goto Next;
1736
1897
                }
1737
1898
                while ((P1=strrchr(Str, ' '))!=NULL or (P2=strrchr(Str, '\t'))!=NULL)
1738
1899
                        if (P1!=NULL) *P1='\0';
1742
1903
                Pos=strspn (Equal, " \t");
1743
1904
                if (Pos==strlen(Equal)) {
1744
1905
                        fprintf(stderr, "Error reading parameter from file %s - Missing value:\n%s\n", FileName, Str);
1745
 
                        goto Next;              // No function name
 
1906
                        goto Next;
1746
1907
                }
1747
1908
                Equal+=Pos;
1748
1909
 
1801
1962
void printVersion()
1802
1963
{
1803
1964
        char* version = VERSION;
1804
 
        printf("\n * usb_modeswitch: handle USB devices with multiple modes\n"
1805
 
                " * Version %s (C) Josua Dietze 2012\n"
1806
 
                " * Based on libusb0 (0.1.12 and above)\n\n"
 
1965
        fprintf(output,"\n * usb_modeswitch: handle USB devices with multiple modes\n"
 
1966
                " * Version %s (C) Josua Dietze 2014\n"
 
1967
                " * Based on libusb1/libusbx\n\n"
1807
1968
                " ! PLEASE REPORT NEW CONFIGURATIONS !\n\n", version);
1808
1969
}
1809
1970
 
1810
1971
void printHelp()
1811
1972
{
1812
 
        fprintf (output,"\nUsage: usb_modeswitch [<params>] [-c filename]\n\n"
 
1973
        fprintf(output,"\nUsage: usb_modeswitch [<params>] [-c filename]\n\n"
1813
1974
        " -h, --help                    this help\n"
1814
1975
        " -e, --version                 print version information and exit\n"
 
1976
        " -j, --find-mbim               return config no. with MBIM interface, exit\n\n"
1815
1977
        " -v, --default-vendor NUM      vendor ID of original mode (mandatory)\n"
1816
1978
        " -p, --default-product NUM     product ID of original mode (mandatory)\n"
1817
1979
        " -V, --target-vendor NUM       target mode vendor ID (optional)\n"
1818
1980
        " -P, --target-product NUM      target mode product ID (optional)\n"
1819
1981
        " -C, --target-class NUM        target mode device class (optional)\n"
1820
 
        " -b, --busnum NUM              system bus number of device (for hard ID)\n"
1821
 
        " -g, --devnum NUM              system device number (for hard ID)\n"
 
1982
        " -b, --bus-num NUM             system bus number of device (for hard ID)\n"
 
1983
        " -g, --device-num NUM          system device number (for hard ID)\n"
1822
1984
        " -m, --message-endpoint NUM    direct the message transfer there (optional)\n"
1823
1985
        " -M, --message-content <msg>   message to send (hex number as string)\n"
1824
1986
        " -2 <msg>, -3 <msg>            additional messages to send (-n recommended)\n"
1825
1987
        " -n, --need-response           read response to the message transfer (CSW)\n"
1826
1988
        " -r, --response-endpoint NUM   read response from there (optional)\n"
 
1989
        " -K, --std-eject               send standard EJECT sequence\n"
1827
1990
        " -d, --detach-only             detach the active driver, no further action\n"
1828
1991
        " -H, --huawei-mode             apply a special procedure\n"
1829
1992
        " -S, --sierra-mode             apply a special procedure\n"
1834
1997
        " -T, --kobil-mode              apply a special procedure\n"
1835
1998
        " -L, --cisco-mode              apply a special procedure\n"
1836
1999
        " -B, --qisda-mode              apply a special procedure\n"
 
2000
        " -E, --quanta-mode             apply a special procedure\n"
1837
2001
        " -R, --reset-usb               reset the device after all other actions\n"
1838
2002
        " -Q, --quiet                   don't show progress or error messages\n"
1839
2003
        " -W, --verbose                 print all settings and debug output\n"
1840
2004
        " -D, --sysmode                 specific result and syslog message\n"
1841
2005
        " -s, --success <seconds>       switching result check with timeout\n"
1842
 
        " -I, --no-inquire              do not get SCSI attributes (default on)\n\n"
 
2006
        " -I, --inquire                 retrieve SCSI attributes initially\n\n"
1843
2007
        " -c, --config-file <filename>  load long configuration from file\n\n"
1844
2008
        " -t, --stdinput                read long configuration from stdin\n\n"
1845
2009
        " -f, --long-config <text>      get long configuration from string\n\n"