transport_local.c revision ae06933cdeb61b1145a1245ea3f40a3d159d215b
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 <string.h> 20dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <errno.h> 21dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 22dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "sysdeps.h" 23dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/types.h> 24dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 25dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define TRACE_TAG TRACE_TRANSPORT 26dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "adb.h" 27dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 28d340d2f57dc0d414ea66b1b556caaf8c98b1e967Marcus Comstedt#ifdef HAVE_BIG_ENDIAN 29dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define H4(x) (((x) & 0xFF000000) >> 24) | (((x) & 0x00FF0000) >> 8) | (((x) & 0x0000FF00) << 8) | (((x) & 0x000000FF) << 24) 30dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic inline void fix_endians(apacket *p) 31dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 32dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.command = H4(p->msg.command); 33dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.arg0 = H4(p->msg.arg0); 34dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.arg1 = H4(p->msg.arg1); 35dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.data_length = H4(p->msg.data_length); 36dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.data_check = H4(p->msg.data_check); 37dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.magic = H4(p->msg.magic); 38dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 39dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else 40dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define fix_endians(p) do {} while (0) 41dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 42dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 43dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if ADB_HOST 44d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger/* we keep a list of opened transports. The atransport struct knows to which 45d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger * local transport it is connected. The list is used to detect when we're 46d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger * trying to connect twice to a given local transport. 47dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 48dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define ADB_LOCAL_TRANSPORT_MAX 16 49dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 50dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectADB_MUTEX_DEFINE( local_transports_lock ); 51dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 52dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic atransport* local_transports[ ADB_LOCAL_TRANSPORT_MAX ]; 53dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif /* ADB_HOST */ 54dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 55dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int remote_read(apacket *p, atransport *t) 56dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 57dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(readx(t->sfd, &p->msg, sizeof(amessage))){ 58dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("remote local: read terminated (message)\n"); 59dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 60dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 61dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 62dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fix_endians(p); 63dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 64d340d2f57dc0d414ea66b1b556caaf8c98b1e967Marcus Comstedt#if 0 && defined HAVE_BIG_ENDIAN 65dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("read remote packet: %04x arg0=%0x arg1=%0x data_length=%0x data_check=%0x magic=%0x\n", 66dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.command, p->msg.arg0, p->msg.arg1, p->msg.data_length, p->msg.data_check, p->msg.magic); 67dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 68dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(check_header(p)) { 69dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("bad header: terminated (data)\n"); 70dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 71dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 72dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 73dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(readx(t->sfd, p->data, p->msg.data_length)){ 74dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("remote local: terminated (data)\n"); 75dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 76dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 77dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 78dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(check_data(p)) { 79dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("bad data: terminated (data)\n"); 80dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 81dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 82dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 83dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 84dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 85dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 86dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int remote_write(apacket *p, atransport *t) 87dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 88dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int length = p->msg.data_length; 89dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 90dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fix_endians(p); 91dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 92d340d2f57dc0d414ea66b1b556caaf8c98b1e967Marcus Comstedt#if 0 && defined HAVE_BIG_ENDIAN 93dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("write remote packet: %04x arg0=%0x arg1=%0x data_length=%0x data_check=%0x magic=%0x\n", 94dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.command, p->msg.arg0, p->msg.arg1, p->msg.data_length, p->msg.data_check, p->msg.magic); 95dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 96dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(writex(t->sfd, &p->msg, sizeof(amessage) + length)) { 97dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("remote local: write terminated\n"); 98dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 99dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 100dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 101dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 102dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 103dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 104dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 105d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzingerint local_connect(int port) { 106d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger return local_connect_arbitrary_ports(port-1, port); 107d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger} 108d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger 109d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzingerint local_connect_arbitrary_ports(int console_port, int adb_port) 110dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 111dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char buf[64]; 112dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int fd = -1; 113dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 114dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if ADB_HOST 115dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project const char *host = getenv("ADBHOST"); 116dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (host) { 117d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger fd = socket_network_client(host, adb_port, SOCK_STREAM); 118dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 119dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 120dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (fd < 0) { 121d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger fd = socket_loopback_client(adb_port, SOCK_STREAM); 122dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 123dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 124dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (fd >= 0) { 125dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("client: connected on remote on fd %d\n", fd); 126dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project close_on_exec(fd); 127dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project disable_tcp_nagle(fd); 128d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger snprintf(buf, sizeof buf, "%s%d", LOCAL_CLIENT_PREFIX, console_port); 129d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger register_socket_transport(fd, buf, adb_port, 1); 130dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 131dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 132dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 133dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 134dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 135dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 136dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void *client_socket_thread(void *x) 137dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 138dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if ADB_HOST 139a84a42eb20d43ffa2695a69d583a6e09532b49d9Stefan Hilzinger int port = DEFAULT_ADB_LOCAL_TRANSPORT_PORT; 140dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int count = ADB_LOCAL_TRANSPORT_MAX; 141dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 142dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("transport: client_socket_thread() starting\n"); 143dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 144dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* try to connect to any number of running emulator instances */ 145dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* this is only done when ADB starts up. later, each new emulator */ 146dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* will send a message to ADB to indicate that is is starting up */ 147dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for ( ; count > 0; count--, port += 2 ) { 148dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project (void) local_connect(port); 149dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 150dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 151dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 152dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 153dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 154ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwoodstatic void *server_socket_thread(void * arg) 155dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 156dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int serverfd, fd; 1579a77f55aada6c5a8da3d330d858bd04c1c0b6c51Kenny Root struct sockaddr addr; 158dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project socklen_t alen; 159ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood int port = (int)arg; 160dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 161dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("transport: server_socket_thread() starting\n"); 162dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project serverfd = -1; 163dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for(;;) { 164dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(serverfd == -1) { 165ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood serverfd = socket_inaddr_any_server(port, SOCK_STREAM); 166dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(serverfd < 0) { 167dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("server: cannot bind socket yet\n"); 168dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_sleep_ms(1000); 169dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project continue; 170dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 171dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project close_on_exec(serverfd); 172dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 173dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 174dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project alen = sizeof(addr); 175ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood D("server: trying to get new connection from %d\n", port); 1769a77f55aada6c5a8da3d330d858bd04c1c0b6c51Kenny Root fd = adb_socket_accept(serverfd, &addr, &alen); 177dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(fd >= 0) { 178dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("server: new connection on fd %d\n", fd); 179dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project close_on_exec(fd); 180dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project disable_tcp_nagle(fd); 181ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood register_socket_transport(fd, "host", port, 1); 182dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 183dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 184dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("transport: server_socket_thread() exiting\n"); 185dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 186dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 187dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 188c4f37eed734ecd3310bbe241df1b940329e91d74Vladimir Chtchetkine/* This is relevant only for ADB daemon running inside the emulator. */ 189c4f37eed734ecd3310bbe241df1b940329e91d74Vladimir Chtchetkine#if !ADB_HOST 190c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine/* 191c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine * Redefine open and write for qemu_pipe.h that contains inlined references 192c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine * to those routines. We will redifine them back after qemu_pipe.h inclusion. 193c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine */ 194c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine#undef open 195c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine#undef write 196c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine#define open adb_open 197c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine#define write adb_write 198c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine#include <hardware/qemu_pipe.h> 199c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine#undef open 200c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine#undef write 201c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine#define open ___xxx_open 202c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine#define write ___xxx_write 203c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine 204c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine/* A worker thread that monitors host connections, and registers a transport for 205c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine * every new host connection. This thread replaces server_socket_thread on 206c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine * condition that adbd daemon runs inside the emulator, and emulator uses QEMUD 207c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine * pipe to communicate with adbd daemon inside the guest. This is done in order 208c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine * to provide more robust communication channel between ADB host and guest. The 209c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine * main issue with server_socket_thread approach is that it runs on top of TCP, 210c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine * and thus is sensitive to network disruptions. For instance, the 211c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine * ConnectionManager may decide to reset all network connections, in which case 212c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine * the connection between ADB host and guest will be lost. To make ADB traffic 213c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine * independent from the network, we use here 'adb' QEMUD service to transfer data 214c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine * between the host, and the guest. See external/qemu/android/adb-*.* that 215c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine * implements the emulator's side of the protocol. Another advantage of using 216c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine * QEMUD approach is that ADB will be up much sooner, since it doesn't depend 217c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine * anymore on network being set up. 218c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine * The guest side of the protocol contains the following phases: 219c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine * - Connect with adb QEMUD service. In this phase a handle to 'adb' QEMUD service 220c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine * is opened, and it becomes clear whether or not emulator supports that 221c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine * protocol. 222c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine * - Wait for the ADB host to create connection with the guest. This is done by 223c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine * sending an 'accept' request to the adb QEMUD service, and waiting on 224c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine * response. 225c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine * - When new ADB host connection is accepted, the connection with adb QEMUD 226c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine * service is registered as the transport, and a 'start' request is sent to the 227c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine * adb QEMUD service, indicating that the guest is ready to receive messages. 228c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine * Note that the guest will ignore messages sent down from the emulator before 229c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine * the transport registration is completed. That's why we need to send the 230c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine * 'start' request after the transport is registered. 231c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine */ 232c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkinestatic void *qemu_socket_thread(void * arg) 233c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine{ 234c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine/* 'accept' request to the adb QEMUD service. */ 235c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkinestatic const char _accept_req[] = "accept"; 236c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine/* 'start' request to the adb QEMUD service. */ 237c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkinestatic const char _start_req[] = "start"; 238c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine/* 'ok' reply from the adb QEMUD service. */ 239c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkinestatic const char _ok_resp[] = "ok"; 240c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine 241c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine const int port = (int)arg; 242c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine int res, fd; 243c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine char tmp[256]; 244c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine char con_name[32]; 245c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine 246c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine D("transport: qemu_socket_thread() starting\n"); 247c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine 248c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine /* adb QEMUD service connection request. */ 249c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine snprintf(con_name, sizeof(con_name), "qemud:adb:%d", port); 250c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine 251c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine /* Connect to the adb QEMUD service. */ 252c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine fd = qemu_pipe_open(con_name); 253c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine if (fd < 0) { 254c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine /* This could be an older version of the emulator, that doesn't 255c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine * implement adb QEMUD service. Fall back to the old TCP way. */ 256c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine adb_thread_t thr; 257c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine D("adb service is not available. Falling back to TCP socket.\n"); 258c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine adb_thread_create(&thr, server_socket_thread, arg); 259c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine return 0; 260c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine } 261c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine 262c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine for(;;) { 263c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine /* 264c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine * Wait till the host creates a new connection. 265c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine */ 266c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine 267c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine /* Send the 'accept' request. */ 268c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine res = adb_write(fd, _accept_req, strlen(_accept_req)); 269ae06933cdeb61b1145a1245ea3f40a3d159d215bEdwin Vane if ((size_t)res == strlen(_accept_req)) { 270c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine /* Wait for the response. In the response we expect 'ok' on success, 271c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine * or 'ko' on failure. */ 272c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine res = adb_read(fd, tmp, sizeof(tmp)); 273c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine if (res != 2 || memcmp(tmp, _ok_resp, 2)) { 274c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine D("Accepting ADB host connection has failed.\n"); 275c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine adb_close(fd); 276c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine } else { 277c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine /* Host is connected. Register the transport, and start the 278c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine * exchange. */ 279c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine register_socket_transport(fd, "host", port, 1); 280c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine adb_write(fd, _start_req, strlen(_start_req)); 281c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine } 282c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine 283c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine /* Prepare for accepting of the next ADB host connection. */ 284c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine fd = qemu_pipe_open(con_name); 285c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine if (fd < 0) { 286c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine D("adb service become unavailable.\n"); 287c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine return 0; 288c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine } 289c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine } else { 290c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine D("Unable to send the '%s' request to ADB service.\n", _accept_req); 291c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine return 0; 292c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine } 293c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine } 294c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine D("transport: qemu_socket_thread() exiting\n"); 295c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine return 0; 296c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine} 297c4f37eed734ecd3310bbe241df1b940329e91d74Vladimir Chtchetkine#endif // !ADB_HOST 298c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine 299ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwoodvoid local_init(int port) 300dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 301dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_thread_t thr; 302dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project void* (*func)(void *); 303dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 304dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(HOST) { 305dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project func = client_socket_thread; 306dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 307c4f37eed734ecd3310bbe241df1b940329e91d74Vladimir Chtchetkine#if ADB_HOST 308c4f37eed734ecd3310bbe241df1b940329e91d74Vladimir Chtchetkine func = server_socket_thread; 309c4f37eed734ecd3310bbe241df1b940329e91d74Vladimir Chtchetkine#else 310c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine /* For the adbd daemon in the system image we need to distinguish 311c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine * between the device, and the emulator. */ 312c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine char is_qemu[PROPERTY_VALUE_MAX]; 313c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine property_get("ro.kernel.qemu", is_qemu, ""); 314c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine if (!strcmp(is_qemu, "1")) { 315c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine /* Running inside the emulator: use QEMUD pipe as the transport. */ 316c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine func = qemu_socket_thread; 317c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine } else { 318c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine /* Running inside the device: use TCP socket as the transport. */ 319c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine func = server_socket_thread; 320c13daef7bdc09886ffbd573d7836a66b01c02084Vladimir Chtchetkine } 321fc656103dba298dbab1377ab07060068f50a5f83Anatol Pomazau#endif // !ADB_HOST 322dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 323dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 324dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("transport: local %s init\n", HOST ? "client" : "server"); 325dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 326ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood if(adb_thread_create(&thr, func, (void *)port)) { 327dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fatal_errno("cannot create local socket %s thread", 328dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project HOST ? "client" : "server"); 329dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 330dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 331dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 332dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void remote_kick(atransport *t) 333dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 334dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int fd = t->sfd; 335dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->sfd = -1; 3368cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood adb_shutdown(fd); 337dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_close(fd); 338dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 339dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if ADB_HOST 340dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(HOST) { 341dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int nn; 342dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_lock( &local_transports_lock ); 343dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (nn = 0; nn < ADB_LOCAL_TRANSPORT_MAX; nn++) { 344dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (local_transports[nn] == t) { 345dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project local_transports[nn] = NULL; 346dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 347dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 348dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 349dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_unlock( &local_transports_lock ); 350dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 351dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 352dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 353dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 354dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void remote_close(atransport *t) 355dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 356dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_close(t->fd); 357dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 358dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 359d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger 360d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger#if ADB_HOST 361d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger/* Only call this function if you already hold local_transports_lock. */ 362d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzingeratransport* find_emulator_transport_by_adb_port_locked(int adb_port) 363d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger{ 364d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger int i; 365d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger for (i = 0; i < ADB_LOCAL_TRANSPORT_MAX; i++) { 366d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger if (local_transports[i] && local_transports[i]->adb_port == adb_port) { 367d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger return local_transports[i]; 368d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger } 369d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger } 370d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger return NULL; 371d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger} 372d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger 373d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzingeratransport* find_emulator_transport_by_adb_port(int adb_port) 374d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger{ 375d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger adb_mutex_lock( &local_transports_lock ); 376d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger atransport* result = find_emulator_transport_by_adb_port_locked(adb_port); 377d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger adb_mutex_unlock( &local_transports_lock ); 378d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger return result; 379d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger} 380d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger 381d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger/* Only call this function if you already hold local_transports_lock. */ 382d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzingerint get_available_local_transport_index_locked() 383d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger{ 384d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger int i; 385d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger for (i = 0; i < ADB_LOCAL_TRANSPORT_MAX; i++) { 386d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger if (local_transports[i] == NULL) { 387d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger return i; 388d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger } 389d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger } 390d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger return -1; 391d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger} 392d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger 393d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzingerint get_available_local_transport_index() 394d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger{ 395d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger adb_mutex_lock( &local_transports_lock ); 396d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger int result = get_available_local_transport_index_locked(); 397d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger adb_mutex_unlock( &local_transports_lock ); 398d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger return result; 399d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger} 400d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger#endif 401d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger 402d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzingerint init_socket_transport(atransport *t, int s, int adb_port, int local) 403dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 404dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int fail = 0; 405dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 406dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->kick = remote_kick; 407dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->close = remote_close; 408dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->read_from_remote = remote_read; 409dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->write_to_remote = remote_write; 410dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->sfd = s; 411dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->sync_token = 1; 412dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->connection_state = CS_OFFLINE; 413dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->type = kTransportLocal; 414d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger t->adb_port = 0; 415dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 416dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if ADB_HOST 417ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood if (HOST && local) { 418dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_lock( &local_transports_lock ); 419dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project { 420d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger t->adb_port = adb_port; 421d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger atransport* existing_transport = 422d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger find_emulator_transport_by_adb_port_locked(adb_port); 423d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger int index = get_available_local_transport_index_locked(); 424d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger if (existing_transport != NULL) { 425dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("local transport for port %d already registered (%p)?\n", 426d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger adb_port, existing_transport); 427dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fail = -1; 428d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger } else if (index < 0) { 429d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger // Too many emulators. 430d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger D("cannot register more emulators. Maximum is %d\n", 431d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger ADB_LOCAL_TRANSPORT_MAX); 432d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger fail = -1; 433d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger } else { 434dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project local_transports[index] = t; 435d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger } 436d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger } 437d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger adb_mutex_unlock( &local_transports_lock ); 438dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 439dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 440dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return fail; 441dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 442