transport.c revision 2ca3e6b35f79136418ebc32fef57580698dbd045
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 38408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall#define MAX_DUMP_HEX_LEN 16 39dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void dump_hex( const unsigned char* ptr, size_t len ) 40dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 41dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int nn, len2 = len; 42408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall // Build a string instead of logging each character. 43408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall // MAX chars in 2 digit hex, one space, MAX chars, one '\0'. 44408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall char buffer[MAX_DUMP_HEX_LEN *2 + 1 + MAX_DUMP_HEX_LEN + 1 ], *pb = buffer; 45dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 46408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall if (len2 > MAX_DUMP_HEX_LEN) len2 = MAX_DUMP_HEX_LEN; 47dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 48408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall for (nn = 0; nn < len2; nn++) { 49408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall sprintf(pb, "%02x", ptr[nn]); 50408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall pb += 2; 51408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall } 52408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall sprintf(pb++, " "); 53dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 54dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (nn = 0; nn < len2; nn++) { 55dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int c = ptr[nn]; 56dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (c < 32 || c > 127) 57dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project c = '.'; 58408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall *pb++ = c; 59dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 60408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall *pb++ = '\0'; 61408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall DR("%s\n", buffer); 62dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 63dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 64dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 65dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid 66dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectkick_transport(atransport* t) 67dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 68dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (t && !t->kicked) 69dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project { 70dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int kicked; 71dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 72dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_lock(&transport_lock); 73dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project kicked = t->kicked; 74dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!kicked) 75dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->kicked = 1; 76dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_unlock(&transport_lock); 77dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 78dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!kicked) 79dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->kick(t); 80dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 81dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 82dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 83dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid 84dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectrun_transport_disconnects(atransport* t) 85dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 86dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adisconnect* dis = t->disconnects.next; 87dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 88730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("%s: run_transport_disconnects\n", t->serial); 89dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while (dis != &t->disconnects) { 90dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adisconnect* next = dis->next; 91dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dis->func( dis->opaque, t ); 92dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dis = next; 93dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 94dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 95dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 96730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner#if ADB_TRACE 97730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turnerstatic void 98730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turnerdump_packet(const char* name, const char* func, apacket* p) 99730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner{ 100730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner unsigned command = p->msg.command; 101730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner int len = p->msg.data_length; 102730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner char cmd[9]; 103730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner char arg0[12], arg1[12]; 104730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner int n; 105730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner 106730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner for (n = 0; n < 4; n++) { 107730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner int b = (command >> (n*8)) & 255; 108730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner if (b < 32 || b >= 127) 109730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner break; 110730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner cmd[n] = (char)b; 111730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner } 112730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner if (n == 4) { 113730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner cmd[4] = 0; 114730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner } else { 115730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner /* There is some non-ASCII name in the command, so dump 116730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner * the hexadecimal value instead */ 117730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner snprintf(cmd, sizeof cmd, "%08x", command); 118730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner } 119730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner 120730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner if (p->msg.arg0 < 256U) 121730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner snprintf(arg0, sizeof arg0, "%d", p->msg.arg0); 122730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner else 123730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner snprintf(arg0, sizeof arg0, "0x%x", p->msg.arg0); 124730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner 125730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner if (p->msg.arg1 < 256U) 126730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner snprintf(arg1, sizeof arg1, "%d", p->msg.arg1); 127730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner else 128730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner snprintf(arg1, sizeof arg1, "0x%x", p->msg.arg1); 129730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner 130730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("%s: %s: [%s] arg0=%s arg1=%s (len=%d) ", 131730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner name, func, cmd, arg0, arg1, len); 132730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner dump_hex(p->data, len); 133730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner} 134730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner#endif /* ADB_TRACE */ 135730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner 136dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int 137730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turnerread_packet(int fd, const char* name, apacket** ppacket) 138dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 139dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *p = (char*)ppacket; /* really read a packet address */ 140dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int r; 141dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int len = sizeof(*ppacket); 142730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner char buff[8]; 143730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner if (!name) { 144730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner snprintf(buff, sizeof buff, "fd=%d", fd); 145730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner name = buff; 146730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner } 147dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while(len > 0) { 148dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project r = adb_read(fd, p, len); 149dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(r > 0) { 150dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len -= r; 151dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p += r; 152dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 153730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("%s: read_packet (fd=%d), error ret=%d errno=%d: %s\n", name, fd, r, errno, strerror(errno)); 154dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if((r < 0) && (errno == EINTR)) continue; 155dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 156dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 157dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 158dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 159dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if ADB_TRACE 160730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner if (ADB_TRACING) { 161730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner dump_packet(name, "from remote", *ppacket); 162dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 163dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 164dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 165dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 166dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 167dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int 168730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turnerwrite_packet(int fd, const char* name, apacket** ppacket) 169dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 170dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *p = (char*) ppacket; /* we really write the packet address */ 171dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int r, len = sizeof(ppacket); 172730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner char buff[8]; 173730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner if (!name) { 174730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner snprintf(buff, sizeof buff, "fd=%d", fd); 175730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner name = buff; 176730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner } 177dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 178dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if ADB_TRACE 179730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner if (ADB_TRACING) { 180730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner dump_packet(name, "to remote", *ppacket); 181dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 182dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 183dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len = sizeof(ppacket); 184dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while(len > 0) { 185dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project r = adb_write(fd, p, len); 186dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(r > 0) { 187dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len -= r; 188dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p += r; 189dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 190730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("%s: write_packet (fd=%d) error ret=%d errno=%d: %s\n", name, fd, r, errno, strerror(errno)); 191dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if((r < 0) && (errno == EINTR)) continue; 192dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 193dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 194dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 195dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 196dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 197dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 198dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void transport_socket_events(int fd, unsigned events, void *_t) 199dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 200730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner atransport *t = _t; 201408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall D("transport_socket_events(fd=%d, events=%04x,...)\n", fd, events); 202dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(events & FDE_READ){ 203dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project apacket *p = 0; 204730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner if(read_packet(fd, t->serial, &p)){ 205730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("%s: failed to read packet from transport socket on fd %d\n", t->serial, fd); 206dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 207dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project handle_packet(p, (atransport *) _t); 208dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 209dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 210dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 211dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 212dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid send_packet(apacket *p, atransport *t) 213dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 214dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned char *x; 215dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned sum; 216dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned count; 217dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 218dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.magic = p->msg.command ^ 0xffffffff; 219dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 220dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project count = p->msg.data_length; 221dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project x = (unsigned char *) p->data; 222dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sum = 0; 223dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while(count-- > 0){ 224dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sum += *x++; 225dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 226dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.data_check = sum; 227dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 228dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project print_packet("send", p); 229dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 230dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (t == NULL) { 2310e7c4274c687446dbe30a814278d7a6b99da8c4eJP Abgrall D("Transport is null \n"); 232408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall // Zap errno because print_packet() and other stuff have errno effect. 233408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall errno = 0; 234408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall fatal_errno("Transport is null"); 235dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 236dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 237730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner if(write_packet(t->transport_socket, t->serial, &p)){ 238dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fatal_errno("cannot enqueue packet on transport socket"); 239dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 240dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 241dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 242dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* The transport is opened by transport_register_func before 243dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** the input and output threads are started. 244dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** 245dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** The output thread issues a SYNC(1, token) message to let 246dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** the input thread know to start things up. In the event 247dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** of transport IO failure, the output thread will post a 248dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** SYNC(0,0) message to ensure shutdown. 249dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** 250dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** The transport will not actually be closed until both 251dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** threads exit, but the input thread will kick the transport 252dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** on its way out to disconnect the underlying device. 253dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project*/ 254dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 255dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void *output_thread(void *_t) 256dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 257dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project atransport *t = _t; 258dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project apacket *p; 259dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 260730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("%s: starting transport output thread on fd %d, SYNC online (%d)\n", 261730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner t->serial, t->fd, t->sync_token + 1); 262dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p = get_apacket(); 263dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.command = A_SYNC; 264dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.arg0 = 1; 265dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.arg1 = ++(t->sync_token); 266dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.magic = A_SYNC ^ 0xffffffff; 267730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner if(write_packet(t->fd, t->serial, &p)) { 268dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project put_apacket(p); 269730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("%s: failed to write SYNC packet\n", t->serial); 270dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto oops; 271dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 272dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 273730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("%s: data pump started\n", t->serial); 274dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for(;;) { 275dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p = get_apacket(); 276dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 277dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(t->read_from_remote(p, t) == 0){ 278730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("%s: received remote packet, sending to transport\n", 279730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner t->serial); 280730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner if(write_packet(t->fd, t->serial, &p)){ 281dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project put_apacket(p); 282730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("%s: failed to write apacket to transport\n", t->serial); 283dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto oops; 284dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 285dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 286730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("%s: remote read failed for transport\n", t->serial); 287dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project put_apacket(p); 288dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 289dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 290dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 291dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 292730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("%s: SYNC offline for transport\n", t->serial); 293dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p = get_apacket(); 294dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.command = A_SYNC; 295dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.arg0 = 0; 296dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.arg1 = 0; 297dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.magic = A_SYNC ^ 0xffffffff; 298730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner if(write_packet(t->fd, t->serial, &p)) { 299dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project put_apacket(p); 300730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("%s: failed to write SYNC apacket to transport", t->serial); 301dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 302dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 303dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectoops: 304730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("%s: transport output thread is exiting\n", t->serial); 305dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project kick_transport(t); 306dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project transport_unref(t); 307dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 308dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 309dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 310dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void *input_thread(void *_t) 311dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 312dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project atransport *t = _t; 313dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project apacket *p; 314dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int active = 0; 315dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 316730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("%s: starting transport input thread, reading from fd %d\n", 317730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner t->serial, t->fd); 318dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 319dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for(;;){ 320730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner if(read_packet(t->fd, t->serial, &p)) { 321730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("%s: failed to read apacket from transport on fd %d\n", 322730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner t->serial, t->fd ); 323dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 324dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 325dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(p->msg.command == A_SYNC){ 326dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(p->msg.arg0 == 0) { 327730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("%s: transport SYNC offline\n", t->serial); 328dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project put_apacket(p); 329dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 330dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 331dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(p->msg.arg1 == t->sync_token) { 332730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("%s: transport SYNC online\n", t->serial); 333dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project active = 1; 334dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 335730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("%s: transport ignoring SYNC %d != %d\n", 336730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner t->serial, p->msg.arg1, t->sync_token); 337dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 338dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 339dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 340dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(active) { 341730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("%s: transport got packet, sending to remote\n", t->serial); 342dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->write_to_remote(p, t); 343dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 344730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("%s: transport ignoring packet while offline\n", t->serial); 345dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 346dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 347dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 348dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project put_apacket(p); 349dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 350dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 351dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // this is necessary to avoid a race condition that occured when a transport closes 352dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // while a client socket is still active. 353dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project close_all_sockets(t); 354dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 355730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("%s: transport input thread is exiting, fd %d\n", t->serial, t->fd); 356dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project kick_transport(t); 357dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project transport_unref(t); 358dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 359dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 360dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 361dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 362dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int transport_registration_send = -1; 363dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int transport_registration_recv = -1; 364dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic fdevent transport_registration_fde; 365dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 366dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 367dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if ADB_HOST 368dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int list_transports_msg(char* buffer, size_t bufferlen) 369dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 370dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char head[5]; 371dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int len; 372dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 373e109d266c12c5f537d429ca4b892f2719e02c2daScott Anderson len = list_transports(buffer+4, bufferlen-4, 0); 374dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project snprintf(head, sizeof(head), "%04x", len); 375dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project memcpy(buffer, head, 4); 376dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len += 4; 377dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return len; 378dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 379dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 380dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* this adds support required by the 'track-devices' service. 381dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * this is used to send the content of "list_transport" to any 382dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * number of client connections that want it through a single 383dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * live TCP connection 384dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 385dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecttypedef struct device_tracker device_tracker; 386dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstruct device_tracker { 387dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project asocket socket; 388dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int update_needed; 389dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project device_tracker* next; 390dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}; 391dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 392dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* linked list of all device trackers */ 393dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic device_tracker* device_tracker_list; 394dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 395dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void 396dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectdevice_tracker_remove( device_tracker* tracker ) 397dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 398dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project device_tracker** pnode = &device_tracker_list; 399dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project device_tracker* node = *pnode; 400dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 401dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_lock( &transport_lock ); 402dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while (node) { 403dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (node == tracker) { 404dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *pnode = node->next; 405dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 406dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 407dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project pnode = &node->next; 408dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project node = *pnode; 409dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 410dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_unlock( &transport_lock ); 411dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 412dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 413dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void 414dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectdevice_tracker_close( asocket* socket ) 415dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 416dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project device_tracker* tracker = (device_tracker*) socket; 417dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project asocket* peer = socket->peer; 418dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 419dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D( "device tracker %p removed\n", tracker); 420dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (peer) { 421dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project peer->peer = NULL; 422dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project peer->close(peer); 423dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 424dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project device_tracker_remove(tracker); 425dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project free(tracker); 426dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 427dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 428dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int 429dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectdevice_tracker_enqueue( asocket* socket, apacket* p ) 430dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 431dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* you can't read from a device tracker, close immediately */ 432dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project put_apacket(p); 433dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project device_tracker_close(socket); 434dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 435dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 436dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 437dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int 438dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectdevice_tracker_send( device_tracker* tracker, 439dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project const char* buffer, 440dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int len ) 441dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 442dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project apacket* p = get_apacket(); 443dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project asocket* peer = tracker->socket.peer; 444dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 445dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project memcpy(p->data, buffer, len); 446dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->len = len; 447dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return peer->enqueue( peer, p ); 448dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 449dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 450dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 451dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void 452dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectdevice_tracker_ready( asocket* socket ) 453dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 454dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project device_tracker* tracker = (device_tracker*) socket; 455dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 456dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* we want to send the device list when the tracker connects 457dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * for the first time, even if no update occured */ 458dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (tracker->update_needed > 0) { 459dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char buffer[1024]; 460dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int len; 461dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 462dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project tracker->update_needed = 0; 463dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 464dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len = list_transports_msg(buffer, sizeof(buffer)); 465dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project device_tracker_send(tracker, buffer, len); 466dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 467dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 468dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 469dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 470dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectasocket* 471dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectcreate_device_tracker(void) 472dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 473dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project device_tracker* tracker = calloc(1,sizeof(*tracker)); 474dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 475dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(tracker == 0) fatal("cannot allocate device tracker"); 476dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 477dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D( "device tracker %p created\n", tracker); 478dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 479dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project tracker->socket.enqueue = device_tracker_enqueue; 480dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project tracker->socket.ready = device_tracker_ready; 481dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project tracker->socket.close = device_tracker_close; 482dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project tracker->update_needed = 1; 483dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 484dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project tracker->next = device_tracker_list; 485dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project device_tracker_list = tracker; 486dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 487dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return &tracker->socket; 488dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 489dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 490dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 491dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* call this function each time the transport list has changed */ 492dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid update_transports(void) 493dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 494dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char buffer[1024]; 495dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int len; 496dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project device_tracker* tracker; 497dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 498dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len = list_transports_msg(buffer, sizeof(buffer)); 499dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 500dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project tracker = device_tracker_list; 501dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while (tracker != NULL) { 502dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project device_tracker* next = tracker->next; 503dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* note: this may destroy the tracker if the connection is closed */ 504dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project device_tracker_send(tracker, buffer, len); 505dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project tracker = next; 506dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 507dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 508dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else 509dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid update_transports(void) 510dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 511dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // nothing to do on the device side 512dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 513dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif // ADB_HOST 514dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 515dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecttypedef struct tmsg tmsg; 516dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstruct tmsg 517dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 518dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project atransport *transport; 519dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int action; 520dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}; 521dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 522dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int 523dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecttransport_read_action(int fd, struct tmsg* m) 524dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 525dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *p = (char*)m; 526dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int len = sizeof(*m); 527dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int r; 528dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 529dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while(len > 0) { 530dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project r = adb_read(fd, p, len); 531dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(r > 0) { 532dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len -= r; 533dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p += r; 534dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 535dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if((r < 0) && (errno == EINTR)) continue; 536730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("transport_read_action: on fd %d, error %d: %s\n", 537dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fd, errno, strerror(errno)); 538dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 539dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 540dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 541dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 542dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 543dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 544dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int 545dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecttransport_write_action(int fd, struct tmsg* m) 546dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 547dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *p = (char*)m; 548dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int len = sizeof(*m); 549dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int r; 550dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 551dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while(len > 0) { 552dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project r = adb_write(fd, p, len); 553dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(r > 0) { 554dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len -= r; 555dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p += r; 556dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 557dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if((r < 0) && (errno == EINTR)) continue; 558730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("transport_write_action: on fd %d, error %d: %s\n", 559dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fd, errno, strerror(errno)); 560dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 561dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 562dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 563dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 564dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 565dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 566dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void transport_registration_func(int _fd, unsigned ev, void *data) 567dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 568dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project tmsg m; 569dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_thread_t output_thread_ptr; 570dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_thread_t input_thread_ptr; 571dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int s[2]; 572dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project atransport *t; 573dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 574dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(!(ev & FDE_READ)) { 575dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 576dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 577dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 578dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(transport_read_action(_fd, &m)) { 579dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fatal_errno("cannot read transport registration socket"); 580dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 581dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 582dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t = m.transport; 583dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 584dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(m.action == 0){ 585730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("transport: %s removing and free'ing %d\n", t->serial, t->transport_socket); 586dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 587dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* IMPORTANT: the remove closes one half of the 588dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ** socket pair. The close closes the other half. 589dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 590dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fdevent_remove(&(t->transport_fde)); 591dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_close(t->fd); 592dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 593dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_lock(&transport_lock); 594dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->next->prev = t->prev; 595dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->prev->next = t->next; 596dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_unlock(&transport_lock); 597dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 598dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project run_transport_disconnects(t); 599dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 600dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (t->product) 601dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project free(t->product); 602dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (t->serial) 603dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project free(t->serial); 604e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson if (t->model) 605e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson free(t->model); 606e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson if (t->device) 607e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson free(t->device); 608e109d266c12c5f537d429ca4b892f2719e02c2daScott Anderson if (t->devpath) 609e109d266c12c5f537d429ca4b892f2719e02c2daScott Anderson free(t->devpath); 610dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 611dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project memset(t,0xee,sizeof(atransport)); 612dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project free(t); 613dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 614dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project update_transports(); 615dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 616dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 617dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 6180927bf9690127bc45cf8837a1467759e9720399aMike Lockwood /* don't create transport threads for inaccessible devices */ 6190927bf9690127bc45cf8837a1467759e9720399aMike Lockwood if (t->connection_state != CS_NOPERM) { 620dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* initial references are the two threads */ 6210927bf9690127bc45cf8837a1467759e9720399aMike Lockwood t->ref_count = 2; 622dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 6230927bf9690127bc45cf8837a1467759e9720399aMike Lockwood if(adb_socketpair(s)) { 6240927bf9690127bc45cf8837a1467759e9720399aMike Lockwood fatal_errno("cannot open transport socketpair"); 6250927bf9690127bc45cf8837a1467759e9720399aMike Lockwood } 6260927bf9690127bc45cf8837a1467759e9720399aMike Lockwood 627730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("transport: %s (%d,%d) starting\n", t->serial, s[0], s[1]); 6280927bf9690127bc45cf8837a1467759e9720399aMike Lockwood 6290927bf9690127bc45cf8837a1467759e9720399aMike Lockwood t->transport_socket = s[0]; 6300927bf9690127bc45cf8837a1467759e9720399aMike Lockwood t->fd = s[1]; 631dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 6320927bf9690127bc45cf8837a1467759e9720399aMike Lockwood fdevent_install(&(t->transport_fde), 6330927bf9690127bc45cf8837a1467759e9720399aMike Lockwood t->transport_socket, 6340927bf9690127bc45cf8837a1467759e9720399aMike Lockwood transport_socket_events, 6350927bf9690127bc45cf8837a1467759e9720399aMike Lockwood t); 6360927bf9690127bc45cf8837a1467759e9720399aMike Lockwood 6370927bf9690127bc45cf8837a1467759e9720399aMike Lockwood fdevent_set(&(t->transport_fde), FDE_READ); 6380927bf9690127bc45cf8837a1467759e9720399aMike Lockwood 6390927bf9690127bc45cf8837a1467759e9720399aMike Lockwood if(adb_thread_create(&input_thread_ptr, input_thread, t)){ 6400927bf9690127bc45cf8837a1467759e9720399aMike Lockwood fatal_errno("cannot create input thread"); 6410927bf9690127bc45cf8837a1467759e9720399aMike Lockwood } 642dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 6430927bf9690127bc45cf8837a1467759e9720399aMike Lockwood if(adb_thread_create(&output_thread_ptr, output_thread, t)){ 6440927bf9690127bc45cf8837a1467759e9720399aMike Lockwood fatal_errno("cannot create output thread"); 6450927bf9690127bc45cf8837a1467759e9720399aMike Lockwood } 6460927bf9690127bc45cf8837a1467759e9720399aMike Lockwood } 647dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 648dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* put us on the master device list */ 649dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_lock(&transport_lock); 650dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->next = &transport_list; 651dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->prev = transport_list.prev; 652dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->next->prev = t; 653dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->prev->next = t; 654dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_unlock(&transport_lock); 655dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 656dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->disconnects.next = t->disconnects.prev = &t->disconnects; 657dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 658dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project update_transports(); 659dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 660dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 661dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid init_transport_registration(void) 662dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 663dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int s[2]; 664dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 665dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(adb_socketpair(s)){ 666dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fatal_errno("cannot open transport registration socketpair"); 667dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 668dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 669dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project transport_registration_send = s[0]; 670dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project transport_registration_recv = s[1]; 671dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 672dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fdevent_install(&transport_registration_fde, 673dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project transport_registration_recv, 674dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project transport_registration_func, 675dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 0); 676dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 677dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fdevent_set(&transport_registration_fde, FDE_READ); 678dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 679dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 680dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* the fdevent select pump is single threaded */ 681dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void register_transport(atransport *transport) 682dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 683dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project tmsg m; 684dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project m.transport = transport; 685dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project m.action = 1; 686730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("transport: %s registered\n", transport->serial); 687dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(transport_write_action(transport_registration_send, &m)) { 688dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fatal_errno("cannot write transport registration socket\n"); 689dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 690dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 691dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 692dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void remove_transport(atransport *transport) 693dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 694dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project tmsg m; 695dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project m.transport = transport; 696dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project m.action = 0; 697730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("transport: %s removed\n", transport->serial); 698dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(transport_write_action(transport_registration_send, &m)) { 699dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fatal_errno("cannot write transport registration socket\n"); 700dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 701dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 702dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 703dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 704cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwoodstatic void transport_unref_locked(atransport *t) 705cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood{ 706cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood t->ref_count--; 707cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood if (t->ref_count == 0) { 708730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("transport: %s unref (kicking and closing)\n", t->serial); 709cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood if (!t->kicked) { 710cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood t->kicked = 1; 711cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood t->kick(t); 712cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood } 713cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood t->close(t); 714cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood remove_transport(t); 715730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner } else { 716730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("transport: %s unref (count=%d)\n", t->serial, t->ref_count); 717cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood } 718cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood} 719cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood 720dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void transport_unref(atransport *t) 721dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 722dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (t) { 723dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_lock(&transport_lock); 724cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood transport_unref_locked(t); 725dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_unlock(&transport_lock); 726dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 727dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 728dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 729dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid add_transport_disconnect(atransport* t, adisconnect* dis) 730dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 731dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_lock(&transport_lock); 732dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dis->next = &t->disconnects; 733dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dis->prev = dis->next->prev; 734dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dis->prev->next = dis; 735dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dis->next->prev = dis; 736dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_unlock(&transport_lock); 737dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 738dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 739dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid remove_transport_disconnect(atransport* t, adisconnect* dis) 740dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 741dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dis->prev->next = dis->next; 742dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dis->next->prev = dis->prev; 743dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dis->next = dis->prev = dis; 744dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 745dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 7462ca3e6b35f79136418ebc32fef57580698dbd045Scott Andersonstatic int qual_char_is_invalid(char ch) 7472ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson{ 7482ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson if ('A' <= ch && ch <= 'Z') 7492ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson return 0; 7502ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson if ('a' <= ch && ch <= 'z') 7512ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson return 0; 7522ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson if ('0' <= ch && ch <= '9') 7532ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson return 0; 7542ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson return 1; 7552ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson} 7562ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson 7572ca3e6b35f79136418ebc32fef57580698dbd045Scott Andersonstatic int qual_match(const char *to_test, 7582ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson const char *prefix, const char *qual, int sanitize_qual) 7592ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson{ 7602ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson if (!to_test || !*to_test) 7612ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson /* Return true if both the qual and to_test are null strings. */ 7622ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson return !qual || !*qual; 7632ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson 7642ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson if (!qual) 7652ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson return 0; 7662ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson 7672ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson if (prefix) { 7682ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson while (*prefix) { 7692ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson if (*prefix++ != *to_test++) 7702ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson return 0; 7712ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson } 7722ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson } 7732ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson 7742ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson while (*qual) { 7752ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson char ch = *qual++; 7762ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson if (sanitize_qual && qual_char_is_invalid(ch)) 7772ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson ch = '_'; 7782ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson if (ch != *to_test++) 7792ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson return 0; 7802ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson } 7812ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson 7822ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson /* Everything matched so far. Return true if *to_test is a NUL. */ 7832ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson return !*to_test; 7842ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson} 785dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 786dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectatransport *acquire_one_transport(int state, transport_type ttype, const char* serial, char** error_out) 787dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 788dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project atransport *t; 789dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project atransport *result = NULL; 790dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int ambiguous = 0; 791dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 792dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectretry: 793dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (error_out) 794dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *error_out = "device not found"; 795dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 796dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_lock(&transport_lock); 797dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (t = transport_list.next; t != &transport_list; t = t->next) { 79837d3111b1c1ce61c3d9b10ed3ccaed9e5fad1e06Mike Lockwood if (t->connection_state == CS_NOPERM) { 79937d3111b1c1ce61c3d9b10ed3ccaed9e5fad1e06Mike Lockwood if (error_out) 80037d3111b1c1ce61c3d9b10ed3ccaed9e5fad1e06Mike Lockwood *error_out = "insufficient permissions for device"; 80137d3111b1c1ce61c3d9b10ed3ccaed9e5fad1e06Mike Lockwood continue; 80237d3111b1c1ce61c3d9b10ed3ccaed9e5fad1e06Mike Lockwood } 8030927bf9690127bc45cf8837a1467759e9720399aMike Lockwood 804dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* check for matching serial number */ 805dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (serial) { 8062ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson if ((t->serial && !strcmp(serial, t->serial)) || 8072ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson (t->devpath && !strcmp(serial, t->devpath)) || 8082ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson qual_match(serial, "product:", t->product, 0) || 8092ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson qual_match(serial, "model:", t->model, 1) || 8102ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson qual_match(serial, "device:", t->device, 0)) { 8112ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson if (result) { 8122ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson if (error_out) 8132ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson *error_out = "more than one device"; 8142ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson ambiguous = 1; 8152ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson result = NULL; 8162ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson break; 8172ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson } 818e109d266c12c5f537d429ca4b892f2719e02c2daScott Anderson result = t; 819e109d266c12c5f537d429ca4b892f2719e02c2daScott Anderson } 820dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 821dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (ttype == kTransportUsb && t->type == kTransportUsb) { 822dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (result) { 823dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (error_out) 824dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *error_out = "more than one device"; 825dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ambiguous = 1; 826dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project result = NULL; 827dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 828dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 829dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project result = t; 830dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (ttype == kTransportLocal && t->type == kTransportLocal) { 831dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (result) { 832dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (error_out) 833dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *error_out = "more than one emulator"; 834dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ambiguous = 1; 835dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project result = NULL; 836dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 837dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 838dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project result = t; 839dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (ttype == kTransportAny) { 840dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (result) { 841dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (error_out) 842dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *error_out = "more than one device and emulator"; 843dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ambiguous = 1; 844dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project result = NULL; 845dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 846dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 847dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project result = t; 848dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 849dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 850dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 851dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_unlock(&transport_lock); 852dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 853dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (result) { 854dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* offline devices are ignored -- they are either being born or dying */ 855dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (result && result->connection_state == CS_OFFLINE) { 856dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (error_out) 857dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *error_out = "device offline"; 858dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project result = NULL; 859dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 860dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* check for required connection state */ 861dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (result && state != CS_ANY && result->connection_state != state) { 862dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (error_out) 863dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *error_out = "invalid device state"; 864dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project result = NULL; 865dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 866dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 867dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 868dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (result) { 869dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* found one that we can take */ 870dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (error_out) 871dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *error_out = NULL; 872dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (state != CS_ANY && (serial || !ambiguous)) { 873dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_sleep_ms(1000); 874dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto retry; 875dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 876dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 877dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return result; 878dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 879dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 880dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if ADB_HOST 881dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic const char *statename(atransport *t) 882dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 883dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project switch(t->connection_state){ 884dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case CS_OFFLINE: return "offline"; 885dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case CS_BOOTLOADER: return "bootloader"; 886dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case CS_DEVICE: return "device"; 887dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case CS_HOST: return "host"; 888dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case CS_RECOVERY: return "recovery"; 8890927bf9690127bc45cf8837a1467759e9720399aMike Lockwood case CS_NOPERM: return "no permissions"; 890dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project default: return "unknown"; 891dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 892dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 893dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 8942ca3e6b35f79136418ebc32fef57580698dbd045Scott Andersonstatic void add_qual(char **buf, size_t *buf_size, 8952ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson const char *prefix, const char *qual, int sanitize_qual) 8962ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson{ 8972ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson size_t len; 8982ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson int prefix_len; 8992ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson 9002ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson if (!buf || !*buf || !buf_size || !*buf_size || !qual || !*qual) 9012ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson return; 9022ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson 9032ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson len = snprintf(*buf, *buf_size, "%s%n%s", prefix, &prefix_len, qual); 9042ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson 9052ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson if (sanitize_qual) { 9062ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson char *cp; 9072ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson for (cp = *buf + prefix_len; cp < *buf + len; cp++) { 9082ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson if (qual_char_is_invalid(*cp)) 9092ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson *cp = '_'; 9102ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson } 9112ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson } 9122ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson 9132ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson *buf_size -= len; 9142ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson *buf += len; 9152ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson} 9162ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson 9172ca3e6b35f79136418ebc32fef57580698dbd045Scott Andersonstatic size_t format_transport(atransport *t, char *buf, size_t bufsize, 9182ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson int long_listing) 9192ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson{ 9202ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson const char* serial = t->serial; 9212ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson if (!serial || !serial[0]) 9222ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson serial = "????????????"; 9232ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson 9242ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson if (!long_listing) { 9252ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson return snprintf(buf, bufsize, "%s\t%s\n", serial, statename(t)); 9262ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson } else { 9272ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson size_t len, remaining = bufsize; 9282ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson 9292ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson len = snprintf(buf, remaining, "%-22s %s", serial, statename(t)); 9302ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson remaining -= len; 9312ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson buf += len; 9322ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson 9332ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson add_qual(&buf, &remaining, " ", t->devpath, 0); 9342ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson add_qual(&buf, &remaining, " product:", t->product, 0); 9352ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson add_qual(&buf, &remaining, " model:", t->model, 1); 9362ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson add_qual(&buf, &remaining, " device:", t->device, 0); 9372ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson 9382ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson len = snprintf(buf, remaining, "\n"); 9392ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson remaining -= len; 9402ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson 9412ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson return bufsize - remaining; 9422ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson } 9432ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson} 9442ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson 9452ca3e6b35f79136418ebc32fef57580698dbd045Scott Andersonint list_transports(char *buf, size_t bufsize, int long_listing) 946dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 947dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char* p = buf; 948dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char* end = buf + bufsize; 949dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int len; 950dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project atransport *t; 951dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 952dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* XXX OVERRUN PROBLEMS XXX */ 953dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_lock(&transport_lock); 954dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for(t = transport_list.next; t != &transport_list; t = t->next) { 9552ca3e6b35f79136418ebc32fef57580698dbd045Scott Anderson len = format_transport(t, p, end - p, long_listing); 956dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (p + len >= end) { 957dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* discard last line if buffer is too short */ 958dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 959dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 960dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p += len; 961dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 962dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p[0] = 0; 963dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_unlock(&transport_lock); 964dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return p - buf; 965dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 966dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 967dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 968dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* hack for osx */ 969dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid close_usb_devices() 970dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 971dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project atransport *t; 972dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 973dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_lock(&transport_lock); 974dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for(t = transport_list.next; t != &transport_list; t = t->next) { 975dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if ( !t->kicked ) { 976dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->kicked = 1; 977dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->kick(t); 978dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 979dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 980dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_unlock(&transport_lock); 981dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 982dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif // ADB_HOST 983dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 984ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwoodvoid register_socket_transport(int s, const char *serial, int port, int local) 985dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 986dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project atransport *t = calloc(1, sizeof(atransport)); 987730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner char buff[32]; 988730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner 989730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner if (!serial) { 990730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner snprintf(buff, sizeof buff, "T-%p", t); 991730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner serial = buff; 992730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner } 993730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("transport: %s init'ing for socket %d, on port %d\n", serial, s, port); 994ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood if ( init_socket_transport(t, s, port, local) < 0 ) { 995dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_close(s); 996dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project free(t); 997dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 998dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 999dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(serial) { 1000dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->serial = strdup(serial); 1001dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1002dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project register_transport(t); 1003dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 1004dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 10058cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood#if ADB_HOST 10068cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwoodatransport *find_transport(const char *serial) 10078cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood{ 10088cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood atransport *t; 10098cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood 10108cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood adb_mutex_lock(&transport_lock); 10118cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood for(t = transport_list.next; t != &transport_list; t = t->next) { 10128cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood if (t->serial && !strcmp(serial, t->serial)) { 10138cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood break; 10148cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood } 10158cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood } 10168cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood adb_mutex_unlock(&transport_lock); 10178cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood 10188cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood if (t != &transport_list) 10198cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood return t; 10208cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood else 10218cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood return 0; 10228cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood} 10238cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood 10248cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwoodvoid unregister_transport(atransport *t) 10258cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood{ 10268cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood adb_mutex_lock(&transport_lock); 10278cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood t->next->prev = t->prev; 10288cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood t->prev->next = t->next; 10298cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood adb_mutex_unlock(&transport_lock); 10308cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood 10318cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood kick_transport(t); 10328cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood transport_unref(t); 10338cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood} 10348cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood 1035cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood// unregisters all non-emulator TCP transports 1036cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwoodvoid unregister_all_tcp_transports() 1037cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood{ 1038cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood atransport *t, *next; 1039cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood adb_mutex_lock(&transport_lock); 1040cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood for (t = transport_list.next; t != &transport_list; t = next) { 1041cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood next = t->next; 1042cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood if (t->type == kTransportLocal && t->adb_port == 0) { 1043cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood t->next->prev = t->prev; 1044cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood t->prev->next = next; 1045cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood // we cannot call kick_transport when holding transport_lock 1046cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood if (!t->kicked) 1047cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood { 1048cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood t->kicked = 1; 1049cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood t->kick(t); 1050cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood } 1051cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood transport_unref_locked(t); 1052cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood } 1053cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood } 1054cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood 1055cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood adb_mutex_unlock(&transport_lock); 1056cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood} 1057cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood 10588cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood#endif 10598cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood 1060e109d266c12c5f537d429ca4b892f2719e02c2daScott Andersonvoid register_usb_transport(usb_handle *usb, const char *serial, const char *devpath, unsigned writeable) 1061dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 1062dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project atransport *t = calloc(1, sizeof(atransport)); 1063dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("transport: %p init'ing for usb_handle %p (sn='%s')\n", t, usb, 1064dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project serial ? serial : ""); 10650927bf9690127bc45cf8837a1467759e9720399aMike Lockwood init_usb_transport(t, usb, (writeable ? CS_OFFLINE : CS_NOPERM)); 1066dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(serial) { 1067dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->serial = strdup(serial); 1068dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1069e109d266c12c5f537d429ca4b892f2719e02c2daScott Anderson if(devpath) { 1070e109d266c12c5f537d429ca4b892f2719e02c2daScott Anderson t->devpath = strdup(devpath); 1071e109d266c12c5f537d429ca4b892f2719e02c2daScott Anderson } 1072dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project register_transport(t); 1073dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 1074dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 10750927bf9690127bc45cf8837a1467759e9720399aMike Lockwood/* this should only be used for transports with connection_state == CS_NOPERM */ 10760927bf9690127bc45cf8837a1467759e9720399aMike Lockwoodvoid unregister_usb_transport(usb_handle *usb) 10770927bf9690127bc45cf8837a1467759e9720399aMike Lockwood{ 10780927bf9690127bc45cf8837a1467759e9720399aMike Lockwood atransport *t; 10790927bf9690127bc45cf8837a1467759e9720399aMike Lockwood adb_mutex_lock(&transport_lock); 10800927bf9690127bc45cf8837a1467759e9720399aMike Lockwood for(t = transport_list.next; t != &transport_list; t = t->next) { 10810927bf9690127bc45cf8837a1467759e9720399aMike Lockwood if (t->usb == usb && t->connection_state == CS_NOPERM) { 10820927bf9690127bc45cf8837a1467759e9720399aMike Lockwood t->next->prev = t->prev; 10830927bf9690127bc45cf8837a1467759e9720399aMike Lockwood t->prev->next = t->next; 10840927bf9690127bc45cf8837a1467759e9720399aMike Lockwood break; 10850927bf9690127bc45cf8837a1467759e9720399aMike Lockwood } 10860927bf9690127bc45cf8837a1467759e9720399aMike Lockwood } 10870927bf9690127bc45cf8837a1467759e9720399aMike Lockwood adb_mutex_unlock(&transport_lock); 10880927bf9690127bc45cf8837a1467759e9720399aMike Lockwood} 1089dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1090dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#undef TRACE_TAG 1091dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define TRACE_TAG TRACE_RWX 1092dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1093dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint readx(int fd, void *ptr, size_t len) 1094dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 1095dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *p = ptr; 1096dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int r; 1097dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if ADB_TRACE 1098dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int len0 = len; 1099dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 1100730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("readx: fd=%d wanted=%d\n", fd, (int)len); 1101dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while(len > 0) { 1102dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project r = adb_read(fd, p, len); 1103dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(r > 0) { 1104dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len -= r; 1105dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p += r; 1106dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 1107730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner if (r < 0) { 1108730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("readx: fd=%d error %d: %s\n", fd, errno, strerror(errno)); 1109730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner if (errno == EINTR) 1110730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner continue; 1111730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner } else { 1112730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("readx: fd=%d disconnected\n", fd); 1113730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner } 1114dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 1115dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1116dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1117dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1118dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if ADB_TRACE 1119730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("readx: fd=%d wanted=%d got=%d\n", fd, len0, len0 - len); 1120dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dump_hex( ptr, len0 ); 1121dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 1122dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 1123dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 1124dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1125dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint writex(int fd, const void *ptr, size_t len) 1126dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 1127dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *p = (char*) ptr; 1128dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int r; 1129dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1130dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if ADB_TRACE 1131730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("writex: fd=%d len=%d: ", fd, (int)len); 1132dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dump_hex( ptr, len ); 1133dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 1134dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while(len > 0) { 1135dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project r = adb_write(fd, p, len); 1136dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(r > 0) { 1137dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len -= r; 1138dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p += r; 1139dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 1140730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner if (r < 0) { 1141730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("writex: fd=%d error %d: %s\n", fd, errno, strerror(errno)); 1142730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner if (errno == EINTR) 1143730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner continue; 1144730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner } else { 1145730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("writex: fd=%d disconnected\n", fd); 1146730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner } 1147dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 1148dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1149dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1150dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 1151dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 1152dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1153dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint check_header(apacket *p) 1154dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 1155dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(p->msg.magic != (p->msg.command ^ 0xffffffff)) { 1156dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("check_header(): invalid magic\n"); 1157dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 1158dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1159dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1160dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(p->msg.data_length > MAX_PAYLOAD) { 1161dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("check_header(): %d > MAX_PAYLOAD\n", p->msg.data_length); 1162dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 1163dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1164dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1165dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 1166dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 1167dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1168dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint check_data(apacket *p) 1169dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 1170dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned count, sum; 1171dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned char *x; 1172dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1173dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project count = p->msg.data_length; 1174dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project x = p->data; 1175dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sum = 0; 1176dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while(count-- > 0) { 1177dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sum += *x++; 1178dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1179dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1180dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(sum != p->msg.data_check) { 1181dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 1182dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 1183dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 1184dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1185dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 1186