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