Subversion Repositories group.NITPanels

Rev

Rev 2 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2 Rev 26
Line 1... Line -...
1
#include <ncurses.h>
-
 
2
#include <malloc.h>
-
 
3
 
-
 
4
#include <stdio.h>
1
#include <stdio.h>
5
#include <stdlib.h>
2
#include <stdlib.h>
6
#include <string.h>
3
#include <string.h>
-
 
4
 
-
 
5
/* this is libusb, see http://libusb.sourceforge.net/ */
7
#include <usb.h>
6
#include <usb.h>
8
 
7
 
9
#define DISPLAYS_ATTACHED 1
-
 
10
 
8
 
11
static int usbGetDescriptorString(usb_dev_handle *dev, int index, int langid, char *buf, int buflen);
9
static int usbGetDescriptorString(usb_dev_handle *dev, int index, int langid, char *buf, int buflen);
12
static usb_dev_handle * usbOpenDevice(int vendor, char *vendorName, int product, char *productName);
10
static usb_dev_handle * usbOpenDevice(int vendor, char *vendorName, int product, char *productName);
13
char sendDigit(char dis, char dig, char val, char dp);
-
 
14
char sendShort(char dis, char dig, short val);
-
 
15
char sendLatch(char dis);
-
 
16
char getInput(char dis);
-
 
17
 
-
 
18
char* getBCD(char maxLen);
-
 
19
short getHex();
-
 
20
void printBCD(char* data);
-
 
21
void printB(char *data);
-
 
22
 
11
 
-
 
12
char getDisplayInput(uint8_t disnum);
-
 
13
char getDisplayCount();
23
void drawScreen();
14
char getControllerVersion();
-
 
15
char getDisplayMeta(uint8_t disnum);
-
 
16
 
-
 
17
char setDisplayLatch(uint8_t disnum);
-
 
18
char setDisplayDigit(uint8_t disnum, uint8_t digit, uint8_t value);
24
 
19
 
25
usb_dev_handle *handle = NULL;
20
usb_dev_handle *handle = NULL;
26
char usbReplyBuf[64];
21
char usbReplyBuf[64];
27
 
22
 
-
 
23
typedef unsigned char uint8_t;
-
 
24
typedef unsigned short uint16_t;
-
 
25
 
-
 
26
#define MAX_DISPLAYS			4
-
 
27
 
-
 
28
#define USB_GET_VERSION			01
-
 
29
#define USB_GET_DISPLAY_COUNT	10
-
 
30
#define USB_GET_DISPLAY_META	11
-
 
31
 
-
 
32
#define USB_SET_LATCH			20
-
 
33
#define USB_SET_DISPLAY_DIGIT	21
-
 
34
#define USB_SET_POINTS			23
-
 
35
#define USB_GET_DISPLAY_INPUT	30
-
 
36
 
28
typedef struct display {
37
typedef struct display {
-
 
38
	uint8_t address;
-
 
39
	unsigned short version;
-
 
40
	char config;
-
 
41
 
29
	char digits[10];
42
	char digits[10];
-
 
43
	
30
	char rotary;
44
	char outer;
-
 
45
	char inner;
31
	char buttons;
46
	char buttons;
-
 
47
	
32
} display_t;
48
} display_t;
33
 
49
 
34
typedef struct controller_t {
50
typedef struct controller_t {
-
 
51
	unsigned char display_count;
-
 
52
	unsigned short version;
35
	display_t* dis[2];
53
	display_t* dis[MAX_DISPLAYS];
36
} controller_t;
54
} controller_t;
37
 
55
 
38
typedef struct cursor_t {
-
 
39
	char dis;
-
 
40
	char dig;
-
 
41
	char val;
-
 
42
	char dp;
-
 
43
} cursor_t;
-
 
44
 
-
 
45
controller_t controller;
56
controller_t controller;
46
cursor_t cursor;
-
 
47
 
57
 
48
main() {
-
 
49
 
-
 
50
 
-
 
51
	handle = usbOpenDevice(0x20a0, "newioit.com.au", 0x4236, "NIT Comm/Nav");
-
 
52
 
-
 
53
	if(handle == NULL) {
58
int main(int argc, char **argv) {
54
		fprintf(stderr, "Could not find USB device!\n");
-
 
55
		exit(1);
-
 
56
	}
-
 
57
 
-
 
58
	initscr();
-
 
59
	raw();
-
 
60
	keypad(stdscr, TRUE);
-
 
61
	noecho();
-
 
62
	nodelay(stdscr, TRUE);
-
 
63
 
-
 
64
	controller.dis[0]->buttons = 0;
-
 
65
	controller.dis[0]->rotary = 0;
-
 
66
 
-
 
67
	cursor.dis = 0x00;
-
 
68
	cursor.dig = 0x00;
-
 
69
	cursor.val = 0x0a;
-
 
70
	cursor.dp = 0x00;
-
 
71
 
-
 
72
	char cont = 1;
59
    int nBytes = 0;
73
 
-
 
74
	//char display[] = {
60
    char buffer[256];
75
 
-
 
76
	while (cont) {
-
 
77
		clear();
-
 
78
 
-
 
79
 
-
 
80
		printw("\nCursor: ");
-
 
81
		printw("Dis: %x ", cursor.dis);
-
 
82
		printw("Dig %x ", cursor.dig);
-
 
83
		printw("Val %x ", cursor.val);
-
 
84
		printw("Dp %x ", cursor.dp);
-
 
85
		printw("\n");
-
 
86
 
-
 
87
		printw("But: %02X ", controller.dis[0]->buttons & 0xff);
-
 
88
		printw("Rot: %02X ", controller.dis[0]->rotary & 0xff);
-
 
89
		printw("\n");
-
 
90
		//printw("\nCursor: ");
-
 
91
 
-
 
92
		char key = 0x00;
-
 
93
		while ((key == getch() != ERR)) {
-
 
94
			if (key == 'q') {
-
 
95
				cont = 0;
-
 
96
			}
-
 
97
		}
-
 
98
 
61
 
-
 
62
    handle = usbOpenDevice(0x20a0, "newioit.com.au", 0x4236, "NIT Comm/Nav");
99
 
63
 
-
 
64
    if(handle == NULL) {
-
 
65
	    fprintf(stderr, "Could not find USB device!\n");
-
 
66
	    exit(1);
-
 
67
    }
-
 
68
 
-
 
69
    getControllerVersion();
-
 
70
    printf("Controller Version: %x\n", controller.version);
-
 
71
    
-
 
72
    getDisplayCount();
-
 
73
    printf("Displays attached: %d\n", controller.display_count);
-
 
74
    int i=0;
-
 
75
    for (i=0; i<controller.display_count; i++) { 
-
 
76
      controller.dis[i] = malloc(sizeof(display_t));
-
 
77
      getDisplayMeta(i);
-
 
78
 
-
 
79
      printf("Display #%i\n", i);
-
 
80
      printf("\tAddress: %x\n", controller.dis[i]->address);
-
 
81
      printf("\tVersion: %x\n", controller.dis[i]->version);
-
 
82
      printf("\tConfig: %x\n", controller.dis[i]->config);
-
 
83
 
-
 
84
      // Clear the current digits
-
 
85
      int j=0;
-
 
86
      for (j=0;j<10;j++)
-
 
87
    	  setDisplayDigit(i,j,0x0a);
-
 
88
 
-
 
89
      setDisplayDigit(i, 0, controller.dis[i]->config);
-
 
90
      setDisplayLatch(i);
-
 
91
 
-
 
92
      getDisplayInput(i);
-
 
93
 
-
 
94
      printf("\n");
-
 
95
      printf("\tButton: %x\n", controller.dis[i]->buttons);
-
 
96
      printf("\tOuter: %x\n", controller.dis[i]->outer);
-
 
97
      printf("\tInner: %x\n", controller.dis[i]->inner);
-
 
98
    }
-
 
99
 
-
 
100
 
-
 
101
    for (i=0; i<controller.display_count; i++) {
-
 
102
    	free(controller.dis[i]);
-
 
103
    }
100
 
104
 
-
 
105
    if (handle!=NULL)
-
 
106
    	usb_close(handle);
101
 
107
 
-
 
108
    printf("Exiting\n");
102
 
109
 
103
	}
-
 
104
 
-
 
105
		/*
-
 
106
		if (key >= 0x30 && key <= 0x39) {
-
 
107
			val = key - '0';
-
 
108
		} else if  (key == 'w') {
-
 
109
			if (val != 10)
-
 
110
				val++;
-
 
111
		} else if (key == 's') {
-
 
112
			if (val != 0)
-
 
113
				val--;
-
 
114
		} else if (key == 'a') {
-
 
115
			if (dig!=0)
-
 
116
				dig--;
-
 
117
		} else if (key == 'd') {
-
 
118
			if (dig != 9)
-
 
119
				dig++;
-
 
120
		} else if (key == 'q') {
-
 
121
			if (dis != DISPLAYS_ATTACHED)
-
 
122
				dis++;
-
 
123
		} else if (key == 'e') {
-
 
124
			if (dis != 0)
-
 
125
				dis--;
-
 
126
		} else if (key == '.') {
-
 
127
			dp = 1 - dp;
-
 
128
		} else if (key == 'g') {
-
 
129
			getInput(0);
-
 
130
			but = usbReplyBuf[0];
-
 
131
			rot = usbReplyBuf[1];
-
 
132
 
-
 
133
		} else if (key == 'p') {
-
 
134
			unsigned short send = 1000;
-
 
135
			sendShort(dis, dig, send);
-
 
136
		} else if (key == 'l') {
-
 
137
			sendLatch(0);
-
 
138
		} else if (key == 'j') {
-
 
139
			printw(":");
-
 
140
			char* data = getBCD(10);
-
 
141
			char i;
-
 
142
			for (i=0; i<10; i++) {
-
 
143
				sendDigit(dis, i, data[i], 0);
-
 
144
			}
-
 
145
			free(data);
-
 
146
		} else if (key == 'k') {
-
 
147
			printw("k");
-
 
148
			char i;
-
 
149
			for (i=0; i<10; i++) {
-
 
150
				sendDigit(0, i, 0x0a, 0);
-
 
151
			}
-
 
152
			sendLatch(0);
-
 
153
		} else if (key == 0x0a) {
-
 
154
			sendDigit(dis, dig, val, dp);
-
 
155
			sendLatch(0);
-
 
156
		} else if (key == 0x1b) {
-
 
157
			cont = 0;
110
    return 0;
158
		}
111
}
159
		*/
-
 
160
 
112
 
161
	printw("\nPress key to exit\n");
113
char setDisplayLatch(uint8_t disnum) {
162
	getch();
-
 
163
	echo();
-
 
164
	nodelay(stdscr, false);
114
	char nBytes = 0;
165
	endwin();
-
 
166
 
115
 
167
	usb_close(handle);
116
	nBytes = usb_control_msg(handle,
-
 
117
		USB_TYPE_VENDOR | USB_ENDPOINT_IN,
-
 
118
		USB_SET_LATCH,
-
 
119
		disnum,								// What value should be displayed
-
 
120
		0,
-
 
121
		(char*)usbReplyBuf,
-
 
122
		sizeof(usbReplyBuf),
-
 
123
		5000);
168
 
124
 
169
	return 0;
125
	return nBytes;
170
}
126
}
171
 
127
 
-
 
128
char setDisplayDigit(uint8_t disnum, uint8_t digit, uint8_t value) {
172
void drawScreen() {
129
	char nBytes = 0;
173
	printw("\nCursor: ");
130
  	nBytes = usb_control_msg(handle,
174
	printw("Dis: %x ", cursor.dis);
131
		USB_TYPE_VENDOR | USB_ENDPOINT_IN,
-
 
132
		USB_SET_DISPLAY_DIGIT,
-
 
133
		(uint16_t)disnum << 8 |(uint16_t)digit,	// HN of display #, LN the digit #
175
	printw("Dig %x ", cursor.dig);
134
		value,					// What value should be displayed
176
	printw("Val %x ", cursor.val);
135
		(char*)usbReplyBuf,
177
	printw("Dp %x ", cursor.dp);
136
		sizeof(usbReplyBuf),
178
	printw("\n");
137
		5000);
179
 
138
 
180
	printw("But: %02X ", controller.dis[0]->buttons & 0xff);
-
 
181
	printw("Rot: %02X ", controller.dis[0]->rotary & 0xff);
-
 
182
	printw("\n");
139
	return nBytes;
183
}
140
}
184
 
141
 
185
char getInput(char dis) {
142
char getDisplayInput(uint8_t disnum) {
186
	char nBytes = 0;
143
	char nBytes = 0;
187
 
144
 
188
	nBytes = usb_control_msg(handle,
145
	nBytes = usb_control_msg(handle,
189
		USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN,
146
		USB_TYPE_VENDOR | USB_ENDPOINT_IN,
190
		30,
147
		USB_GET_DISPLAY_INPUT,
191
		dis,
148
		disnum,
192
		0,
149
		0,
193
		(char*)usbReplyBuf,
150
		(char*)usbReplyBuf,
194
		sizeof(usbReplyBuf),
151
		sizeof(usbReplyBuf),
195
		5000);
152
		5000);
196
 
153
 
-
 
154
	controller.dis[disnum]->buttons = usbReplyBuf[0];
-
 
155
	controller.dis[disnum]->outer = usbReplyBuf[1];
-
 
156
	controller.dis[disnum]->inner = usbReplyBuf[2];
-
 
157
 
197
	return nBytes;
158
	return nBytes;
198
}
159
}
199
 
160
 
200
char sendLatch(char dis) {
161
char getDisplayCount() {
201
	char nBytes = 0;
162
	char nBytes = 0;
202
 
163
 
203
	nBytes = usb_control_msg(handle,
164
	nBytes = usb_control_msg(handle,
204
		USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN,
165
		USB_TYPE_VENDOR | USB_ENDPOINT_IN,
205
		20,
166
		USB_GET_DISPLAY_COUNT,
206
		dis,
167
		0,
207
		0,
168
		0,
208
		(char*)usbReplyBuf,
169
		(char*)usbReplyBuf,
209
		sizeof(usbReplyBuf),
170
		sizeof(usbReplyBuf),
210
		5000);
171
		5000);
211
 
172
 
-
 
173
	controller.display_count = usbReplyBuf[0];
212
	return nBytes;
174
	return nBytes;
213
}
175
}
214
 
176
 
215
char sendDigit(char dis, char dig, char val, char dp) {
177
char getDisplayMeta(uint8_t disnum) {
216
	char nBytes = 0;
178
	char nBytes = 0;
217
 
179
 
218
	nBytes = usb_control_msg(handle,
180
	nBytes = usb_control_msg(handle,
219
		USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN,
181
		USB_TYPE_VENDOR | USB_ENDPOINT_IN,
220
		21,
-
 
221
		(short)dis<<8 | dig,
182
		USB_GET_DISPLAY_META,
222
		dp << 8 | val,
183
		disnum,
-
 
184
		0,
223
		(char*)usbReplyBuf,
185
		(char*)usbReplyBuf,
224
		sizeof(usbReplyBuf),
186
		sizeof(usbReplyBuf),
225
		5000);
187
		5000);
-
 
188
 
-
 
189
	controller.dis[disnum]->version = (uint16_t)(usbReplyBuf[0] << 8);
-
 
190
	controller.dis[disnum]->version |= (uint16_t)usbReplyBuf[1] & 0xff;
-
 
191
	controller.dis[disnum]->address = usbReplyBuf[2];
-
 
192
	controller.dis[disnum]->config = usbReplyBuf[3];
-
 
193
	return nBytes;
226
}
194
}
227
 
195
 
228
char sendShort(char dis, char dig, short val) {
196
char getControllerVersion() {
229
	char nBytes = 0;
197
	char nBytes = 0;
230
 
198
 
231
	nBytes = usb_control_msg(handle,
199
	nBytes = usb_control_msg(handle,
232
		USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN,
200
		USB_TYPE_VENDOR | USB_ENDPOINT_IN,
-
 
201
		USB_GET_VERSION,
233
		50,
202
		0,
234
		(short)dis<<8 | dig,
-
 
235
		val,
203
		0,
236
		(char*)usbReplyBuf,
204
		(char*)usbReplyBuf,
237
		sizeof(usbReplyBuf),
205
		sizeof(usbReplyBuf),
238
		5000);
206
		5000);
239
	return nBytes;
-
 
240
}
-
 
241
 
-
 
242
char* getBCD(char maxLen) {
-
 
243
	if (maxLen > 10) maxLen == 10;
-
 
244
	char* buffer = malloc(sizeof(char) * maxLen);
-
 
245
	char len = 0;
-
 
246
 
-
 
247
	nodelay(stdscr, false);
-
 
248
	while (1) {
-
 
249
		char key = 0x00;
-
 
250
		key = getch();
-
 
251
		if ((key >= 0x30 && key <= 0x39) && len <= maxLen) {
-
 
252
			buffer[len] = key - '0';
-
 
253
			len++;
-
 
254
			printw("%c", key);
-
 
255
		} else if (key == 0x07) {
-
 
256
			delch();
-
 
257
			delch();
-
 
258
			len--;
-
 
259
			buffer[len] = 0x00;
-
 
260
		} else if  (key == 0x0a) {
-
 
261
			return buffer;
-
 
262
		} else if (key == 0x1b) {
-
 
263
			return malloc(sizeof(char));
-
 
264
		} else if (key == 0x71) {
-
 
265
 
-
 
266
		}
-
 
267
 
207
 
268
	}
-
 
-
 
208
	controller.version = ((unsigned short)usbReplyBuf[0]) << 8;
-
 
209
	controller.version |= (usbReplyBuf[1] & 0xff);
269
	nodelay(stdscr, false);
210
	return nBytes;
270
}
211
}
271
 
212
 
272
 
213
 
273
 
-
 
274
/* Used to get descriptor strings for device identification */
214
/* Used to get descriptor strings for device identification */
275
static int usbGetDescriptorString(usb_dev_handle *dev, int index, int langid,
215
static int usbGetDescriptorString(usb_dev_handle *dev, int index, int langid, 
276
                                  char *buf, int buflen) {
216
                                  char *buf, int buflen) {
277
    char buffer[256];
217
    char buffer[256];
278
    int rval, i;
218
    int rval, i;
279
 
219
 
280
	// make standard request GET_DESCRIPTOR, type string and given index
220
	// make standard request GET_DESCRIPTOR, type string and given index 
281
    // (e.g. dev->iProduct)
221
    // (e.g. dev->iProduct)
282
	rval = usb_control_msg(dev,
222
	rval = usb_control_msg(dev, 
283
        USB_TYPE_STANDARD | USB_RECIP_DEVICE | USB_ENDPOINT_IN,
223
        USB_TYPE_STANDARD | USB_RECIP_DEVICE | USB_ENDPOINT_IN, 
284
        USB_REQ_GET_DESCRIPTOR, (USB_DT_STRING << 8) + index, langid,
224
        USB_REQ_GET_DESCRIPTOR, (USB_DT_STRING << 8) + index, langid, 
285
        buffer, sizeof(buffer), 1000);
225
        buffer, sizeof(buffer), 1000);
286
 
226
        
287
    if(rval < 0) // error
227
    if(rval < 0) // error
288
		return rval;
228
		return rval;
289
 
229
	
290
    // rval should be bytes read, but buffer[0] contains the actual response size
230
    // rval should be bytes read, but buffer[0] contains the actual response size
291
	if((unsigned char)buffer[0] < rval)
231
	if((unsigned char)buffer[0] < rval)
292
		rval = (unsigned char)buffer[0]; // string is inter than bytes read
232
		rval = (unsigned char)buffer[0]; // string is shorter than bytes read
293
 
233
	
294
	if(buffer[1] != USB_DT_STRING) // second byte is the data type
234
	if(buffer[1] != USB_DT_STRING) // second byte is the data type
295
		return 0; // invalid return type
235
		return 0; // invalid return type
296
 
236
		
297
	// we're dealing with UTF-16LE here so actual chars is half of rval,
237
	// we're dealing with UTF-16LE here so actual chars is half of rval,
298
	// and index 0 doesn't count
238
	// and index 0 doesn't count
299
	rval /= 2;
239
	rval /= 2;
300
 
240
	
301
	/* lossy conversion to ISO Latin1 */
241
	/* lossy conversion to ISO Latin1 */
302
	for(i = 1; i < rval && i < buflen; i++) {
242
	for(i = 1; i < rval && i < buflen; i++) {
303
		if(buffer[2 * i + 1] == 0)
243
		if(buffer[2 * i + 1] == 0)
304
			buf[i-1] = buffer[2 * i];
244
			buf[i-1] = buffer[2 * i];
305
		else
245
		else
306
			buf[i-1] = '?'; /* outside of ISO Latin1 range */
246
			buf[i-1] = '?'; /* outside of ISO Latin1 range */
307
	}
247
	}
308
	buf[i-1] = 0;
248
	buf[i-1] = 0;
309
 
249
	
310
	return i-1;
250
	return i-1;
311
}
251
}
312
 
252
 
313
static usb_dev_handle * usbOpenDevice(int vendor, char *vendorName,
253
static usb_dev_handle * usbOpenDevice(int vendor, char *vendorName, 
314
                                      int product, char *productName) {
254
                                      int product, char *productName) {
315
	struct usb_bus *bus;
255
	struct usb_bus *bus;
316
	struct usb_device *dev;
256
	struct usb_device *dev;
317
	char devVendor[256], devProduct[256];
257
	char devVendor[256], devProduct[256];
318
 
258
    
319
	usb_dev_handle * handle = NULL;
259
	usb_dev_handle * handle = NULL;
320
 
260
	
321
	usb_init();
261
	usb_init();
322
	usb_find_busses();
262
	usb_find_busses();
323
	usb_find_devices();
263
	usb_find_devices();
324
 
264
	
325
	for(bus=usb_get_busses(); bus; bus=bus->next) {
265
	for(bus=usb_get_busses(); bus; bus=bus->next) {
326
		for(dev=bus->devices; dev; dev=dev->next) {
266
		for(dev=bus->devices; dev; dev=dev->next) {			
327
 
267
			
328
			if(dev->descriptor.idVendor != vendor ||
268
			if(dev->descriptor.idVendor != vendor ||
329
               			dev->descriptor.idProduct != product)
269
               			dev->descriptor.idProduct != product)
330
                		continue;
270
                		continue;
331
 
-
 
-
 
271
                
332
		         /* we need to open the device in order to query strings */
272
		         /* we need to open the device in order to query strings */
333
            		if(!(handle = usb_open(dev))) {
273
            		if(!(handle = usb_open(dev))) {
334
                		fprintf(stderr, "Warning: cannot open USB device: %s\n",
274
                		fprintf(stderr, "Warning: cannot open USB device: %s\n",
335
                    		usb_strerror());
275
                    		usb_strerror());
336
                		continue;
276
                		continue;
337
            		}
277
            		}
338
 
278
            
339
			/* get vendor name */
279
			/* get vendor name */
340
            		if(usbGetDescriptorString(handle, dev->descriptor.iManufacturer, 0x0409, devVendor, sizeof(devVendor)) < 0) {
280
            		if(usbGetDescriptorString(handle, dev->descriptor.iManufacturer, 0x0409, devVendor, sizeof(devVendor)) < 0) {
341
                		fprintf(stderr, "Warning: cannot query manufacturer for device: %s\n", usb_strerror());
281
                		fprintf(stderr, "Warning: cannot query manufacturer for device: %s\n", usb_strerror());
342
                		usb_close(handle);
282
                		usb_close(handle);
343
                		continue;
283
                		continue;
344
            		}
284
            		}
345
 
285
            
346
            		/* get product name */
286
            		/* get product name */
347
            		if(usbGetDescriptorString(handle, dev->descriptor.iProduct, 0x0409, devProduct, sizeof(devVendor)) < 0) {
287
            		if(usbGetDescriptorString(handle, dev->descriptor.iProduct, 0x0409, devProduct, sizeof(devVendor)) < 0) {
348
                		fprintf(stderr, "Warning: cannot query product for device: %s\n", usb_strerror()); usb_close(handle);
288
                		fprintf(stderr, "Warning: cannot query product for device: %s\n", usb_strerror()); usb_close(handle);
349
                		continue;
289
                		continue;
350
            		}
290
            		}
351
 
291
            
352
            		if(strcmp(devVendor, vendorName) == 0 && strcmp(devProduct, productName) == 0)
292
            		if(strcmp(devVendor, vendorName) == 0 && strcmp(devProduct, productName) == 0)
353
                		return handle;
293
                		return handle;
354
            		else
294
            		else
355
                		usb_close(handle);
295
                		usb_close(handle);
356
		}
296
		}
357
	}
297
	}
358
 
298
	
359
	return NULL;
299
	return NULL;
360
}
300
}