summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThe Android Open Source Project2009-03-03 21:32:55 -0600
committerThe Android Open Source Project2009-03-03 21:32:55 -0600
commitdd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0 (patch)
tree2ba8d1a0846d69b18f623515e8d9b5d9fe38b590 /adb/sockets.c
parente54eebbf1a908d65ee8cf80bab62821c05666d70 (diff)
downloadplatform-system-core-dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0.tar.gz
platform-system-core-dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0.tar.xz
platform-system-core-dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0.zip
auto import from //depot/cupcake/@135843
Diffstat (limited to 'adb/sockets.c')
-rw-r--r--adb/sockets.c787
1 files changed, 787 insertions, 0 deletions
diff --git a/adb/sockets.c b/adb/sockets.c
new file mode 100644
index 000000000..9f1b59870
--- /dev/null
+++ b/adb/sockets.c
@@ -0,0 +1,787 @@
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 <errno.h>
21#include <string.h>
22#include <ctype.h>
23
24#include "sysdeps.h"
25
26#define TRACE_TAG TRACE_SOCKETS
27#include "adb.h"
28
29ADB_MUTEX_DEFINE( socket_list_lock );
30
31static void local_socket_close_locked(asocket *s);
32
33int sendfailmsg(int fd, const char *reason)
34{
35 char buf[9];
36 int len;
37 len = strlen(reason);
38 if(len > 0xffff) len = 0xffff;
39 snprintf(buf, sizeof buf, "FAIL%04x", len);
40 if(writex(fd, buf, 8)) return -1;
41 return writex(fd, reason, len);
42}
43
44//extern int online;
45
46static unsigned local_socket_next_id = 1;
47
48static asocket local_socket_list = {
49 .next = &local_socket_list,
50 .prev = &local_socket_list,
51};
52
53/* the the list of currently closing local sockets.
54** these have no peer anymore, but still packets to
55** write to their fd.
56*/
57static asocket local_socket_closing_list = {
58 .next = &local_socket_closing_list,
59 .prev = &local_socket_closing_list,
60};
61
62asocket *find_local_socket(unsigned id)
63{
64 asocket *s;
65 asocket *result = NULL;
66
67 adb_mutex_lock(&socket_list_lock);
68 for(s = local_socket_list.next; s != &local_socket_list && !result; s = s->next) {
69 if(s->id == id) result = s;
70 }
71 adb_mutex_unlock(&socket_list_lock);
72
73 return result;
74}
75
76static void
77insert_local_socket(asocket* s, asocket* list)
78{
79 s->next = list;
80 s->prev = s->next->prev;
81 s->prev->next = s;
82 s->next->prev = s;
83}
84
85
86void install_local_socket(asocket *s)
87{
88 adb_mutex_lock(&socket_list_lock);
89
90 s->id = local_socket_next_id++;
91 insert_local_socket(s, &local_socket_list);
92
93 adb_mutex_unlock(&socket_list_lock);
94}
95
96void remove_socket(asocket *s)
97{
98 // socket_list_lock should already be held
99 if (s->prev && s->next)
100 {
101 s->prev->next = s->next;
102 s->next->prev = s->prev;
103 s->next = 0;
104 s->prev = 0;
105 s->id = 0;
106 }
107}
108
109void close_all_sockets(atransport *t)
110{
111 asocket *s;
112
113 /* this is a little gross, but since s->close() *will* modify
114 ** the list out from under you, your options are limited.
115 */
116 adb_mutex_lock(&socket_list_lock);
117restart:
118 for(s = local_socket_list.next; s != &local_socket_list; s = s->next){
119 if(s->transport == t || (s->peer && s->peer->transport == t)) {
120 local_socket_close_locked(s);
121 goto restart;
122 }
123 }
124 adb_mutex_unlock(&socket_list_lock);
125}
126
127static int local_socket_enqueue(asocket *s, apacket *p)
128{
129 D("LS(%d): enqueue %d\n", s->id, p->len);
130
131 p->ptr = p->data;
132
133 /* if there is already data queue'd, we will receive
134 ** events when it's time to write. just add this to
135 ** the tail
136 */
137 if(s->pkt_first) {
138 goto enqueue;
139 }
140
141 /* write as much as we can, until we
142 ** would block or there is an error/eof
143 */
144 while(p->len > 0) {
145 int r = adb_write(s->fd, p->ptr, p->len);
146 if(r > 0) {
147 p->len -= r;
148 p->ptr += r;
149 continue;
150 }
151 if((r == 0) || (errno != EAGAIN)) {
152 D( "LS(%d): not ready, errno=%d: %s\n", s->id, errno, strerror(errno) );
153 s->close(s);
154 return 1; /* not ready (error) */
155 } else {
156 break;
157 }
158 }
159
160 if(p->len == 0) {
161 put_apacket(p);
162 return 0; /* ready for more data */
163 }
164
165enqueue:
166 p->next = 0;
167 if(s->pkt_first) {
168 s->pkt_last->next = p;
169 } else {
170 s->pkt_first = p;
171 }
172 s->pkt_last = p;
173
174 /* make sure we are notified when we can drain the queue */
175 fdevent_add(&s->fde, FDE_WRITE);
176
177 return 1; /* not ready (backlog) */
178}
179
180static void local_socket_ready(asocket *s)
181{
182 /* far side is ready for data, pay attention to
183 readable events */
184 fdevent_add(&s->fde, FDE_READ);
185// D("LS(%d): ready()\n", s->id);
186}
187
188static void local_socket_close(asocket *s)
189{
190 adb_mutex_lock(&socket_list_lock);
191 local_socket_close_locked(s);
192 adb_mutex_unlock(&socket_list_lock);
193}
194
195// be sure to hold the socket list lock when calling this
196static void local_socket_destroy(asocket *s)
197{
198 apacket *p, *n;
199
200 /* IMPORTANT: the remove closes the fd
201 ** that belongs to this socket
202 */
203 fdevent_remove(&s->fde);
204
205 /* dispose of any unwritten data */
206 for(p = s->pkt_first; p; p = n) {
207 D("LS(%d): discarding %d bytes\n", s->id, p->len);
208 n = p->next;
209 put_apacket(p);
210 }
211 remove_socket(s);
212 free(s);
213}
214
215
216static void local_socket_close_locked(asocket *s)
217{
218 if(s->peer) {
219 s->peer->peer = 0;
220 // tweak to avoid deadlock
221 if (s->peer->close == local_socket_close)
222 local_socket_close_locked(s->peer);
223 else
224 s->peer->close(s->peer);
225 }
226
227 /* If we are already closing, or if there are no
228 ** pending packets, destroy immediately
229 */
230 if (s->closing || s->pkt_first == NULL) {
231 int id = s->id;
232 local_socket_destroy(s);
233 D("LS(%d): closed\n", id);
234 return;
235 }
236
237 /* otherwise, put on the closing list
238 */
239 D("LS(%d): closing\n", s->id);
240 s->closing = 1;
241 fdevent_del(&s->fde, FDE_READ);
242 remove_socket(s);
243 insert_local_socket(s, &local_socket_closing_list);
244}
245
246static void local_socket_event_func(int fd, unsigned ev, void *_s)
247{
248 asocket *s = _s;
249
250 /* put the FDE_WRITE processing before the FDE_READ
251 ** in order to simplify the code.
252 */
253 if(ev & FDE_WRITE){
254 apacket *p;
255
256 while((p = s->pkt_first) != 0) {
257 while(p->len > 0) {
258 int r = adb_write(fd, p->ptr, p->len);
259 if(r > 0) {
260 p->ptr += r;
261 p->len -= r;
262 continue;
263 }
264 if(r < 0) {
265 /* returning here is ok because FDE_READ will
266 ** be processed in the next iteration loop
267 */
268 if(errno == EAGAIN) return;
269 if(errno == EINTR) continue;
270 }
271 s->close(s);
272 return;
273 }
274
275 if(p->len == 0) {
276 s->pkt_first = p->next;
277 if(s->pkt_first == 0) s->pkt_last = 0;
278 put_apacket(p);
279 }
280 }
281
282 /* if we sent the last packet of a closing socket,
283 ** we can now destroy it.
284 */
285 if (s->closing) {
286 s->close(s);
287 return;
288 }
289
290 /* no more packets queued, so we can ignore
291 ** writable events again and tell our peer
292 ** to resume writing
293 */
294 fdevent_del(&s->fde, FDE_WRITE);
295 s->peer->ready(s->peer);
296 }
297
298
299 if(ev & FDE_READ){
300 apacket *p = get_apacket();
301 unsigned char *x = p->data;
302 size_t avail = MAX_PAYLOAD;
303 int r;
304 int is_eof = 0;
305
306 while(avail > 0) {
307 r = adb_read(fd, x, avail);
308 if(r > 0) {
309 avail -= r;
310 x += r;
311 continue;
312 }
313 if(r < 0) {
314 if(errno == EAGAIN) break;
315 if(errno == EINTR) continue;
316 }
317
318 /* r = 0 or unhandled error */
319 is_eof = 1;
320 break;
321 }
322
323 if((avail == MAX_PAYLOAD) || (s->peer == 0)) {
324 put_apacket(p);
325 } else {
326 p->len = MAX_PAYLOAD - avail;
327
328 r = s->peer->enqueue(s->peer, p);
329
330 if(r < 0) {
331 /* error return means they closed us as a side-effect
332 ** and we must return immediately.
333 **
334 ** note that if we still have buffered packets, the
335 ** socket will be placed on the closing socket list.
336 ** this handler function will be called again
337 ** to process FDE_WRITE events.
338 */
339 return;
340 }
341
342 if(r > 0) {
343 /* if the remote cannot accept further events,
344 ** we disable notification of READs. They'll
345 ** be enabled again when we get a call to ready()
346 */
347 fdevent_del(&s->fde, FDE_READ);
348 }
349 }
350
351 if(is_eof) {
352 s->close(s);
353 }
354 }
355
356 if(ev & FDE_ERROR){
357 /* this should be caught be the next read or write
358 ** catching it here means we may skip the last few
359 ** bytes of readable data.
360 */
361// s->close(s);
362 return;
363 }
364}
365
366asocket *create_local_socket(int fd)
367{
368 asocket *s = calloc(1, sizeof(asocket));
369 if(s == 0) fatal("cannot allocate socket");
370 install_local_socket(s);
371 s->fd = fd;
372 s->enqueue = local_socket_enqueue;
373 s->ready = local_socket_ready;
374 s->close = local_socket_close;
375
376 fdevent_install(&s->fde, fd, local_socket_event_func, s);
377/* fdevent_add(&s->fde, FDE_ERROR); */
378 //fprintf(stderr, "Created local socket in create_local_socket \n");
379 D("LS(%d): created (fd=%d)\n", s->id, s->fd);
380 return s;
381}
382
383asocket *create_local_service_socket(const char *name)
384{
385 asocket *s;
386 int fd;
387
388#if !ADB_HOST
389 if (!strcmp(name,"jdwp")) {
390 return create_jdwp_service_socket();
391 }
392 if (!strcmp(name,"track-jdwp")) {
393 return create_jdwp_tracker_service_socket();
394 }
395#endif
396 fd = service_to_fd(name);
397 if(fd < 0) return 0;
398
399 s = create_local_socket(fd);
400 D("LS(%d): bound to '%s'\n", s->id, name);
401 return s;
402}
403
404#if ADB_HOST
405static asocket *create_host_service_socket(const char *name, const char* serial)
406{
407 asocket *s;
408
409 s = host_service_to_socket(name, serial);
410
411 if (s != NULL) {
412 D("LS(%d) bound to '%s'\n", s->id, name);
413 return s;
414 }
415
416 return s;
417}
418#endif /* ADB_HOST */
419
420/* a Remote socket is used to send/receive data to/from a given transport object
421** it needs to be closed when the transport is forcibly destroyed by the user
422*/
423typedef struct aremotesocket {
424 asocket socket;
425 adisconnect disconnect;
426} aremotesocket;
427
428static int remote_socket_enqueue(asocket *s, apacket *p)
429{
430 D("Calling remote_socket_enqueue\n");
431 p->msg.command = A_WRTE;
432 p->msg.arg0 = s->peer->id;
433 p->msg.arg1 = s->id;
434 p->msg.data_length = p->len;
435 send_packet(p, s->transport);
436 return 1;
437}
438
439static void remote_socket_ready(asocket *s)
440{
441 D("Calling remote_socket_ready\n");
442 apacket *p = get_apacket();
443 p->msg.command = A_OKAY;
444 p->msg.arg0 = s->peer->id;
445 p->msg.arg1 = s->id;
446 send_packet(p, s->transport);
447}
448
449static void remote_socket_close(asocket *s)
450{
451 D("Calling remote_socket_close\n");
452 apacket *p = get_apacket();
453 p->msg.command = A_CLSE;
454 if(s->peer) {
455 p->msg.arg0 = s->peer->id;
456 s->peer->peer = 0;
457 s->peer->close(s->peer);
458 }
459 p->msg.arg1 = s->id;
460 send_packet(p, s->transport);
461 D("RS(%d): closed\n", s->id);
462 remove_transport_disconnect( s->transport, &((aremotesocket*)s)->disconnect );
463 free(s);
464}
465
466static void remote_socket_disconnect(void* _s, atransport* t)
467{
468 asocket* s = _s;
469 asocket* peer = s->peer;
470
471 D("remote_socket_disconnect RS(%d)\n", s->id);
472 if (peer) {
473 peer->peer = NULL;
474 peer->close(peer);
475 }
476 remove_transport_disconnect( s->transport, &((aremotesocket*)s)->disconnect );
477 free(s);
478}
479
480asocket *create_remote_socket(unsigned id, atransport *t)
481{
482 asocket *s = calloc(1, sizeof(aremotesocket));
483 adisconnect* dis = &((aremotesocket*)s)->disconnect;
484
485 if(s == 0) fatal("cannot allocate socket");
486 s->id = id;
487 s->enqueue = remote_socket_enqueue;
488 s->ready = remote_socket_ready;
489 s->close = remote_socket_close;
490 s->transport = t;
491
492 dis->func = remote_socket_disconnect;
493 dis->opaque = s;
494 add_transport_disconnect( t, dis );
495 D("RS(%d): created\n", s->id);
496 return s;
497}
498
499void connect_to_remote(asocket *s, const char *destination)
500{
501 D("Connect_to_remote call \n");
502 apacket *p = get_apacket();
503 int len = strlen(destination) + 1;
504
505 if(len > (MAX_PAYLOAD-1)) {
506 fatal("destination oversized");
507 }
508
509 D("LS(%d): connect('%s')\n", s->id, destination);
510 p->msg.command = A_OPEN;
511 p->msg.arg0 = s->id;
512 p->msg.data_length = len;
513 strcpy((char*) p->data, destination);
514 send_packet(p, s->transport);
515}
516
517
518/* this is used by magic sockets to rig local sockets to
519 send the go-ahead message when they connect */
520static void local_socket_ready_notify(asocket *s)
521{
522 s->ready = local_socket_ready;
523 s->close = local_socket_close;
524 adb_write(s->fd, "OKAY", 4);
525 s->ready(s);
526}
527
528/* this is used by magic sockets to rig local sockets to
529 send the failure message if they are closed before
530 connected (to avoid closing them without a status message) */
531static void local_socket_close_notify(asocket *s)
532{
533 s->ready = local_socket_ready;
534 s->close = local_socket_close;
535 sendfailmsg(s->fd, "closed");
536 s->close(s);
537}
538
539unsigned unhex(unsigned char *s, int len)
540{
541 unsigned n = 0, c;
542
543 while(len-- > 0) {
544 switch((c = *s++)) {
545 case '0': case '1': case '2':
546 case '3': case '4': case '5':
547 case '6': case '7': case '8':
548 case '9':
549 c -= '0';
550 break;
551 case 'a': case 'b': case 'c':
552 case 'd': case 'e': case 'f':
553 c = c - 'a' + 10;
554 break;
555 case 'A': case 'B': case 'C':
556 case 'D': case 'E': case 'F':
557 c = c - 'A' + 10;
558 break;
559 default:
560 return 0xffffffff;
561 }
562
563 n = (n << 4) | c;
564 }
565
566 return n;
567}
568
569static int smart_socket_enqueue(asocket *s, apacket *p)
570{
571 unsigned len;
572#if ADB_HOST
573 char *service = NULL;
574 char* serial = NULL;
575 transport_type ttype = kTransportAny;
576#endif
577
578 D("SS(%d): enqueue %d\n", s->id, p->len);
579
580 if(s->pkt_first == 0) {
581 s->pkt_first = p;
582 s->pkt_last = p;
583 } else {
584 if((s->pkt_first->len + p->len) > MAX_PAYLOAD) {
585 D("SS(%d): overflow\n", s->id);
586 put_apacket(p);
587 goto fail;
588 }
589
590 memcpy(s->pkt_first->data + s->pkt_first->len,
591 p->data, p->len);
592 s->pkt_first->len += p->len;
593 put_apacket(p);
594
595 p = s->pkt_first;
596 }
597
598 /* don't bother if we can't decode the length */
599 if(p->len < 4) return 0;
600
601 len = unhex(p->data, 4);
602 if((len < 1) || (len > 1024)) {
603 D("SS(%d): bad size (%d)\n", s->id, len);
604 goto fail;
605 }
606
607 D("SS(%d): len is %d\n", s->id, len );
608 /* can't do anything until we have the full header */
609 if((len + 4) > p->len) {
610 D("SS(%d): waiting for %d more bytes\n", s->id, len+4 - p->len);
611 return 0;
612 }
613
614 p->data[len + 4] = 0;
615
616 D("SS(%d): '%s'\n", s->id, (char*) (p->data + 4));
617
618#if ADB_HOST
619 service = (char *)p->data + 4;
620 if(!strncmp(service, "host-serial:", strlen("host-serial:"))) {
621 char* serial_end;
622 service += strlen("host-serial:");
623
624 // serial number should follow "host:"
625 serial_end = strchr(service, ':');
626 if (serial_end) {
627 *serial_end = 0; // terminate string
628 serial = service;
629 service = serial_end + 1;
630 }
631 } else if (!strncmp(service, "host-usb:", strlen("host-usb:"))) {
632 ttype = kTransportUsb;
633 service += strlen("host-usb:");
634 } else if (!strncmp(service, "host-local:", strlen("host-local:"))) {
635 ttype = kTransportLocal;
636 service += strlen("host-local:");
637 } else if (!strncmp(service, "host:", strlen("host:"))) {
638 ttype = kTransportAny;
639 service += strlen("host:");
640 } else {
641 service = NULL;
642 }
643
644 if (service) {
645 asocket *s2;
646
647 /* some requests are handled immediately -- in that
648 ** case the handle_host_request() routine has sent
649 ** the OKAY or FAIL message and all we have to do
650 ** is clean up.
651 */
652 if(handle_host_request(service, ttype, serial, s->peer->fd, s) == 0) {
653 /* XXX fail message? */
654 D( "SS(%d): handled host service '%s'\n", s->id, service );
655 goto fail;
656 }
657 if (!strncmp(service, "transport", strlen("transport"))) {
658 D( "SS(%d): okay transport\n", s->id );
659 p->len = 0;
660 return 0;
661 }
662
663 /* try to find a local service with this name.
664 ** if no such service exists, we'll fail out
665 ** and tear down here.
666 */
667 s2 = create_host_service_socket(service, serial);
668 if(s2 == 0) {
669 D( "SS(%d): couldn't create host service '%s'\n", s->id, service );
670 sendfailmsg(s->peer->fd, "unknown host service");
671 goto fail;
672 }
673
674 /* we've connected to a local host service,
675 ** so we make our peer back into a regular
676 ** local socket and bind it to the new local
677 ** service socket, acknowledge the successful
678 ** connection, and close this smart socket now
679 ** that its work is done.
680 */
681 adb_write(s->peer->fd, "OKAY", 4);
682
683 s->peer->ready = local_socket_ready;
684 s->peer->close = local_socket_close;
685 s->peer->peer = s2;
686 s2->peer = s->peer;
687 s->peer = 0;
688 D( "SS(%d): okay\n", s->id );
689 s->close(s);
690
691 /* initial state is "ready" */
692 s2->ready(s2);
693 return 0;
694 }
695#else /* !ADB_HOST */
696 if (s->transport == NULL) {
697 char* error_string = "unknown failure";
698 s->transport = acquire_one_transport (CS_ANY,
699 kTransportAny, NULL, &error_string);
700
701 if (s->transport == NULL) {
702 sendfailmsg(s->peer->fd, error_string);
703 goto fail;
704 }
705 }
706#endif
707
708 if(!(s->transport) || (s->transport->connection_state == CS_OFFLINE)) {
709 /* if there's no remote we fail the connection
710 ** right here and terminate it
711 */
712 sendfailmsg(s->peer->fd, "device offline (x)");
713 goto fail;
714 }
715
716
717 /* instrument our peer to pass the success or fail
718 ** message back once it connects or closes, then
719 ** detach from it, request the connection, and
720 ** tear down
721 */
722 s->peer->ready = local_socket_ready_notify;
723 s->peer->close = local_socket_close_notify;
724 s->peer->peer = 0;
725 /* give him our transport and upref it */
726 s->peer->transport = s->transport;
727
728 connect_to_remote(s->peer, (char*) (p->data + 4));
729 s->peer = 0;
730 s->close(s);
731 return 1;
732
733fail:
734 /* we're going to close our peer as a side-effect, so
735 ** return -1 to signal that state to the local socket
736 ** who is enqueueing against us
737 */
738 s->close(s);
739 return -1;
740}
741
742static void smart_socket_ready(asocket *s)
743{
744 D("SS(%d): ready\n", s->id);
745}
746
747static void smart_socket_close(asocket *s)
748{
749 D("SS(%d): closed\n", s->id);
750 if(s->pkt_first){
751 put_apacket(s->pkt_first);
752 }
753 if(s->peer) {
754 s->peer->peer = 0;
755 s->peer->close(s->peer);
756 }
757 free(s);
758}
759
760asocket *create_smart_socket(void (*action_cb)(asocket *s, const char *act))
761{
762 D("Creating smart socket \n");
763 asocket *s = calloc(1, sizeof(asocket));
764 if(s == 0) fatal("cannot allocate socket");
765 s->id = 0;
766 s->enqueue = smart_socket_enqueue;
767 s->ready = smart_socket_ready;
768 s->close = smart_socket_close;
769 s->extra = action_cb;
770
771 D("SS(%d): created %p\n", s->id, action_cb);
772 return s;
773}
774
775void smart_socket_action(asocket *s, const char *act)
776{
777
778}
779
780void connect_to_smartsocket(asocket *s)
781{
782 D("Connecting to smart socket \n");
783 asocket *ss = create_smart_socket(smart_socket_action);
784 s->peer = ss;
785 ss->peer = s;
786 s->ready(s);
787}