Home | History | Annotate | Download | only in minadbd
      1 /*
      2  * Copyright (C) 2007 The Android Open Source Project
      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 <stdio.h>
     18 #include <stdlib.h>
     19 #include <unistd.h>
     20 #include <string.h>
     21 
     22 #include <sys/ioctl.h>
     23 #include <sys/types.h>
     24 #include <dirent.h>
     25 #include <errno.h>
     26 
     27 #include "sysdeps.h"
     28 
     29 #define   TRACE_TAG  TRACE_USB
     30 #include "adb.h"
     31 
     32 
     33 struct usb_handle
     34 {
     35     int fd;
     36     adb_cond_t notify;
     37     adb_mutex_t lock;
     38 };
     39 
     40 void usb_cleanup()
     41 {
     42     // nothing to do here
     43 }
     44 
     45 static void *usb_open_thread(void *x)
     46 {
     47     struct usb_handle *usb = (struct usb_handle *)x;
     48     int fd;
     49 
     50     while (1) {
     51         // wait until the USB device needs opening
     52         adb_mutex_lock(&usb->lock);
     53         while (usb->fd != -1)
     54             adb_cond_wait(&usb->notify, &usb->lock);
     55         adb_mutex_unlock(&usb->lock);
     56 
     57         D("[ usb_thread - opening device ]\n");
     58         do {
     59             /* XXX use inotify? */
     60             fd = unix_open("/dev/android_adb", O_RDWR);
     61             if (fd < 0) {
     62                 // to support older kernels
     63                 fd = unix_open("/dev/android", O_RDWR);
     64             }
     65             if (fd < 0) {
     66                 adb_sleep_ms(1000);
     67             }
     68         } while (fd < 0);
     69         D("[ opening device succeeded ]\n");
     70 
     71         close_on_exec(fd);
     72         usb->fd = fd;
     73 
     74         D("[ usb_thread - registering device ]\n");
     75         register_usb_transport(usb, 0, 1);
     76     }
     77 
     78     // never gets here
     79     return 0;
     80 }
     81 
     82 int usb_write(usb_handle *h, const void *data, int len)
     83 {
     84     int n;
     85 
     86     D("about to write (fd=%d, len=%d)\n", h->fd, len);
     87     n = adb_write(h->fd, data, len);
     88     if(n != len) {
     89         D("ERROR: fd = %d, n = %d, errno = %d (%s)\n",
     90             h->fd, n, errno, strerror(errno));
     91         return -1;
     92     }
     93     D("[ done fd=%d ]\n", h->fd);
     94     return 0;
     95 }
     96 
     97 int usb_read(usb_handle *h, void *data, int len)
     98 {
     99     int n;
    100 
    101     D("about to read (fd=%d, len=%d)\n", h->fd, len);
    102     n = adb_read(h->fd, data, len);
    103     if(n != len) {
    104         D("ERROR: fd = %d, n = %d, errno = %d (%s)\n",
    105             h->fd, n, errno, strerror(errno));
    106         return -1;
    107     }
    108     D("[ done fd=%d ]\n", h->fd);
    109     return 0;
    110 }
    111 
    112 void usb_init()
    113 {
    114     usb_handle *h;
    115     adb_thread_t tid;
    116     int fd;
    117 
    118     h = calloc(1, sizeof(usb_handle));
    119     h->fd = -1;
    120     adb_cond_init(&h->notify, 0);
    121     adb_mutex_init(&h->lock, 0);
    122 
    123     // Open the file /dev/android_adb_enable to trigger
    124     // the enabling of the adb USB function in the kernel.
    125     // We never touch this file again - just leave it open
    126     // indefinitely so the kernel will know when we are running
    127     // and when we are not.
    128     fd = unix_open("/dev/android_adb_enable", O_RDWR);
    129     if (fd < 0) {
    130        D("failed to open /dev/android_adb_enable\n");
    131     } else {
    132         close_on_exec(fd);
    133     }
    134 
    135     D("[ usb_init - starting thread ]\n");
    136     if(adb_thread_create(&tid, usb_open_thread, h)){
    137         fatal_errno("cannot create usb thread");
    138     }
    139 }
    140 
    141 void usb_kick(usb_handle *h)
    142 {
    143     D("usb_kick\n");
    144     adb_mutex_lock(&h->lock);
    145     adb_close(h->fd);
    146     h->fd = -1;
    147 
    148     // notify usb_open_thread that we are disconnected
    149     adb_cond_signal(&h->notify);
    150     adb_mutex_unlock(&h->lock);
    151 }
    152 
    153 int usb_close(usb_handle *h)
    154 {
    155     // nothing to do here
    156     return 0;
    157 }
    158