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

« back to all changes in this revision

Viewing changes to usb_modeswitch.c

  • Committer: Bazaar Package Importer
  • Author(s): Didier Raboud
  • Date: 2010-01-12 15:58:14 UTC
  • mfrom: (1.1.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20100112155814-8ve516a5iirpx5sg
Tags: 1.0.7-1
* New 1.0.7 upstream version (Closes: #563527).
  - Update the manpage
  - Split source in binary and data packages.
* Patches:
  - 01_correct_broken_huawei_conf.patch
      Removed.
  + 03_build_system_to_policy.patch
      Refreshed.
  - 04_convert_umconf_to_unicode.patch
      Removed.
  + 05_move_wrappers_to_usr.patch
      Refreshed.
  - 06_disables_rules.patch
      Removed.
* Add a preinst to delete configuration files forgotten in previous releases
  - Also delete /etc/udev/rules.d/80-usb_modeswitch.rules.
  - Delete only the data files not included in the -data upload
* Update README.Debian.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
  Mode switching tool for controlling flip flop (multiple device) USB gear
3
 
  Version 1.0.5, 2009/08/26
 
3
  Version 1.0.7, 2010/01/06
4
4
 
5
 
  Copyright (C) 2007, 2008, 2009 Josua Dietze (mail to "usb_admin" at the
 
5
  Copyright (C) 2007, 2008, 2009, 2010 Josua Dietze (mail to "usb_admin" at the
6
6
  domain from the README; please do not post the complete address to The Net!
7
7
  Or write a personal message through the forum to "Josh")
8
8
 
22
22
  Hexstr2bin function borrowed from:
23
23
    Jouni Malinen (http://hostap.epitest.fi/wpa_supplicant, from "common.c")
24
24
 
25
 
  Code, fixes and ideas from:
 
25
  Code, fixes, ideas and testing assistance from:
26
26
    Aki Makkonen
27
27
    Denis Sutter
28
28
    Lucas Benedicic
32
32
    Daniel Cooper
33
33
    Andrew Bird
34
34
    Steven Fernandez
 
35
    Yaroslav Levandovskiy
35
36
 
36
37
  More contributors are listed in the config file.
37
38
 
51
52
 
52
53
/* Recommended tab size: 4 */
53
54
 
54
 
char *version="1.0.5";
 
55
char *version="1.0.7";
55
56
 
56
57
#include <stdio.h>
57
58
#include <stdlib.h>
91
92
int devnum=-1, busnum=-1;
92
93
int ret;
93
94
 
94
 
char DetachStorageOnly=0, HuaweiMode=0, SierraMode=0, SonyMode=0;
 
95
char DetachStorageOnly=0, HuaweiMode=0, SierraMode=0, SonyMode=0, GCTMode=0;
95
96
char verbose=0, show_progress=1, ResetUSB=0, CheckSuccess=0, config_read=0;
96
97
char NeedResponse=0, InquireDevice=1;
97
98
 
121
122
        {"huawei-mode",                 no_argument, 0, 'H'},
122
123
        {"sierra-mode",                 no_argument, 0, 'S'},
123
124
        {"sony-mode",                   no_argument, 0, 'O'},
 
125
        {"gct-mode",                    no_argument, 0, 'G'},
124
126
        {"need-response",               no_argument, 0, 'n'},
125
127
        {"reset-usb",                   no_argument, 0, 'R'},
126
128
        {"config",                              required_argument, 0, 'c'},
140
142
        if (verbose) printf("Reading config file: %s\n", configFilename);
141
143
        ParseParamHex(configFilename, TargetVendor);
142
144
        ParseParamHex(configFilename, TargetProduct);
143
 
        if (!TargetProduct)
144
 
                ParseParamString(configFilename, TargetProductList);
 
145
        ParseParamString(configFilename, TargetProductList);
145
146
        ParseParamHex(configFilename, TargetClass);
146
147
        ParseParamHex(configFilename, DefaultVendor);
147
148
        ParseParamHex(configFilename, DefaultProduct);
149
150
        ParseParamBool(configFilename, HuaweiMode);
150
151
        ParseParamBool(configFilename, SierraMode);
151
152
        ParseParamBool(configFilename, SonyMode);
 
153
        ParseParamBool(configFilename, GCTMode);
152
154
        ParseParamHex(configFilename, MessageEndpoint);
153
155
        ParseParamString(configFilename, MessageContent);
154
156
        ParseParamHex(configFilename, NeedResponse);
159
161
        ParseParamHex(configFilename, Interface);
160
162
        ParseParamHex(configFilename, Configuration);
161
163
        ParseParamHex(configFilename, AltSetting);
 
164
 
 
165
        // TargetProductList has priority over TargetProduct
 
166
        if (strlen(TargetProductList))
 
167
                TargetProduct = 0;
 
168
 
162
169
        config_read = 1;
163
170
}
164
171
 
165
172
 
166
173
void printConfig()
167
174
{
168
 
        printf ("DefaultVendor=  0x%04x\n",             DefaultVendor);
169
 
        printf ("DefaultProduct= 0x%04x\n",     DefaultProduct);
 
175
        printf ("DefaultVendor=  0x%04x\n",                     DefaultVendor);
 
176
        printf ("DefaultProduct= 0x%04x\n",                     DefaultProduct);
170
177
        if ( TargetVendor )
171
178
                printf ("TargetVendor=   0x%04x\n",             TargetVendor);
172
179
        else
175
182
                printf ("TargetProduct=  0x%04x\n",             TargetProduct);
176
183
        else
177
184
                printf ("TargetProduct=  not set\n");
 
185
        if ( strlen(TargetProductList) )
 
186
                printf ("TargetProductList=%s\n",               TargetProductList);
 
187
//      else
 
188
//              printf ("TargetProduct=  not set\n");
178
189
        if ( TargetClass )
179
190
                printf ("TargetClass=    0x%02x\n",             TargetClass);
180
191
        else
183
194
        printf ("HuaweiMode=%i\n",                      (int)HuaweiMode);
184
195
        printf ("SierraMode=%i\n",                      (int)SierraMode);
185
196
        printf ("SonyMode=%i\n",                        (int)SonyMode);
 
197
        printf ("GCTMode=%i\n",                 (int)GCTMode);
186
198
        if ( MessageEndpoint )
187
199
                printf ("MessageEndpoint=0x%02x\n",     MessageEndpoint);
188
200
        else
220
232
 
221
233
        while (1)
222
234
        {
223
 
                c = getopt_long (argc, argv, "heWQndHSORIv:p:V:P:C:m:M:r:c:i:u:a:s:",
 
235
                c = getopt_long (argc, argv, "heWQndHSOGRIv:p:V:P:C:m:M:r:c:i:u:a:s:",
224
236
                                                long_options, &option_index);
225
237
        
226
238
                /* Detect the end of the options. */
243
255
                        case 'H': HuaweiMode = 1; break;
244
256
                        case 'S': SierraMode = 1; break;
245
257
                        case 'O': SonyMode = 1; break;
 
258
                        case 'G': GCTMode = 1; break;
246
259
                        case 'c': readConfigFile(optarg); break;
247
260
                        case 'W': verbose = 1; show_progress = 1; count--; break;
248
261
                        case 'Q': show_progress = 0; verbose = 0; count--; break;
275
288
                                printf (" -H, --huawei-mode             apply a special procedure\n");
276
289
                                printf (" -S, --sierra-mode             apply a special procedure\n");
277
290
                                printf (" -O, --sony-mode               apply a special procedure\n");
 
291
                                printf (" -G, --gct-mode                apply a special procedure\n");
278
292
                                printf (" -R, --reset-usb               reset the device in the end\n");
279
293
                                printf (" -c, --config [filename]       load different config file\n");
280
294
                                printf (" -Q, --quiet                   don't show progress or error messages\n");
281
295
                                printf (" -W, --verbose                 print all settings before running\n");
282
296
                                printf (" -s, --success [nr]            check switching result after [nr] secs\n");
283
297
                                printf (" -I, --no-inquire              do not get device details (default on)\n\n");
284
 
                                printf (" -i, --interface               select initial USB interface (default 0)\n");
285
 
                                printf (" -u, --configuration           select USB configuration\n");
286
 
                                printf (" -a, --altsetting              select alternative USB interface setting\n\n");
 
298
                                printf (" -i, --interface [nr]          select initial USB interface (default 0)\n");
 
299
                                printf (" -u, --configuration [nr]      select USB configuration\n");
 
300
                                printf (" -a, --altsetting [nr]         select alternative USB interface setting\n\n");
287
301
                                exit(0);
288
302
                                break;
289
303
                
346
360
                }
347
361
        }
348
362
        SHOW_PROGRESS("\n");
 
363
 
349
364
        if (show_progress)
350
 
                if (CheckSuccess && !(TargetVendor || TargetProduct) && !TargetClass)
 
365
                if (CheckSuccess && !(TargetVendor || TargetProduct || strlen(TargetProductList)) && !TargetClass)
351
366
                        printf("Note: target parameter missing; success check limited\n");
352
367
 
353
368
        // Count existing target devices (remember for success check)
362
377
 
363
378
        // Count default devices, return the last one found
364
379
        SHOW_PROGRESS("Looking for default devices ...\n");
365
 
        dev = search_devices(&numDefaults, DefaultVendor, DefaultProduct, NULL, TargetClass);
 
380
        dev = search_devices(&numDefaults, DefaultVendor, DefaultProduct, "\0", TargetClass);
366
381
        if (numDefaults) {
367
382
                SHOW_PROGRESS(" Found default devices (%d)\n", numDefaults);
368
383
                if (TargetClass && !(TargetVendor || TargetProduct)) {
388
403
        defaultClass = dev->descriptor.bDeviceClass;
389
404
        if (defaultClass == 0)
390
405
                defaultClass = dev->config[0].interface[0].altsetting[0].bInterfaceClass;
 
406
        else 
 
407
                if (dev->config[0].interface[0].altsetting[0].bInterfaceClass == 8 && defaultClass != 8) {
 
408
                        // Weird device with default class other than 0 and differing interface class
 
409
                        SHOW_PROGRESS("Ambiguous Class/InterfaceClass: 0x%02x/0x08", defaultClass);
 
410
                        defaultClass = 8;
 
411
                }
391
412
 
392
413
        // Check or get endpoints if needed
393
414
        if (!MessageEndpoint && (strlen(MessageContent) || InquireDevice) ) {
425
446
 
426
447
        deviceDescription();
427
448
        if (show_progress) {
428
 
                printf("\nDevice description data (identification)\n");
 
449
                printf("\nUSB description data (for identification)\n");
429
450
                printf("-------------------------\n");
430
451
                printf("Manufacturer: %s\n", imanufact);
431
452
                printf("     Product: %s\n", iproduct);
449
470
 
450
471
#ifdef USE_SYSLOG
451
472
        openlog("usb_modeswitch", 0, LOG_SYSLOG);
452
 
//      syslog(LOG_NOTICE, "v1.0.3 (C) 2009 Josua Dietze");
453
473
        syslog(LOG_NOTICE, "switching %04x:%04x (%s: %s)", DefaultVendor, DefaultProduct, imanufact, iproduct);
454
474
#endif
455
475
 
470
490
        if (SierraMode) {
471
491
                switchSierraMode();
472
492
        }
 
493
        if (GCTMode) {
 
494
                detachDriver();
 
495
                switchGCTMode();
 
496
        }
473
497
        if (SonyMode) {
474
498
                sonySuccess = switchSonyMode();
475
499
        }
550
574
#endif
551
575
                exit(0);
552
576
        }
 
577
        return 0;
553
578
}
554
579
 
555
580
 
556
581
/* Get descriptor strings if available (identification details) */
557
 
deviceDescription ()
 
582
void deviceDescription ()
558
583
{
559
 
        int i, ret;
 
584
        int ret;
560
585
        char* c;
561
586
        memset (imanufact, ' ', DESCR_MAX);
562
587
        memset (iproduct, ' ', DESCR_MAX);
636
661
 
637
662
        i = usb_bulk_read(devh, ResponseEndpoint, command, 13, 0);
638
663
 
639
 
        printf("\nReceived inquiry data (detailed identification)\n");
 
664
        printf("\nSCSI inquiry data (for identification)\n");
640
665
        printf("-------------------------\n");
641
666
 
642
667
        printf("  Vendor String: ");
661
686
}
662
687
 
663
688
 
664
 
int resetUSB ()
 
689
void resetUSB ()
665
690
{
666
691
        int success;
667
692
        int bpoint = 0;
743
768
        if (ret == 0 ) {
744
769
                SHOW_PROGRESS(" OK, configuration set\n");
745
770
                return 1;
746
 
        } else {
747
 
                SHOW_PROGRESS(" Setting the configuration returned error %d. Trying to continue\n", ret);
748
 
                return 0;
749
771
        }
 
772
        SHOW_PROGRESS(" Setting the configuration returned error %d. Trying to continue\n", ret);
 
773
        return 0;
750
774
}
751
775
 
752
776
 
768
792
}
769
793
 
770
794
 
771
 
int switchHuaweiMode ()
 
795
void switchHuaweiMode ()
772
796
{
773
797
        int ret;
774
798
 
782
806
}
783
807
 
784
808
 
785
 
int switchSierraMode ()
 
809
void switchSierraMode ()
786
810
{
787
811
        int ret;
788
812
 
796
820
}
797
821
 
798
822
 
 
823
void switchGCTMode ()
 
824
{
 
825
        int ret;
 
826
 
 
827
        ret = usb_claim_interface(devh, Interface);
 
828
        if (ret != 0) {
 
829
                SHOW_PROGRESS(" Could not claim interface (error %d). Skipping GCT sequence \n", ret);
 
830
                return;
 
831
        }
 
832
 
 
833
        SHOW_PROGRESS("Sending GCT control message 1 ...\n");
 
834
        ret = usb_control_msg(devh, 0xa1, 0xa0, 0, Interface, buffer, 1, 1000);
 
835
        SHOW_PROGRESS("Sending GCT control message 2 ...\n");
 
836
        ret = usb_control_msg(devh, 0xa1, 0xfe, 0, Interface, buffer, 1, 1000);
 
837
        SHOW_PROGRESS(" OK, GCT control messages sent\n");
 
838
        usb_release_interface(devh, Interface);
 
839
}
 
840
 
 
841
 
799
842
int switchSonyMode ()
800
843
{
801
844
        int i, found, ret;
816
859
 
817
860
        usb_close(devh);
818
861
 
 
862
        /* Now waiting for the device to reappear */
 
863
        devnum=-1;
 
864
        busnum=-1;
819
865
        i=0;
820
866
        dev = NULL;
821
867
        while ( dev == NULL && i < 30 ) {
857
903
        if (ret < 0) {
858
904
                fprintf(stderr, "Error: sending Sony control message (2) failed (error %d)\n", ret);
859
905
                return 0;
860
 
        } else {
861
 
                SHOW_PROGRESS(" OK, control message sent\n");
862
 
                return 1;
863
906
        }
864
 
 
865
 
        Interface=8;
866
 
        AltSetting=2;
 
907
        SHOW_PROGRESS(" OK, control message sent\n");
 
908
        return 1;
867
909
}
868
910
 
869
911
 
915
957
        sleep(1);
916
958
 
917
959
        if (devh) // devh is 0 if device vanished during command transmission
918
 
                for (i; i < CheckSuccess; i++) {
 
960
                for (i=0; i < CheckSuccess; i++) {
919
961
 
920
962
                        // Test if default device still can be accessed; positive result does
921
963
                        // not necessarily mean failure
943
985
                present = 0;
944
986
        }
945
987
 
946
 
        if ( (TargetVendor && (TargetProduct || TargetProductList)) || TargetClass )
 
988
        if ( (TargetVendor && (TargetProduct || strlen(TargetProductList))) || TargetClass )
947
989
 
948
990
                // Recount target devices (compare with previous count) if target data is given.
949
991
                // Target device on the same bus with higher device number is returned,
950
992
                // description is read for syslog message
951
 
                for (i; i < CheckSuccess; i++) {
 
993
                for (i=i; i < CheckSuccess; i++) {
952
994
                        SHOW_PROGRESS(" Searching for target devices ...\n");
953
995
                        usb_find_devices();
954
996
                        dev = search_devices(&newTargetCount, TargetVendor, TargetProduct, TargetProductList, TargetClass);
1018
1060
                } else
1019
1061
                        SHOW_PROGRESS(" Sending the message returned error %d. Trying to continue\n", ret);
1020
1062
        return ret;
 
1063
 
1021
1064
}
1022
1065
 
1023
1066
int read_bulk(int endpoint, char *buffer, int length)
1033
1076
                } else
1034
1077
                        SHOW_PROGRESS(" Response reading got error %d, can probably be ignored\n", ret);
1035
1078
        return ret;
 
1079
 
1036
1080
}
1037
1081
 
1038
1082
void release_usb_device(int dummy) {
1039
 
        int ret;
1040
1083
        SHOW_PROGRESS("Program cancelled by system. Bye.\n\n");
1041
1084
        usb_release_interface(devh, Interface);
1042
1085
        usb_close(devh);
1044
1087
        closelog();
1045
1088
#endif
1046
1089
        exit(0);
 
1090
 
1047
1091
}
1048
1092
 
1049
1093
 
1053
1097
{
1054
1098
        struct usb_bus *bus;
1055
1099
        char *listcopy, *token, buffer[2];
1056
 
        int devClass, product_match = 0;
 
1100
        int devClass;
1057
1101
        struct usb_device* right_dev = NULL;
1058
1102
        
1059
1103
        if ( targetClass && !(vendor || product) ) {
1070
1114
                struct usb_device *dev;
1071
1115
                for (dev = bus->devices; dev; dev = dev->next) {
1072
1116
                        // product list given
1073
 
                        if (productList != NULL) {
 
1117
                        if ( strlen(productList) ) {
1074
1118
                                strcpy(listcopy, productList);
1075
1119
                                token = strtok(listcopy, ",");
1076
1120
                                while (token != NULL) {
1108
1152
                                        devClass = dev->descriptor.bDeviceClass;
1109
1153
                                        if (devClass == 0)
1110
1154
                                                devClass = dev->config[0].interface[0].altsetting[0].bInterfaceClass;
 
1155
                                        else
 
1156
                                                if (devClass != dev->config[0].interface[0].altsetting[0].bInterfaceClass)
 
1157
                                                        devClass = dev->config[0].interface[0].altsetting[0].bInterfaceClass;
1111
1158
                                        if (busnum == -1) {
1112
1159
                                                if (devClass != targetClass || targetClass == 0)
1113
1160
                                                        right_dev = dev;
1114
1161
                                        } else
1115
 
                                                if (devClass == targetClass)
 
1162
                                                if (devClass == targetClass || targetClass == 0)
1116
1163
                                                        if (dev->devnum >= devnum && (int)strtol(dev->bus->dirname,NULL,10) == busnum)
1117
1164
                                                                right_dev = dev;
1118
1165
                                }
1283
1330
        return 0;
1284
1331
}
1285
1332
 
1286
 
printVersion()
 
1333
void printVersion()
1287
1334
{
1288
1335
        printf("\n * usb_modeswitch: handle USB devices with multiple modes\n");
1289
1336
        printf(" * Version %s (C) Josua Dietze 2009\n", version);
1290
1337
        printf(" * Based on libusb 0.1.12\n\n");
1291
 
}
 
 
b'\\ No newline at end of file'
 
1338
        printf(" ! PLEASE REPORT NEW CONFIGURATIONS !\n\n");
 
1339
}