2 Activate the smartcard interface on the kobil midentity usb device
3 Copyright (C) 2006 Norbert Federa <norbert.federa@neoware.com>
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public License
16 along with this library; if not, write to the Free Software Foundation,
17 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 Author: Norbert Federa <norbert.federa@neoware.com>
25 This tool is needed to activate the smartcard interface on the kobil midentity
26 usb device (vendor 0x04D6 id 0x4081)
28 Kobil's own implementation was a kernel usb driver which did just send a
29 libusb_control_transfer in the probe routine.
31 We do the same via libusb and call this program from our /sbin/hotblug script
32 if the mIDentity gets added.
34 The kobil switcher driver was found inside this zip ...
35 http://www.kobil.com/download/partner/KOBIL_mIDentity_SDK_Build_20060320_RELEASE.zip
36 ... under Interfaces/Linux/module_with_binary_final.tar.gz.
38 Here the interesting part of the kernel driver inside the probe function:
40 if (dev->descriptor.idVendor == KOBIL_VENDOR_ID){
41 printk("!!!!! DEVICE FOUND !!! !\n");
42 ret = libusb_control_transfer(dev,
53 Initally the it did not work with libusb because the ioctl gets ignored with
54 the used RequestType of 0x22 in combination with index 0x0001, but index 0x0002
55 worked. See usb/devio.c functions proc_control() -> check_ctrlrecip() ->
56 findintfep() in order to understand why.
68 #define KOBIL_VENDOR_ID 0x0D46
69 #define MID_DEVICE_ID 0x4081
70 #define KOBIL_TIMEOUT 5000
71 #define VAL_STARTUP_4080 1
72 #define VAL_STARTUP_4000 2
73 #define VAL_STARTUP_4020 3
74 #define VAL_STARTUP_40A0 4
75 #define HIDCMD_SWITCH_DEVICE 0x0004
77 #define bmRequestType 0x22
80 #define wIndex 0x0002 /* this was originally 0x0001 */
83 static int kobil_midentity_control_msg(libusb_device_handle *usb)
87 unsigned char switchCmd[10];
89 unsigned char Sleep = 1;
90 unsigned char hardDisk = 1;
92 unsigned char param = ((hardDisk) << 4) | (Sleep);
94 memset(switchCmd, 0x0, sizeof(switchCmd));
95 switchCmd[0] = HIDCMD_SWITCH_DEVICE >> 8;
96 switchCmd[1] = HIDCMD_SWITCH_DEVICE;
97 switchCmd[5] = VAL_STARTUP_4000;
100 ret = libusb_control_transfer(usb, bmRequestType, bRequest, wValue, wIndex,
101 switchCmd, sizeof(switchCmd), KOBIL_TIMEOUT);
103 return(!(ret==sizeof(switchCmd)));
107 static int kobil_midentity_claim_interface(libusb_device_handle *usb, int ifnum)
111 printf("claiming interface #%d ... ", ifnum);
112 rv = libusb_claim_interface(usb, ifnum);
121 printf("failed with error %d, trying to detach kernel driver ....\n", rv);
122 rv = libusb_detach_kernel_driver(usb, ifnum);
125 printf("success, claiming interface again ...");
126 rv = libusb_claim_interface(usb, ifnum);
136 printf("failed with error %d, giving up.\n", rv);
141 int main(int argc, char *argv[])
143 libusb_device **devs, *dev;
144 libusb_device *found_dev = NULL;
145 struct libusb_device_handle *usb = NULL;
152 rv = libusb_init(NULL);
155 (void)printf("libusb_init() failed\n");
159 cnt = libusb_get_device_list(NULL, &devs);
162 (void)printf("libusb_get_device_list() failed\n");
166 /* for every device */
168 while ((dev = devs[i++]) != NULL)
170 struct libusb_device_descriptor desc;
172 rv = libusb_get_device_descriptor(dev, &desc);
174 (void)printf("failed to get device descriptor\n");
178 printf("vendor/product: %04X %04X\n", desc.idVendor, desc.idProduct);
179 if (desc.idVendor == KOBIL_VENDOR_ID && desc.idProduct == MID_DEVICE_ID)
183 if (found_dev == NULL)
185 printf("device not found. aborting.\n");
187 printf("Try to rerun this program as root.\n");
191 printf("Device found, opening ... ");
192 rv = libusb_open(found_dev, &usb);
195 printf("failed, aborting.\n");
200 rv = kobil_midentity_claim_interface(usb, 0);
207 rv = kobil_midentity_claim_interface(usb, 1);
214 printf("Activating the CCID configuration .... ");
215 rv = kobil_midentity_control_msg(usb);
219 printf("failed with error %d, giving up.\n", rv);