• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2011 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 "qemu-common.h"
18 #include "sockets.h"
19 #include "iolooper.h"
20 #include "android/async-utils.h"
21 #include "android/utils/debug.h"
22 #include "android/utils/list.h"
23 #include "android/utils/misc.h"
24 #include "android/adb-server.h"
25 
26 #define  E(...)    derror(__VA_ARGS__)
27 #define  W(...)    dwarning(__VA_ARGS__)
28 #define  D(...)    VERBOSE_PRINT(adbserver,__VA_ARGS__)
29 #define  D_ACTIVE  VERBOSE_CHECK(adbserver)
30 #define  QB(b, s)  quote_bytes((const char*)b, (s < 32) ? s : 32)
31 
32 typedef struct AdbServer    AdbServer;
33 typedef struct AdbHost      AdbHost;
34 typedef struct AdbGuest     AdbGuest;
35 
36 /* ADB guest connection descriptor. */
37 struct AdbGuest {
38     /* Entry in the list of pending or connected ADB guests.
39      * NOTE: This must be the first entry in the descriptor! */
40     ACList              list_entry;
41     /* Opaque pointer associated with the guest. */
42     void*               opaque;
43     /* ADB server for this guest. */
44     AdbServer*          adb_srv;
45     /* ADB host connected with this ADB guest. */
46     AdbHost*            adb_host;
47     /* Callback routines for the ADB guest. */
48     AdbGuestRoutines*   callbacks;
49     /* ADB guest connection status. If 0 indicates that ADB guest is not yet
50      * ready to receive data from the host. */
51     int                 is_connected;
52 };
53 
54 /* ADB host connection descriptor. */
55 struct AdbHost {
56     /* Entry in the list of pending or connected ADB hosts.
57      * NOTE: This must be the first entry in the descriptor! */
58     ACList      list_entry;
59     /* ADB server for this host. */
60     AdbServer*  adb_srv;
61     /* ADB socket connected with the host. */
62     int         host_so;
63     /* I/O port for asynchronous I/O on the host socket. */
64     LoopIo      io[1];
65     /* ADB guest connected with this ADB host. */
66     AdbGuest*   adb_guest;
67     /* Pending data to send to the guest when it is fully connected. */
68     uint8_t*    pending_data;
69     /* Size of the pending data buffer. */
70     int         pending_data_size;
71     /* Contains data that are pending to be sent to the host. */
72     uint8_t*    pending_send_buffer;
73     /* Number of bytes that are pending to be sent to the host. */
74     int         pending_send_data_size;
75     /* Size of the pending_send_buffer */
76     int         pending_send_buffer_size;
77 };
78 
79 /* ADB server descriptor. */
80 struct AdbServer {
81     /* ADB socket address. */
82     SockAddress socket_address;
83     /* Looper for async I/O on ADB server socket. */
84     Looper*     looper;
85     /* I/O port for asynchronous I/O on ADB server socket. */
86     LoopIo      io[1];
87     /* ADB port. */
88     int         port;
89     /* Server socket. */
90     int         so;
91     /* List of connected ADB hosts. */
92     ACList      adb_hosts;
93     /* List of connected ADB guests. */
94     ACList      adb_guests;
95     /* List of ADB hosts pending connection with ADB guest. */
96     ACList      pending_hosts;
97     /* List of ADB guests pending connection with ADB host. */
98     ACList      pending_guests;
99 };
100 
101 /* One and only one ADB server instance. */
102 static AdbServer    _adb_server;
103 /* ADB server initialization flag. */
104 static int          _adb_server_initialized = 0;
105 
106 /********************************************************************************
107  *                             ADB host API
108  *******************************************************************************/
109 
110 /* Creates and initializes a new AdbHost instance. */
111 static AdbHost*
_adb_host_new(AdbServer * adb_srv)112 _adb_host_new(AdbServer* adb_srv)
113 {
114     AdbHost* adb_host;
115 
116     ANEW0(adb_host);
117     alist_init(&adb_host->list_entry);
118     adb_host->adb_srv = adb_srv;
119     adb_host->host_so = -1;
120 
121     return adb_host;
122 }
123 
124 /* Frees AdbHost instance created with _adb_host_new routine. */
125 static void
_adb_host_free(AdbHost * adb_host)126 _adb_host_free(AdbHost* adb_host)
127 {
128     if (adb_host != NULL) {
129         /* At this point it must not be listed anywhere. */
130         assert(alist_is_empty(&adb_host->list_entry));
131 
132         /* Close the host socket. */
133         if (adb_host->host_so >= 0) {
134             loopIo_done(adb_host->io);
135             socket_close(adb_host->host_so);
136         }
137 
138         /* Free pending data buffers. */
139         if (adb_host->pending_data != NULL) {
140             free(adb_host->pending_data);
141         }
142         if (adb_host->pending_send_buffer != NULL) {
143             free(adb_host->pending_send_buffer);
144         }
145 
146         AFREE(adb_host);
147     }
148 }
149 
150 static void
_adb_host_append_message(AdbHost * adb_host,const void * msg,int msglen)151 _adb_host_append_message(AdbHost* adb_host, const void* msg, int msglen)
152 {
153     printf("Append %d bytes to ADB host buffer.\n", msglen);
154 
155     /* Make sure that buffer can contain the appending data. */
156     if (adb_host->pending_send_buffer == NULL) {
157         adb_host->pending_send_buffer = (uint8_t*)malloc(msglen);
158         adb_host->pending_send_buffer_size = msglen;
159     } else if ((adb_host->pending_send_data_size + msglen) >
160                adb_host->pending_send_buffer_size) {
161         adb_host->pending_send_buffer =
162             (uint8_t*)realloc(adb_host->pending_send_buffer,
163                               adb_host->pending_send_data_size + msglen);
164         adb_host->pending_send_buffer_size =
165             adb_host->pending_send_data_size + msglen;
166     }
167 
168     if (adb_host->pending_send_buffer == NULL) {
169         D("Unable to allocate %d bytes for pending ADB host data.",
170           adb_host->pending_send_data_size + msglen);
171         adb_host->pending_send_buffer_size = adb_host->pending_send_data_size = 0;
172         loopIo_dontWantWrite(adb_host->io);
173         return;
174     }
175 
176     memcpy(adb_host->pending_send_buffer + adb_host->pending_send_data_size,
177            msg, msglen);
178     loopIo_wantWrite(adb_host->io);
179 }
180 
181 /* Connects ADB host with ADB guest. */
182 static void
_adb_connect(AdbHost * adb_host,AdbGuest * adb_guest)183 _adb_connect(AdbHost* adb_host, AdbGuest* adb_guest)
184 {
185     D("Connecting ADB host %p(so=%d) with ADB guest %p(o=%p)",
186       adb_host, adb_host->host_so, adb_guest, adb_guest->opaque);
187 
188     adb_guest->adb_host = adb_host;
189     adb_host->adb_guest = adb_guest;
190     adb_guest->callbacks->on_connected(adb_guest->opaque, adb_guest);
191 }
192 
193 /* Callback invoked when ADB host socket gets disconnected. */
194 static void
_on_adb_host_disconnected(AdbHost * adb_host)195 _on_adb_host_disconnected(AdbHost* adb_host)
196 {
197     AdbGuest* const adb_guest = adb_host->adb_guest;
198 
199     /* Notify the ADB guest that the host got disconnected. */
200     if (adb_guest != NULL) {
201         D("Disconnecting ADB host %p(so=%d) from ADB guest %p(o=%p)",
202           adb_host, adb_host->host_so, adb_guest, adb_guest->opaque);
203         adb_host->adb_guest = NULL;
204         adb_guest->callbacks->on_disconnect(adb_guest->opaque, adb_guest);
205         adb_guest->adb_host = NULL;
206     } else {
207         D("Disconnecting ADB host %p(so=%d)", adb_host, adb_host->host_so);
208     }
209 
210     /* Destroy the host. */
211     alist_remove(&adb_host->list_entry);
212     _adb_host_free(adb_host);
213 
214     /* Remove the guest from the list. */
215     if (adb_guest != NULL) {
216         alist_remove(&adb_guest->list_entry);
217     }
218 }
219 
220 /* Read I/O callback on ADB host socket. */
221 static void
_on_adb_host_read(AdbHost * adb_host)222 _on_adb_host_read(AdbHost* adb_host)
223 {
224     char buff[4096];
225 
226     /* Read data from the socket. */
227     const int size = socket_recv(adb_host->host_so, buff, sizeof(buff));
228     if (size < 0) {
229         D("Error while reading from ADB host %p(so=%d). Error: %s",
230           adb_host, adb_host->host_so, strerror(errno));
231     } else if (size == 0) {
232         /* This is a "disconnect" condition. */
233         _on_adb_host_disconnected(adb_host);
234     } else {
235         D("%s %d bytes received from ADB host %p(so=%d): %s",
236            adb_host->adb_guest ? "Transfer" : "Pend", size, adb_host,
237            adb_host->host_so, QB(buff, size));
238 
239         /* Lets see if there is an ADB guest associated with this host, and it
240          * is ready to receive host data. */
241         AdbGuest* const adb_guest = adb_host->adb_guest;
242         if (adb_guest != NULL && adb_guest->is_connected) {
243             /* Channel the data through... */
244             adb_guest->callbacks->on_read(adb_guest->opaque, adb_guest, buff, size);
245         } else {
246             /* Pend the data for the upcoming guest connection. */
247             if (adb_host->pending_data == NULL) {
248                 adb_host->pending_data = malloc(size);
249             } else {
250                 adb_host->pending_data = realloc(adb_host->pending_data,
251                                                  adb_host->pending_data_size + size);
252             }
253             if (adb_host->pending_data != NULL) {
254                 memcpy(adb_host->pending_data + adb_host->pending_data_size,
255                        buff, size);
256                 adb_host->pending_data_size += size;
257             } else {
258                 D("Unable to (re)allocate %d bytes for pending ADB host data",
259                   adb_host->pending_data_size + size);
260             }
261         }
262     }
263 }
264 
265 /* Write I/O callback on ADB host socket. */
266 static void
_on_adb_host_write(AdbHost * adb_host)267 _on_adb_host_write(AdbHost* adb_host)
268 {
269     while (adb_host->pending_send_data_size && adb_host->pending_send_buffer != NULL) {
270         const int sent = socket_send(adb_host->host_so,
271                                      adb_host->pending_send_buffer,
272                                      adb_host->pending_send_data_size);
273         if (sent < 0) {
274             if (errno == EWOULDBLOCK) {
275                 /* Try again later. */
276                 return;
277             } else {
278                 D("Unable to send pending data to the ADB host: %s",
279                    strerror(errno));
280                 free(adb_host->pending_send_buffer);
281                 adb_host->pending_send_buffer = NULL;
282                 adb_host->pending_send_buffer_size = 0;
283                 adb_host->pending_send_data_size = 0;
284                 break;
285             }
286         } else if (sent == 0) {
287             /* Disconnect condition. */
288             free(adb_host->pending_send_buffer);
289             adb_host->pending_send_buffer = NULL;
290             adb_host->pending_send_buffer_size = 0;
291             adb_host->pending_send_data_size = 0;
292             _on_adb_host_disconnected(adb_host);
293             break;
294         } else if (sent == adb_host->pending_send_data_size) {
295             free(adb_host->pending_send_buffer);
296             adb_host->pending_send_buffer = NULL;
297             adb_host->pending_send_buffer_size = 0;
298             adb_host->pending_send_data_size = 0;
299         } else {
300             adb_host->pending_send_data_size -= sent;
301             memmove(adb_host->pending_send_buffer,
302                     adb_host->pending_send_buffer + sent,
303                     adb_host->pending_send_data_size);
304             return;
305         }
306     }
307 
308     loopIo_dontWantWrite(adb_host->io);
309 }
310 
311 /* I/O callback on ADB host socket. */
312 static void
_on_adb_host_io(void * opaque,int fd,unsigned events)313 _on_adb_host_io(void* opaque, int fd, unsigned events)
314 {
315     AdbHost* const adb_host = (AdbHost*)opaque;
316     assert(fd == adb_host->host_so);
317 
318     /* Dispatch I/O to read / write handlers. */
319     if ((events & LOOP_IO_READ) != 0) {
320         _on_adb_host_read(adb_host);
321     }
322     if ((events & LOOP_IO_WRITE) != 0) {
323         _on_adb_host_write(adb_host);
324     }
325 }
326 
327 /********************************************************************************
328  *                            ADB guest API
329  *******************************************************************************/
330 
331 /* Creates and initializes a new AdbGuest instance. */
332 static AdbGuest*
_adb_guest_new(AdbServer * adb_srv)333 _adb_guest_new(AdbServer* adb_srv)
334 {
335     AdbGuest* adb_guest;
336 
337     ANEW0(adb_guest);
338     alist_init(&adb_guest->list_entry);
339     adb_guest->adb_srv = adb_srv;
340 
341     return adb_guest;
342 }
343 
344 /* Frees AdbGuest instance created with _adb_guest_new routine. */
345 static void
_adb_guest_free(AdbGuest * adb_guest)346 _adb_guest_free(AdbGuest* adb_guest)
347 {
348     if (adb_guest != NULL) {
349         /* At this poin the guest must not be in any of the lists. */
350         assert(alist_is_empty(&adb_guest->list_entry));
351         AFREE(adb_guest);
352     }
353 }
354 
355 /********************************************************************************
356  *                            ADB server internals
357  *******************************************************************************/
358 
359 /* I/O callback on ADB server socket. */
360 static void
_on_server_socket_io(void * opaque,int fd,unsigned events)361 _on_server_socket_io(void* opaque, int fd, unsigned events)
362 {
363     AdbHost* adb_host;
364     AdbGuest* adb_guest;
365     AdbServer* adb_srv = (AdbServer*)opaque;
366     assert(adb_srv->so == fd);
367 
368     /* Since this is a server socket, we only expect a connection I/O here. */
369     if ((events & LOOP_IO_READ) == 0) {
370         D("Unexpected write I/O on ADB server socket");
371         return;
372     }
373 
374     /* Create AdbHost instance for the new host connection. */
375     adb_host = _adb_host_new(adb_srv);
376 
377     /* Accept the connection. */
378     adb_host->host_so = socket_accept(fd, &adb_srv->socket_address);
379     if (adb_host->host_so < 0) {
380         D("Unable to accept ADB connection: %s", strerror(errno));
381         _adb_host_free(adb_host);
382         return;
383     }
384 
385     /* Prepare for I/O on the host connection socket. */
386     loopIo_init(adb_host->io, adb_srv->looper, adb_host->host_so,
387                 _on_adb_host_io, adb_host);
388 
389     /* Lets see if there is an ADB guest waiting for a host connection. */
390     adb_guest = (AdbGuest*)alist_remove_head(&adb_srv->pending_guests);
391     if (adb_guest != NULL) {
392         /* Tie up ADB host with the ADB guest. */
393         alist_insert_tail(&adb_srv->adb_guests, &adb_guest->list_entry);
394         alist_insert_tail(&adb_srv->adb_hosts, &adb_host->list_entry);
395         _adb_connect(adb_host, adb_guest);
396     } else {
397         /* Pend this connection. */
398         D("Pend ADB host %p(so=%d)", adb_host, adb_host->host_so);
399         alist_insert_tail(&adb_srv->pending_hosts, &adb_host->list_entry);
400     }
401 
402     /* Enable I/O on the host socket. */
403     loopIo_wantRead(adb_host->io);
404 }
405 
406 /********************************************************************************
407  *                            ADB server API
408  *******************************************************************************/
409 int
adb_server_init(int port)410 adb_server_init(int port)
411 {
412     if (!_adb_server_initialized) {
413         /* Initialize the descriptor. */
414         memset(&_adb_server, 0, sizeof(_adb_server));
415         alist_init(&_adb_server.adb_hosts);
416         alist_init(&_adb_server.adb_guests);
417         alist_init(&_adb_server.pending_hosts);
418         alist_init(&_adb_server.pending_guests);
419         _adb_server.port = port;
420 
421         /* Create looper for an async I/O on the server. */
422         _adb_server.looper = looper_newCore();
423         if (_adb_server.looper == NULL) {
424             E("Unable to create I/O looper for ADB server");
425             return -1;
426         }
427 
428         /* Create loopback server socket for the ADB port. */
429         sock_address_init_inet(&_adb_server.socket_address,
430                                SOCK_ADDRESS_INET_LOOPBACK, port);
431         _adb_server.so = socket_loopback_server(port, SOCKET_STREAM);
432         if (_adb_server.so < 0) {
433             E("Unable to create ADB server socket: %s", strerror(errno));
434             return -1;
435         }
436 
437         /* Prepare server socket for I/O */
438         socket_set_nonblock(_adb_server.so);
439         loopIo_init(_adb_server.io, _adb_server.looper, _adb_server.so,
440                     _on_server_socket_io, &_adb_server);
441         loopIo_wantRead(_adb_server.io);
442 
443         D("ADB server has been initialized for port %d. Socket: %d",
444           port, _adb_server.so);
445 
446         _adb_server_initialized = 1;
447     }
448 
449     return 0;
450 }
451 
452 int
adb_server_is_initialized(void)453 adb_server_is_initialized(void)
454 {
455     return _adb_server_initialized;
456 }
457 
458 void*
adb_server_register_guest(void * opaque,AdbGuestRoutines * callbacks)459 adb_server_register_guest(void* opaque, AdbGuestRoutines* callbacks)
460 {
461     if (_adb_server_initialized) {
462         AdbHost* adb_host;
463 
464         /* Create and initialize ADB guest descriptor. */
465         AdbGuest* const adb_guest = _adb_guest_new(&_adb_server);
466         adb_guest->opaque = opaque;
467         adb_guest->callbacks = callbacks;
468 
469         /* Lets see if there is a pending ADB host for the new guest. */
470         adb_host = (AdbHost*)alist_remove_head(&_adb_server.pending_hosts);
471         if (adb_host != NULL) {
472             /* Tie up ADB host with the ADB guest. */
473             alist_insert_tail(&_adb_server.adb_guests, &adb_guest->list_entry);
474             alist_insert_tail(&_adb_server.adb_hosts, &adb_host->list_entry);
475             _adb_connect(adb_host, adb_guest);
476         } else {
477             /* Host is not available. Pend this guest. */
478             D("Pend ADB guest %p(o=%p)", adb_guest, adb_guest->opaque);
479             alist_insert_tail(&_adb_server.pending_guests, &adb_guest->list_entry);
480         }
481 
482         return adb_guest;
483     } else {
484         D("%s is called on an uninitialized ADB server.", __FUNCTION__);
485         return NULL;
486     }
487 }
488 
489 void
adb_server_complete_connection(void * opaque)490 adb_server_complete_connection(void* opaque)
491 {
492     AdbGuest* const adb_guest = (AdbGuest*)opaque;
493     AdbHost* const adb_host = adb_guest->adb_host;
494 
495     /* Mark the guest as fully connected and ready for the host data. */
496     adb_guest->is_connected = 1;
497 
498     /* Lets see if there is a host data pending transmission to the guest. */
499     if (adb_host->pending_data != NULL && adb_host->pending_data_size != 0) {
500         /* Send the pending data to the guest. */
501         D("Pushing %d bytes of the pending ADB host data.",
502           adb_host->pending_data_size);
503         adb_guest->callbacks->on_read(adb_guest->opaque, adb_guest,
504                                       adb_host->pending_data,
505                                       adb_host->pending_data_size);
506         free(adb_host->pending_data);
507         adb_host->pending_data = NULL;
508         adb_host->pending_data_size = 0;
509     }
510 }
511 
512 void
adb_server_on_guest_message(void * opaque,const uint8_t * msg,int msglen)513 adb_server_on_guest_message(void* opaque, const uint8_t* msg, int msglen)
514 {
515     AdbGuest* const adb_guest = (AdbGuest*)opaque;
516     AdbHost* const adb_host = adb_guest->adb_host;
517 
518     if (adb_host != NULL) {
519         D("Sending %d bytes to the ADB host: %s", msglen, QB(msg, msglen));
520 
521         /* Lets see if we can send the data immediatelly... */
522         if (adb_host->pending_send_buffer == NULL) {
523             /* There are no data that are pending to be sent to the host. Do the
524              * direct send. */
525             const int sent = socket_send(adb_host->host_so, msg, msglen);
526             if (sent < 0) {
527                 if (errno == EWOULDBLOCK) {
528                 } else {
529                     D("Unable to send data to ADB host: %s", strerror(errno));
530                 }
531             } else if (sent == 0) {
532                 /* Disconnect condition. */
533                 _on_adb_host_disconnected(adb_host);
534             } else if (sent < msglen) {
535                 /* Couldn't send everything. Schedule write via I/O callback. */
536                 _adb_host_append_message(adb_host, msg + sent, msglen - sent);
537             }
538         } else {
539             /* There are data that are pending to be sent to the host. We need
540              * to append new data to the end of the pending data buffer. */
541             _adb_host_append_message(adb_host, msg, msglen);
542         }
543     } else {
544         D("ADB host is disconneted and can't accept %d bytes in %s",
545           msglen, QB(msg, msglen));
546     }
547 }
548 
549 void
adb_server_on_guest_closed(void * opaque)550 adb_server_on_guest_closed(void* opaque)
551 {
552     AdbGuest* const adb_guest = (AdbGuest*)opaque;
553     AdbHost* const adb_host = adb_guest->adb_host;
554 
555     /* Remove the guest from the list */
556     if (!alist_is_empty(&adb_guest->list_entry)) {
557         alist_remove(&adb_guest->list_entry);
558     }
559 
560     /* Disassociate the host. */
561     if (adb_host != NULL) {
562         if (!alist_is_empty(&adb_host->list_entry)) {
563             alist_remove(&adb_host->list_entry);
564         }
565         _adb_host_free(adb_host);
566     }
567     _adb_guest_free(adb_guest);
568 }
569