blob: da894c3f036be33534ada427094dac70a8568a11 [file] [log] [blame]
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001/*
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>
Josh Gao5218ad32016-06-21 15:38:14 -070023#include <pthread.h>
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080024
25#include "sysdeps.h"
26
27#define TRACE_TAG TRACE_SOCKETS
28#include "adb.h"
29
Josh Gaoa9c0ac02016-10-21 11:25:46 -070030static pthread_mutex_t socket_list_lock;
31static void __attribute__((constructor)) socket_list_lock_init(void) {
32 pthread_mutexattr_t attr;
33 pthread_mutexattr_init(&attr);
34 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
35 pthread_mutex_init(&socket_list_lock, &attr);
36}
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080037
38int sendfailmsg(int fd, const char *reason)
39{
40 char buf[9];
41 int len;
42 len = strlen(reason);
43 if(len > 0xffff) len = 0xffff;
44 snprintf(buf, sizeof buf, "FAIL%04x", len);
45 if(writex(fd, buf, 8)) return -1;
46 return writex(fd, reason, len);
47}
48
49//extern int online;
50
51static unsigned local_socket_next_id = 1;
52
53static asocket local_socket_list = {
54 .next = &local_socket_list,
55 .prev = &local_socket_list,
56};
57
58/* the the list of currently closing local sockets.
59** these have no peer anymore, but still packets to
60** write to their fd.
61*/
62static asocket local_socket_closing_list = {
63 .next = &local_socket_closing_list,
64 .prev = &local_socket_closing_list,
65};
66
67asocket *find_local_socket(unsigned id)
68{
69 asocket *s;
70 asocket *result = NULL;
71
Josh Gao5218ad32016-06-21 15:38:14 -070072 pthread_mutex_lock(&socket_list_lock);
André Goddard Rosa81828292010-06-12 11:40:20 -030073 for (s = local_socket_list.next; s != &local_socket_list; s = s->next) {
74 if (s->id == id) {
75 result = s;
76 break;
77 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080078 }
Josh Gao5218ad32016-06-21 15:38:14 -070079 pthread_mutex_unlock(&socket_list_lock);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080080
81 return result;
82}
83
84static void
85insert_local_socket(asocket* s, asocket* list)
86{
87 s->next = list;
88 s->prev = s->next->prev;
89 s->prev->next = s;
90 s->next->prev = s;
91}
92
93
94void install_local_socket(asocket *s)
95{
Josh Gao5218ad32016-06-21 15:38:14 -070096 pthread_mutex_lock(&socket_list_lock);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080097
98 s->id = local_socket_next_id++;
99 insert_local_socket(s, &local_socket_list);
100
Josh Gao5218ad32016-06-21 15:38:14 -0700101 pthread_mutex_unlock(&socket_list_lock);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800102}
103
104void remove_socket(asocket *s)
105{
106 // socket_list_lock should already be held
107 if (s->prev && s->next)
108 {
109 s->prev->next = s->next;
110 s->next->prev = s->prev;
111 s->next = 0;
112 s->prev = 0;
113 s->id = 0;
114 }
115}
116
117void close_all_sockets(atransport *t)
118{
119 asocket *s;
120
121 /* this is a little gross, but since s->close() *will* modify
122 ** the list out from under you, your options are limited.
123 */
Josh Gao5218ad32016-06-21 15:38:14 -0700124 pthread_mutex_lock(&socket_list_lock);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800125restart:
126 for(s = local_socket_list.next; s != &local_socket_list; s = s->next){
127 if(s->transport == t || (s->peer && s->peer->transport == t)) {
Josh Gao5218ad32016-06-21 15:38:14 -0700128 s->close(s);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800129 goto restart;
130 }
131 }
Josh Gao5218ad32016-06-21 15:38:14 -0700132 pthread_mutex_unlock(&socket_list_lock);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800133}
134
135static int local_socket_enqueue(asocket *s, apacket *p)
136{
137 D("LS(%d): enqueue %d\n", s->id, p->len);
138
139 p->ptr = p->data;
140
141 /* if there is already data queue'd, we will receive
142 ** events when it's time to write. just add this to
143 ** the tail
144 */
145 if(s->pkt_first) {
146 goto enqueue;
147 }
148
149 /* write as much as we can, until we
150 ** would block or there is an error/eof
151 */
152 while(p->len > 0) {
153 int r = adb_write(s->fd, p->ptr, p->len);
154 if(r > 0) {
155 p->len -= r;
156 p->ptr += r;
157 continue;
158 }
159 if((r == 0) || (errno != EAGAIN)) {
160 D( "LS(%d): not ready, errno=%d: %s\n", s->id, errno, strerror(errno) );
161 s->close(s);
162 return 1; /* not ready (error) */
163 } else {
164 break;
165 }
166 }
167
168 if(p->len == 0) {
169 put_apacket(p);
170 return 0; /* ready for more data */
171 }
172
173enqueue:
174 p->next = 0;
175 if(s->pkt_first) {
176 s->pkt_last->next = p;
177 } else {
178 s->pkt_first = p;
179 }
180 s->pkt_last = p;
181
182 /* make sure we are notified when we can drain the queue */
183 fdevent_add(&s->fde, FDE_WRITE);
184
185 return 1; /* not ready (backlog) */
186}
187
188static void local_socket_ready(asocket *s)
189{
190 /* far side is ready for data, pay attention to
191 readable events */
192 fdevent_add(&s->fde, FDE_READ);
193// D("LS(%d): ready()\n", s->id);
194}
195
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800196// be sure to hold the socket list lock when calling this
197static void local_socket_destroy(asocket *s)
198{
199 apacket *p, *n;
Benoit Gobyf366b362012-03-16 14:50:07 -0700200 int exit_on_close = s->exit_on_close;
201
JP Abgrall408fa572011-03-16 15:57:42 -0700202 D("LS(%d): destroying fde.fd=%d\n", s->id, s->fde.fd);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800203
204 /* IMPORTANT: the remove closes the fd
205 ** that belongs to this socket
206 */
207 fdevent_remove(&s->fde);
208
209 /* dispose of any unwritten data */
210 for(p = s->pkt_first; p; p = n) {
211 D("LS(%d): discarding %d bytes\n", s->id, p->len);
212 n = p->next;
213 put_apacket(p);
214 }
215 remove_socket(s);
216 free(s);
Benoit Gobyf366b362012-03-16 14:50:07 -0700217
218 if (exit_on_close) {
219 D("local_socket_destroy: exiting\n");
220 exit(1);
221 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800222}
223
224
Josh Gao5218ad32016-06-21 15:38:14 -0700225static void local_socket_close(asocket *s)
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800226{
Josh Gao5218ad32016-06-21 15:38:14 -0700227 pthread_mutex_lock(&socket_list_lock);
JP Abgrall408fa572011-03-16 15:57:42 -0700228 D("entered. LS(%d) fd=%d\n", s->id, s->fd);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800229 if(s->peer) {
JP Abgrall408fa572011-03-16 15:57:42 -0700230 D("LS(%d): closing peer. peer->id=%d peer->fd=%d\n",
231 s->id, s->peer->id, s->peer->fd);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800232 s->peer->peer = 0;
Josh Gao5218ad32016-06-21 15:38:14 -0700233 s->peer->close(s->peer);
Tom Marlin49f18572011-05-13 13:24:55 -0500234 s->peer = 0;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800235 }
236
237 /* If we are already closing, or if there are no
238 ** pending packets, destroy immediately
239 */
240 if (s->closing || s->pkt_first == NULL) {
241 int id = s->id;
242 local_socket_destroy(s);
243 D("LS(%d): closed\n", id);
Josh Gao5218ad32016-06-21 15:38:14 -0700244 pthread_mutex_unlock(&socket_list_lock);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800245 return;
246 }
247
248 /* otherwise, put on the closing list
249 */
250 D("LS(%d): closing\n", s->id);
251 s->closing = 1;
252 fdevent_del(&s->fde, FDE_READ);
253 remove_socket(s);
JP Abgrall408fa572011-03-16 15:57:42 -0700254 D("LS(%d): put on socket_closing_list fd=%d\n", s->id, s->fd);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800255 insert_local_socket(s, &local_socket_closing_list);
Josh Gao5218ad32016-06-21 15:38:14 -0700256 pthread_mutex_unlock(&socket_list_lock);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800257}
258
259static void local_socket_event_func(int fd, unsigned ev, void *_s)
260{
261 asocket *s = _s;
262
JP Abgrall408fa572011-03-16 15:57:42 -0700263 D("LS(%d): event_func(fd=%d(==%d), ev=%04x)\n", s->id, s->fd, fd, ev);
264
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800265 /* put the FDE_WRITE processing before the FDE_READ
266 ** in order to simplify the code.
267 */
268 if(ev & FDE_WRITE){
269 apacket *p;
270
271 while((p = s->pkt_first) != 0) {
272 while(p->len > 0) {
273 int r = adb_write(fd, p->ptr, p->len);
274 if(r > 0) {
275 p->ptr += r;
276 p->len -= r;
277 continue;
278 }
279 if(r < 0) {
280 /* returning here is ok because FDE_READ will
281 ** be processed in the next iteration loop
282 */
283 if(errno == EAGAIN) return;
284 if(errno == EINTR) continue;
285 }
Christopher Tate5b811fa2011-06-10 11:38:37 -0700286 D(" closing after write because r=%d and errno is %d\n", r, errno);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800287 s->close(s);
288 return;
289 }
290
291 if(p->len == 0) {
292 s->pkt_first = p->next;
293 if(s->pkt_first == 0) s->pkt_last = 0;
294 put_apacket(p);
295 }
296 }
297
298 /* if we sent the last packet of a closing socket,
299 ** we can now destroy it.
300 */
301 if (s->closing) {
Christopher Tate5b811fa2011-06-10 11:38:37 -0700302 D(" closing because 'closing' is set after write\n");
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800303 s->close(s);
304 return;
305 }
306
307 /* no more packets queued, so we can ignore
308 ** writable events again and tell our peer
309 ** to resume writing
310 */
311 fdevent_del(&s->fde, FDE_WRITE);
312 s->peer->ready(s->peer);
313 }
314
315
316 if(ev & FDE_READ){
317 apacket *p = get_apacket();
318 unsigned char *x = p->data;
319 size_t avail = MAX_PAYLOAD;
320 int r;
321 int is_eof = 0;
322
323 while(avail > 0) {
324 r = adb_read(fd, x, avail);
JP Abgrall408fa572011-03-16 15:57:42 -0700325 D("LS(%d): post adb_read(fd=%d,...) r=%d (errno=%d) avail=%d\n", s->id, s->fd, r, r<0?errno:0, avail);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800326 if(r > 0) {
327 avail -= r;
328 x += r;
329 continue;
330 }
331 if(r < 0) {
332 if(errno == EAGAIN) break;
333 if(errno == EINTR) continue;
334 }
335
336 /* r = 0 or unhandled error */
337 is_eof = 1;
338 break;
339 }
JP Abgrall408fa572011-03-16 15:57:42 -0700340 D("LS(%d): fd=%d post avail loop. r=%d is_eof=%d forced_eof=%d\n",
341 s->id, s->fd, r, is_eof, s->fde.force_eof);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800342 if((avail == MAX_PAYLOAD) || (s->peer == 0)) {
343 put_apacket(p);
344 } else {
345 p->len = MAX_PAYLOAD - avail;
346
347 r = s->peer->enqueue(s->peer, p);
JP Abgrall408fa572011-03-16 15:57:42 -0700348 D("LS(%d): fd=%d post peer->enqueue(). r=%d\n", s->id, s->fd, r);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800349
350 if(r < 0) {
351 /* error return means they closed us as a side-effect
352 ** and we must return immediately.
353 **
354 ** note that if we still have buffered packets, the
355 ** socket will be placed on the closing socket list.
356 ** this handler function will be called again
357 ** to process FDE_WRITE events.
358 */
359 return;
360 }
361
362 if(r > 0) {
363 /* if the remote cannot accept further events,
364 ** we disable notification of READs. They'll
365 ** be enabled again when we get a call to ready()
366 */
367 fdevent_del(&s->fde, FDE_READ);
368 }
369 }
JP Abgrall112445b2011-04-12 22:01:58 -0700370 /* Don't allow a forced eof if data is still there */
371 if((s->fde.force_eof && !r) || is_eof) {
Christopher Tate5b811fa2011-06-10 11:38:37 -0700372 D(" closing because is_eof=%d r=%d s->fde.force_eof=%d\n", is_eof, r, s->fde.force_eof);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800373 s->close(s);
374 }
375 }
376
377 if(ev & FDE_ERROR){
378 /* this should be caught be the next read or write
379 ** catching it here means we may skip the last few
380 ** bytes of readable data.
381 */
382// s->close(s);
JP Abgrall408fa572011-03-16 15:57:42 -0700383 D("LS(%d): FDE_ERROR (fd=%d)\n", s->id, s->fd);
384
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800385 return;
386 }
387}
388
389asocket *create_local_socket(int fd)
390{
391 asocket *s = calloc(1, sizeof(asocket));
André Goddard Rosac419e2a2010-06-10 20:48:19 -0300392 if (s == NULL) fatal("cannot allocate socket");
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800393 s->fd = fd;
394 s->enqueue = local_socket_enqueue;
395 s->ready = local_socket_ready;
396 s->close = local_socket_close;
JP Abgrall408fa572011-03-16 15:57:42 -0700397 install_local_socket(s);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800398
399 fdevent_install(&s->fde, fd, local_socket_event_func, s);
400/* fdevent_add(&s->fde, FDE_ERROR); */
401 //fprintf(stderr, "Created local socket in create_local_socket \n");
402 D("LS(%d): created (fd=%d)\n", s->id, s->fd);
403 return s;
404}
405
406asocket *create_local_service_socket(const char *name)
407{
408 asocket *s;
409 int fd;
410
411#if !ADB_HOST
412 if (!strcmp(name,"jdwp")) {
413 return create_jdwp_service_socket();
414 }
415 if (!strcmp(name,"track-jdwp")) {
416 return create_jdwp_tracker_service_socket();
417 }
418#endif
419 fd = service_to_fd(name);
420 if(fd < 0) return 0;
421
422 s = create_local_socket(fd);
JP Abgrall408fa572011-03-16 15:57:42 -0700423 D("LS(%d): bound to '%s' via %d\n", s->id, name, fd);
Benoit Gobyf366b362012-03-16 14:50:07 -0700424
JP Abgrallf91259a2012-03-30 13:19:11 -0700425#if !ADB_HOST
Benoit Gobyaeceb512012-06-12 12:12:18 -0700426 if ((!strncmp(name, "root:", 5) && getuid() != 0)
427 || !strncmp(name, "usb:", 4)
428 || !strncmp(name, "tcpip:", 6)) {
Benoit Gobyf366b362012-03-16 14:50:07 -0700429 D("LS(%d): enabling exit_on_close\n", s->id);
430 s->exit_on_close = 1;
431 }
JP Abgrallf91259a2012-03-30 13:19:11 -0700432#endif
Benoit Gobyf366b362012-03-16 14:50:07 -0700433
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800434 return s;
435}
436
437#if ADB_HOST
438static asocket *create_host_service_socket(const char *name, const char* serial)
439{
440 asocket *s;
441
442 s = host_service_to_socket(name, serial);
443
444 if (s != NULL) {
445 D("LS(%d) bound to '%s'\n", s->id, name);
446 return s;
447 }
448
449 return s;
450}
451#endif /* ADB_HOST */
452
453/* a Remote socket is used to send/receive data to/from a given transport object
454** it needs to be closed when the transport is forcibly destroyed by the user
455*/
456typedef struct aremotesocket {
457 asocket socket;
458 adisconnect disconnect;
459} aremotesocket;
460
461static int remote_socket_enqueue(asocket *s, apacket *p)
462{
JP Abgrall408fa572011-03-16 15:57:42 -0700463 D("entered remote_socket_enqueue RS(%d) WRITE fd=%d peer.fd=%d\n",
464 s->id, s->fd, s->peer->fd);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800465 p->msg.command = A_WRTE;
466 p->msg.arg0 = s->peer->id;
467 p->msg.arg1 = s->id;
468 p->msg.data_length = p->len;
469 send_packet(p, s->transport);
470 return 1;
471}
472
473static void remote_socket_ready(asocket *s)
474{
JP Abgrall408fa572011-03-16 15:57:42 -0700475 D("entered remote_socket_ready RS(%d) OKAY fd=%d peer.fd=%d\n",
476 s->id, s->fd, s->peer->fd);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800477 apacket *p = get_apacket();
478 p->msg.command = A_OKAY;
479 p->msg.arg0 = s->peer->id;
480 p->msg.arg1 = s->id;
481 send_packet(p, s->transport);
482}
483
484static void remote_socket_close(asocket *s)
485{
JP Abgrall408fa572011-03-16 15:57:42 -0700486 D("entered remote_socket_close RS(%d) CLOSE fd=%d peer->fd=%d\n",
487 s->id, s->fd, s->peer?s->peer->fd:-1);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800488 apacket *p = get_apacket();
489 p->msg.command = A_CLSE;
490 if(s->peer) {
491 p->msg.arg0 = s->peer->id;
492 s->peer->peer = 0;
JP Abgrall408fa572011-03-16 15:57:42 -0700493 D("RS(%d) peer->close()ing peer->id=%d peer->fd=%d\n",
494 s->id, s->peer->id, s->peer->fd);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800495 s->peer->close(s->peer);
496 }
497 p->msg.arg1 = s->id;
498 send_packet(p, s->transport);
499 D("RS(%d): closed\n", s->id);
500 remove_transport_disconnect( s->transport, &((aremotesocket*)s)->disconnect );
501 free(s);
502}
503
504static void remote_socket_disconnect(void* _s, atransport* t)
505{
506 asocket* s = _s;
507 asocket* peer = s->peer;
508
509 D("remote_socket_disconnect RS(%d)\n", s->id);
510 if (peer) {
511 peer->peer = NULL;
512 peer->close(peer);
513 }
514 remove_transport_disconnect( s->transport, &((aremotesocket*)s)->disconnect );
515 free(s);
516}
517
518asocket *create_remote_socket(unsigned id, atransport *t)
519{
520 asocket *s = calloc(1, sizeof(aremotesocket));
521 adisconnect* dis = &((aremotesocket*)s)->disconnect;
522
André Goddard Rosac419e2a2010-06-10 20:48:19 -0300523 if (s == NULL) fatal("cannot allocate socket");
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800524 s->id = id;
525 s->enqueue = remote_socket_enqueue;
526 s->ready = remote_socket_ready;
527 s->close = remote_socket_close;
528 s->transport = t;
529
530 dis->func = remote_socket_disconnect;
531 dis->opaque = s;
532 add_transport_disconnect( t, dis );
533 D("RS(%d): created\n", s->id);
534 return s;
535}
536
537void connect_to_remote(asocket *s, const char *destination)
538{
JP Abgrall408fa572011-03-16 15:57:42 -0700539 D("Connect_to_remote call RS(%d) fd=%d\n", s->id, s->fd);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800540 apacket *p = get_apacket();
541 int len = strlen(destination) + 1;
542
543 if(len > (MAX_PAYLOAD-1)) {
544 fatal("destination oversized");
545 }
546
547 D("LS(%d): connect('%s')\n", s->id, destination);
548 p->msg.command = A_OPEN;
549 p->msg.arg0 = s->id;
550 p->msg.data_length = len;
551 strcpy((char*) p->data, destination);
552 send_packet(p, s->transport);
553}
554
555
556/* this is used by magic sockets to rig local sockets to
557 send the go-ahead message when they connect */
558static void local_socket_ready_notify(asocket *s)
559{
560 s->ready = local_socket_ready;
561 s->close = local_socket_close;
562 adb_write(s->fd, "OKAY", 4);
563 s->ready(s);
564}
565
566/* this is used by magic sockets to rig local sockets to
567 send the failure message if they are closed before
568 connected (to avoid closing them without a status message) */
569static void local_socket_close_notify(asocket *s)
570{
571 s->ready = local_socket_ready;
572 s->close = local_socket_close;
573 sendfailmsg(s->fd, "closed");
574 s->close(s);
575}
576
577unsigned unhex(unsigned char *s, int len)
578{
579 unsigned n = 0, c;
580
581 while(len-- > 0) {
582 switch((c = *s++)) {
583 case '0': case '1': case '2':
584 case '3': case '4': case '5':
585 case '6': case '7': case '8':
586 case '9':
587 c -= '0';
588 break;
589 case 'a': case 'b': case 'c':
590 case 'd': case 'e': case 'f':
591 c = c - 'a' + 10;
592 break;
593 case 'A': case 'B': case 'C':
594 case 'D': case 'E': case 'F':
595 c = c - 'A' + 10;
596 break;
597 default:
598 return 0xffffffff;
599 }
600
601 n = (n << 4) | c;
602 }
603
604 return n;
605}
606
Scott Anderson2ca3e6b2012-05-30 18:11:27 -0700607#define PREFIX(str) { str, sizeof(str) - 1 }
608static const struct prefix_struct {
609 const char *str;
610 const size_t len;
611} prefixes[] = {
612 PREFIX("usb:"),
613 PREFIX("product:"),
614 PREFIX("model:"),
615 PREFIX("device:"),
616};
617static const int num_prefixes = (sizeof(prefixes) / sizeof(prefixes[0]));
618
Terence Haddock28e13902011-03-16 09:43:56 +0100619/* skip_host_serial return the position in a string
620 skipping over the 'serial' parameter in the ADB protocol,
621 where parameter string may be a host:port string containing
622 the protocol delimiter (colon). */
623char *skip_host_serial(char *service) {
624 char *first_colon, *serial_end;
Scott Anderson2ca3e6b2012-05-30 18:11:27 -0700625 int i;
Terence Haddock28e13902011-03-16 09:43:56 +0100626
Scott Anderson2ca3e6b2012-05-30 18:11:27 -0700627 for (i = 0; i < num_prefixes; i++) {
628 if (!strncmp(service, prefixes[i].str, prefixes[i].len))
629 return strchr(service + prefixes[i].len, ':');
Scott Anderson3608d832012-05-31 12:04:23 -0700630 }
631
Terence Haddock28e13902011-03-16 09:43:56 +0100632 first_colon = strchr(service, ':');
633 if (!first_colon) {
634 /* No colon in service string. */
635 return NULL;
636 }
637 serial_end = first_colon;
638 if (isdigit(serial_end[1])) {
639 serial_end++;
640 while ((*serial_end) && isdigit(*serial_end)) {
641 serial_end++;
642 }
643 if ((*serial_end) != ':') {
644 // Something other than numbers was found, reset the end.
645 serial_end = first_colon;
646 }
647 }
648 return serial_end;
649}
650
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800651static int smart_socket_enqueue(asocket *s, apacket *p)
652{
653 unsigned len;
654#if ADB_HOST
655 char *service = NULL;
656 char* serial = NULL;
657 transport_type ttype = kTransportAny;
658#endif
659
660 D("SS(%d): enqueue %d\n", s->id, p->len);
661
662 if(s->pkt_first == 0) {
663 s->pkt_first = p;
664 s->pkt_last = p;
665 } else {
666 if((s->pkt_first->len + p->len) > MAX_PAYLOAD) {
667 D("SS(%d): overflow\n", s->id);
668 put_apacket(p);
669 goto fail;
670 }
671
672 memcpy(s->pkt_first->data + s->pkt_first->len,
673 p->data, p->len);
674 s->pkt_first->len += p->len;
675 put_apacket(p);
676
677 p = s->pkt_first;
678 }
679
680 /* don't bother if we can't decode the length */
681 if(p->len < 4) return 0;
682
683 len = unhex(p->data, 4);
684 if((len < 1) || (len > 1024)) {
685 D("SS(%d): bad size (%d)\n", s->id, len);
686 goto fail;
687 }
688
689 D("SS(%d): len is %d\n", s->id, len );
690 /* can't do anything until we have the full header */
691 if((len + 4) > p->len) {
692 D("SS(%d): waiting for %d more bytes\n", s->id, len+4 - p->len);
693 return 0;
694 }
695
696 p->data[len + 4] = 0;
697
698 D("SS(%d): '%s'\n", s->id, (char*) (p->data + 4));
699
700#if ADB_HOST
701 service = (char *)p->data + 4;
702 if(!strncmp(service, "host-serial:", strlen("host-serial:"))) {
703 char* serial_end;
704 service += strlen("host-serial:");
705
Terence Haddock28e13902011-03-16 09:43:56 +0100706 // serial number should follow "host:" and could be a host:port string.
707 serial_end = skip_host_serial(service);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800708 if (serial_end) {
709 *serial_end = 0; // terminate string
710 serial = service;
711 service = serial_end + 1;
712 }
713 } else if (!strncmp(service, "host-usb:", strlen("host-usb:"))) {
714 ttype = kTransportUsb;
715 service += strlen("host-usb:");
716 } else if (!strncmp(service, "host-local:", strlen("host-local:"))) {
717 ttype = kTransportLocal;
718 service += strlen("host-local:");
719 } else if (!strncmp(service, "host:", strlen("host:"))) {
720 ttype = kTransportAny;
721 service += strlen("host:");
722 } else {
723 service = NULL;
724 }
725
726 if (service) {
727 asocket *s2;
728
729 /* some requests are handled immediately -- in that
730 ** case the handle_host_request() routine has sent
731 ** the OKAY or FAIL message and all we have to do
732 ** is clean up.
733 */
734 if(handle_host_request(service, ttype, serial, s->peer->fd, s) == 0) {
735 /* XXX fail message? */
736 D( "SS(%d): handled host service '%s'\n", s->id, service );
737 goto fail;
738 }
739 if (!strncmp(service, "transport", strlen("transport"))) {
740 D( "SS(%d): okay transport\n", s->id );
741 p->len = 0;
742 return 0;
743 }
744
745 /* try to find a local service with this name.
746 ** if no such service exists, we'll fail out
747 ** and tear down here.
748 */
749 s2 = create_host_service_socket(service, serial);
750 if(s2 == 0) {
751 D( "SS(%d): couldn't create host service '%s'\n", s->id, service );
752 sendfailmsg(s->peer->fd, "unknown host service");
753 goto fail;
754 }
755
756 /* we've connected to a local host service,
757 ** so we make our peer back into a regular
758 ** local socket and bind it to the new local
759 ** service socket, acknowledge the successful
760 ** connection, and close this smart socket now
761 ** that its work is done.
762 */
763 adb_write(s->peer->fd, "OKAY", 4);
764
765 s->peer->ready = local_socket_ready;
766 s->peer->close = local_socket_close;
767 s->peer->peer = s2;
768 s2->peer = s->peer;
769 s->peer = 0;
770 D( "SS(%d): okay\n", s->id );
771 s->close(s);
772
773 /* initial state is "ready" */
774 s2->ready(s2);
775 return 0;
776 }
777#else /* !ADB_HOST */
778 if (s->transport == NULL) {
779 char* error_string = "unknown failure";
780 s->transport = acquire_one_transport (CS_ANY,
781 kTransportAny, NULL, &error_string);
782
783 if (s->transport == NULL) {
784 sendfailmsg(s->peer->fd, error_string);
785 goto fail;
786 }
787 }
788#endif
789
790 if(!(s->transport) || (s->transport->connection_state == CS_OFFLINE)) {
791 /* if there's no remote we fail the connection
792 ** right here and terminate it
793 */
794 sendfailmsg(s->peer->fd, "device offline (x)");
795 goto fail;
796 }
797
798
799 /* instrument our peer to pass the success or fail
800 ** message back once it connects or closes, then
801 ** detach from it, request the connection, and
802 ** tear down
803 */
804 s->peer->ready = local_socket_ready_notify;
805 s->peer->close = local_socket_close_notify;
806 s->peer->peer = 0;
807 /* give him our transport and upref it */
808 s->peer->transport = s->transport;
809
810 connect_to_remote(s->peer, (char*) (p->data + 4));
811 s->peer = 0;
812 s->close(s);
813 return 1;
814
815fail:
816 /* we're going to close our peer as a side-effect, so
817 ** return -1 to signal that state to the local socket
818 ** who is enqueueing against us
819 */
820 s->close(s);
821 return -1;
822}
823
824static void smart_socket_ready(asocket *s)
825{
826 D("SS(%d): ready\n", s->id);
827}
828
829static void smart_socket_close(asocket *s)
830{
831 D("SS(%d): closed\n", s->id);
832 if(s->pkt_first){
833 put_apacket(s->pkt_first);
834 }
835 if(s->peer) {
836 s->peer->peer = 0;
837 s->peer->close(s->peer);
Tom Marlin49f18572011-05-13 13:24:55 -0500838 s->peer = 0;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800839 }
840 free(s);
841}
842
Benoit Goby9470c2f2013-02-20 15:04:53 -0800843static asocket *create_smart_socket(void)
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800844{
845 D("Creating smart socket \n");
846 asocket *s = calloc(1, sizeof(asocket));
André Goddard Rosac419e2a2010-06-10 20:48:19 -0300847 if (s == NULL) fatal("cannot allocate socket");
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800848 s->enqueue = smart_socket_enqueue;
849 s->ready = smart_socket_ready;
850 s->close = smart_socket_close;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800851
Benoit Goby9470c2f2013-02-20 15:04:53 -0800852 D("SS(%d)\n", s->id);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800853 return s;
854}
855
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800856void connect_to_smartsocket(asocket *s)
857{
858 D("Connecting to smart socket \n");
Benoit Goby9470c2f2013-02-20 15:04:53 -0800859 asocket *ss = create_smart_socket();
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800860 s->peer = ss;
861 ss->peer = s;
862 s->ready(s);
863}