• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
usb_cleanup()40 void usb_cleanup()
41 {
42     // nothing to do here
43 }
44 
usb_open_thread(void * x)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 
usb_write(usb_handle * h,const void * data,int len)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 
usb_read(usb_handle * h,void * data,int len)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 
usb_init()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 
usb_kick(usb_handle * h)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 
usb_close(usb_handle * h)153 int usb_close(usb_handle *h)
154 {
155     // nothing to do here
156     return 0;
157 }
158