Tizen 2.1 base
[sdk/target/sdbd.git] / src / usb_libusb.c
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <sys/endian.h>
18 #include <sys/ioctl.h>
19 #include <sys/types.h>
20 #include <sys/uio.h>
21
22 #include <err.h>
23 #include <errno.h>
24 #include <poll.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <strings.h>
28 #include <string.h>
29 #include <sysexits.h>
30 #include <unistd.h>
31 #include <libusb.h>
32 #include "sysdeps.h"
33
34 #define   TRACE_TAG  TRACE_USB
35 #include "sdb.h"
36
37 static sdb_mutex_t usb_lock = SDB_MUTEX_INITIALIZER;
38 static libusb_context *ctx = NULL;
39
40 struct usb_handle
41 {
42     usb_handle            *prev;
43     usb_handle            *next;
44
45     libusb_device         *dev;
46     libusb_device_handle  *devh;
47     int                   interface;
48     uint8_t               dev_bus;
49     uint8_t               dev_addr;
50         
51     int                   zero_mask;
52     unsigned char         end_point_address[2];
53     char                  serial[128];
54     
55     sdb_cond_t            notify;
56     sdb_mutex_t           lock;
57 };
58
59 static struct usb_handle handle_list = {
60         .prev = &handle_list,
61         .next = &handle_list,
62 };
63
64 void
65 usb_cleanup()
66 {
67         libusb_exit(ctx);
68 }
69
70 void
71 report_bulk_libusb_error(int r)
72 {
73     switch (r) {
74     case LIBUSB_ERROR_TIMEOUT:
75         D("Transfer timeout\n");
76         break;
77
78     case LIBUSB_ERROR_PIPE:
79         D("Control request is not supported\n");
80         break;
81
82     case LIBUSB_ERROR_OVERFLOW:
83         D("Device offered more data\n");
84         break;
85
86     case LIBUSB_ERROR_NO_DEVICE :
87         D("Device was disconnected\n");
88         break;
89
90     default:
91         D("Error %d during transfer\n", r);
92         break;
93     };
94 }
95
96 static int
97 usb_bulk_write(usb_handle *uh, const void *data, int len)
98 {
99     int r = 0;
100     int transferred = 0;
101
102     r = libusb_bulk_transfer(uh->devh, uh->end_point_address[1], (void *)data, len,
103                              &transferred, 0);
104    
105     if (r != 0) {
106         D("usb_bulk_write(): ");
107         report_bulk_libusb_error(r);
108         return r;
109     }
110    
111     return (transferred);
112 }
113
114 static int
115 usb_bulk_read(usb_handle *uh, void *data, int len)
116 {
117     int r = 0;
118     int transferred = 0;
119
120     r = libusb_bulk_transfer(uh->devh, uh->end_point_address[0], data, len,
121                              &transferred, 0);
122
123     if (r != 0) {
124         D("usb_bulk_read(): ");
125         report_bulk_libusb_error(r);
126         return r;
127     }
128    
129     return (transferred);
130 }
131
132 int
133 usb_write(struct usb_handle *uh, const void *_data, int len)
134 {
135     unsigned char *data = (unsigned char*) _data;
136     int n;
137     int need_zero = 0;
138
139     if (uh->zero_mask == 1) {
140         if (!(len & uh->zero_mask)) {
141             need_zero = 1;
142         }
143     }
144
145     D("usb_write(): %p:%d -> transport %p\n", _data, len, uh);
146     
147     while (len > 0) {
148         int xfer = (len > 4096) ? 4096 : len;
149
150         n = usb_bulk_write(uh, data, xfer);
151         
152         if (n != xfer) {
153             D("usb_write(): failed for transport %p (%d bytes left)\n", uh, len);
154             return -1;
155         }
156
157         len -= xfer;
158         data += xfer;
159     }
160
161     if (need_zero){
162         n = usb_bulk_write(uh, _data, 0);
163         
164         if (n < 0) {
165             D("usb_write(): failed to finish operation for transport %p\n", uh);
166         }
167         return n;
168     }
169
170     return 0;
171 }
172
173 int
174 usb_read(struct usb_handle *uh, void *_data, int len)
175 {
176     unsigned char *data = (unsigned char*) _data;
177     int n;
178
179     D("usb_read(): %p:%d <- transport %p\n", _data, len, uh);
180     
181     while (len > 0) {
182         int xfer = (len > 4096) ? 4096 : len;
183
184         n = usb_bulk_read(uh, data, xfer);
185         
186         if (n != xfer) {
187             if (n > 0) {
188                 data += n;
189                 len -= n;
190                 continue;
191             }
192             
193             D("usb_read(): failed for transport %p (%d bytes left)\n", uh, len);
194             return -1;
195         }
196
197         len -= xfer;
198         data += xfer;
199     }
200
201     return 0;
202  }
203
204 int
205 usb_close(struct usb_handle *h)
206 {
207     D("usb_close(): closing transport %p\n", h);
208     sdb_mutex_lock(&usb_lock);
209     
210     h->next->prev = h->prev;
211     h->prev->next = h->next;
212     h->prev = NULL;
213     h->next = NULL;
214
215     libusb_release_interface(h->devh, h->interface);
216     libusb_close(h->devh);
217     libusb_unref_device(h->dev);
218     
219     sdb_mutex_unlock(&usb_lock);
220
221     free(h);
222
223     return (0);
224 }
225
226 void usb_kick(struct usb_handle *h)
227 {
228     D("usb_cick(): kicking transport %p\n", h);
229     
230     sdb_mutex_lock(&h->lock);
231     unregister_usb_transport(h);
232     sdb_mutex_unlock(&h->lock);
233     
234     h->next->prev = h->prev;
235     h->prev->next = h->next;
236     h->prev = NULL;
237     h->next = NULL;
238
239     libusb_release_interface(h->devh, h->interface);
240     libusb_close(h->devh);
241     libusb_unref_device(h->dev);
242     free(h);
243 }
244
245 int
246 check_usb_interface(libusb_interface *interface,
247                     libusb_device_descriptor *desc,
248                     struct usb_handle *uh)
249 {    
250     int e;
251     
252     if (interface->num_altsetting == 0) {
253         D("check_usb_interface(): No interface settings\n");
254         return -1;
255     }
256     
257     libusb_interface_descriptor *idesc = &interface->altsetting[0];
258     
259     if (idesc->bNumEndpoints != 2) {
260         D("check_usb_interface(): Interface have not 2 endpoints, ignoring\n");
261         return -1;
262     }
263
264     for (e = 0; e < idesc->bNumEndpoints; e++) {
265         libusb_endpoint_descriptor *edesc = &idesc->endpoint[e];
266         
267         if (edesc->bmAttributes != LIBUSB_TRANSFER_TYPE_BULK) {
268             D("check_usb_interface(): Endpoint (%u) is not bulk (%u), ignoring\n",
269                     edesc->bmAttributes, LIBUSB_TRANSFER_TYPE_BULK);
270             return -1;
271         }
272         
273         if (edesc->bEndpointAddress & LIBUSB_ENDPOINT_IN)
274             uh->end_point_address[0] = edesc->bEndpointAddress;
275         else
276             uh->end_point_address[1] = edesc->bEndpointAddress;
277         
278             /* aproto 01 needs 0 termination */
279         if (idesc->bInterfaceProtocol == 0x01) {
280             uh->zero_mask = edesc->wMaxPacketSize - 1;
281             D("check_usb_interface(): Forced Android interface protocol v.1\n");
282         }
283     }
284
285     D("check_usb_interface(): Device: %04x:%04x "
286       "iclass: %x, isclass: %x, iproto: %x ep: %x/%x-> ",
287         desc->idVendor, desc->idProduct, idesc->bInterfaceClass,
288         idesc->bInterfaceSubClass, idesc->bInterfaceProtocol,
289         uh->end_point_address[0], uh->end_point_address[1]);
290     
291     if (!is_sdb_interface(desc->idVendor, desc->idProduct,
292             idesc->bInterfaceClass, idesc->bInterfaceSubClass,
293             idesc->bInterfaceProtocol))
294     {
295         D("not matches\n");
296         return -1;
297     }
298
299     D("matches\n");
300     return 1;
301 }
302
303 int
304 check_usb_interfaces(libusb_config_descriptor *config,
305                      libusb_device_descriptor *desc, struct usb_handle *uh)
306 {  
307     int i;
308     
309     for (i = 0; i < config->bNumInterfaces; ++i) {
310         if (check_usb_interface(&config->interface[i], desc, uh) != -1) {
311             /* found some interface and saved information about it */
312             D("check_usb_interfaces(): Interface %d of %04x:%04x "
313               "matches Android device\n", i, desc->idVendor,
314               desc->idProduct);
315             
316             return  i;
317         }
318     }
319     
320     return -1;
321 }
322
323 int
324 register_device(struct usb_handle *uh, const char *serial)
325 {
326     D("register_device(): Registering %p [%s] as USB transport\n",
327        uh, serial);
328
329     struct usb_handle *usb= NULL;
330
331     usb = calloc(1, sizeof(struct usb_handle));
332     memcpy(usb, uh, sizeof(struct usb_handle));
333     strcpy(usb->serial, uh->serial);
334
335     sdb_cond_init(&usb->notify, 0);
336     sdb_mutex_init(&usb->lock, 0);
337
338     sdb_mutex_lock(&usb_lock);
339     
340     usb->next = &handle_list;
341     usb->prev = handle_list.prev;
342     usb->prev->next = usb;
343     usb->next->prev = usb;
344
345     sdb_mutex_unlock(&usb_lock);
346
347     register_usb_transport(usb, serial, 1); 
348
349     return (1);
350 }
351
352 int
353 already_registered(usb_handle *uh)
354 {
355     struct usb_handle *usb= NULL;
356     int exists = 0;
357     
358     sdb_mutex_lock(&usb_lock);
359
360     for (usb = handle_list.next; usb != &handle_list; usb = usb->next) {
361         if ((usb->dev_bus == uh->dev_bus) &&
362             (usb->dev_addr == uh->dev_addr))
363         {
364             exists = 1;
365             break;
366         }
367     }
368
369     sdb_mutex_unlock(&usb_lock);
370
371     return exists;
372 }
373
374 void
375 check_device(libusb_device *dev) 
376 {
377     struct usb_handle uh;
378     int i = 0;
379     int found = -1;
380     char serial[256] = {0};
381
382     libusb_device_descriptor desc;
383     libusb_config_descriptor *config = NULL;
384     
385     int r = libusb_get_device_descriptor(dev, &desc);
386
387     if (r != LIBUSB_SUCCESS) {
388         D("check_device(): Failed to get device descriptor\n");
389         return;
390     }
391     
392     if ((desc.idVendor == 0) && (desc.idProduct == 0))
393         return;
394     
395     D("check_device(): Probing usb device %04x:%04x\n",
396         desc.idVendor, desc.idProduct);
397     
398     if (!is_sdb_interface (desc.idVendor, desc.idProduct,
399                            SDB_CLASS, SDB_SUBCLASS, SDB_PROTOCOL))
400     {
401         D("check_device(): Ignored due unknown vendor id\n");
402         return;
403     }
404     
405     uh.dev_bus = libusb_get_bus_number(dev);
406     uh.dev_addr = libusb_get_device_address(dev);
407     
408     if (already_registered(&uh)) {
409         D("check_device(): Device (bus: %d, address: %d) "
410           "is already registered\n", uh.dev_bus, uh.dev_addr);
411         return;
412     }
413     
414     D("check_device(): Device bus: %d, address: %d\n",
415         uh.dev_bus, uh.dev_addr);
416
417     r = libusb_get_active_config_descriptor(dev, &config);
418     
419     if (r != 0) {
420         if (r == LIBUSB_ERROR_NOT_FOUND) {
421             D("check_device(): Device %4x:%4x is unconfigured\n", 
422                 desc.idVendor, desc.idProduct);
423             return;
424         }
425         
426         D("check_device(): Failed to get configuration for %4x:%4x\n",
427             desc.idVendor, desc.idProduct);
428         return;
429     }
430     
431     if (config == NULL) {
432         D("check_device(): Sanity check failed after "
433           "getting active config\n");
434         return;
435     }
436     
437     if (config->interface != NULL) {
438         found = check_usb_interfaces(config, &desc, &uh);
439     }
440     
441     /* not needed anymore */
442     libusb_free_config_descriptor(config);
443     
444     r = libusb_open(dev, &uh.devh);
445     uh.dev = dev;
446
447     if (r != 0) {
448         switch (r) {
449             case LIBUSB_ERROR_NO_MEM:
450                 D("check_device(): Memory allocation problem\n");
451                 break;
452                 
453             case LIBUSB_ERROR_ACCESS:
454                 D("check_device(): Permissions problem, "
455                   "current user priveleges are messed up?\n");
456                 break;
457                 
458             case LIBUSB_ERROR_NO_DEVICE:
459                 D("check_device(): Device disconected, bad cable?\n");
460                 break;
461             
462             default:
463                 D("check_device(): libusb triggered error %d\n", r);
464         }
465         // skip rest
466         found = -1;
467     }
468     
469     if (found >= 0) {
470         D("check_device(): Device matches Android interface\n");
471         // read the device's serial number
472         memset(serial, 0, sizeof(serial));
473         uh.interface = found;
474         
475         r = libusb_claim_interface(uh.devh, uh.interface);
476         
477         if (r < 0) {
478             D("check_device(): Failed to claim interface %d\n",
479                 uh.interface);
480
481             goto fail;
482         }
483
484         if (desc.iSerialNumber) {
485             // reading serial
486             uint16_t    buffer[128] = {0};
487             uint16_t    languages[128] = {0};
488             int languageCount = 0;
489
490             memset(languages, 0, sizeof(languages));
491             r = libusb_control_transfer(uh.devh, 
492                 LIBUSB_ENDPOINT_IN |  LIBUSB_REQUEST_TYPE_STANDARD | LIBUSB_RECIPIENT_DEVICE,
493                 LIBUSB_REQUEST_GET_DESCRIPTOR, LIBUSB_DT_STRING << 8,
494                 0, (uint8_t *)languages, sizeof(languages), 0);
495
496             if (r <= 0) {
497                 D("check_device(): Failed to get languages count\n");
498                 goto fail;
499             } 
500             
501             languageCount = (r - 2) / 2;
502             
503             for (i = 1; i <= languageCount; ++i) {
504                 memset(buffer, 0, sizeof(buffer));
505
506                 r = libusb_control_transfer(uh.devh, 
507                     LIBUSB_ENDPOINT_IN |  LIBUSB_REQUEST_TYPE_STANDARD | LIBUSB_RECIPIENT_DEVICE,
508                     LIBUSB_REQUEST_GET_DESCRIPTOR, (LIBUSB_DT_STRING << 8) | desc.iSerialNumber,
509                     languages[i], (uint8_t *)buffer, sizeof(buffer), 0);
510             
511                 if (r > 0) { /* converting serial */
512                     int j = 0;
513                     r /= 2;
514                 
515                     for (j = 1; j < r; ++j)
516                         serial[j - 1] = buffer[j];
517                 
518                     serial[j - 1] = '\0';
519                     break; /* languagesCount cycle */
520                 }
521             }
522             
523             if (register_device(&uh, serial) == 0) {
524                 D("check_device(): Failed to register device\n");
525                 goto fail_interface;
526             }
527             
528             libusb_ref_device(dev);
529         }
530     }
531     
532     return;
533
534 fail_interface:
535     libusb_release_interface(uh.devh, uh.interface);
536
537 fail:
538     libusb_close(uh.devh);
539     uh.devh = NULL;
540 }
541
542 int
543 check_device_connected(struct usb_handle *uh)
544 {
545     int r = libusb_kernel_driver_active(uh->devh, uh->interface);
546     
547     if (r == LIBUSB_ERROR_NO_DEVICE)
548         return 0;
549     
550     if (r < 0)
551         return -1;
552     
553     return 1;
554 }
555
556 void
557 kick_disconnected()
558 {
559     struct usb_handle *usb= NULL;
560     
561     sdb_mutex_lock(&usb_lock);
562
563     for (usb = handle_list.next; usb != &handle_list; usb = usb->next) {
564         
565         if (check_device_connected(usb) == 0) {
566             D("kick_disconnected(): Transport %p is not online anymore\n",
567                 usb);
568
569             usb_kick(usb);
570         }
571     }
572     
573     sdb_mutex_unlock(&usb_lock);
574 }
575
576 void
577 scan_usb_devices()
578 {
579     D("scan_usb_devices(): started\n");
580     
581     libusb_device **devs= NULL;
582     libusb_device *dev= NULL;
583     ssize_t cnt = libusb_get_device_list(ctx, &devs);
584
585     if (cnt < 0) {
586         D("scan_usb_devices(): Failed to get device list (error: %d)\n",
587             cnt);
588
589         return;
590     }
591     
592     int i = 0;
593
594     while ((dev = devs[i++]) != NULL) {
595         check_device(dev);
596     }
597
598     libusb_free_device_list(devs, 1);
599 }
600
601 void *
602 device_poll_thread(void* unused)
603 {
604     D("device_poll_thread(): Created USB scan thread\n");
605     
606     for (;;) {
607         sleep(5);
608         kick_disconnected();
609         scan_usb_devices();
610     }
611
612     /* never reaching this point */
613     return (NULL);
614 }
615
616 static void
617 sigalrm_handler(int signo)
618 {
619     /* nothing */
620 }
621
622 void
623 usb_init()
624 {
625     D("usb_init(): started\n");
626     sdb_thread_t        tid;
627     struct sigaction actions;
628
629     int r = libusb_init(&ctx);
630
631     if (r != LIBUSB_SUCCESS) {
632         err(EX_IOERR, "Failed to init libusb\n");
633     }
634
635     memset(&actions, 0, sizeof(actions));
636     
637     sigemptyset(&actions.sa_mask);
638     
639     actions.sa_flags = 0;
640     actions.sa_handler = sigalrm_handler;
641     
642     sigaction(SIGALRM, &actions, NULL);
643
644         /* initial device scan */
645         scan_usb_devices();
646         
647         /* starting USB event polling thread */
648     if (sdb_thread_create(&tid, device_poll_thread, NULL)) {
649             err(EX_IOERR, "cannot create USB scan thread\n");
650     }
651     
652     D("usb_init(): finished\n");
653 }
654