transport.c revision 0e7c4274c687446dbe30a814278d7a6b99da8c4e
1dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* 2dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project 3dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 4dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * you may not use this file except in compliance with the License. 6dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * You may obtain a copy of the License at 7dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 8dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 10dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * See the License for the specific language governing permissions and 14dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * limitations under the License. 15dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 16dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 17dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdio.h> 18dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdlib.h> 19dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <unistd.h> 20dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <string.h> 21dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <errno.h> 22dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 23dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "sysdeps.h" 24dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 25dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define TRACE_TAG TRACE_TRANSPORT 26dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "adb.h" 27dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 28dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void transport_unref(atransport *t); 29dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 30dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic atransport transport_list = { 31dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project .next = &transport_list, 32dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project .prev = &transport_list, 33dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}; 34dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 35dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectADB_MUTEX_DEFINE( transport_lock ); 36dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 37dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if ADB_TRACE 38dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void dump_hex( const unsigned char* ptr, size_t len ) 39dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 40dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int nn, len2 = len; 41dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 420e7c4274c687446dbe30a814278d7a6b99da8c4eJP Abgrall if (len2 > 16) len2 = 16; 43dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 440e7c4274c687446dbe30a814278d7a6b99da8c4eJP Abgrall for (nn = 0; nn < len2; nn++) 450e7c4274c687446dbe30a814278d7a6b99da8c4eJP Abgrall D("%02x", ptr[nn]); 460e7c4274c687446dbe30a814278d7a6b99da8c4eJP Abgrall D(" "); 47dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 48dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (nn = 0; nn < len2; nn++) { 49dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int c = ptr[nn]; 50dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (c < 32 || c > 127) 51dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project c = '.'; 520e7c4274c687446dbe30a814278d7a6b99da8c4eJP Abgrall D("%c", c); 53dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 540e7c4274c687446dbe30a814278d7a6b99da8c4eJP Abgrall D("\n"); 550e7c4274c687446dbe30a814278d7a6b99da8c4eJP Abgrall fflush(stdout); 56dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 57dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 58dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 59dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid 60dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectkick_transport(atransport* t) 61dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 62dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (t && !t->kicked) 63dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project { 64dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int kicked; 65dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 66dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_lock(&transport_lock); 67dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project kicked = t->kicked; 68dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!kicked) 69dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->kicked = 1; 70dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_unlock(&transport_lock); 71dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 72dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!kicked) 73dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->kick(t); 74dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 75dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 76dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 77dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid 78dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectrun_transport_disconnects(atransport* t) 79dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 80dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adisconnect* dis = t->disconnects.next; 81dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 82730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("%s: run_transport_disconnects\n", t->serial); 83dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while (dis != &t->disconnects) { 84dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adisconnect* next = dis->next; 85dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dis->func( dis->opaque, t ); 86dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dis = next; 87dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 88dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 89dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 90730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner#if ADB_TRACE 91730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turnerstatic void 92730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turnerdump_packet(const char* name, const char* func, apacket* p) 93730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner{ 94730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner unsigned command = p->msg.command; 95730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner int len = p->msg.data_length; 96730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner char cmd[9]; 97730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner char arg0[12], arg1[12]; 98730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner int n; 99730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner 100730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner for (n = 0; n < 4; n++) { 101730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner int b = (command >> (n*8)) & 255; 102730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner if (b < 32 || b >= 127) 103730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner break; 104730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner cmd[n] = (char)b; 105730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner } 106730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner if (n == 4) { 107730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner cmd[4] = 0; 108730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner } else { 109730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner /* There is some non-ASCII name in the command, so dump 110730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner * the hexadecimal value instead */ 111730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner snprintf(cmd, sizeof cmd, "%08x", command); 112730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner } 113730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner 114730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner if (p->msg.arg0 < 256U) 115730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner snprintf(arg0, sizeof arg0, "%d", p->msg.arg0); 116730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner else 117730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner snprintf(arg0, sizeof arg0, "0x%x", p->msg.arg0); 118730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner 119730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner if (p->msg.arg1 < 256U) 120730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner snprintf(arg1, sizeof arg1, "%d", p->msg.arg1); 121730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner else 122730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner snprintf(arg1, sizeof arg1, "0x%x", p->msg.arg1); 123730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner 124730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("%s: %s: [%s] arg0=%s arg1=%s (len=%d) ", 125730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner name, func, cmd, arg0, arg1, len); 126730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner dump_hex(p->data, len); 127730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner} 128730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner#endif /* ADB_TRACE */ 129730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner 130dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int 131730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turnerread_packet(int fd, const char* name, apacket** ppacket) 132dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 133dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *p = (char*)ppacket; /* really read a packet address */ 134dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int r; 135dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int len = sizeof(*ppacket); 136730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner char buff[8]; 137730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner if (!name) { 138730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner snprintf(buff, sizeof buff, "fd=%d", fd); 139730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner name = buff; 140730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner } 141dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while(len > 0) { 142dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project r = adb_read(fd, p, len); 143dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(r > 0) { 144dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len -= r; 145dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p += r; 146dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 147730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("%s: read_packet (fd=%d), error ret=%d errno=%d: %s\n", name, fd, r, errno, strerror(errno)); 148dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if((r < 0) && (errno == EINTR)) continue; 149dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 150dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 151dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 152dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 153dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if ADB_TRACE 154730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner if (ADB_TRACING) { 155730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner dump_packet(name, "from remote", *ppacket); 156dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 157dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 158dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 159dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 160dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 161dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int 162730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turnerwrite_packet(int fd, const char* name, apacket** ppacket) 163dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 164dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *p = (char*) ppacket; /* we really write the packet address */ 165dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int r, len = sizeof(ppacket); 166730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner char buff[8]; 167730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner if (!name) { 168730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner snprintf(buff, sizeof buff, "fd=%d", fd); 169730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner name = buff; 170730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner } 171dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 172dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if ADB_TRACE 173730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner if (ADB_TRACING) { 174730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner dump_packet(name, "to remote", *ppacket); 175dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 176dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 177dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len = sizeof(ppacket); 178dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while(len > 0) { 179dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project r = adb_write(fd, p, len); 180dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(r > 0) { 181dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len -= r; 182dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p += r; 183dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 184730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("%s: write_packet (fd=%d) error ret=%d errno=%d: %s\n", name, fd, r, errno, strerror(errno)); 185dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if((r < 0) && (errno == EINTR)) continue; 186dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 187dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 188dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 189dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 190dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 191dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 192dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void transport_socket_events(int fd, unsigned events, void *_t) 193dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 194730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner atransport *t = _t; 195dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(events & FDE_READ){ 196dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project apacket *p = 0; 197730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner if(read_packet(fd, t->serial, &p)){ 198730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("%s: failed to read packet from transport socket on fd %d\n", t->serial, fd); 199dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 200dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project handle_packet(p, (atransport *) _t); 201dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 202dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 203dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 204dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 205dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid send_packet(apacket *p, atransport *t) 206dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 207dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned char *x; 208dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned sum; 209dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned count; 210dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 211dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.magic = p->msg.command ^ 0xffffffff; 212dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 213dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project count = p->msg.data_length; 214dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project x = (unsigned char *) p->data; 215dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sum = 0; 216dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while(count-- > 0){ 217dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sum += *x++; 218dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 219dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.data_check = sum; 220dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 221dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project print_packet("send", p); 222dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 223dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (t == NULL) { 22469c5c4c45bd4f1575ae8bdba13795297be7deb8cJP Abgrall fatal_errno("Transport is null"); 2250e7c4274c687446dbe30a814278d7a6b99da8c4eJP Abgrall D("Transport is null \n"); 226dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 227dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 228730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner if(write_packet(t->transport_socket, t->serial, &p)){ 229dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fatal_errno("cannot enqueue packet on transport socket"); 230dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 231dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 232dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 233dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* The transport is opened by transport_register_func before 234dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** the input and output threads are started. 235dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** 236dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** The output thread issues a SYNC(1, token) message to let 237dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** the input thread know to start things up. In the event 238dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** of transport IO failure, the output thread will post a 239dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** SYNC(0,0) message to ensure shutdown. 240dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** 241dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** The transport will not actually be closed until both 242dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** threads exit, but the input thread will kick the transport 243dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** on its way out to disconnect the underlying device. 244dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project*/ 245dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 246dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void *output_thread(void *_t) 247dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 248dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project atransport *t = _t; 249dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project apacket *p; 250dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 251730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("%s: starting transport output thread on fd %d, SYNC online (%d)\n", 252730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner t->serial, t->fd, t->sync_token + 1); 253dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p = get_apacket(); 254dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.command = A_SYNC; 255dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.arg0 = 1; 256dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.arg1 = ++(t->sync_token); 257dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.magic = A_SYNC ^ 0xffffffff; 258730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner if(write_packet(t->fd, t->serial, &p)) { 259dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project put_apacket(p); 260730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("%s: failed to write SYNC packet\n", t->serial); 261dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto oops; 262dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 263dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 264730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("%s: data pump started\n", t->serial); 265dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for(;;) { 266dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p = get_apacket(); 267dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 268dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(t->read_from_remote(p, t) == 0){ 269730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("%s: received remote packet, sending to transport\n", 270730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner t->serial); 271730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner if(write_packet(t->fd, t->serial, &p)){ 272dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project put_apacket(p); 273730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("%s: failed to write apacket to transport\n", t->serial); 274dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto oops; 275dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 276dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 277730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("%s: remote read failed for transport\n", t->serial); 278dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project put_apacket(p); 279dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 280dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 281dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 282dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 283730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("%s: SYNC offline for transport\n", t->serial); 284dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p = get_apacket(); 285dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.command = A_SYNC; 286dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.arg0 = 0; 287dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.arg1 = 0; 288dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.magic = A_SYNC ^ 0xffffffff; 289730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner if(write_packet(t->fd, t->serial, &p)) { 290dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project put_apacket(p); 291730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("%s: failed to write SYNC apacket to transport", t->serial); 292dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 293dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 294dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectoops: 295730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("%s: transport output thread is exiting\n", t->serial); 296dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project kick_transport(t); 297dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project transport_unref(t); 298dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 299dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 300dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 301dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void *input_thread(void *_t) 302dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 303dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project atransport *t = _t; 304dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project apacket *p; 305dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int active = 0; 306dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 307730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("%s: starting transport input thread, reading from fd %d\n", 308730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner t->serial, t->fd); 309dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 310dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for(;;){ 311730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner if(read_packet(t->fd, t->serial, &p)) { 312730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("%s: failed to read apacket from transport on fd %d\n", 313730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner t->serial, t->fd ); 314dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 315dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 316dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(p->msg.command == A_SYNC){ 317dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(p->msg.arg0 == 0) { 318730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("%s: transport SYNC offline\n", t->serial); 319dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project put_apacket(p); 320dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 321dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 322dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(p->msg.arg1 == t->sync_token) { 323730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("%s: transport SYNC online\n", t->serial); 324dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project active = 1; 325dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 326730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("%s: transport ignoring SYNC %d != %d\n", 327730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner t->serial, p->msg.arg1, t->sync_token); 328dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 329dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 330dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 331dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(active) { 332730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("%s: transport got packet, sending to remote\n", t->serial); 333dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->write_to_remote(p, t); 334dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 335730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("%s: transport ignoring packet while offline\n", t->serial); 336dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 337dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 338dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 339dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project put_apacket(p); 340dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 341dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 342dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // this is necessary to avoid a race condition that occured when a transport closes 343dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // while a client socket is still active. 344dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project close_all_sockets(t); 345dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 346730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("%s: transport input thread is exiting, fd %d\n", t->serial, t->fd); 347dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project kick_transport(t); 348dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project transport_unref(t); 349dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 350dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 351dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 352dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 353dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int transport_registration_send = -1; 354dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int transport_registration_recv = -1; 355dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic fdevent transport_registration_fde; 356dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 357dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 358dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if ADB_HOST 359dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int list_transports_msg(char* buffer, size_t bufferlen) 360dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 361dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char head[5]; 362dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int len; 363dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 364dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len = list_transports(buffer+4, bufferlen-4); 365dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project snprintf(head, sizeof(head), "%04x", len); 366dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project memcpy(buffer, head, 4); 367dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len += 4; 368dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return len; 369dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 370dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 371dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* this adds support required by the 'track-devices' service. 372dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * this is used to send the content of "list_transport" to any 373dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * number of client connections that want it through a single 374dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * live TCP connection 375dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 376dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecttypedef struct device_tracker device_tracker; 377dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstruct device_tracker { 378dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project asocket socket; 379dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int update_needed; 380dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project device_tracker* next; 381dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}; 382dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 383dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* linked list of all device trackers */ 384dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic device_tracker* device_tracker_list; 385dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 386dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void 387dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectdevice_tracker_remove( device_tracker* tracker ) 388dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 389dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project device_tracker** pnode = &device_tracker_list; 390dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project device_tracker* node = *pnode; 391dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 392dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_lock( &transport_lock ); 393dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while (node) { 394dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (node == tracker) { 395dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *pnode = node->next; 396dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 397dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 398dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project pnode = &node->next; 399dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project node = *pnode; 400dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 401dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_unlock( &transport_lock ); 402dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 403dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 404dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void 405dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectdevice_tracker_close( asocket* socket ) 406dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 407dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project device_tracker* tracker = (device_tracker*) socket; 408dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project asocket* peer = socket->peer; 409dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 410dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D( "device tracker %p removed\n", tracker); 411dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (peer) { 412dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project peer->peer = NULL; 413dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project peer->close(peer); 414dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 415dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project device_tracker_remove(tracker); 416dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project free(tracker); 417dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 418dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 419dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int 420dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectdevice_tracker_enqueue( asocket* socket, apacket* p ) 421dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 422dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* you can't read from a device tracker, close immediately */ 423dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project put_apacket(p); 424dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project device_tracker_close(socket); 425dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 426dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 427dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 428dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int 429dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectdevice_tracker_send( device_tracker* tracker, 430dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project const char* buffer, 431dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int len ) 432dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 433dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project apacket* p = get_apacket(); 434dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project asocket* peer = tracker->socket.peer; 435dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 436dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project memcpy(p->data, buffer, len); 437dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->len = len; 438dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return peer->enqueue( peer, p ); 439dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 440dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 441dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 442dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void 443dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectdevice_tracker_ready( asocket* socket ) 444dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 445dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project device_tracker* tracker = (device_tracker*) socket; 446dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 447dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* we want to send the device list when the tracker connects 448dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * for the first time, even if no update occured */ 449dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (tracker->update_needed > 0) { 450dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char buffer[1024]; 451dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int len; 452dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 453dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project tracker->update_needed = 0; 454dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 455dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len = list_transports_msg(buffer, sizeof(buffer)); 456dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project device_tracker_send(tracker, buffer, len); 457dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 458dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 459dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 460dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 461dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectasocket* 462dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectcreate_device_tracker(void) 463dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 464dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project device_tracker* tracker = calloc(1,sizeof(*tracker)); 465dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 466dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(tracker == 0) fatal("cannot allocate device tracker"); 467dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 468dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D( "device tracker %p created\n", tracker); 469dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 470dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project tracker->socket.enqueue = device_tracker_enqueue; 471dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project tracker->socket.ready = device_tracker_ready; 472dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project tracker->socket.close = device_tracker_close; 473dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project tracker->update_needed = 1; 474dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 475dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project tracker->next = device_tracker_list; 476dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project device_tracker_list = tracker; 477dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 478dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return &tracker->socket; 479dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 480dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 481dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 482dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* call this function each time the transport list has changed */ 483dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid update_transports(void) 484dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 485dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char buffer[1024]; 486dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int len; 487dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project device_tracker* tracker; 488dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 489dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len = list_transports_msg(buffer, sizeof(buffer)); 490dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 491dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project tracker = device_tracker_list; 492dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while (tracker != NULL) { 493dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project device_tracker* next = tracker->next; 494dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* note: this may destroy the tracker if the connection is closed */ 495dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project device_tracker_send(tracker, buffer, len); 496dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project tracker = next; 497dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 498dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 499dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else 500dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid update_transports(void) 501dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 502dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // nothing to do on the device side 503dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 504dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif // ADB_HOST 505dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 506dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecttypedef struct tmsg tmsg; 507dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstruct tmsg 508dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 509dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project atransport *transport; 510dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int action; 511dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}; 512dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 513dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int 514dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecttransport_read_action(int fd, struct tmsg* m) 515dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 516dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *p = (char*)m; 517dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int len = sizeof(*m); 518dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int r; 519dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 520dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while(len > 0) { 521dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project r = adb_read(fd, p, len); 522dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(r > 0) { 523dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len -= r; 524dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p += r; 525dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 526dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if((r < 0) && (errno == EINTR)) continue; 527730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("transport_read_action: on fd %d, error %d: %s\n", 528dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fd, errno, strerror(errno)); 529dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 530dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 531dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 532dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 533dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 534dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 535dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int 536dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecttransport_write_action(int fd, struct tmsg* m) 537dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 538dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *p = (char*)m; 539dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int len = sizeof(*m); 540dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int r; 541dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 542dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while(len > 0) { 543dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project r = adb_write(fd, p, len); 544dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(r > 0) { 545dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len -= r; 546dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p += r; 547dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 548dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if((r < 0) && (errno == EINTR)) continue; 549730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("transport_write_action: on fd %d, error %d: %s\n", 550dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fd, errno, strerror(errno)); 551dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 552dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 553dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 554dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 555dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 556dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 557dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void transport_registration_func(int _fd, unsigned ev, void *data) 558dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 559dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project tmsg m; 560dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_thread_t output_thread_ptr; 561dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_thread_t input_thread_ptr; 562dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int s[2]; 563dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project atransport *t; 564dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 565dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(!(ev & FDE_READ)) { 566dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 567dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 568dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 569dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(transport_read_action(_fd, &m)) { 570dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fatal_errno("cannot read transport registration socket"); 571dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 572dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 573dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t = m.transport; 574dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 575dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(m.action == 0){ 576730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("transport: %s removing and free'ing %d\n", t->serial, t->transport_socket); 577dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 578dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* IMPORTANT: the remove closes one half of the 579dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ** socket pair. The close closes the other half. 580dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 581dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fdevent_remove(&(t->transport_fde)); 582dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_close(t->fd); 583dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 584dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_lock(&transport_lock); 585dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->next->prev = t->prev; 586dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->prev->next = t->next; 587dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_unlock(&transport_lock); 588dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 589dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project run_transport_disconnects(t); 590dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 591dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (t->product) 592dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project free(t->product); 593dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (t->serial) 594dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project free(t->serial); 595dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 596dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project memset(t,0xee,sizeof(atransport)); 597dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project free(t); 598dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 599dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project update_transports(); 600dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 601dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 602dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 6030927bf9690127bc45cf8837a1467759e9720399aMike Lockwood /* don't create transport threads for inaccessible devices */ 6040927bf9690127bc45cf8837a1467759e9720399aMike Lockwood if (t->connection_state != CS_NOPERM) { 605dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* initial references are the two threads */ 6060927bf9690127bc45cf8837a1467759e9720399aMike Lockwood t->ref_count = 2; 607dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 6080927bf9690127bc45cf8837a1467759e9720399aMike Lockwood if(adb_socketpair(s)) { 6090927bf9690127bc45cf8837a1467759e9720399aMike Lockwood fatal_errno("cannot open transport socketpair"); 6100927bf9690127bc45cf8837a1467759e9720399aMike Lockwood } 6110927bf9690127bc45cf8837a1467759e9720399aMike Lockwood 612730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("transport: %s (%d,%d) starting\n", t->serial, s[0], s[1]); 6130927bf9690127bc45cf8837a1467759e9720399aMike Lockwood 6140927bf9690127bc45cf8837a1467759e9720399aMike Lockwood t->transport_socket = s[0]; 6150927bf9690127bc45cf8837a1467759e9720399aMike Lockwood t->fd = s[1]; 616dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 6170927bf9690127bc45cf8837a1467759e9720399aMike Lockwood fdevent_install(&(t->transport_fde), 6180927bf9690127bc45cf8837a1467759e9720399aMike Lockwood t->transport_socket, 6190927bf9690127bc45cf8837a1467759e9720399aMike Lockwood transport_socket_events, 6200927bf9690127bc45cf8837a1467759e9720399aMike Lockwood t); 6210927bf9690127bc45cf8837a1467759e9720399aMike Lockwood 6220927bf9690127bc45cf8837a1467759e9720399aMike Lockwood fdevent_set(&(t->transport_fde), FDE_READ); 6230927bf9690127bc45cf8837a1467759e9720399aMike Lockwood 6240927bf9690127bc45cf8837a1467759e9720399aMike Lockwood if(adb_thread_create(&input_thread_ptr, input_thread, t)){ 6250927bf9690127bc45cf8837a1467759e9720399aMike Lockwood fatal_errno("cannot create input thread"); 6260927bf9690127bc45cf8837a1467759e9720399aMike Lockwood } 627dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 6280927bf9690127bc45cf8837a1467759e9720399aMike Lockwood if(adb_thread_create(&output_thread_ptr, output_thread, t)){ 6290927bf9690127bc45cf8837a1467759e9720399aMike Lockwood fatal_errno("cannot create output thread"); 6300927bf9690127bc45cf8837a1467759e9720399aMike Lockwood } 6310927bf9690127bc45cf8837a1467759e9720399aMike Lockwood } 632dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 633dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* put us on the master device list */ 634dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_lock(&transport_lock); 635dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->next = &transport_list; 636dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->prev = transport_list.prev; 637dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->next->prev = t; 638dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->prev->next = t; 639dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_unlock(&transport_lock); 640dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 641dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->disconnects.next = t->disconnects.prev = &t->disconnects; 642dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 643dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project update_transports(); 644dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 645dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 646dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid init_transport_registration(void) 647dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 648dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int s[2]; 649dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 650dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(adb_socketpair(s)){ 651dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fatal_errno("cannot open transport registration socketpair"); 652dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 653dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 654dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project transport_registration_send = s[0]; 655dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project transport_registration_recv = s[1]; 656dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 657dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fdevent_install(&transport_registration_fde, 658dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project transport_registration_recv, 659dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project transport_registration_func, 660dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 0); 661dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 662dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fdevent_set(&transport_registration_fde, FDE_READ); 663dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 664dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 665dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* the fdevent select pump is single threaded */ 666dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void register_transport(atransport *transport) 667dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 668dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project tmsg m; 669dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project m.transport = transport; 670dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project m.action = 1; 671730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("transport: %s registered\n", transport->serial); 672dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(transport_write_action(transport_registration_send, &m)) { 673dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fatal_errno("cannot write transport registration socket\n"); 674dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 675dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 676dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 677dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void remove_transport(atransport *transport) 678dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 679dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project tmsg m; 680dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project m.transport = transport; 681dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project m.action = 0; 682730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("transport: %s removed\n", transport->serial); 683dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(transport_write_action(transport_registration_send, &m)) { 684dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fatal_errno("cannot write transport registration socket\n"); 685dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 686dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 687dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 688dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 689cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwoodstatic void transport_unref_locked(atransport *t) 690cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood{ 691cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood t->ref_count--; 692cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood if (t->ref_count == 0) { 693730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("transport: %s unref (kicking and closing)\n", t->serial); 694cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood if (!t->kicked) { 695cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood t->kicked = 1; 696cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood t->kick(t); 697cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood } 698cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood t->close(t); 699cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood remove_transport(t); 700730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner } else { 701730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("transport: %s unref (count=%d)\n", t->serial, t->ref_count); 702cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood } 703cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood} 704cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood 705dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void transport_unref(atransport *t) 706dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 707dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (t) { 708dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_lock(&transport_lock); 709cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood transport_unref_locked(t); 710dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_unlock(&transport_lock); 711dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 712dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 713dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 714dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid add_transport_disconnect(atransport* t, adisconnect* dis) 715dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 716dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_lock(&transport_lock); 717dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dis->next = &t->disconnects; 718dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dis->prev = dis->next->prev; 719dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dis->prev->next = dis; 720dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dis->next->prev = dis; 721dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_unlock(&transport_lock); 722dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 723dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 724dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid remove_transport_disconnect(atransport* t, adisconnect* dis) 725dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 726dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dis->prev->next = dis->next; 727dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dis->next->prev = dis->prev; 728dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dis->next = dis->prev = dis; 729dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 730dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 731dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 732dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectatransport *acquire_one_transport(int state, transport_type ttype, const char* serial, char** error_out) 733dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 734dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project atransport *t; 735dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project atransport *result = NULL; 736dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int ambiguous = 0; 737dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 738dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectretry: 739dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (error_out) 740dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *error_out = "device not found"; 741dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 742dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_lock(&transport_lock); 743dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (t = transport_list.next; t != &transport_list; t = t->next) { 74437d3111b1c1ce61c3d9b10ed3ccaed9e5fad1e06Mike Lockwood if (t->connection_state == CS_NOPERM) { 74537d3111b1c1ce61c3d9b10ed3ccaed9e5fad1e06Mike Lockwood if (error_out) 74637d3111b1c1ce61c3d9b10ed3ccaed9e5fad1e06Mike Lockwood *error_out = "insufficient permissions for device"; 74737d3111b1c1ce61c3d9b10ed3ccaed9e5fad1e06Mike Lockwood continue; 74837d3111b1c1ce61c3d9b10ed3ccaed9e5fad1e06Mike Lockwood } 7490927bf9690127bc45cf8837a1467759e9720399aMike Lockwood 750dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* check for matching serial number */ 751dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (serial) { 752dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (t->serial && !strcmp(serial, t->serial)) { 753dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project result = t; 754dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 755dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 756dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 757dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (ttype == kTransportUsb && t->type == kTransportUsb) { 758dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (result) { 759dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (error_out) 760dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *error_out = "more than one device"; 761dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ambiguous = 1; 762dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project result = NULL; 763dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 764dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 765dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project result = t; 766dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (ttype == kTransportLocal && t->type == kTransportLocal) { 767dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (result) { 768dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (error_out) 769dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *error_out = "more than one emulator"; 770dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ambiguous = 1; 771dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project result = NULL; 772dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 773dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 774dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project result = t; 775dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (ttype == kTransportAny) { 776dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (result) { 777dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (error_out) 778dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *error_out = "more than one device and emulator"; 779dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ambiguous = 1; 780dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project result = NULL; 781dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 782dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 783dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project result = t; 784dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 785dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 786dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 787dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_unlock(&transport_lock); 788dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 789dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (result) { 790dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* offline devices are ignored -- they are either being born or dying */ 791dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (result && result->connection_state == CS_OFFLINE) { 792dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (error_out) 793dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *error_out = "device offline"; 794dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project result = NULL; 795dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 796dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* check for required connection state */ 797dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (result && state != CS_ANY && result->connection_state != state) { 798dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (error_out) 799dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *error_out = "invalid device state"; 800dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project result = NULL; 801dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 802dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 803dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 804dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (result) { 805dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* found one that we can take */ 806dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (error_out) 807dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *error_out = NULL; 808dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (state != CS_ANY && (serial || !ambiguous)) { 809dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_sleep_ms(1000); 810dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto retry; 811dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 812dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 813dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return result; 814dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 815dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 816dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if ADB_HOST 817dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic const char *statename(atransport *t) 818dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 819dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project switch(t->connection_state){ 820dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case CS_OFFLINE: return "offline"; 821dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case CS_BOOTLOADER: return "bootloader"; 822dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case CS_DEVICE: return "device"; 823dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case CS_HOST: return "host"; 824dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case CS_RECOVERY: return "recovery"; 8250927bf9690127bc45cf8837a1467759e9720399aMike Lockwood case CS_NOPERM: return "no permissions"; 826dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project default: return "unknown"; 827dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 828dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 829dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 830dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint list_transports(char *buf, size_t bufsize) 831dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 832dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char* p = buf; 833dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char* end = buf + bufsize; 834dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int len; 835dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project atransport *t; 836dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 837dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* XXX OVERRUN PROBLEMS XXX */ 838dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_lock(&transport_lock); 839dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for(t = transport_list.next; t != &transport_list; t = t->next) { 8400927bf9690127bc45cf8837a1467759e9720399aMike Lockwood const char* serial = t->serial; 8410927bf9690127bc45cf8837a1467759e9720399aMike Lockwood if (!serial || !serial[0]) 8420927bf9690127bc45cf8837a1467759e9720399aMike Lockwood serial = "????????????"; 8430927bf9690127bc45cf8837a1467759e9720399aMike Lockwood len = snprintf(p, end - p, "%s\t%s\n", serial, statename(t)); 844dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 845dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (p + len >= end) { 846dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* discard last line if buffer is too short */ 847dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 848dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 849dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p += len; 850dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 851dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p[0] = 0; 852dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_unlock(&transport_lock); 853dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return p - buf; 854dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 855dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 856dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 857dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* hack for osx */ 858dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid close_usb_devices() 859dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 860dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project atransport *t; 861dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 862dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_lock(&transport_lock); 863dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for(t = transport_list.next; t != &transport_list; t = t->next) { 864dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if ( !t->kicked ) { 865dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->kicked = 1; 866dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->kick(t); 867dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 868dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 869dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_unlock(&transport_lock); 870dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 871dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif // ADB_HOST 872dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 873ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwoodvoid register_socket_transport(int s, const char *serial, int port, int local) 874dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 875dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project atransport *t = calloc(1, sizeof(atransport)); 876730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner char buff[32]; 877730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner 878730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner if (!serial) { 879730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner snprintf(buff, sizeof buff, "T-%p", t); 880730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner serial = buff; 881730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner } 882730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("transport: %s init'ing for socket %d, on port %d\n", serial, s, port); 883ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood if ( init_socket_transport(t, s, port, local) < 0 ) { 884dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_close(s); 885dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project free(t); 886dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 887dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 888dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(serial) { 889dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->serial = strdup(serial); 890dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 891dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project register_transport(t); 892dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 893dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 8948cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood#if ADB_HOST 8958cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwoodatransport *find_transport(const char *serial) 8968cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood{ 8978cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood atransport *t; 8988cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood 8998cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood adb_mutex_lock(&transport_lock); 9008cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood for(t = transport_list.next; t != &transport_list; t = t->next) { 9018cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood if (t->serial && !strcmp(serial, t->serial)) { 9028cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood break; 9038cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood } 9048cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood } 9058cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood adb_mutex_unlock(&transport_lock); 9068cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood 9078cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood if (t != &transport_list) 9088cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood return t; 9098cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood else 9108cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood return 0; 9118cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood} 9128cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood 9138cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwoodvoid unregister_transport(atransport *t) 9148cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood{ 9158cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood adb_mutex_lock(&transport_lock); 9168cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood t->next->prev = t->prev; 9178cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood t->prev->next = t->next; 9188cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood adb_mutex_unlock(&transport_lock); 9198cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood 9208cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood kick_transport(t); 9218cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood transport_unref(t); 9228cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood} 9238cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood 924cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood// unregisters all non-emulator TCP transports 925cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwoodvoid unregister_all_tcp_transports() 926cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood{ 927cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood atransport *t, *next; 928cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood adb_mutex_lock(&transport_lock); 929cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood for (t = transport_list.next; t != &transport_list; t = next) { 930cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood next = t->next; 931cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood if (t->type == kTransportLocal && t->adb_port == 0) { 932cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood t->next->prev = t->prev; 933cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood t->prev->next = next; 934cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood // we cannot call kick_transport when holding transport_lock 935cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood if (!t->kicked) 936cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood { 937cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood t->kicked = 1; 938cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood t->kick(t); 939cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood } 940cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood transport_unref_locked(t); 941cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood } 942cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood } 943cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood 944cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood adb_mutex_unlock(&transport_lock); 945cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood} 946cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood 9478cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood#endif 9488cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood 9490927bf9690127bc45cf8837a1467759e9720399aMike Lockwoodvoid register_usb_transport(usb_handle *usb, const char *serial, unsigned writeable) 950dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 951dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project atransport *t = calloc(1, sizeof(atransport)); 952dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("transport: %p init'ing for usb_handle %p (sn='%s')\n", t, usb, 953dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project serial ? serial : ""); 9540927bf9690127bc45cf8837a1467759e9720399aMike Lockwood init_usb_transport(t, usb, (writeable ? CS_OFFLINE : CS_NOPERM)); 955dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(serial) { 956dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project t->serial = strdup(serial); 957dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 958dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project register_transport(t); 959dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 960dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 9610927bf9690127bc45cf8837a1467759e9720399aMike Lockwood/* this should only be used for transports with connection_state == CS_NOPERM */ 9620927bf9690127bc45cf8837a1467759e9720399aMike Lockwoodvoid unregister_usb_transport(usb_handle *usb) 9630927bf9690127bc45cf8837a1467759e9720399aMike Lockwood{ 9640927bf9690127bc45cf8837a1467759e9720399aMike Lockwood atransport *t; 9650927bf9690127bc45cf8837a1467759e9720399aMike Lockwood adb_mutex_lock(&transport_lock); 9660927bf9690127bc45cf8837a1467759e9720399aMike Lockwood for(t = transport_list.next; t != &transport_list; t = t->next) { 9670927bf9690127bc45cf8837a1467759e9720399aMike Lockwood if (t->usb == usb && t->connection_state == CS_NOPERM) { 9680927bf9690127bc45cf8837a1467759e9720399aMike Lockwood t->next->prev = t->prev; 9690927bf9690127bc45cf8837a1467759e9720399aMike Lockwood t->prev->next = t->next; 9700927bf9690127bc45cf8837a1467759e9720399aMike Lockwood break; 9710927bf9690127bc45cf8837a1467759e9720399aMike Lockwood } 9720927bf9690127bc45cf8837a1467759e9720399aMike Lockwood } 9730927bf9690127bc45cf8837a1467759e9720399aMike Lockwood adb_mutex_unlock(&transport_lock); 9740927bf9690127bc45cf8837a1467759e9720399aMike Lockwood} 975dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 976dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#undef TRACE_TAG 977dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define TRACE_TAG TRACE_RWX 978dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 979dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint readx(int fd, void *ptr, size_t len) 980dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 981dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *p = ptr; 982dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int r; 983dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if ADB_TRACE 984dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int len0 = len; 985dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 986730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("readx: fd=%d wanted=%d\n", fd, (int)len); 987dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while(len > 0) { 988dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project r = adb_read(fd, p, len); 989dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(r > 0) { 990dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len -= r; 991dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p += r; 992dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 993730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner if (r < 0) { 994730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("readx: fd=%d error %d: %s\n", fd, errno, strerror(errno)); 995730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner if (errno == EINTR) 996730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner continue; 997730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner } else { 998730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("readx: fd=%d disconnected\n", fd); 999730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner } 1000dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 1001dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1002dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1003dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1004dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if ADB_TRACE 1005730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("readx: fd=%d wanted=%d got=%d\n", fd, len0, len0 - len); 1006dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dump_hex( ptr, len0 ); 1007dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 1008dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 1009dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 1010dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1011dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint writex(int fd, const void *ptr, size_t len) 1012dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 1013dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *p = (char*) ptr; 1014dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int r; 1015dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1016dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if ADB_TRACE 1017730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("writex: fd=%d len=%d: ", fd, (int)len); 1018dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dump_hex( ptr, len ); 1019dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 1020dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while(len > 0) { 1021dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project r = adb_write(fd, p, len); 1022dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(r > 0) { 1023dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len -= r; 1024dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p += r; 1025dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 1026730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner if (r < 0) { 1027730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("writex: fd=%d error %d: %s\n", fd, errno, strerror(errno)); 1028730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner if (errno == EINTR) 1029730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner continue; 1030730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner } else { 1031730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner D("writex: fd=%d disconnected\n", fd); 1032730ff3b786058dadde98743522d760bd9331a9ddDavid 'Digit' Turner } 1033dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 1034dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1035dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1036dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 1037dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 1038dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1039dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint check_header(apacket *p) 1040dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 1041dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(p->msg.magic != (p->msg.command ^ 0xffffffff)) { 1042dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("check_header(): invalid magic\n"); 1043dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 1044dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1045dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1046dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(p->msg.data_length > MAX_PAYLOAD) { 1047dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("check_header(): %d > MAX_PAYLOAD\n", p->msg.data_length); 1048dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 1049dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1050dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1051dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 1052dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 1053dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1054dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint check_data(apacket *p) 1055dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 1056dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned count, sum; 1057dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned char *x; 1058dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1059dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project count = p->msg.data_length; 1060dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project x = p->data; 1061dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sum = 0; 1062dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while(count-- > 0) { 1063dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sum += *x++; 1064dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1065dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1066dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(sum != p->msg.data_check) { 1067dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 1068dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 1069dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 1070dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1071dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 10720e7c4274c687446dbe30a814278d7a6b99da8c4eJP Abgrall 1073