transport.c revision 0927bf9690127bc45cf8837a1467759e9720399a
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 <string.h> 21dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <errno.h> 22dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 23dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "sysdeps.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 Projectstatic void transport_unref(atransport *t); 29dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 30dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic atransport transport_list = { 31dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project .next = &transport_list, 32dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project .prev = &transport_list, 33dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}; 34dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 35dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectADB_MUTEX_DEFINE( transport_lock ); 36dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 37dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if ADB_TRACE 38dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void dump_hex( const unsigned char* ptr, size_t len ) 39dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 40dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int nn, len2 = len; 41dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 42dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (len2 > 16) len2 = 16; 43dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 44dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (nn = 0; nn < len2; nn++) 45dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("%02x", ptr[nn]); 46dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D(" "); 47dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 48dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (nn = 0; nn < len2; nn++) { 49dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int c = ptr[nn]; 50dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (c < 32 || c > 127) 51dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project c = '.'; 52dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("%c", c); 53dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 54dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("\n"); 55dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fflush(stdout); 56dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 57dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 58dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 59dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid 60dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectkick_transport(atransport* t) 61dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 62dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (t && !t->kicked) 63dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project { 64dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int kicked; 65dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 66dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_lock(&transport_lock); 67dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project kicked = t->kicked; 68dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!kicked) 69dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->kicked = 1; 70dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_unlock(&transport_lock); 71dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 72dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!kicked) 73dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->kick(t); 74dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 75dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 76dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 77dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid 78dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectrun_transport_disconnects(atransport* t) 79dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 80dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adisconnect* dis = t->disconnects.next; 81dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 82dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("run_transport_disconnects: %p (%s)\n", t, t->serial ? t->serial : "unknown" ); 83dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while (dis != &t->disconnects) { 84dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adisconnect* next = dis->next; 85dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dis->func( dis->opaque, t ); 86dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dis = next; 87dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 88dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 89dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 90dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int 91dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectread_packet(int fd, apacket** ppacket) 92dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 93dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *p = (char*)ppacket; /* really read a packet address */ 94dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int r; 95dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int len = sizeof(*ppacket); 96dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while(len > 0) { 97dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project r = adb_read(fd, p, len); 98dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(r > 0) { 99dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len -= r; 100dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p += r; 101dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 102dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("read_packet: %d error %d %d\n", fd, r, errno); 103dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if((r < 0) && (errno == EINTR)) continue; 104dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 105dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 106dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 107dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 108dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if ADB_TRACE 109dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (ADB_TRACING) 110dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project { 111dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned command = (*ppacket)->msg.command; 112dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int len = (*ppacket)->msg.data_length; 113dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char cmd[5]; 114dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int n; 115dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 116dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (n = 0; n < 4; n++) { 117dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int b = (command >> (n*8)) & 255; 118dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (b >= 32 && b < 127) 119dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmd[n] = (char)b; 120dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project else 121dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmd[n] = '.'; 122dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 123dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmd[4] = 0; 124dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 125dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("read_packet: %d ok: [%08x %s] %08x %08x (%d) ", 126dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fd, command, cmd, (*ppacket)->msg.arg0, (*ppacket)->msg.arg1, len); 127dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dump_hex((*ppacket)->data, len); 128dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 129dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 130dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 131dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 132dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 133dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int 134dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectwrite_packet(int fd, apacket** ppacket) 135dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 136dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *p = (char*) ppacket; /* we really write the packet address */ 137dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int r, len = sizeof(ppacket); 138dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 139dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if ADB_TRACE 140dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (ADB_TRACING) 141dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project { 142dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned command = (*ppacket)->msg.command; 143dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int len = (*ppacket)->msg.data_length; 144dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char cmd[5]; 145dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int n; 146dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 147dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (n = 0; n < 4; n++) { 148dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int b = (command >> (n*8)) & 255; 149dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (b >= 32 && b < 127) 150dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmd[n] = (char)b; 151dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project else 152dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmd[n] = '.'; 153dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 154dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmd[4] = 0; 155dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 156dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("write_packet: %d [%08x %s] %08x %08x (%d) ", 157dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fd, command, cmd, (*ppacket)->msg.arg0, (*ppacket)->msg.arg1, len); 158dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dump_hex((*ppacket)->data, len); 159dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 160dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 161dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len = sizeof(ppacket); 162dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while(len > 0) { 163dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project r = adb_write(fd, p, len); 164dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(r > 0) { 165dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len -= r; 166dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p += r; 167dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 168dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("write_packet: %d error %d %d\n", fd, r, errno); 169dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if((r < 0) && (errno == EINTR)) continue; 170dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 171dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 172dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 173dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 174dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 175dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 176dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void transport_socket_events(int fd, unsigned events, void *_t) 177dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 178dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(events & FDE_READ){ 179dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project apacket *p = 0; 180dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(read_packet(fd, &p)){ 181dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("failed to read packet from transport socket on fd %d\n", fd); 182dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 183dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project handle_packet(p, (atransport *) _t); 184dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 185dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 186dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 187dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 188dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid send_packet(apacket *p, atransport *t) 189dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 190dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned char *x; 191dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned sum; 192dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned count; 193dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 194dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.magic = p->msg.command ^ 0xffffffff; 195dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 196dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project count = p->msg.data_length; 197dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project x = (unsigned char *) p->data; 198dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sum = 0; 199dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while(count-- > 0){ 200dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sum += *x++; 201dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 202dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.data_check = sum; 203dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 204dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project print_packet("send", p); 205dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 206dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (t == NULL) { 207dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fatal_errno("Transport is null"); 208dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("Transport is null \n"); 209dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 210dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 211dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(write_packet(t->transport_socket, &p)){ 212dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fatal_errno("cannot enqueue packet on transport socket"); 213dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 214dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 215dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 216dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* The transport is opened by transport_register_func before 217dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** the input and output threads are started. 218dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** 219dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** The output thread issues a SYNC(1, token) message to let 220dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** the input thread know to start things up. In the event 221dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** of transport IO failure, the output thread will post a 222dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** SYNC(0,0) message to ensure shutdown. 223dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** 224dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** The transport will not actually be closed until both 225dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** threads exit, but the input thread will kick the transport 226dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** on its way out to disconnect the underlying device. 227dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project*/ 228dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 229dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void *output_thread(void *_t) 230dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 231dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project atransport *t = _t; 232dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project apacket *p; 233dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 234dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("from_remote: starting thread for transport %p, on fd %d\n", t, t->fd ); 235dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 236dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("from_remote: transport %p SYNC online (%d)\n", t, t->sync_token + 1); 237dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p = get_apacket(); 238dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.command = A_SYNC; 239dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.arg0 = 1; 240dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.arg1 = ++(t->sync_token); 241dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.magic = A_SYNC ^ 0xffffffff; 242dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(write_packet(t->fd, &p)) { 243dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project put_apacket(p); 244dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("from_remote: failed to write SYNC apacket to transport %p", t); 245dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto oops; 246dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 247dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 248dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("from_remote: data pump for transport %p\n", t); 249dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for(;;) { 250dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p = get_apacket(); 251dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 252dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(t->read_from_remote(p, t) == 0){ 253dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("from_remote: received remote packet, sending to transport %p\n", 254dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t); 255dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(write_packet(t->fd, &p)){ 256dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project put_apacket(p); 257dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("from_remote: failed to write apacket to transport %p", t); 258dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto oops; 259dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 260dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 261dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("from_remote: remote read failed for transport %p\n", p); 262dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project put_apacket(p); 263dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 264dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 265dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 266dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 267dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("from_remote: SYNC offline for transport %p\n", t); 268dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p = get_apacket(); 269dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.command = A_SYNC; 270dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.arg0 = 0; 271dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.arg1 = 0; 272dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.magic = A_SYNC ^ 0xffffffff; 273dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(write_packet(t->fd, &p)) { 274dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project put_apacket(p); 275dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("from_remote: failed to write SYNC apacket to transport %p", t); 276dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 277dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 278dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectoops: 279dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("from_remote: thread is exiting for transport %p\n", t); 280dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project kick_transport(t); 281dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project transport_unref(t); 282dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 283dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 284dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 285dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void *input_thread(void *_t) 286dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 287dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project atransport *t = _t; 288dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project apacket *p; 289dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int active = 0; 290dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 291dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("to_remote: starting input_thread for %p, reading from fd %d\n", 292dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t, t->fd); 293dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 294dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for(;;){ 295dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(read_packet(t->fd, &p)) { 296dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("to_remote: failed to read apacket from transport %p on fd %d\n", 297dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t, t->fd ); 298dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 299dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 300dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(p->msg.command == A_SYNC){ 301dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(p->msg.arg0 == 0) { 302dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("to_remote: transport %p SYNC offline\n", t); 303dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project put_apacket(p); 304dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 305dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 306dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(p->msg.arg1 == t->sync_token) { 307dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("to_remote: transport %p SYNC online\n", t); 308dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project active = 1; 309dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 310dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("to_remote: trandport %p ignoring SYNC %d != %d\n", 311dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t, p->msg.arg1, t->sync_token); 312dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 313dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 314dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 315dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(active) { 316dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("to_remote: transport %p got packet, sending to remote\n", t); 317dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->write_to_remote(p, t); 318dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 319dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("to_remote: transport %p ignoring packet while offline\n", t); 320dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 321dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 322dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 323dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project put_apacket(p); 324dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 325dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 326dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // this is necessary to avoid a race condition that occured when a transport closes 327dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // while a client socket is still active. 328dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project close_all_sockets(t); 329dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 330dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("to_remote: thread is exiting for transport %p, fd %d\n", t, t->fd); 331dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project kick_transport(t); 332dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project transport_unref(t); 333dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 334dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 335dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 336dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 337dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int transport_registration_send = -1; 338dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int transport_registration_recv = -1; 339dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic fdevent transport_registration_fde; 340dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 341dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 342dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if ADB_HOST 343dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int list_transports_msg(char* buffer, size_t bufferlen) 344dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 345dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char head[5]; 346dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int len; 347dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 348dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len = list_transports(buffer+4, bufferlen-4); 349dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project snprintf(head, sizeof(head), "%04x", len); 350dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project memcpy(buffer, head, 4); 351dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len += 4; 352dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return len; 353dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 354dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 355dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* this adds support required by the 'track-devices' service. 356dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * this is used to send the content of "list_transport" to any 357dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * number of client connections that want it through a single 358dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * live TCP connection 359dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 360dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecttypedef struct device_tracker device_tracker; 361dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstruct device_tracker { 362dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project asocket socket; 363dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int update_needed; 364dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project device_tracker* next; 365dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}; 366dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 367dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* linked list of all device trackers */ 368dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic device_tracker* device_tracker_list; 369dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 370dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void 371dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectdevice_tracker_remove( device_tracker* tracker ) 372dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 373dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project device_tracker** pnode = &device_tracker_list; 374dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project device_tracker* node = *pnode; 375dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 376dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_lock( &transport_lock ); 377dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while (node) { 378dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (node == tracker) { 379dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *pnode = node->next; 380dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 381dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 382dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project pnode = &node->next; 383dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project node = *pnode; 384dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 385dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_unlock( &transport_lock ); 386dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 387dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 388dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void 389dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectdevice_tracker_close( asocket* socket ) 390dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 391dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project device_tracker* tracker = (device_tracker*) socket; 392dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project asocket* peer = socket->peer; 393dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 394dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D( "device tracker %p removed\n", tracker); 395dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (peer) { 396dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project peer->peer = NULL; 397dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project peer->close(peer); 398dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 399dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project device_tracker_remove(tracker); 400dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project free(tracker); 401dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 402dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 403dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int 404dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectdevice_tracker_enqueue( asocket* socket, apacket* p ) 405dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 406dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* you can't read from a device tracker, close immediately */ 407dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project put_apacket(p); 408dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project device_tracker_close(socket); 409dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 410dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 411dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 412dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int 413dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectdevice_tracker_send( device_tracker* tracker, 414dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project const char* buffer, 415dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int len ) 416dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 417dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project apacket* p = get_apacket(); 418dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project asocket* peer = tracker->socket.peer; 419dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 420dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project memcpy(p->data, buffer, len); 421dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->len = len; 422dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return peer->enqueue( peer, p ); 423dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 424dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 425dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 426dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void 427dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectdevice_tracker_ready( asocket* socket ) 428dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 429dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project device_tracker* tracker = (device_tracker*) socket; 430dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 431dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* we want to send the device list when the tracker connects 432dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * for the first time, even if no update occured */ 433dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (tracker->update_needed > 0) { 434dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char buffer[1024]; 435dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int len; 436dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 437dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project tracker->update_needed = 0; 438dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 439dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len = list_transports_msg(buffer, sizeof(buffer)); 440dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project device_tracker_send(tracker, buffer, len); 441dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 442dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 443dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 444dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 445dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectasocket* 446dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectcreate_device_tracker(void) 447dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 448dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project device_tracker* tracker = calloc(1,sizeof(*tracker)); 449dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 450dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(tracker == 0) fatal("cannot allocate device tracker"); 451dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 452dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D( "device tracker %p created\n", tracker); 453dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 454dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project tracker->socket.enqueue = device_tracker_enqueue; 455dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project tracker->socket.ready = device_tracker_ready; 456dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project tracker->socket.close = device_tracker_close; 457dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project tracker->update_needed = 1; 458dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 459dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project tracker->next = device_tracker_list; 460dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project device_tracker_list = tracker; 461dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 462dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return &tracker->socket; 463dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 464dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 465dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 466dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* call this function each time the transport list has changed */ 467dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid update_transports(void) 468dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 469dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char buffer[1024]; 470dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int len; 471dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project device_tracker* tracker; 472dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 473dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len = list_transports_msg(buffer, sizeof(buffer)); 474dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 475dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project tracker = device_tracker_list; 476dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while (tracker != NULL) { 477dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project device_tracker* next = tracker->next; 478dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* note: this may destroy the tracker if the connection is closed */ 479dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project device_tracker_send(tracker, buffer, len); 480dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project tracker = next; 481dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 482dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 483dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else 484dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid update_transports(void) 485dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 486dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // nothing to do on the device side 487dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 488dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif // ADB_HOST 489dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 490dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecttypedef struct tmsg tmsg; 491dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstruct tmsg 492dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 493dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project atransport *transport; 494dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int action; 495dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}; 496dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 497dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int 498dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecttransport_read_action(int fd, struct tmsg* m) 499dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 500dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *p = (char*)m; 501dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int len = sizeof(*m); 502dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int r; 503dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 504dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while(len > 0) { 505dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project r = adb_read(fd, p, len); 506dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(r > 0) { 507dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len -= r; 508dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p += r; 509dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 510dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if((r < 0) && (errno == EINTR)) continue; 511dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("transport_read_action: on fd %d, error %d: %s\n", 512dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fd, errno, strerror(errno)); 513dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 514dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 515dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 516dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 517dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 518dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 519dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int 520dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecttransport_write_action(int fd, struct tmsg* m) 521dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 522dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *p = (char*)m; 523dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int len = sizeof(*m); 524dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int r; 525dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 526dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while(len > 0) { 527dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project r = adb_write(fd, p, len); 528dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(r > 0) { 529dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len -= r; 530dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p += r; 531dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 532dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if((r < 0) && (errno == EINTR)) continue; 533dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("transport_write_action: on fd %d, error %d: %s\n", 534dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fd, errno, strerror(errno)); 535dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 536dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 537dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 538dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 539dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 540dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 541dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void transport_registration_func(int _fd, unsigned ev, void *data) 542dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 543dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project tmsg m; 544dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_thread_t output_thread_ptr; 545dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_thread_t input_thread_ptr; 546dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int s[2]; 547dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project atransport *t; 548dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 549dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(!(ev & FDE_READ)) { 550dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 551dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 552dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 553dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(transport_read_action(_fd, &m)) { 554dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fatal_errno("cannot read transport registration socket"); 555dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 556dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 557dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t = m.transport; 558dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 559dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(m.action == 0){ 560dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("transport: %p removing and free'ing %d\n", t, t->transport_socket); 561dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 562dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* IMPORTANT: the remove closes one half of the 563dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ** socket pair. The close closes the other half. 564dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 565dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fdevent_remove(&(t->transport_fde)); 566dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_close(t->fd); 567dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 568dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_lock(&transport_lock); 569dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->next->prev = t->prev; 570dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->prev->next = t->next; 571dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_unlock(&transport_lock); 572dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 573dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project run_transport_disconnects(t); 574dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 575dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (t->product) 576dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project free(t->product); 577dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (t->serial) 578dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project free(t->serial); 579dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 580dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project memset(t,0xee,sizeof(atransport)); 581dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project free(t); 582dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 583dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project update_transports(); 584dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 585dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 586dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 5870927bf9690127bc45cf8837a1467759e9720399aMike Lockwood /* don't create transport threads for inaccessible devices */ 5880927bf9690127bc45cf8837a1467759e9720399aMike Lockwood if (t->connection_state != CS_NOPERM) { 589dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* initial references are the two threads */ 5900927bf9690127bc45cf8837a1467759e9720399aMike Lockwood t->ref_count = 2; 591dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 5920927bf9690127bc45cf8837a1467759e9720399aMike Lockwood if(adb_socketpair(s)) { 5930927bf9690127bc45cf8837a1467759e9720399aMike Lockwood fatal_errno("cannot open transport socketpair"); 5940927bf9690127bc45cf8837a1467759e9720399aMike Lockwood } 5950927bf9690127bc45cf8837a1467759e9720399aMike Lockwood 5960927bf9690127bc45cf8837a1467759e9720399aMike Lockwood D("transport: %p (%d,%d) starting\n", t, s[0], s[1]); 5970927bf9690127bc45cf8837a1467759e9720399aMike Lockwood 5980927bf9690127bc45cf8837a1467759e9720399aMike Lockwood t->transport_socket = s[0]; 5990927bf9690127bc45cf8837a1467759e9720399aMike Lockwood t->fd = s[1]; 600dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 6010927bf9690127bc45cf8837a1467759e9720399aMike Lockwood D("transport: %p install %d\n", t, t->transport_socket ); 6020927bf9690127bc45cf8837a1467759e9720399aMike Lockwood fdevent_install(&(t->transport_fde), 6030927bf9690127bc45cf8837a1467759e9720399aMike Lockwood t->transport_socket, 6040927bf9690127bc45cf8837a1467759e9720399aMike Lockwood transport_socket_events, 6050927bf9690127bc45cf8837a1467759e9720399aMike Lockwood t); 6060927bf9690127bc45cf8837a1467759e9720399aMike Lockwood 6070927bf9690127bc45cf8837a1467759e9720399aMike Lockwood fdevent_set(&(t->transport_fde), FDE_READ); 6080927bf9690127bc45cf8837a1467759e9720399aMike Lockwood 6090927bf9690127bc45cf8837a1467759e9720399aMike Lockwood if(adb_thread_create(&input_thread_ptr, input_thread, t)){ 6100927bf9690127bc45cf8837a1467759e9720399aMike Lockwood fatal_errno("cannot create input thread"); 6110927bf9690127bc45cf8837a1467759e9720399aMike Lockwood } 612dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 6130927bf9690127bc45cf8837a1467759e9720399aMike Lockwood if(adb_thread_create(&output_thread_ptr, output_thread, t)){ 6140927bf9690127bc45cf8837a1467759e9720399aMike Lockwood fatal_errno("cannot create output thread"); 6150927bf9690127bc45cf8837a1467759e9720399aMike Lockwood } 6160927bf9690127bc45cf8837a1467759e9720399aMike Lockwood } 617dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 618dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* put us on the master device list */ 619dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_lock(&transport_lock); 620dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->next = &transport_list; 621dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->prev = transport_list.prev; 622dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->next->prev = t; 623dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->prev->next = t; 624dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_unlock(&transport_lock); 625dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 626dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->disconnects.next = t->disconnects.prev = &t->disconnects; 627dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 628dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project update_transports(); 629dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 630dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 631dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid init_transport_registration(void) 632dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 633dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int s[2]; 634dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 635dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(adb_socketpair(s)){ 636dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fatal_errno("cannot open transport registration socketpair"); 637dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 638dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 639dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project transport_registration_send = s[0]; 640dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project transport_registration_recv = s[1]; 641dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 642dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fdevent_install(&transport_registration_fde, 643dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project transport_registration_recv, 644dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project transport_registration_func, 645dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 0); 646dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 647dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fdevent_set(&transport_registration_fde, FDE_READ); 648dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 649dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 650dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* the fdevent select pump is single threaded */ 651dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void register_transport(atransport *transport) 652dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 653dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project tmsg m; 654dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project m.transport = transport; 655dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project m.action = 1; 656dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("transport: %p registered\n", transport); 657dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(transport_write_action(transport_registration_send, &m)) { 658dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fatal_errno("cannot write transport registration socket\n"); 659dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 660dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 661dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 662dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void remove_transport(atransport *transport) 663dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 664dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project tmsg m; 665dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project m.transport = transport; 666dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project m.action = 0; 667dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("transport: %p removed\n", transport); 668dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(transport_write_action(transport_registration_send, &m)) { 669dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fatal_errno("cannot write transport registration socket\n"); 670dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 671dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 672dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 673dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 674dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void transport_unref(atransport *t) 675dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 676dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (t) { 677dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_lock(&transport_lock); 678dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->ref_count--; 679dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("transport: %p R- (ref=%d)\n", t, t->ref_count); 680dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (t->ref_count == 0) { 681dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("transport: %p kicking and closing\n", t); 682dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!t->kicked) { 683dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->kicked = 1; 684dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->kick(t); 685dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 686dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->close(t); 687dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project remove_transport(t); 688dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 689dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_unlock(&transport_lock); 690dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 691dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 692dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 693dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid add_transport_disconnect(atransport* t, adisconnect* dis) 694dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 695dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_lock(&transport_lock); 696dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dis->next = &t->disconnects; 697dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dis->prev = dis->next->prev; 698dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dis->prev->next = dis; 699dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dis->next->prev = dis; 700dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_unlock(&transport_lock); 701dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 702dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 703dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid remove_transport_disconnect(atransport* t, adisconnect* dis) 704dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 705dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dis->prev->next = dis->next; 706dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dis->next->prev = dis->prev; 707dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dis->next = dis->prev = dis; 708dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 709dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 710dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 711dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectatransport *acquire_one_transport(int state, transport_type ttype, const char* serial, char** error_out) 712dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 713dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project atransport *t; 714dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project atransport *result = NULL; 715dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int ambiguous = 0; 716dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 717dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectretry: 718dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (error_out) 719dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *error_out = "device not found"; 720dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 721dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_lock(&transport_lock); 722dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (t = transport_list.next; t != &transport_list; t = t->next) { 7230927bf9690127bc45cf8837a1467759e9720399aMike Lockwood if (t->connection_state == CS_NOPERM) continue; 7240927bf9690127bc45cf8837a1467759e9720399aMike Lockwood 725dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* check for matching serial number */ 726dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (serial) { 727dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (t->serial && !strcmp(serial, t->serial)) { 728dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project result = t; 729dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 730dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 731dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 732dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (ttype == kTransportUsb && t->type == kTransportUsb) { 733dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (result) { 734dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (error_out) 735dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *error_out = "more than one device"; 736dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ambiguous = 1; 737dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project result = NULL; 738dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 739dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 740dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project result = t; 741dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (ttype == kTransportLocal && t->type == kTransportLocal) { 742dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (result) { 743dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (error_out) 744dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *error_out = "more than one emulator"; 745dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ambiguous = 1; 746dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project result = NULL; 747dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 748dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 749dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project result = t; 750dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (ttype == kTransportAny) { 751dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (result) { 752dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (error_out) 753dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *error_out = "more than one device and emulator"; 754dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ambiguous = 1; 755dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project result = NULL; 756dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 757dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 758dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project result = t; 759dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 760dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 761dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 762dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_unlock(&transport_lock); 763dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 764dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (result) { 765dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* offline devices are ignored -- they are either being born or dying */ 766dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (result && result->connection_state == CS_OFFLINE) { 767dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (error_out) 768dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *error_out = "device offline"; 769dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project result = NULL; 770dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 7710927bf9690127bc45cf8837a1467759e9720399aMike Lockwood if (result && result->connection_state == CS_NOPERM) { 7720927bf9690127bc45cf8837a1467759e9720399aMike Lockwood if (error_out) 7730927bf9690127bc45cf8837a1467759e9720399aMike Lockwood *error_out = "no permissions for device"; 7740927bf9690127bc45cf8837a1467759e9720399aMike Lockwood result = NULL; 7750927bf9690127bc45cf8837a1467759e9720399aMike Lockwood } 776dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 777dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* check for required connection state */ 778dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (result && state != CS_ANY && result->connection_state != state) { 779dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (error_out) 780dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *error_out = "invalid device state"; 781dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project result = NULL; 782dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 783dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 784dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 785dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (result) { 786dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* found one that we can take */ 787dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (error_out) 788dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *error_out = NULL; 789dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (state != CS_ANY && (serial || !ambiguous)) { 790dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_sleep_ms(1000); 791dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto retry; 792dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 793dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 794dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return result; 795dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 796dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 797dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if ADB_HOST 798dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic const char *statename(atransport *t) 799dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 800dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project switch(t->connection_state){ 801dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case CS_OFFLINE: return "offline"; 802dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case CS_BOOTLOADER: return "bootloader"; 803dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case CS_DEVICE: return "device"; 804dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case CS_HOST: return "host"; 805dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case CS_RECOVERY: return "recovery"; 8060927bf9690127bc45cf8837a1467759e9720399aMike Lockwood case CS_NOPERM: return "no permissions"; 807dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project default: return "unknown"; 808dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 809dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 810dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 811dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint list_transports(char *buf, size_t bufsize) 812dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 813dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char* p = buf; 814dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char* end = buf + bufsize; 815dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int len; 816dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project atransport *t; 817dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 818dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* XXX OVERRUN PROBLEMS XXX */ 819dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_lock(&transport_lock); 820dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for(t = transport_list.next; t != &transport_list; t = t->next) { 8210927bf9690127bc45cf8837a1467759e9720399aMike Lockwood const char* serial = t->serial; 8220927bf9690127bc45cf8837a1467759e9720399aMike Lockwood if (!serial || !serial[0]) 8230927bf9690127bc45cf8837a1467759e9720399aMike Lockwood serial = "????????????"; 8240927bf9690127bc45cf8837a1467759e9720399aMike Lockwood len = snprintf(p, end - p, "%s\t%s\n", serial, statename(t)); 825dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 826dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (p + len >= end) { 827dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* discard last line if buffer is too short */ 828dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 829dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 830dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p += len; 831dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 832dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p[0] = 0; 833dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_unlock(&transport_lock); 834dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return p - buf; 835dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 836dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 837dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 838dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* hack for osx */ 839dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid close_usb_devices() 840dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 841dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project atransport *t; 842dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 843dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_lock(&transport_lock); 844dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for(t = transport_list.next; t != &transport_list; t = t->next) { 845dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if ( !t->kicked ) { 846dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->kicked = 1; 847dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->kick(t); 848dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 849dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 850dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_unlock(&transport_lock); 851dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 852dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif // ADB_HOST 853dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 854dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid register_socket_transport(int s, const char *serial, int port) 855dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 856dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project atransport *t = calloc(1, sizeof(atransport)); 857dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("transport: %p init'ing for socket %d, on port %d\n", t, s, port); 858dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if ( init_socket_transport(t, s, port) < 0 ) { 859dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_close(s); 860dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project free(t); 861dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 862dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 863dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(serial) { 864dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->serial = strdup(serial); 865dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 866dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project register_transport(t); 867dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 868dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 8690927bf9690127bc45cf8837a1467759e9720399aMike Lockwoodvoid register_usb_transport(usb_handle *usb, const char *serial, unsigned writeable) 870dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 871dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project atransport *t = calloc(1, sizeof(atransport)); 872dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("transport: %p init'ing for usb_handle %p (sn='%s')\n", t, usb, 873dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project serial ? serial : ""); 8740927bf9690127bc45cf8837a1467759e9720399aMike Lockwood init_usb_transport(t, usb, (writeable ? CS_OFFLINE : CS_NOPERM)); 875dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(serial) { 876dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->serial = strdup(serial); 877dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 878dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project register_transport(t); 879dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 880dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 8810927bf9690127bc45cf8837a1467759e9720399aMike Lockwood/* this should only be used for transports with connection_state == CS_NOPERM */ 8820927bf9690127bc45cf8837a1467759e9720399aMike Lockwoodvoid unregister_usb_transport(usb_handle *usb) 8830927bf9690127bc45cf8837a1467759e9720399aMike Lockwood{ 8840927bf9690127bc45cf8837a1467759e9720399aMike Lockwood atransport *t; 8850927bf9690127bc45cf8837a1467759e9720399aMike Lockwood adb_mutex_lock(&transport_lock); 8860927bf9690127bc45cf8837a1467759e9720399aMike Lockwood for(t = transport_list.next; t != &transport_list; t = t->next) { 8870927bf9690127bc45cf8837a1467759e9720399aMike Lockwood if (t->usb == usb && t->connection_state == CS_NOPERM) { 8880927bf9690127bc45cf8837a1467759e9720399aMike Lockwood t->next->prev = t->prev; 8890927bf9690127bc45cf8837a1467759e9720399aMike Lockwood t->prev->next = t->next; 8900927bf9690127bc45cf8837a1467759e9720399aMike Lockwood break; 8910927bf9690127bc45cf8837a1467759e9720399aMike Lockwood } 8920927bf9690127bc45cf8837a1467759e9720399aMike Lockwood } 8930927bf9690127bc45cf8837a1467759e9720399aMike Lockwood adb_mutex_unlock(&transport_lock); 8940927bf9690127bc45cf8837a1467759e9720399aMike Lockwood} 895dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 896dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#undef TRACE_TAG 897dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define TRACE_TAG TRACE_RWX 898dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 899dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint readx(int fd, void *ptr, size_t len) 900dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 901dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *p = ptr; 902dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int r; 903dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if ADB_TRACE 904dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int len0 = len; 905dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 906dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("readx: %d %p %d\n", fd, ptr, (int)len); 907dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while(len > 0) { 908dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project r = adb_read(fd, p, len); 909dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(r > 0) { 910dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len -= r; 911dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p += r; 912dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 913dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("readx: %d %d %s\n", fd, r, strerror(errno)); 914dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if((r < 0) && (errno == EINTR)) continue; 915dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 916dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 917dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 918dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 919dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if ADB_TRACE 920dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("readx: %d ok: ", fd); 921dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dump_hex( ptr, len0 ); 922dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 923dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 924dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 925dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 926dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint writex(int fd, const void *ptr, size_t len) 927dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 928dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *p = (char*) ptr; 929dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int r; 930dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 931dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if ADB_TRACE 932dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("writex: %d %p %d: ", fd, ptr, (int)len); 933dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dump_hex( ptr, len ); 934dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 935dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while(len > 0) { 936dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project r = adb_write(fd, p, len); 937dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(r > 0) { 938dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len -= r; 939dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p += r; 940dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 941dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("writex: %d %d %s\n", fd, r, strerror(errno)); 942dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if((r < 0) && (errno == EINTR)) continue; 943dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 944dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 945dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 946dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 947dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("writex: %d ok\n", fd); 948dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 949dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 950dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 951dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint check_header(apacket *p) 952dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 953dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(p->msg.magic != (p->msg.command ^ 0xffffffff)) { 954dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("check_header(): invalid magic\n"); 955dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 956dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 957dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 958dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(p->msg.data_length > MAX_PAYLOAD) { 959dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("check_header(): %d > MAX_PAYLOAD\n", p->msg.data_length); 960dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 961dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 962dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 963dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 964dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 965dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 966dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint check_data(apacket *p) 967dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 968dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned count, sum; 969dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned char *x; 970dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 971dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project count = p->msg.data_length; 972dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project x = p->data; 973dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sum = 0; 974dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while(count-- > 0) { 975dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sum += *x++; 976dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 977dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 978dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(sum != p->msg.data_check) { 979dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 980dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 981dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 982dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 983dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 984dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 985