transport.c revision 69c5c4c45bd4f1575ae8bdba13795297be7deb8c
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 3869c5c4c45bd4f1575ae8bdba13795297be7deb8cJP 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; 4269c5c4c45bd4f1575ae8bdba13795297be7deb8cJP Abgrall // Build a string instead of logging each character. 4369c5c4c45bd4f1575ae8bdba13795297be7deb8cJP Abgrall // MAX chars in 2 digit hex, one space, MAX chars, one '\0'. 4469c5c4c45bd4f1575ae8bdba13795297be7deb8cJP Abgrall char buffer[MAX_DUMP_HEX_LEN *2 + 1 + MAX_DUMP_HEX_LEN + 1 ], *pb = buffer; 45dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 4669c5c4c45bd4f1575ae8bdba13795297be7deb8cJP Abgrall if (len2 > MAX_DUMP_HEX_LEN) len2 = MAX_DUMP_HEX_LEN; 47dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 4869c5c4c45bd4f1575ae8bdba13795297be7deb8cJP Abgrall for (nn = 0; nn < len2; nn++) { 4969c5c4c45bd4f1575ae8bdba13795297be7deb8cJP Abgrall sprintf(pb, "%02x", ptr[nn]); 5069c5c4c45bd4f1575ae8bdba13795297be7deb8cJP Abgrall pb += 2; 5169c5c4c45bd4f1575ae8bdba13795297be7deb8cJP Abgrall } 5269c5c4c45bd4f1575ae8bdba13795297be7deb8cJP 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 = '.'; 5869c5c4c45bd4f1575ae8bdba13795297be7deb8cJP Abgrall *pb++ = c; 59dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 6069c5c4c45bd4f1575ae8bdba13795297be7deb8cJP Abgrall *pb++ = '\0'; 6169c5c4c45bd4f1575ae8bdba13795297be7deb8cJP 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; 20169c5c4c45bd4f1575ae8bdba13795297be7deb8cJP 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) { 231dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("Transport is null \n"); 23269c5c4c45bd4f1575ae8bdba13795297be7deb8cJP Abgrall fatal_errno("Transport is null"); 233dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 234dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 235730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner if(write_packet(t->transport_socket, t->serial, &p)){ 236dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fatal_errno("cannot enqueue packet on transport socket"); 237dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 238dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 239dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 240dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* The transport is opened by transport_register_func before 241dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** the input and output threads are started. 242dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** 243dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** The output thread issues a SYNC(1, token) message to let 244dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** the input thread know to start things up. In the event 245dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** of transport IO failure, the output thread will post a 246dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** SYNC(0,0) message to ensure shutdown. 247dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** 248dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** The transport will not actually be closed until both 249dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** threads exit, but the input thread will kick the transport 250dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** on its way out to disconnect the underlying device. 251dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project*/ 252dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 253dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void *output_thread(void *_t) 254dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 255dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project atransport *t = _t; 256dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project apacket *p; 257dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 258730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("%s: starting transport output thread on fd %d, SYNC online (%d)\n", 259730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner t->serial, t->fd, t->sync_token + 1); 260dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p = get_apacket(); 261dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.command = A_SYNC; 262dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.arg0 = 1; 263dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.arg1 = ++(t->sync_token); 264dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.magic = A_SYNC ^ 0xffffffff; 265730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner if(write_packet(t->fd, t->serial, &p)) { 266dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project put_apacket(p); 267730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("%s: failed to write SYNC packet\n", t->serial); 268dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto oops; 269dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 270dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 271730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("%s: data pump started\n", t->serial); 272dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for(;;) { 273dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p = get_apacket(); 274dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 275dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(t->read_from_remote(p, t) == 0){ 276730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("%s: received remote packet, sending to transport\n", 277730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner t->serial); 278730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner if(write_packet(t->fd, t->serial, &p)){ 279dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project put_apacket(p); 280730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("%s: failed to write apacket to transport\n", t->serial); 281dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto oops; 282dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 283dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 284730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("%s: remote read failed for transport\n", t->serial); 285dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project put_apacket(p); 286dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 287dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 288dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 289dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 290730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("%s: SYNC offline for transport\n", t->serial); 291dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p = get_apacket(); 292dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.command = A_SYNC; 293dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.arg0 = 0; 294dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.arg1 = 0; 295dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.magic = A_SYNC ^ 0xffffffff; 296730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner if(write_packet(t->fd, t->serial, &p)) { 297dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project put_apacket(p); 298730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("%s: failed to write SYNC apacket to transport", t->serial); 299dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 300dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 301dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectoops: 302730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("%s: transport output thread is exiting\n", t->serial); 303dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project kick_transport(t); 304dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project transport_unref(t); 305dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 306dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 307dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 308dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void *input_thread(void *_t) 309dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 310dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project atransport *t = _t; 311dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project apacket *p; 312dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int active = 0; 313dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 314730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("%s: starting transport input thread, reading from fd %d\n", 315730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner t->serial, t->fd); 316dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 317dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for(;;){ 318730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner if(read_packet(t->fd, t->serial, &p)) { 319730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("%s: failed to read apacket from transport on fd %d\n", 320730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner t->serial, t->fd ); 321dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 322dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 323dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(p->msg.command == A_SYNC){ 324dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(p->msg.arg0 == 0) { 325730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("%s: transport SYNC offline\n", t->serial); 326dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project put_apacket(p); 327dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 328dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 329dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(p->msg.arg1 == t->sync_token) { 330730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("%s: transport SYNC online\n", t->serial); 331dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project active = 1; 332dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 333730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("%s: transport ignoring SYNC %d != %d\n", 334730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner t->serial, p->msg.arg1, t->sync_token); 335dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 336dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 337dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 338dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(active) { 339730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("%s: transport got packet, sending to remote\n", t->serial); 340dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->write_to_remote(p, t); 341dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 342730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("%s: transport ignoring packet while offline\n", t->serial); 343dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 344dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 345dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 346dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project put_apacket(p); 347dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 348dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 349dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // this is necessary to avoid a race condition that occured when a transport closes 350dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // while a client socket is still active. 351dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project close_all_sockets(t); 352dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 353730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("%s: transport input thread is exiting, fd %d\n", t->serial, t->fd); 354dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project kick_transport(t); 355dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project transport_unref(t); 356dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 357dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 358dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 359dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 360dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int transport_registration_send = -1; 361dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int transport_registration_recv = -1; 362dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic fdevent transport_registration_fde; 363dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 364dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 365dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if ADB_HOST 366dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int list_transports_msg(char* buffer, size_t bufferlen) 367dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 368dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char head[5]; 369dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int len; 370dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 371dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len = list_transports(buffer+4, bufferlen-4); 372dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project snprintf(head, sizeof(head), "%04x", len); 373dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project memcpy(buffer, head, 4); 374dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len += 4; 375dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return len; 376dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 377dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 378dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* this adds support required by the 'track-devices' service. 379dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * this is used to send the content of "list_transport" to any 380dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * number of client connections that want it through a single 381dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * live TCP connection 382dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 383dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecttypedef struct device_tracker device_tracker; 384dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstruct device_tracker { 385dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project asocket socket; 386dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int update_needed; 387dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project device_tracker* next; 388dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}; 389dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 390dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* linked list of all device trackers */ 391dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic device_tracker* device_tracker_list; 392dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 393dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void 394dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectdevice_tracker_remove( device_tracker* tracker ) 395dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 396dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project device_tracker** pnode = &device_tracker_list; 397dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project device_tracker* node = *pnode; 398dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 399dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_lock( &transport_lock ); 400dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while (node) { 401dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (node == tracker) { 402dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *pnode = node->next; 403dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 404dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 405dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project pnode = &node->next; 406dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project node = *pnode; 407dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 408dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_unlock( &transport_lock ); 409dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 410dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 411dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void 412dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectdevice_tracker_close( asocket* socket ) 413dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 414dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project device_tracker* tracker = (device_tracker*) socket; 415dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project asocket* peer = socket->peer; 416dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 417dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D( "device tracker %p removed\n", tracker); 418dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (peer) { 419dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project peer->peer = NULL; 420dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project peer->close(peer); 421dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 422dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project device_tracker_remove(tracker); 423dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project free(tracker); 424dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 425dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 426dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int 427dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectdevice_tracker_enqueue( asocket* socket, apacket* p ) 428dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 429dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* you can't read from a device tracker, close immediately */ 430dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project put_apacket(p); 431dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project device_tracker_close(socket); 432dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 433dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 434dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 435dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int 436dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectdevice_tracker_send( device_tracker* tracker, 437dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project const char* buffer, 438dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int len ) 439dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 440dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project apacket* p = get_apacket(); 441dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project asocket* peer = tracker->socket.peer; 442dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 443dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project memcpy(p->data, buffer, len); 444dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->len = len; 445dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return peer->enqueue( peer, p ); 446dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 447dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 448dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 449dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void 450dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectdevice_tracker_ready( asocket* socket ) 451dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 452dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project device_tracker* tracker = (device_tracker*) socket; 453dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 454dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* we want to send the device list when the tracker connects 455dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * for the first time, even if no update occured */ 456dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (tracker->update_needed > 0) { 457dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char buffer[1024]; 458dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int len; 459dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 460dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project tracker->update_needed = 0; 461dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 462dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len = list_transports_msg(buffer, sizeof(buffer)); 463dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project device_tracker_send(tracker, buffer, len); 464dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 465dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 466dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 467dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 468dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectasocket* 469dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectcreate_device_tracker(void) 470dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 471dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project device_tracker* tracker = calloc(1,sizeof(*tracker)); 472dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 473dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(tracker == 0) fatal("cannot allocate device tracker"); 474dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 475dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D( "device tracker %p created\n", tracker); 476dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 477dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project tracker->socket.enqueue = device_tracker_enqueue; 478dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project tracker->socket.ready = device_tracker_ready; 479dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project tracker->socket.close = device_tracker_close; 480dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project tracker->update_needed = 1; 481dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 482dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project tracker->next = device_tracker_list; 483dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project device_tracker_list = tracker; 484dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 485dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return &tracker->socket; 486dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 487dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 488dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 489dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* call this function each time the transport list has changed */ 490dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid update_transports(void) 491dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 492dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char buffer[1024]; 493dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int len; 494dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project device_tracker* tracker; 495dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 496dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len = list_transports_msg(buffer, sizeof(buffer)); 497dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 498dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project tracker = device_tracker_list; 499dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while (tracker != NULL) { 500dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project device_tracker* next = tracker->next; 501dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* note: this may destroy the tracker if the connection is closed */ 502dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project device_tracker_send(tracker, buffer, len); 503dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project tracker = next; 504dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 505dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 506dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else 507dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid update_transports(void) 508dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 509dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // nothing to do on the device side 510dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 511dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif // ADB_HOST 512dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 513dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecttypedef struct tmsg tmsg; 514dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstruct tmsg 515dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 516dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project atransport *transport; 517dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int action; 518dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}; 519dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 520dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int 521dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecttransport_read_action(int fd, struct tmsg* m) 522dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 523dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *p = (char*)m; 524dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int len = sizeof(*m); 525dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int r; 526dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 527dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while(len > 0) { 528dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project r = adb_read(fd, p, len); 529dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(r > 0) { 530dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len -= r; 531dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p += r; 532dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 533dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if((r < 0) && (errno == EINTR)) continue; 534730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("transport_read_action: on fd %d, error %d: %s\n", 535dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fd, errno, strerror(errno)); 536dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 537dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 538dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 539dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 540dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 541dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 542dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int 543dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecttransport_write_action(int fd, struct tmsg* m) 544dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 545dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *p = (char*)m; 546dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int len = sizeof(*m); 547dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int r; 548dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 549dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while(len > 0) { 550dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project r = adb_write(fd, p, len); 551dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(r > 0) { 552dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len -= r; 553dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p += r; 554dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 555dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if((r < 0) && (errno == EINTR)) continue; 556730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("transport_write_action: on fd %d, error %d: %s\n", 557dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fd, errno, strerror(errno)); 558dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 559dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 560dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 561dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 562dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 563dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 564dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void transport_registration_func(int _fd, unsigned ev, void *data) 565dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 566dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project tmsg m; 567dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_thread_t output_thread_ptr; 568dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_thread_t input_thread_ptr; 569dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int s[2]; 570dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project atransport *t; 571dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 572dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(!(ev & FDE_READ)) { 573dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 574dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 575dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 576dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(transport_read_action(_fd, &m)) { 577dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fatal_errno("cannot read transport registration socket"); 578dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 579dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 580dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t = m.transport; 581dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 582dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(m.action == 0){ 583730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("transport: %s removing and free'ing %d\n", t->serial, t->transport_socket); 584dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 585dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* IMPORTANT: the remove closes one half of the 586dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ** socket pair. The close closes the other half. 587dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 588dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fdevent_remove(&(t->transport_fde)); 589dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_close(t->fd); 590dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 591dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_lock(&transport_lock); 592dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->next->prev = t->prev; 593dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->prev->next = t->next; 594dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_unlock(&transport_lock); 595dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 596dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project run_transport_disconnects(t); 597dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 598dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (t->product) 599dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project free(t->product); 600dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (t->serial) 601dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project free(t->serial); 602dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 603dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project memset(t,0xee,sizeof(atransport)); 604dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project free(t); 605dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 606dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project update_transports(); 607dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 608dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 609dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 6100927bf9690127bc45cf8837a1467759e9720399aMike Lockwood /* don't create transport threads for inaccessible devices */ 6110927bf9690127bc45cf8837a1467759e9720399aMike Lockwood if (t->connection_state != CS_NOPERM) { 612dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* initial references are the two threads */ 6130927bf9690127bc45cf8837a1467759e9720399aMike Lockwood t->ref_count = 2; 614dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 6150927bf9690127bc45cf8837a1467759e9720399aMike Lockwood if(adb_socketpair(s)) { 6160927bf9690127bc45cf8837a1467759e9720399aMike Lockwood fatal_errno("cannot open transport socketpair"); 6170927bf9690127bc45cf8837a1467759e9720399aMike Lockwood } 6180927bf9690127bc45cf8837a1467759e9720399aMike Lockwood 619730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("transport: %s (%d,%d) starting\n", t->serial, s[0], s[1]); 6200927bf9690127bc45cf8837a1467759e9720399aMike Lockwood 6210927bf9690127bc45cf8837a1467759e9720399aMike Lockwood t->transport_socket = s[0]; 6220927bf9690127bc45cf8837a1467759e9720399aMike Lockwood t->fd = s[1]; 623dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 6240927bf9690127bc45cf8837a1467759e9720399aMike Lockwood fdevent_install(&(t->transport_fde), 6250927bf9690127bc45cf8837a1467759e9720399aMike Lockwood t->transport_socket, 6260927bf9690127bc45cf8837a1467759e9720399aMike Lockwood transport_socket_events, 6270927bf9690127bc45cf8837a1467759e9720399aMike Lockwood t); 6280927bf9690127bc45cf8837a1467759e9720399aMike Lockwood 6290927bf9690127bc45cf8837a1467759e9720399aMike Lockwood fdevent_set(&(t->transport_fde), FDE_READ); 6300927bf9690127bc45cf8837a1467759e9720399aMike Lockwood 6310927bf9690127bc45cf8837a1467759e9720399aMike Lockwood if(adb_thread_create(&input_thread_ptr, input_thread, t)){ 6320927bf9690127bc45cf8837a1467759e9720399aMike Lockwood fatal_errno("cannot create input thread"); 6330927bf9690127bc45cf8837a1467759e9720399aMike Lockwood } 634dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 6350927bf9690127bc45cf8837a1467759e9720399aMike Lockwood if(adb_thread_create(&output_thread_ptr, output_thread, t)){ 6360927bf9690127bc45cf8837a1467759e9720399aMike Lockwood fatal_errno("cannot create output thread"); 6370927bf9690127bc45cf8837a1467759e9720399aMike Lockwood } 6380927bf9690127bc45cf8837a1467759e9720399aMike Lockwood } 639dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 640dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* put us on the master device list */ 641dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_lock(&transport_lock); 642dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->next = &transport_list; 643dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->prev = transport_list.prev; 644dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->next->prev = t; 645dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->prev->next = t; 646dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_unlock(&transport_lock); 647dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 648dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->disconnects.next = t->disconnects.prev = &t->disconnects; 649dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 650dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project update_transports(); 651dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 652dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 653dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid init_transport_registration(void) 654dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 655dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int s[2]; 656dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 657dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(adb_socketpair(s)){ 658dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fatal_errno("cannot open transport registration socketpair"); 659dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 660dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 661dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project transport_registration_send = s[0]; 662dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project transport_registration_recv = s[1]; 663dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 664dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fdevent_install(&transport_registration_fde, 665dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project transport_registration_recv, 666dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project transport_registration_func, 667dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 0); 668dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 669dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fdevent_set(&transport_registration_fde, FDE_READ); 670dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 671dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 672dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* the fdevent select pump is single threaded */ 673dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void register_transport(atransport *transport) 674dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 675dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project tmsg m; 676dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project m.transport = transport; 677dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project m.action = 1; 678730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("transport: %s registered\n", transport->serial); 679dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(transport_write_action(transport_registration_send, &m)) { 680dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fatal_errno("cannot write transport registration socket\n"); 681dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 682dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 683dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 684dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void remove_transport(atransport *transport) 685dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 686dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project tmsg m; 687dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project m.transport = transport; 688dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project m.action = 0; 689730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("transport: %s removed\n", transport->serial); 690dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(transport_write_action(transport_registration_send, &m)) { 691dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fatal_errno("cannot write transport registration socket\n"); 692dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 693dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 694dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 695dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 696cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwoodstatic void transport_unref_locked(atransport *t) 697cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood{ 698cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood t->ref_count--; 699cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood if (t->ref_count == 0) { 700730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("transport: %s unref (kicking and closing)\n", t->serial); 701cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood if (!t->kicked) { 702cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood t->kicked = 1; 703cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood t->kick(t); 704cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood } 705cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood t->close(t); 706cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood remove_transport(t); 707730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner } else { 708730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("transport: %s unref (count=%d)\n", t->serial, t->ref_count); 709cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood } 710cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood} 711cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood 712dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void transport_unref(atransport *t) 713dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 714dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (t) { 715dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_lock(&transport_lock); 716cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood transport_unref_locked(t); 717dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_unlock(&transport_lock); 718dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 719dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 720dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 721dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid add_transport_disconnect(atransport* t, adisconnect* dis) 722dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 723dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_lock(&transport_lock); 724dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dis->next = &t->disconnects; 725dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dis->prev = dis->next->prev; 726dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dis->prev->next = dis; 727dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dis->next->prev = dis; 728dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_unlock(&transport_lock); 729dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 730dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 731dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid remove_transport_disconnect(atransport* t, adisconnect* dis) 732dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 733dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dis->prev->next = dis->next; 734dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dis->next->prev = dis->prev; 735dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dis->next = dis->prev = dis; 736dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 737dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 738dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 739dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectatransport *acquire_one_transport(int state, transport_type ttype, const char* serial, char** error_out) 740dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 741dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project atransport *t; 742dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project atransport *result = NULL; 743dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int ambiguous = 0; 744dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 745dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectretry: 746dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (error_out) 747dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *error_out = "device not found"; 748dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 749dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_lock(&transport_lock); 750dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (t = transport_list.next; t != &transport_list; t = t->next) { 75137d3111b1c1ce61c3d9b10ed3ccaed9e5fad1e06Mike Lockwood if (t->connection_state == CS_NOPERM) { 75237d3111b1c1ce61c3d9b10ed3ccaed9e5fad1e06Mike Lockwood if (error_out) 75337d3111b1c1ce61c3d9b10ed3ccaed9e5fad1e06Mike Lockwood *error_out = "insufficient permissions for device"; 75437d3111b1c1ce61c3d9b10ed3ccaed9e5fad1e06Mike Lockwood continue; 75537d3111b1c1ce61c3d9b10ed3ccaed9e5fad1e06Mike Lockwood } 7560927bf9690127bc45cf8837a1467759e9720399aMike Lockwood 757dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* check for matching serial number */ 758dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (serial) { 759dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (t->serial && !strcmp(serial, t->serial)) { 760dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project result = t; 761dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 762dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 763dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 764dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (ttype == kTransportUsb && t->type == kTransportUsb) { 765dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (result) { 766dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (error_out) 767dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *error_out = "more than one device"; 768dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ambiguous = 1; 769dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project result = NULL; 770dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 771dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 772dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project result = t; 773dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (ttype == kTransportLocal && t->type == kTransportLocal) { 774dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (result) { 775dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (error_out) 776dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *error_out = "more than one emulator"; 777dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ambiguous = 1; 778dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project result = NULL; 779dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 780dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 781dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project result = t; 782dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (ttype == kTransportAny) { 783dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (result) { 784dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (error_out) 785dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *error_out = "more than one device and emulator"; 786dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ambiguous = 1; 787dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project result = NULL; 788dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 789dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 790dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project result = t; 791dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 792dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 793dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 794dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_unlock(&transport_lock); 795dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 796dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (result) { 797dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* offline devices are ignored -- they are either being born or dying */ 798dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (result && result->connection_state == CS_OFFLINE) { 799dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (error_out) 800dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *error_out = "device offline"; 801dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project result = NULL; 802dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 803dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* check for required connection state */ 804dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (result && state != CS_ANY && result->connection_state != state) { 805dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (error_out) 806dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *error_out = "invalid device state"; 807dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project result = NULL; 808dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 809dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 810dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 811dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (result) { 812dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* found one that we can take */ 813dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (error_out) 814dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *error_out = NULL; 815dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (state != CS_ANY && (serial || !ambiguous)) { 816dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_sleep_ms(1000); 817dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto retry; 818dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 819dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 820dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return result; 821dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 822dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 823dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if ADB_HOST 824dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic const char *statename(atransport *t) 825dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 826dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project switch(t->connection_state){ 827dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case CS_OFFLINE: return "offline"; 828dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case CS_BOOTLOADER: return "bootloader"; 829dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case CS_DEVICE: return "device"; 830dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case CS_HOST: return "host"; 831dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case CS_RECOVERY: return "recovery"; 8320927bf9690127bc45cf8837a1467759e9720399aMike Lockwood case CS_NOPERM: return "no permissions"; 833dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project default: return "unknown"; 834dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 835dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 836dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 837dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint list_transports(char *buf, size_t bufsize) 838dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 839dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char* p = buf; 840dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char* end = buf + bufsize; 841dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int len; 842dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project atransport *t; 843dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 844dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* XXX OVERRUN PROBLEMS XXX */ 845dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_lock(&transport_lock); 846dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for(t = transport_list.next; t != &transport_list; t = t->next) { 8470927bf9690127bc45cf8837a1467759e9720399aMike Lockwood const char* serial = t->serial; 8480927bf9690127bc45cf8837a1467759e9720399aMike Lockwood if (!serial || !serial[0]) 8490927bf9690127bc45cf8837a1467759e9720399aMike Lockwood serial = "????????????"; 8500927bf9690127bc45cf8837a1467759e9720399aMike Lockwood len = snprintf(p, end - p, "%s\t%s\n", serial, statename(t)); 851dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 852dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (p + len >= end) { 853dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* discard last line if buffer is too short */ 854dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 855dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 856dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p += len; 857dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 858dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p[0] = 0; 859dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_unlock(&transport_lock); 860dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return p - buf; 861dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 862dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 863dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 864dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* hack for osx */ 865dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid close_usb_devices() 866dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 867dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project atransport *t; 868dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 869dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_lock(&transport_lock); 870dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for(t = transport_list.next; t != &transport_list; t = t->next) { 871dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if ( !t->kicked ) { 872dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->kicked = 1; 873dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->kick(t); 874dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 875dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 876dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_unlock(&transport_lock); 877dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 878dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif // ADB_HOST 879dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 880ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwoodvoid register_socket_transport(int s, const char *serial, int port, int local) 881dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 882dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project atransport *t = calloc(1, sizeof(atransport)); 883730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner char buff[32]; 884730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner 885730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner if (!serial) { 886730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner snprintf(buff, sizeof buff, "T-%p", t); 887730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner serial = buff; 888730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner } 889730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("transport: %s init'ing for socket %d, on port %d\n", serial, s, port); 890ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood if ( init_socket_transport(t, s, port, local) < 0 ) { 891dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_close(s); 892dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project free(t); 893dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 894dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 895dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(serial) { 896dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->serial = strdup(serial); 897dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 898dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project register_transport(t); 899dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 900dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 9018cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood#if ADB_HOST 9028cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwoodatransport *find_transport(const char *serial) 9038cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood{ 9048cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood atransport *t; 9058cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood 9068cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood adb_mutex_lock(&transport_lock); 9078cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood for(t = transport_list.next; t != &transport_list; t = t->next) { 9088cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood if (t->serial && !strcmp(serial, t->serial)) { 9098cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood break; 9108cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood } 9118cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood } 9128cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood adb_mutex_unlock(&transport_lock); 9138cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood 9148cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood if (t != &transport_list) 9158cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood return t; 9168cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood else 9178cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood return 0; 9188cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood} 9198cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood 9208cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwoodvoid unregister_transport(atransport *t) 9218cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood{ 9228cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood adb_mutex_lock(&transport_lock); 9238cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood t->next->prev = t->prev; 9248cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood t->prev->next = t->next; 9258cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood adb_mutex_unlock(&transport_lock); 9268cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood 9278cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood kick_transport(t); 9288cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood transport_unref(t); 9298cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood} 9308cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood 931cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood// unregisters all non-emulator TCP transports 932cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwoodvoid unregister_all_tcp_transports() 933cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood{ 934cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood atransport *t, *next; 935cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood adb_mutex_lock(&transport_lock); 936cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood for (t = transport_list.next; t != &transport_list; t = next) { 937cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood next = t->next; 938cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood if (t->type == kTransportLocal && t->adb_port == 0) { 939cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood t->next->prev = t->prev; 940cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood t->prev->next = next; 941cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood // we cannot call kick_transport when holding transport_lock 942cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood if (!t->kicked) 943cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood { 944cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood t->kicked = 1; 945cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood t->kick(t); 946cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood } 947cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood transport_unref_locked(t); 948cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood } 949cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood } 950cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood 951cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood adb_mutex_unlock(&transport_lock); 952cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood} 953cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood 9548cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood#endif 9558cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood 9560927bf9690127bc45cf8837a1467759e9720399aMike Lockwoodvoid register_usb_transport(usb_handle *usb, const char *serial, unsigned writeable) 957dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 958dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project atransport *t = calloc(1, sizeof(atransport)); 959dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("transport: %p init'ing for usb_handle %p (sn='%s')\n", t, usb, 960dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project serial ? serial : ""); 9610927bf9690127bc45cf8837a1467759e9720399aMike Lockwood init_usb_transport(t, usb, (writeable ? CS_OFFLINE : CS_NOPERM)); 962dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(serial) { 963dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->serial = strdup(serial); 964dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 965dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project register_transport(t); 966dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 967dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 9680927bf9690127bc45cf8837a1467759e9720399aMike Lockwood/* this should only be used for transports with connection_state == CS_NOPERM */ 9690927bf9690127bc45cf8837a1467759e9720399aMike Lockwoodvoid unregister_usb_transport(usb_handle *usb) 9700927bf9690127bc45cf8837a1467759e9720399aMike Lockwood{ 9710927bf9690127bc45cf8837a1467759e9720399aMike Lockwood atransport *t; 9720927bf9690127bc45cf8837a1467759e9720399aMike Lockwood adb_mutex_lock(&transport_lock); 9730927bf9690127bc45cf8837a1467759e9720399aMike Lockwood for(t = transport_list.next; t != &transport_list; t = t->next) { 9740927bf9690127bc45cf8837a1467759e9720399aMike Lockwood if (t->usb == usb && t->connection_state == CS_NOPERM) { 9750927bf9690127bc45cf8837a1467759e9720399aMike Lockwood t->next->prev = t->prev; 9760927bf9690127bc45cf8837a1467759e9720399aMike Lockwood t->prev->next = t->next; 9770927bf9690127bc45cf8837a1467759e9720399aMike Lockwood break; 9780927bf9690127bc45cf8837a1467759e9720399aMike Lockwood } 9790927bf9690127bc45cf8837a1467759e9720399aMike Lockwood } 9800927bf9690127bc45cf8837a1467759e9720399aMike Lockwood adb_mutex_unlock(&transport_lock); 9810927bf9690127bc45cf8837a1467759e9720399aMike Lockwood} 982dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 983dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#undef TRACE_TAG 984dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define TRACE_TAG TRACE_RWX 985dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 986dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint readx(int fd, void *ptr, size_t len) 987dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 988dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *p = ptr; 989dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int r; 990dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if ADB_TRACE 991dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int len0 = len; 992dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 993730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("readx: fd=%d wanted=%d\n", fd, (int)len); 994dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while(len > 0) { 995dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project r = adb_read(fd, p, len); 996dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(r > 0) { 997dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len -= r; 998dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p += r; 999dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 1000730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner if (r < 0) { 1001730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("readx: fd=%d error %d: %s\n", fd, errno, strerror(errno)); 1002730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner if (errno == EINTR) 1003730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner continue; 1004730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner } else { 1005730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("readx: fd=%d disconnected\n", fd); 1006730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner } 1007dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 1008dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1009dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1010dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1011dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if ADB_TRACE 1012730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("readx: fd=%d wanted=%d got=%d\n", fd, len0, len0 - len); 1013dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dump_hex( ptr, len0 ); 1014dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 1015dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 1016dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 1017dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1018dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint writex(int fd, const void *ptr, size_t len) 1019dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 1020dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *p = (char*) ptr; 1021dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int r; 1022dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1023dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if ADB_TRACE 1024730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("writex: fd=%d len=%d: ", fd, (int)len); 1025dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dump_hex( ptr, len ); 1026dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 1027dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while(len > 0) { 1028dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project r = adb_write(fd, p, len); 1029dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(r > 0) { 1030dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len -= r; 1031dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p += r; 1032dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 1033730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner if (r < 0) { 1034730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("writex: fd=%d error %d: %s\n", fd, errno, strerror(errno)); 1035730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner if (errno == EINTR) 1036730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner continue; 1037730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner } else { 1038730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("writex: fd=%d disconnected\n", fd); 1039730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner } 1040dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 1041dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1042dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1043dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 1044dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 1045dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1046dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint check_header(apacket *p) 1047dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 1048dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(p->msg.magic != (p->msg.command ^ 0xffffffff)) { 1049dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("check_header(): invalid magic\n"); 1050dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 1051dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1052dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1053dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(p->msg.data_length > MAX_PAYLOAD) { 1054dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("check_header(): %d > MAX_PAYLOAD\n", p->msg.data_length); 1055dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 1056dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1057dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1058dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 1059dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 1060dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1061dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint check_data(apacket *p) 1062dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 1063dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned count, sum; 1064dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned char *x; 1065dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1066dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project count = p->msg.data_length; 1067dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project x = p->data; 1068dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sum = 0; 1069dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while(count-- > 0) { 1070dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sum += *x++; 1071dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1072dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1073dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(sum != p->msg.data_check) { 1074dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 1075dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 1076dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 1077dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1078dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 1079