blob: 117b7a8679383c33bbedcb4c0db1d17fee0f8693 [file] [log] [blame]
Vladimir Chtchetkined86c7242011-12-09 15:45:46 -08001/*
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"
David 'Digit' Turnercc330d42013-12-14 23:26:42 +010018#include "android/sockets.h"
David 'Digit' Turnerd413fa52013-12-14 23:35:20 +010019#include "android/iolooper.h"
Vladimir Chtchetkined86c7242011-12-09 15:45:46 -080020#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
32typedef struct AdbServer AdbServer;
33typedef struct AdbHost AdbHost;
34typedef struct AdbGuest AdbGuest;
35
36/* ADB guest connection descriptor. */
37struct 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. */
55struct 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. */
80struct 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. */
102static AdbServer _adb_server;
103/* ADB server initialization flag. */
104static int _adb_server_initialized = 0;
105
106/********************************************************************************
107 * ADB host API
108 *******************************************************************************/
109
110/* Creates and initializes a new AdbHost instance. */
111static AdbHost*
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. */
125static void
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
150static void
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. */
182static void
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. */
194static void
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. */
221static void
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. */
266static void
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. */
312static void
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. */
332static AdbGuest*
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. */
345static void
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. */
360static void
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 *******************************************************************************/
409int
410adb_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
452int
453adb_server_is_initialized(void)
454{
455 return _adb_server_initialized;
456}
457
458void*
459adb_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
489void
490adb_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
512void
513adb_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
549void
550adb_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}