Home | History | Annotate | Download | only in adb
      1 /*
      2  * Copyright (C) 2007 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include <stdio.h>
     18 #include <stdlib.h>
     19 #include <string.h>
     20 #include <errno.h>
     21 
     22 #include "sysdeps.h"
     23 #include <sys/types.h>
     24 
     25 #define  TRACE_TAG  TRACE_TRANSPORT
     26 #include "adb.h"
     27 
     28 #ifdef HAVE_BIG_ENDIAN
     29 #define H4(x)	(((x) & 0xFF000000) >> 24) | (((x) & 0x00FF0000) >> 8) | (((x) & 0x0000FF00) << 8) | (((x) & 0x000000FF) << 24)
     30 static inline void fix_endians(apacket *p)
     31 {
     32     p->msg.command     = H4(p->msg.command);
     33     p->msg.arg0        = H4(p->msg.arg0);
     34     p->msg.arg1        = H4(p->msg.arg1);
     35     p->msg.data_length = H4(p->msg.data_length);
     36     p->msg.data_check  = H4(p->msg.data_check);
     37     p->msg.magic       = H4(p->msg.magic);
     38 }
     39 #else
     40 #define fix_endians(p) do {} while (0)
     41 #endif
     42 
     43 #if ADB_HOST
     44 /* we keep a list of opened transports. The atransport struct knows to which
     45  * local transport it is connected. The list is used to detect when we're
     46  * trying to connect twice to a given local transport.
     47  */
     48 #define  ADB_LOCAL_TRANSPORT_MAX  16
     49 
     50 ADB_MUTEX_DEFINE( local_transports_lock );
     51 
     52 static atransport*  local_transports[ ADB_LOCAL_TRANSPORT_MAX ];
     53 #endif /* ADB_HOST */
     54 
     55 static int remote_read(apacket *p, atransport *t)
     56 {
     57     if(readx(t->sfd, &p->msg, sizeof(amessage))){
     58         D("remote local: read terminated (message)\n");
     59         return -1;
     60     }
     61 
     62     fix_endians(p);
     63 
     64 #if 0 && defined HAVE_BIG_ENDIAN
     65     D("read remote packet: %04x arg0=%0x arg1=%0x data_length=%0x data_check=%0x magic=%0x\n",
     66       p->msg.command, p->msg.arg0, p->msg.arg1, p->msg.data_length, p->msg.data_check, p->msg.magic);
     67 #endif
     68     if(check_header(p)) {
     69         D("bad header: terminated (data)\n");
     70         return -1;
     71     }
     72 
     73     if(readx(t->sfd, p->data, p->msg.data_length)){
     74         D("remote local: terminated (data)\n");
     75         return -1;
     76     }
     77 
     78     if(check_data(p)) {
     79         D("bad data: terminated (data)\n");
     80         return -1;
     81     }
     82 
     83     return 0;
     84 }
     85 
     86 static int remote_write(apacket *p, atransport *t)
     87 {
     88     int   length = p->msg.data_length;
     89 
     90     fix_endians(p);
     91 
     92 #if 0 && defined HAVE_BIG_ENDIAN
     93     D("write remote packet: %04x arg0=%0x arg1=%0x data_length=%0x data_check=%0x magic=%0x\n",
     94       p->msg.command, p->msg.arg0, p->msg.arg1, p->msg.data_length, p->msg.data_check, p->msg.magic);
     95 #endif
     96     if(writex(t->sfd, &p->msg, sizeof(amessage) + length)) {
     97         D("remote local: write terminated\n");
     98         return -1;
     99     }
    100 
    101     return 0;
    102 }
    103 
    104 
    105 int local_connect(int port) {
    106     return local_connect_arbitrary_ports(port-1, port);
    107 }
    108 
    109 int local_connect_arbitrary_ports(int console_port, int adb_port)
    110 {
    111     char buf[64];
    112     int  fd = -1;
    113 
    114 #if ADB_HOST
    115     const char *host = getenv("ADBHOST");
    116     if (host) {
    117         fd = socket_network_client(host, adb_port, SOCK_STREAM);
    118     }
    119 #endif
    120     if (fd < 0) {
    121         fd = socket_loopback_client(adb_port, SOCK_STREAM);
    122     }
    123 
    124     if (fd >= 0) {
    125         D("client: connected on remote on fd %d\n", fd);
    126         close_on_exec(fd);
    127         disable_tcp_nagle(fd);
    128         snprintf(buf, sizeof buf, "%s%d", LOCAL_CLIENT_PREFIX, console_port);
    129         register_socket_transport(fd, buf, adb_port, 1);
    130         return 0;
    131     }
    132     return -1;
    133 }
    134 
    135 
    136 static void *client_socket_thread(void *x)
    137 {
    138 #if ADB_HOST
    139     int  port  = DEFAULT_ADB_LOCAL_TRANSPORT_PORT;
    140     int  count = ADB_LOCAL_TRANSPORT_MAX;
    141 
    142     D("transport: client_socket_thread() starting\n");
    143 
    144     /* try to connect to any number of running emulator instances     */
    145     /* this is only done when ADB starts up. later, each new emulator */
    146     /* will send a message to ADB to indicate that is is starting up  */
    147     for ( ; count > 0; count--, port += 2 ) {
    148         (void) local_connect(port);
    149     }
    150 #endif
    151     return 0;
    152 }
    153 
    154 static void *server_socket_thread(void * arg)
    155 {
    156     int serverfd, fd;
    157     struct sockaddr addr;
    158     socklen_t alen;
    159     int port = (int)arg;
    160 
    161     D("transport: server_socket_thread() starting\n");
    162     serverfd = -1;
    163     for(;;) {
    164         if(serverfd == -1) {
    165             serverfd = socket_inaddr_any_server(port, SOCK_STREAM);
    166             if(serverfd < 0) {
    167                 D("server: cannot bind socket yet\n");
    168                 adb_sleep_ms(1000);
    169                 continue;
    170             }
    171             close_on_exec(serverfd);
    172         }
    173 
    174         alen = sizeof(addr);
    175         D("server: trying to get new connection from %d\n", port);
    176         fd = adb_socket_accept(serverfd, &addr, &alen);
    177         if(fd >= 0) {
    178             D("server: new connection on fd %d\n", fd);
    179             close_on_exec(fd);
    180             disable_tcp_nagle(fd);
    181             register_socket_transport(fd, "host", port, 1);
    182         }
    183     }
    184     D("transport: server_socket_thread() exiting\n");
    185     return 0;
    186 }
    187 
    188 void local_init(int port)
    189 {
    190     adb_thread_t thr;
    191     void* (*func)(void *);
    192 
    193     if(HOST) {
    194         func = client_socket_thread;
    195     } else {
    196         func = server_socket_thread;
    197     }
    198 
    199     D("transport: local %s init\n", HOST ? "client" : "server");
    200 
    201     if(adb_thread_create(&thr, func, (void *)port)) {
    202         fatal_errno("cannot create local socket %s thread",
    203                     HOST ? "client" : "server");
    204     }
    205 }
    206 
    207 static void remote_kick(atransport *t)
    208 {
    209     int fd = t->sfd;
    210     t->sfd = -1;
    211     adb_shutdown(fd);
    212     adb_close(fd);
    213 
    214 #if ADB_HOST
    215     if(HOST) {
    216         int  nn;
    217         adb_mutex_lock( &local_transports_lock );
    218         for (nn = 0; nn < ADB_LOCAL_TRANSPORT_MAX; nn++) {
    219             if (local_transports[nn] == t) {
    220                 local_transports[nn] = NULL;
    221                 break;
    222             }
    223         }
    224         adb_mutex_unlock( &local_transports_lock );
    225     }
    226 #endif
    227 }
    228 
    229 static void remote_close(atransport *t)
    230 {
    231     adb_close(t->fd);
    232 }
    233 
    234 
    235 #if ADB_HOST
    236 /* Only call this function if you already hold local_transports_lock. */
    237 atransport* find_emulator_transport_by_adb_port_locked(int adb_port)
    238 {
    239     int i;
    240     for (i = 0; i < ADB_LOCAL_TRANSPORT_MAX; i++) {
    241         if (local_transports[i] && local_transports[i]->adb_port == adb_port) {
    242             return local_transports[i];
    243         }
    244     }
    245     return NULL;
    246 }
    247 
    248 atransport* find_emulator_transport_by_adb_port(int adb_port)
    249 {
    250     adb_mutex_lock( &local_transports_lock );
    251     atransport* result = find_emulator_transport_by_adb_port_locked(adb_port);
    252     adb_mutex_unlock( &local_transports_lock );
    253     return result;
    254 }
    255 
    256 /* Only call this function if you already hold local_transports_lock. */
    257 int get_available_local_transport_index_locked()
    258 {
    259     int i;
    260     for (i = 0; i < ADB_LOCAL_TRANSPORT_MAX; i++) {
    261         if (local_transports[i] == NULL) {
    262             return i;
    263         }
    264     }
    265     return -1;
    266 }
    267 
    268 int get_available_local_transport_index()
    269 {
    270     adb_mutex_lock( &local_transports_lock );
    271     int result = get_available_local_transport_index_locked();
    272     adb_mutex_unlock( &local_transports_lock );
    273     return result;
    274 }
    275 #endif
    276 
    277 int init_socket_transport(atransport *t, int s, int adb_port, int local)
    278 {
    279     int  fail = 0;
    280 
    281     t->kick = remote_kick;
    282     t->close = remote_close;
    283     t->read_from_remote = remote_read;
    284     t->write_to_remote = remote_write;
    285     t->sfd = s;
    286     t->sync_token = 1;
    287     t->connection_state = CS_OFFLINE;
    288     t->type = kTransportLocal;
    289     t->adb_port = 0;
    290 
    291 #if ADB_HOST
    292     if (HOST && local) {
    293         adb_mutex_lock( &local_transports_lock );
    294         {
    295             t->adb_port = adb_port;
    296             atransport* existing_transport =
    297                     find_emulator_transport_by_adb_port_locked(adb_port);
    298             int index = get_available_local_transport_index_locked();
    299             if (existing_transport != NULL) {
    300                 D("local transport for port %d already registered (%p)?\n",
    301                 adb_port, existing_transport);
    302                 fail = -1;
    303             } else if (index < 0) {
    304                 // Too many emulators.
    305                 D("cannot register more emulators. Maximum is %d\n",
    306                         ADB_LOCAL_TRANSPORT_MAX);
    307                 fail = -1;
    308             } else {
    309                 local_transports[index] = t;
    310             }
    311        }
    312        adb_mutex_unlock( &local_transports_lock );
    313     }
    314 #endif
    315     return fail;
    316 }
    317