transport.c revision e109d266c12c5f537d429ca4b892f2719e02c2da
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); 604e109d266c12c5f537d429ca4b892f2719e02c2daScott Anderson if (t->devpath) 605e109d266c12c5f537d429ca4b892f2719e02c2daScott Anderson free(t->devpath); 606dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 607dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project memset(t,0xee,sizeof(atransport)); 608dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project free(t); 609dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 610dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project update_transports(); 611dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 612dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 613dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 6140927bf9690127bc45cf8837a1467759e9720399aMike Lockwood /* don't create transport threads for inaccessible devices */ 6150927bf9690127bc45cf8837a1467759e9720399aMike Lockwood if (t->connection_state != CS_NOPERM) { 616dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* initial references are the two threads */ 6170927bf9690127bc45cf8837a1467759e9720399aMike Lockwood t->ref_count = 2; 618dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 6190927bf9690127bc45cf8837a1467759e9720399aMike Lockwood if(adb_socketpair(s)) { 6200927bf9690127bc45cf8837a1467759e9720399aMike Lockwood fatal_errno("cannot open transport socketpair"); 6210927bf9690127bc45cf8837a1467759e9720399aMike Lockwood } 6220927bf9690127bc45cf8837a1467759e9720399aMike Lockwood 623730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("transport: %s (%d,%d) starting\n", t->serial, s[0], s[1]); 6240927bf9690127bc45cf8837a1467759e9720399aMike Lockwood 6250927bf9690127bc45cf8837a1467759e9720399aMike Lockwood t->transport_socket = s[0]; 6260927bf9690127bc45cf8837a1467759e9720399aMike Lockwood t->fd = s[1]; 627dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 6280927bf9690127bc45cf8837a1467759e9720399aMike Lockwood fdevent_install(&(t->transport_fde), 6290927bf9690127bc45cf8837a1467759e9720399aMike Lockwood t->transport_socket, 6300927bf9690127bc45cf8837a1467759e9720399aMike Lockwood transport_socket_events, 6310927bf9690127bc45cf8837a1467759e9720399aMike Lockwood t); 6320927bf9690127bc45cf8837a1467759e9720399aMike Lockwood 6330927bf9690127bc45cf8837a1467759e9720399aMike Lockwood fdevent_set(&(t->transport_fde), FDE_READ); 6340927bf9690127bc45cf8837a1467759e9720399aMike Lockwood 6350927bf9690127bc45cf8837a1467759e9720399aMike Lockwood if(adb_thread_create(&input_thread_ptr, input_thread, t)){ 6360927bf9690127bc45cf8837a1467759e9720399aMike Lockwood fatal_errno("cannot create input thread"); 6370927bf9690127bc45cf8837a1467759e9720399aMike Lockwood } 638dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 6390927bf9690127bc45cf8837a1467759e9720399aMike Lockwood if(adb_thread_create(&output_thread_ptr, output_thread, t)){ 6400927bf9690127bc45cf8837a1467759e9720399aMike Lockwood fatal_errno("cannot create output thread"); 6410927bf9690127bc45cf8837a1467759e9720399aMike Lockwood } 6420927bf9690127bc45cf8837a1467759e9720399aMike Lockwood } 643dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 644dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* put us on the master device list */ 645dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_lock(&transport_lock); 646dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->next = &transport_list; 647dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->prev = transport_list.prev; 648dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->next->prev = t; 649dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->prev->next = t; 650dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_unlock(&transport_lock); 651dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 652dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->disconnects.next = t->disconnects.prev = &t->disconnects; 653dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 654dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project update_transports(); 655dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 656dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 657dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid init_transport_registration(void) 658dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 659dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int s[2]; 660dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 661dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(adb_socketpair(s)){ 662dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fatal_errno("cannot open transport registration socketpair"); 663dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 664dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 665dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project transport_registration_send = s[0]; 666dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project transport_registration_recv = s[1]; 667dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 668dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fdevent_install(&transport_registration_fde, 669dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project transport_registration_recv, 670dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project transport_registration_func, 671dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 0); 672dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 673dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fdevent_set(&transport_registration_fde, FDE_READ); 674dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 675dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 676dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* the fdevent select pump is single threaded */ 677dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void register_transport(atransport *transport) 678dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 679dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project tmsg m; 680dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project m.transport = transport; 681dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project m.action = 1; 682730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("transport: %s registered\n", transport->serial); 683dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(transport_write_action(transport_registration_send, &m)) { 684dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fatal_errno("cannot write transport registration socket\n"); 685dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 686dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 687dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 688dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void remove_transport(atransport *transport) 689dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 690dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project tmsg m; 691dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project m.transport = transport; 692dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project m.action = 0; 693730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("transport: %s removed\n", transport->serial); 694dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(transport_write_action(transport_registration_send, &m)) { 695dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fatal_errno("cannot write transport registration socket\n"); 696dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 697dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 698dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 699dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 700cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwoodstatic void transport_unref_locked(atransport *t) 701cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood{ 702cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood t->ref_count--; 703cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood if (t->ref_count == 0) { 704730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("transport: %s unref (kicking and closing)\n", t->serial); 705cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood if (!t->kicked) { 706cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood t->kicked = 1; 707cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood t->kick(t); 708cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood } 709cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood t->close(t); 710cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood remove_transport(t); 711730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner } else { 712730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("transport: %s unref (count=%d)\n", t->serial, t->ref_count); 713cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood } 714cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood} 715cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood 716dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void transport_unref(atransport *t) 717dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 718dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (t) { 719dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_lock(&transport_lock); 720cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood transport_unref_locked(t); 721dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_unlock(&transport_lock); 722dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 723dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 724dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 725dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid add_transport_disconnect(atransport* t, adisconnect* dis) 726dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 727dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_lock(&transport_lock); 728dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dis->next = &t->disconnects; 729dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dis->prev = dis->next->prev; 730dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dis->prev->next = dis; 731dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dis->next->prev = dis; 732dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_unlock(&transport_lock); 733dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 734dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 735dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid remove_transport_disconnect(atransport* t, adisconnect* dis) 736dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 737dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dis->prev->next = dis->next; 738dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dis->next->prev = dis->prev; 739dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dis->next = dis->prev = dis; 740dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 741dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 742dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 743dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectatransport *acquire_one_transport(int state, transport_type ttype, const char* serial, char** error_out) 744dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 745dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project atransport *t; 746dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project atransport *result = NULL; 747dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int ambiguous = 0; 748dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 749dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectretry: 750dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (error_out) 751dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *error_out = "device not found"; 752dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 753dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_lock(&transport_lock); 754dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (t = transport_list.next; t != &transport_list; t = t->next) { 75537d3111b1c1ce61c3d9b10ed3ccaed9e5fad1e06Mike Lockwood if (t->connection_state == CS_NOPERM) { 75637d3111b1c1ce61c3d9b10ed3ccaed9e5fad1e06Mike Lockwood if (error_out) 75737d3111b1c1ce61c3d9b10ed3ccaed9e5fad1e06Mike Lockwood *error_out = "insufficient permissions for device"; 75837d3111b1c1ce61c3d9b10ed3ccaed9e5fad1e06Mike Lockwood continue; 75937d3111b1c1ce61c3d9b10ed3ccaed9e5fad1e06Mike Lockwood } 7600927bf9690127bc45cf8837a1467759e9720399aMike Lockwood 761dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* check for matching serial number */ 762dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (serial) { 763dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (t->serial && !strcmp(serial, t->serial)) { 764dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project result = t; 765dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 766dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 767e109d266c12c5f537d429ca4b892f2719e02c2daScott Anderson if (t->devpath && !strcmp(serial, t->devpath)) { 768e109d266c12c5f537d429ca4b892f2719e02c2daScott Anderson result = t; 769e109d266c12c5f537d429ca4b892f2719e02c2daScott Anderson break; 770e109d266c12c5f537d429ca4b892f2719e02c2daScott Anderson } 771dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 772dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (ttype == kTransportUsb && t->type == kTransportUsb) { 773dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (result) { 774dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (error_out) 775dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *error_out = "more than one device"; 776dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ambiguous = 1; 777dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project result = NULL; 778dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 779dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 780dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project result = t; 781dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (ttype == kTransportLocal && t->type == kTransportLocal) { 782dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (result) { 783dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (error_out) 784dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *error_out = "more than one emulator"; 785dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ambiguous = 1; 786dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project result = NULL; 787dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 788dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 789dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project result = t; 790dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (ttype == kTransportAny) { 791dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (result) { 792dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (error_out) 793dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *error_out = "more than one device and emulator"; 794dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ambiguous = 1; 795dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project result = NULL; 796dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 797dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 798dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project result = t; 799dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 800dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 801dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 802dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_unlock(&transport_lock); 803dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 804dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (result) { 805dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* offline devices are ignored -- they are either being born or dying */ 806dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (result && result->connection_state == CS_OFFLINE) { 807dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (error_out) 808dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *error_out = "device offline"; 809dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project result = NULL; 810dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 811dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* check for required connection state */ 812dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (result && state != CS_ANY && result->connection_state != state) { 813dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (error_out) 814dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *error_out = "invalid device state"; 815dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project result = NULL; 816dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 817dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 818dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 819dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (result) { 820dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* found one that we can take */ 821dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (error_out) 822dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *error_out = NULL; 823dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (state != CS_ANY && (serial || !ambiguous)) { 824dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_sleep_ms(1000); 825dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto retry; 826dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 827dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 828dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return result; 829dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 830dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 831dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if ADB_HOST 832dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic const char *statename(atransport *t) 833dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 834dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project switch(t->connection_state){ 835dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case CS_OFFLINE: return "offline"; 836dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case CS_BOOTLOADER: return "bootloader"; 837dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case CS_DEVICE: return "device"; 838dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case CS_HOST: return "host"; 839dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case CS_RECOVERY: return "recovery"; 8400927bf9690127bc45cf8837a1467759e9720399aMike Lockwood case CS_NOPERM: return "no permissions"; 841dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project default: return "unknown"; 842dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 843dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 844dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 845e109d266c12c5f537d429ca4b892f2719e02c2daScott Andersonint list_transports(char *buf, size_t bufsize, int show_devpath) 846dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 847dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char* p = buf; 848dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char* end = buf + bufsize; 849dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int len; 850dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project atransport *t; 851dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 852dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* XXX OVERRUN PROBLEMS XXX */ 853dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_lock(&transport_lock); 854dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for(t = transport_list.next; t != &transport_list; t = t->next) { 8550927bf9690127bc45cf8837a1467759e9720399aMike Lockwood const char* serial = t->serial; 8560927bf9690127bc45cf8837a1467759e9720399aMike Lockwood if (!serial || !serial[0]) 8570927bf9690127bc45cf8837a1467759e9720399aMike Lockwood serial = "????????????"; 858e109d266c12c5f537d429ca4b892f2719e02c2daScott Anderson if (show_devpath) { 859e109d266c12c5f537d429ca4b892f2719e02c2daScott Anderson const char* devpath = t->devpath; 860e109d266c12c5f537d429ca4b892f2719e02c2daScott Anderson if (!devpath || !devpath[0]) 861e109d266c12c5f537d429ca4b892f2719e02c2daScott Anderson devpath = "????????????"; 862e109d266c12c5f537d429ca4b892f2719e02c2daScott Anderson len = snprintf(p, end - p, "%s\t%s\t%s\n", serial, devpath, statename(t)); 863e109d266c12c5f537d429ca4b892f2719e02c2daScott Anderson } else 864e109d266c12c5f537d429ca4b892f2719e02c2daScott Anderson len = snprintf(p, end - p, "%s\t%s\n", serial, statename(t)); 865dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 866dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (p + len >= end) { 867dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* discard last line if buffer is too short */ 868dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 869dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 870dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p += len; 871dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 872dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p[0] = 0; 873dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_unlock(&transport_lock); 874dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return p - buf; 875dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 876dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 877dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 878dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* hack for osx */ 879dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid close_usb_devices() 880dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 881dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project atransport *t; 882dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 883dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_lock(&transport_lock); 884dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for(t = transport_list.next; t != &transport_list; t = t->next) { 885dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if ( !t->kicked ) { 886dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->kicked = 1; 887dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->kick(t); 888dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 889dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 890dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_unlock(&transport_lock); 891dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 892dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif // ADB_HOST 893dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 894ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwoodvoid register_socket_transport(int s, const char *serial, int port, int local) 895dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 896dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project atransport *t = calloc(1, sizeof(atransport)); 897730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner char buff[32]; 898730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner 899730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner if (!serial) { 900730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner snprintf(buff, sizeof buff, "T-%p", t); 901730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner serial = buff; 902730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner } 903730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("transport: %s init'ing for socket %d, on port %d\n", serial, s, port); 904ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood if ( init_socket_transport(t, s, port, local) < 0 ) { 905dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_close(s); 906dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project free(t); 907dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 908dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 909dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(serial) { 910dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->serial = strdup(serial); 911dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 912dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project register_transport(t); 913dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 914dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 9158cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood#if ADB_HOST 9168cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwoodatransport *find_transport(const char *serial) 9178cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood{ 9188cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood atransport *t; 9198cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood 9208cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood adb_mutex_lock(&transport_lock); 9218cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood for(t = transport_list.next; t != &transport_list; t = t->next) { 9228cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood if (t->serial && !strcmp(serial, t->serial)) { 9238cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood break; 9248cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood } 925e109d266c12c5f537d429ca4b892f2719e02c2daScott Anderson if (t->devpath && !strcmp(serial, t->devpath)) { 926e109d266c12c5f537d429ca4b892f2719e02c2daScott Anderson break; 927e109d266c12c5f537d429ca4b892f2719e02c2daScott Anderson } 9288cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood } 9298cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood adb_mutex_unlock(&transport_lock); 9308cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood 9318cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood if (t != &transport_list) 9328cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood return t; 9338cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood else 9348cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood return 0; 9358cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood} 9368cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood 9378cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwoodvoid unregister_transport(atransport *t) 9388cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood{ 9398cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood adb_mutex_lock(&transport_lock); 9408cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood t->next->prev = t->prev; 9418cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood t->prev->next = t->next; 9428cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood adb_mutex_unlock(&transport_lock); 9438cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood 9448cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood kick_transport(t); 9458cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood transport_unref(t); 9468cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood} 9478cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood 948cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood// unregisters all non-emulator TCP transports 949cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwoodvoid unregister_all_tcp_transports() 950cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood{ 951cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood atransport *t, *next; 952cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood adb_mutex_lock(&transport_lock); 953cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood for (t = transport_list.next; t != &transport_list; t = next) { 954cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood next = t->next; 955cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood if (t->type == kTransportLocal && t->adb_port == 0) { 956cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood t->next->prev = t->prev; 957cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood t->prev->next = next; 958cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood // we cannot call kick_transport when holding transport_lock 959cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood if (!t->kicked) 960cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood { 961cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood t->kicked = 1; 962cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood t->kick(t); 963cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood } 964cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood transport_unref_locked(t); 965cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood } 966cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood } 967cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood 968cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood adb_mutex_unlock(&transport_lock); 969cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood} 970cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood 9718cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood#endif 9728cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood 973e109d266c12c5f537d429ca4b892f2719e02c2daScott Andersonvoid register_usb_transport(usb_handle *usb, const char *serial, const char *devpath, unsigned writeable) 974dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 975dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project atransport *t = calloc(1, sizeof(atransport)); 976dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("transport: %p init'ing for usb_handle %p (sn='%s')\n", t, usb, 977dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project serial ? serial : ""); 9780927bf9690127bc45cf8837a1467759e9720399aMike Lockwood init_usb_transport(t, usb, (writeable ? CS_OFFLINE : CS_NOPERM)); 979dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(serial) { 980dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->serial = strdup(serial); 981dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 982e109d266c12c5f537d429ca4b892f2719e02c2daScott Anderson if(devpath) { 983e109d266c12c5f537d429ca4b892f2719e02c2daScott Anderson t->devpath = strdup(devpath); 984e109d266c12c5f537d429ca4b892f2719e02c2daScott Anderson } 985dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project register_transport(t); 986dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 987dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 9880927bf9690127bc45cf8837a1467759e9720399aMike Lockwood/* this should only be used for transports with connection_state == CS_NOPERM */ 9890927bf9690127bc45cf8837a1467759e9720399aMike Lockwoodvoid unregister_usb_transport(usb_handle *usb) 9900927bf9690127bc45cf8837a1467759e9720399aMike Lockwood{ 9910927bf9690127bc45cf8837a1467759e9720399aMike Lockwood atransport *t; 9920927bf9690127bc45cf8837a1467759e9720399aMike Lockwood adb_mutex_lock(&transport_lock); 9930927bf9690127bc45cf8837a1467759e9720399aMike Lockwood for(t = transport_list.next; t != &transport_list; t = t->next) { 9940927bf9690127bc45cf8837a1467759e9720399aMike Lockwood if (t->usb == usb && t->connection_state == CS_NOPERM) { 9950927bf9690127bc45cf8837a1467759e9720399aMike Lockwood t->next->prev = t->prev; 9960927bf9690127bc45cf8837a1467759e9720399aMike Lockwood t->prev->next = t->next; 9970927bf9690127bc45cf8837a1467759e9720399aMike Lockwood break; 9980927bf9690127bc45cf8837a1467759e9720399aMike Lockwood } 9990927bf9690127bc45cf8837a1467759e9720399aMike Lockwood } 10000927bf9690127bc45cf8837a1467759e9720399aMike Lockwood adb_mutex_unlock(&transport_lock); 10010927bf9690127bc45cf8837a1467759e9720399aMike Lockwood} 1002dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1003dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#undef TRACE_TAG 1004dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define TRACE_TAG TRACE_RWX 1005dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1006dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint readx(int fd, void *ptr, size_t len) 1007dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 1008dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *p = ptr; 1009dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int r; 1010dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if ADB_TRACE 1011dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int len0 = len; 1012dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 1013730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("readx: fd=%d wanted=%d\n", fd, (int)len); 1014dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while(len > 0) { 1015dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project r = adb_read(fd, p, len); 1016dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(r > 0) { 1017dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len -= r; 1018dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p += r; 1019dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 1020730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner if (r < 0) { 1021730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("readx: fd=%d error %d: %s\n", fd, errno, strerror(errno)); 1022730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner if (errno == EINTR) 1023730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner continue; 1024730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner } else { 1025730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("readx: fd=%d disconnected\n", fd); 1026730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner } 1027dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 1028dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1029dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1030dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1031dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if ADB_TRACE 1032730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("readx: fd=%d wanted=%d got=%d\n", fd, len0, len0 - len); 1033dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dump_hex( ptr, len0 ); 1034dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 1035dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 1036dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 1037dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1038dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint writex(int fd, const void *ptr, size_t len) 1039dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 1040dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *p = (char*) ptr; 1041dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int r; 1042dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1043dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if ADB_TRACE 1044730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("writex: fd=%d len=%d: ", fd, (int)len); 1045dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dump_hex( ptr, len ); 1046dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 1047dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while(len > 0) { 1048dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project r = adb_write(fd, p, len); 1049dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(r > 0) { 1050dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len -= r; 1051dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p += r; 1052dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 1053730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner if (r < 0) { 1054730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("writex: fd=%d error %d: %s\n", fd, errno, strerror(errno)); 1055730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner if (errno == EINTR) 1056730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner continue; 1057730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner } else { 1058730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("writex: fd=%d disconnected\n", fd); 1059730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner } 1060dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 1061dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1062dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1063dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 1064dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 1065dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1066dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint check_header(apacket *p) 1067dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 1068dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(p->msg.magic != (p->msg.command ^ 0xffffffff)) { 1069dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("check_header(): invalid magic\n"); 1070dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 1071dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1072dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1073dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(p->msg.data_length > MAX_PAYLOAD) { 1074dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("check_header(): %d > MAX_PAYLOAD\n", p->msg.data_length); 1075dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 1076dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1077dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1078dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 1079dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 1080dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1081dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint check_data(apacket *p) 1082dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 1083dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned count, sum; 1084dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned char *x; 1085dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1086dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project count = p->msg.data_length; 1087dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project x = p->data; 1088dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sum = 0; 1089dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while(count-- > 0) { 1090dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sum += *x++; 1091dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1092dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1093dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(sum != p->msg.data_check) { 1094dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 1095dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 1096dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 1097dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1098dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 1099