transport_local.c revision d9d1ca47802395e9e42e7deb05b2683d9d306598
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 28dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifdef __ppc__ 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 64dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if 0 && defined __ppc__ 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 92dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if 0 && defined __ppc__ 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; 157dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 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); 176dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 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 188ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwoodvoid local_init(int port) 189dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 190dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_thread_t thr; 191dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project void* (*func)(void *); 192dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 193dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(HOST) { 194dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project func = client_socket_thread; 195dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 196dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project func = server_socket_thread; 197dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 198dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 199dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("transport: local %s init\n", HOST ? "client" : "server"); 200dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 201ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood if(adb_thread_create(&thr, func, (void *)port)) { 202dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fatal_errno("cannot create local socket %s thread", 203dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project HOST ? "client" : "server"); 204dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 205dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 206dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 207dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void remote_kick(atransport *t) 208dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 209dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int fd = t->sfd; 210dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->sfd = -1; 2118cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood adb_shutdown(fd); 212dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_close(fd); 213dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 214dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if ADB_HOST 215dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(HOST) { 216dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int nn; 217dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_lock( &local_transports_lock ); 218dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (nn = 0; nn < ADB_LOCAL_TRANSPORT_MAX; nn++) { 219dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (local_transports[nn] == t) { 220dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project local_transports[nn] = NULL; 221dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 222dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 223dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 224dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_unlock( &local_transports_lock ); 225dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 226dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 227dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 228dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 229dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void remote_close(atransport *t) 230dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 231dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_close(t->fd); 232dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 233dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 234d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger 235d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger#if ADB_HOST 236d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger/* Only call this function if you already hold local_transports_lock. */ 237d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzingeratransport* find_emulator_transport_by_adb_port_locked(int adb_port) 238d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger{ 239d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger int i; 240d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger for (i = 0; i < ADB_LOCAL_TRANSPORT_MAX; i++) { 241d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger if (local_transports[i] && local_transports[i]->adb_port == adb_port) { 242d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger return local_transports[i]; 243d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger } 244d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger } 245d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger return NULL; 246d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger} 247d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger 248d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzingeratransport* find_emulator_transport_by_adb_port(int adb_port) 249d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger{ 250d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger adb_mutex_lock( &local_transports_lock ); 251d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger atransport* result = find_emulator_transport_by_adb_port_locked(adb_port); 252d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger adb_mutex_unlock( &local_transports_lock ); 253d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger return result; 254d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger} 255d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger 256d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger/* Only call this function if you already hold local_transports_lock. */ 257d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzingerint get_available_local_transport_index_locked() 258d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger{ 259d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger int i; 260d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger for (i = 0; i < ADB_LOCAL_TRANSPORT_MAX; i++) { 261d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger if (local_transports[i] == NULL) { 262d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger return i; 263d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger } 264d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger } 265d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger return -1; 266d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger} 267d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger 268d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzingerint get_available_local_transport_index() 269d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger{ 270d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger adb_mutex_lock( &local_transports_lock ); 271d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger int result = get_available_local_transport_index_locked(); 272d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger adb_mutex_unlock( &local_transports_lock ); 273d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger return result; 274d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger} 275d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger#endif 276d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger 277d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzingerint init_socket_transport(atransport *t, int s, int adb_port, int local) 278dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 279dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int fail = 0; 280dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 281dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->kick = remote_kick; 282dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->close = remote_close; 283dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->read_from_remote = remote_read; 284dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->write_to_remote = remote_write; 285dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->sfd = s; 286dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->sync_token = 1; 287dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->connection_state = CS_OFFLINE; 288dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->type = kTransportLocal; 289d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger t->adb_port = 0; 290dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 291dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if ADB_HOST 292ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood if (HOST && local) { 293dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_lock( &local_transports_lock ); 294dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project { 295d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger t->adb_port = adb_port; 296d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger atransport* existing_transport = 297d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger find_emulator_transport_by_adb_port_locked(adb_port); 298d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger int index = get_available_local_transport_index_locked(); 299d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger if (existing_transport != NULL) { 300dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("local transport for port %d already registered (%p)?\n", 301d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger adb_port, existing_transport); 302dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fail = -1; 303d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger } else if (index < 0) { 304d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger // Too many emulators. 305d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger D("cannot register more emulators. Maximum is %d\n", 306d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger ADB_LOCAL_TRANSPORT_MAX); 307d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger fail = -1; 308d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger } else { 309dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project local_transports[index] = t; 310d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger } 311d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger } 312d9d1ca47802395e9e42e7deb05b2683d9d306598Stefan Hilzinger adb_mutex_unlock( &local_transports_lock ); 313dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 314dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 315dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return fail; 316dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 317