sockets.c revision 5b811fa5dd00288954f15209a56aea03d5e4a004
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 <errno.h> 21dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <string.h> 22dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <ctype.h> 23dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 24dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "sysdeps.h" 25dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 26dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define TRACE_TAG TRACE_SOCKETS 27dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "adb.h" 28dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 29dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectADB_MUTEX_DEFINE( socket_list_lock ); 30dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 31dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void local_socket_close_locked(asocket *s); 32dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 33dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint sendfailmsg(int fd, const char *reason) 34dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 35dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char buf[9]; 36dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int len; 37dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len = strlen(reason); 38dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(len > 0xffff) len = 0xffff; 39dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project snprintf(buf, sizeof buf, "FAIL%04x", len); 40dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(writex(fd, buf, 8)) return -1; 41dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return writex(fd, reason, len); 42dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 43dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 44dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project//extern int online; 45dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 46dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic unsigned local_socket_next_id = 1; 47dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 48dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic asocket local_socket_list = { 49dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project .next = &local_socket_list, 50dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project .prev = &local_socket_list, 51dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}; 52dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 53dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* the the list of currently closing local sockets. 54dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** these have no peer anymore, but still packets to 55dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** write to their fd. 56dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project*/ 57dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic asocket local_socket_closing_list = { 58dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project .next = &local_socket_closing_list, 59dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project .prev = &local_socket_closing_list, 60dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}; 61dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 62dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectasocket *find_local_socket(unsigned id) 63dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 64dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project asocket *s; 65dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project asocket *result = NULL; 66dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 67dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_lock(&socket_list_lock); 688182829ccb46fc5b043ea258672602dc2928dee2André Goddard Rosa for (s = local_socket_list.next; s != &local_socket_list; s = s->next) { 698182829ccb46fc5b043ea258672602dc2928dee2André Goddard Rosa if (s->id == id) { 708182829ccb46fc5b043ea258672602dc2928dee2André Goddard Rosa result = s; 718182829ccb46fc5b043ea258672602dc2928dee2André Goddard Rosa break; 728182829ccb46fc5b043ea258672602dc2928dee2André Goddard Rosa } 73dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 74dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_unlock(&socket_list_lock); 75dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 76dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return result; 77dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 78dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 79dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void 80dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinsert_local_socket(asocket* s, asocket* list) 81dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 82dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->next = list; 83dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->prev = s->next->prev; 84dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->prev->next = s; 85dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->next->prev = s; 86dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 87dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 88dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 89dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid install_local_socket(asocket *s) 90dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 91dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_lock(&socket_list_lock); 92dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 93dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->id = local_socket_next_id++; 94dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project insert_local_socket(s, &local_socket_list); 95dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 96dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_unlock(&socket_list_lock); 97dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 98dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 99dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid remove_socket(asocket *s) 100dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 101dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // socket_list_lock should already be held 102dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (s->prev && s->next) 103dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project { 104dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->prev->next = s->next; 105dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->next->prev = s->prev; 106dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->next = 0; 107dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->prev = 0; 108dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->id = 0; 109dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 110dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 111dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 112dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid close_all_sockets(atransport *t) 113dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 114dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project asocket *s; 115dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 116dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* this is a little gross, but since s->close() *will* modify 117dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ** the list out from under you, your options are limited. 118dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 119dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_lock(&socket_list_lock); 120dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectrestart: 121dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for(s = local_socket_list.next; s != &local_socket_list; s = s->next){ 122dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(s->transport == t || (s->peer && s->peer->transport == t)) { 123dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project local_socket_close_locked(s); 124dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto restart; 125dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 126dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 127dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_unlock(&socket_list_lock); 128dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 129dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 130dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int local_socket_enqueue(asocket *s, apacket *p) 131dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 132dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("LS(%d): enqueue %d\n", s->id, p->len); 133dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 134dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->ptr = p->data; 135dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 136dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* if there is already data queue'd, we will receive 137dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ** events when it's time to write. just add this to 138dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ** the tail 139dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 140dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(s->pkt_first) { 141dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto enqueue; 142dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 143dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 144dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* write as much as we can, until we 145dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ** would block or there is an error/eof 146dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 147dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while(p->len > 0) { 148dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int r = adb_write(s->fd, p->ptr, p->len); 149dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(r > 0) { 150dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->len -= r; 151dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->ptr += r; 152dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project continue; 153dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 154dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if((r == 0) || (errno != EAGAIN)) { 155dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D( "LS(%d): not ready, errno=%d: %s\n", s->id, errno, strerror(errno) ); 156dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->close(s); 157dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 1; /* not ready (error) */ 158dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 159dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 160dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 161dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 162dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 163dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(p->len == 0) { 164dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project put_apacket(p); 165dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; /* ready for more data */ 166dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 167dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 168dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectenqueue: 169dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->next = 0; 170dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(s->pkt_first) { 171dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->pkt_last->next = p; 172dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 173dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->pkt_first = p; 174dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 175dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->pkt_last = p; 176dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 177dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* make sure we are notified when we can drain the queue */ 178dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fdevent_add(&s->fde, FDE_WRITE); 179dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 180dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 1; /* not ready (backlog) */ 181dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 182dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 183dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void local_socket_ready(asocket *s) 184dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 185dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* far side is ready for data, pay attention to 186dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project readable events */ 187dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fdevent_add(&s->fde, FDE_READ); 188dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// D("LS(%d): ready()\n", s->id); 189dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 190dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 191dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void local_socket_close(asocket *s) 192dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 193d15e6ac95dc898fb78fb5917bb2e4498b40b716fMike Lockwood#if ADB_HOST 194d15e6ac95dc898fb78fb5917bb2e4498b40b716fMike Lockwood /* to special case commands that cause the remote daemon to terminate */ 195d15e6ac95dc898fb78fb5917bb2e4498b40b716fMike Lockwood if (s->kick_on_close && s->transport) { 196d15e6ac95dc898fb78fb5917bb2e4498b40b716fMike Lockwood kick_transport(s->transport); 197d15e6ac95dc898fb78fb5917bb2e4498b40b716fMike Lockwood /* delay to work around a race condition */ 198b0a8aae3eda5e245b93cb6d3af286202dc8c011cKenny Root adb_sleep_ms(1000); 199d15e6ac95dc898fb78fb5917bb2e4498b40b716fMike Lockwood } 200d15e6ac95dc898fb78fb5917bb2e4498b40b716fMike Lockwood#endif 201dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_lock(&socket_list_lock); 202dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project local_socket_close_locked(s); 203dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_unlock(&socket_list_lock); 204dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 205dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 206dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// be sure to hold the socket list lock when calling this 207dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void local_socket_destroy(asocket *s) 208dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 209dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project apacket *p, *n; 210408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall D("LS(%d): destroying fde.fd=%d\n", s->id, s->fde.fd); 211dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 212dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* IMPORTANT: the remove closes the fd 213dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ** that belongs to this socket 214dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 215dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fdevent_remove(&s->fde); 216dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 217dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* dispose of any unwritten data */ 218dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for(p = s->pkt_first; p; p = n) { 219dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("LS(%d): discarding %d bytes\n", s->id, p->len); 220dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project n = p->next; 221dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project put_apacket(p); 222dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 223dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project remove_socket(s); 224dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project free(s); 225dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 226dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 227dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 228dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void local_socket_close_locked(asocket *s) 229dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 230408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall D("entered. LS(%d) fd=%d\n", s->id, s->fd); 231dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(s->peer) { 232408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall D("LS(%d): closing peer. peer->id=%d peer->fd=%d\n", 233408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall s->id, s->peer->id, s->peer->fd); 234dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->peer->peer = 0; 235dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // tweak to avoid deadlock 23649f1857dd8b64cdd57f28e965a1ff5fa0c2b0547Tom Marlin if (s->peer->close == local_socket_close) { 237dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project local_socket_close_locked(s->peer); 23849f1857dd8b64cdd57f28e965a1ff5fa0c2b0547Tom Marlin } else { 239dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->peer->close(s->peer); 24049f1857dd8b64cdd57f28e965a1ff5fa0c2b0547Tom Marlin } 24149f1857dd8b64cdd57f28e965a1ff5fa0c2b0547Tom Marlin s->peer = 0; 242dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 243dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 244dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* If we are already closing, or if there are no 245dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ** pending packets, destroy immediately 246dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 247dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (s->closing || s->pkt_first == NULL) { 248dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int id = s->id; 249dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project local_socket_destroy(s); 250dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("LS(%d): closed\n", id); 251dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 252dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 253dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 254dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* otherwise, put on the closing list 255dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 256dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("LS(%d): closing\n", s->id); 257dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->closing = 1; 258dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fdevent_del(&s->fde, FDE_READ); 259dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project remove_socket(s); 260408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall D("LS(%d): put on socket_closing_list fd=%d\n", s->id, s->fd); 261dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project insert_local_socket(s, &local_socket_closing_list); 262dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 263dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 264dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void local_socket_event_func(int fd, unsigned ev, void *_s) 265dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 266dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project asocket *s = _s; 267dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 268408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall D("LS(%d): event_func(fd=%d(==%d), ev=%04x)\n", s->id, s->fd, fd, ev); 269408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall 270dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* put the FDE_WRITE processing before the FDE_READ 271dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ** in order to simplify the code. 272dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 273dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(ev & FDE_WRITE){ 274dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project apacket *p; 275dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 276dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while((p = s->pkt_first) != 0) { 277dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while(p->len > 0) { 278dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int r = adb_write(fd, p->ptr, p->len); 279dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(r > 0) { 280dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->ptr += r; 281dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->len -= r; 282dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project continue; 283dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 284dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(r < 0) { 285dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* returning here is ok because FDE_READ will 286dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ** be processed in the next iteration loop 287dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 288dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(errno == EAGAIN) return; 289dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(errno == EINTR) continue; 290dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 2915b811fa5dd00288954f15209a56aea03d5e4a004Christopher Tate D(" closing after write because r=%d and errno is %d\n", r, errno); 292dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->close(s); 293dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 294dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 295dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 296dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(p->len == 0) { 297dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->pkt_first = p->next; 298dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(s->pkt_first == 0) s->pkt_last = 0; 299dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project put_apacket(p); 300dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 301dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 302dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 303dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* if we sent the last packet of a closing socket, 304dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ** we can now destroy it. 305dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 306dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (s->closing) { 3075b811fa5dd00288954f15209a56aea03d5e4a004Christopher Tate D(" closing because 'closing' is set after write\n"); 308dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->close(s); 309dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 310dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 311dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 312dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* no more packets queued, so we can ignore 313dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ** writable events again and tell our peer 314dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ** to resume writing 315dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 316dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fdevent_del(&s->fde, FDE_WRITE); 317dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->peer->ready(s->peer); 318dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 319dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 320dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 321dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(ev & FDE_READ){ 322dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project apacket *p = get_apacket(); 323dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned char *x = p->data; 324dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project size_t avail = MAX_PAYLOAD; 325dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int r; 326dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int is_eof = 0; 327dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 328dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while(avail > 0) { 329dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project r = adb_read(fd, x, avail); 330408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall D("LS(%d): post adb_read(fd=%d,...) r=%d (errno=%d) avail=%d\n", s->id, s->fd, r, r<0?errno:0, avail); 331dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(r > 0) { 332dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project avail -= r; 333dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project x += r; 334dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project continue; 335dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 336dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(r < 0) { 337dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(errno == EAGAIN) break; 338dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(errno == EINTR) continue; 339dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 340dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 341dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* r = 0 or unhandled error */ 342dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project is_eof = 1; 343dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 344dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 345408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall D("LS(%d): fd=%d post avail loop. r=%d is_eof=%d forced_eof=%d\n", 346408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall s->id, s->fd, r, is_eof, s->fde.force_eof); 347dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if((avail == MAX_PAYLOAD) || (s->peer == 0)) { 348dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project put_apacket(p); 349dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 350dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->len = MAX_PAYLOAD - avail; 351dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 352dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project r = s->peer->enqueue(s->peer, p); 353408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall D("LS(%d): fd=%d post peer->enqueue(). r=%d\n", s->id, s->fd, r); 354dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 355dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(r < 0) { 356dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* error return means they closed us as a side-effect 357dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ** and we must return immediately. 358dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ** 359dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ** note that if we still have buffered packets, the 360dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ** socket will be placed on the closing socket list. 361dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ** this handler function will be called again 362dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ** to process FDE_WRITE events. 363dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 364dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 365dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 366dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 367dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(r > 0) { 368dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* if the remote cannot accept further events, 369dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ** we disable notification of READs. They'll 370dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ** be enabled again when we get a call to ready() 371dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 372dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fdevent_del(&s->fde, FDE_READ); 373dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 374dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 375112445b8a752ce174f36cf853d5f1c356c3f5286JP Abgrall /* Don't allow a forced eof if data is still there */ 376112445b8a752ce174f36cf853d5f1c356c3f5286JP Abgrall if((s->fde.force_eof && !r) || is_eof) { 3775b811fa5dd00288954f15209a56aea03d5e4a004Christopher Tate D(" closing because is_eof=%d r=%d s->fde.force_eof=%d\n", is_eof, r, s->fde.force_eof); 378dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->close(s); 379dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 380dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 381dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 382dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(ev & FDE_ERROR){ 383dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* this should be caught be the next read or write 384dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ** catching it here means we may skip the last few 385dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ** bytes of readable data. 386dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 387dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// s->close(s); 388408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall D("LS(%d): FDE_ERROR (fd=%d)\n", s->id, s->fd); 389408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall 390dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 391dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 392dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 393dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 394dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectasocket *create_local_socket(int fd) 395dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 396dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project asocket *s = calloc(1, sizeof(asocket)); 397c419e2a210ad7e37a1f749f2ab4de7c7f95b90d7André Goddard Rosa if (s == NULL) fatal("cannot allocate socket"); 398dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->fd = fd; 399dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->enqueue = local_socket_enqueue; 400dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->ready = local_socket_ready; 401dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->close = local_socket_close; 402408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall install_local_socket(s); 403dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 404dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fdevent_install(&s->fde, fd, local_socket_event_func, s); 405dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* fdevent_add(&s->fde, FDE_ERROR); */ 406dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project //fprintf(stderr, "Created local socket in create_local_socket \n"); 407dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("LS(%d): created (fd=%d)\n", s->id, s->fd); 408dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return s; 409dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 410dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 411dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectasocket *create_local_service_socket(const char *name) 412dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 413dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project asocket *s; 414dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int fd; 415dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 416dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if !ADB_HOST 417dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!strcmp(name,"jdwp")) { 418dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return create_jdwp_service_socket(); 419dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 420dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!strcmp(name,"track-jdwp")) { 421dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return create_jdwp_tracker_service_socket(); 422dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 423dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 424dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fd = service_to_fd(name); 425dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(fd < 0) return 0; 426dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 427dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s = create_local_socket(fd); 428408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall D("LS(%d): bound to '%s' via %d\n", s->id, name, fd); 429dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return s; 430dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 431dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 432dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if ADB_HOST 433dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic asocket *create_host_service_socket(const char *name, const char* serial) 434dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 435dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project asocket *s; 436dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 437dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s = host_service_to_socket(name, serial); 438dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 439dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (s != NULL) { 440dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("LS(%d) bound to '%s'\n", s->id, name); 441dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return s; 442dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 443dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 444dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return s; 445dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 446dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif /* ADB_HOST */ 447dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 448dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* a Remote socket is used to send/receive data to/from a given transport object 449dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** it needs to be closed when the transport is forcibly destroyed by the user 450dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project*/ 451dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecttypedef struct aremotesocket { 452dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project asocket socket; 453dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adisconnect disconnect; 454dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} aremotesocket; 455dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 456dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int remote_socket_enqueue(asocket *s, apacket *p) 457dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 458408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall D("entered remote_socket_enqueue RS(%d) WRITE fd=%d peer.fd=%d\n", 459408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall s->id, s->fd, s->peer->fd); 460dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.command = A_WRTE; 461dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.arg0 = s->peer->id; 462dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.arg1 = s->id; 463dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.data_length = p->len; 464dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project send_packet(p, s->transport); 465dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 1; 466dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 467dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 468dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void remote_socket_ready(asocket *s) 469dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 470408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall D("entered remote_socket_ready RS(%d) OKAY fd=%d peer.fd=%d\n", 471408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall s->id, s->fd, s->peer->fd); 472dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project apacket *p = get_apacket(); 473dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.command = A_OKAY; 474dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.arg0 = s->peer->id; 475dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.arg1 = s->id; 476dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project send_packet(p, s->transport); 477dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 478dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 479dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void remote_socket_close(asocket *s) 480dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 481408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall D("entered remote_socket_close RS(%d) CLOSE fd=%d peer->fd=%d\n", 482408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall s->id, s->fd, s->peer?s->peer->fd:-1); 483dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project apacket *p = get_apacket(); 484dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.command = A_CLSE; 485dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(s->peer) { 486dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.arg0 = s->peer->id; 487dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->peer->peer = 0; 488408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall D("RS(%d) peer->close()ing peer->id=%d peer->fd=%d\n", 489408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall s->id, s->peer->id, s->peer->fd); 490dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->peer->close(s->peer); 491dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 492dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.arg1 = s->id; 493dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project send_packet(p, s->transport); 494dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("RS(%d): closed\n", s->id); 495dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project remove_transport_disconnect( s->transport, &((aremotesocket*)s)->disconnect ); 496dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project free(s); 497dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 498dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 499dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void remote_socket_disconnect(void* _s, atransport* t) 500dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 501dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project asocket* s = _s; 502dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project asocket* peer = s->peer; 503dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 504dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("remote_socket_disconnect RS(%d)\n", s->id); 505dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (peer) { 506dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project peer->peer = NULL; 507dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project peer->close(peer); 508dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 509dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project remove_transport_disconnect( s->transport, &((aremotesocket*)s)->disconnect ); 510dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project free(s); 511dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 512dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 513dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectasocket *create_remote_socket(unsigned id, atransport *t) 514dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 515dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project asocket *s = calloc(1, sizeof(aremotesocket)); 516dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adisconnect* dis = &((aremotesocket*)s)->disconnect; 517dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 518c419e2a210ad7e37a1f749f2ab4de7c7f95b90d7André Goddard Rosa if (s == NULL) fatal("cannot allocate socket"); 519dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->id = id; 520dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->enqueue = remote_socket_enqueue; 521dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->ready = remote_socket_ready; 522dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->close = remote_socket_close; 523dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->transport = t; 524dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 525dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dis->func = remote_socket_disconnect; 526dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dis->opaque = s; 527dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project add_transport_disconnect( t, dis ); 528dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("RS(%d): created\n", s->id); 529dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return s; 530dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 531dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 532dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid connect_to_remote(asocket *s, const char *destination) 533dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 534408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall D("Connect_to_remote call RS(%d) fd=%d\n", s->id, s->fd); 535dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project apacket *p = get_apacket(); 536dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int len = strlen(destination) + 1; 537dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 538d15e6ac95dc898fb78fb5917bb2e4498b40b716fMike Lockwood#if ADB_HOST 539d15e6ac95dc898fb78fb5917bb2e4498b40b716fMike Lockwood /* special case commands that cause the remote daemon to terminate */ 540d15e6ac95dc898fb78fb5917bb2e4498b40b716fMike Lockwood if (!strcmp(destination, "root:")) { 541d15e6ac95dc898fb78fb5917bb2e4498b40b716fMike Lockwood D("connect_to_remote setting kick_on_close for %s\n", destination); 542d15e6ac95dc898fb78fb5917bb2e4498b40b716fMike Lockwood s->kick_on_close = 1; 543d15e6ac95dc898fb78fb5917bb2e4498b40b716fMike Lockwood } 544d15e6ac95dc898fb78fb5917bb2e4498b40b716fMike Lockwood#endif 545d15e6ac95dc898fb78fb5917bb2e4498b40b716fMike Lockwood 546dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(len > (MAX_PAYLOAD-1)) { 547dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fatal("destination oversized"); 548dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 549dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 550dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("LS(%d): connect('%s')\n", s->id, destination); 551dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.command = A_OPEN; 552dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.arg0 = s->id; 553dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.data_length = len; 554dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project strcpy((char*) p->data, destination); 555dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project send_packet(p, s->transport); 556dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 557dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 558dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 559dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* this is used by magic sockets to rig local sockets to 560dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project send the go-ahead message when they connect */ 561dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void local_socket_ready_notify(asocket *s) 562dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 563dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->ready = local_socket_ready; 564dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->close = local_socket_close; 565dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_write(s->fd, "OKAY", 4); 566dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->ready(s); 567dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 568dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 569dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* this is used by magic sockets to rig local sockets to 570dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project send the failure message if they are closed before 571dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project connected (to avoid closing them without a status message) */ 572dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void local_socket_close_notify(asocket *s) 573dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 574dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->ready = local_socket_ready; 575dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->close = local_socket_close; 576dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sendfailmsg(s->fd, "closed"); 577dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->close(s); 578dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 579dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 580dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectunsigned unhex(unsigned char *s, int len) 581dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 582dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned n = 0, c; 583dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 584dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while(len-- > 0) { 585dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project switch((c = *s++)) { 586dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case '0': case '1': case '2': 587dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case '3': case '4': case '5': 588dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case '6': case '7': case '8': 589dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case '9': 590dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project c -= '0'; 591dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 592dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 'a': case 'b': case 'c': 593dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 'd': case 'e': case 'f': 594dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project c = c - 'a' + 10; 595dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 596dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 'A': case 'B': case 'C': 597dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 'D': case 'E': case 'F': 598dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project c = c - 'A' + 10; 599dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 600dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project default: 601dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0xffffffff; 602dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 603dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 604dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project n = (n << 4) | c; 605dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 606dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 607dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return n; 608dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 609dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 61028e1390e688f721e13a9877d3c41884bf151db60Terence Haddock/* skip_host_serial return the position in a string 61128e1390e688f721e13a9877d3c41884bf151db60Terence Haddock skipping over the 'serial' parameter in the ADB protocol, 61228e1390e688f721e13a9877d3c41884bf151db60Terence Haddock where parameter string may be a host:port string containing 61328e1390e688f721e13a9877d3c41884bf151db60Terence Haddock the protocol delimiter (colon). */ 61428e1390e688f721e13a9877d3c41884bf151db60Terence Haddockchar *skip_host_serial(char *service) { 61528e1390e688f721e13a9877d3c41884bf151db60Terence Haddock char *first_colon, *serial_end; 61628e1390e688f721e13a9877d3c41884bf151db60Terence Haddock 61728e1390e688f721e13a9877d3c41884bf151db60Terence Haddock first_colon = strchr(service, ':'); 61828e1390e688f721e13a9877d3c41884bf151db60Terence Haddock if (!first_colon) { 61928e1390e688f721e13a9877d3c41884bf151db60Terence Haddock /* No colon in service string. */ 62028e1390e688f721e13a9877d3c41884bf151db60Terence Haddock return NULL; 62128e1390e688f721e13a9877d3c41884bf151db60Terence Haddock } 62228e1390e688f721e13a9877d3c41884bf151db60Terence Haddock serial_end = first_colon; 62328e1390e688f721e13a9877d3c41884bf151db60Terence Haddock if (isdigit(serial_end[1])) { 62428e1390e688f721e13a9877d3c41884bf151db60Terence Haddock serial_end++; 62528e1390e688f721e13a9877d3c41884bf151db60Terence Haddock while ((*serial_end) && isdigit(*serial_end)) { 62628e1390e688f721e13a9877d3c41884bf151db60Terence Haddock serial_end++; 62728e1390e688f721e13a9877d3c41884bf151db60Terence Haddock } 62828e1390e688f721e13a9877d3c41884bf151db60Terence Haddock if ((*serial_end) != ':') { 62928e1390e688f721e13a9877d3c41884bf151db60Terence Haddock // Something other than numbers was found, reset the end. 63028e1390e688f721e13a9877d3c41884bf151db60Terence Haddock serial_end = first_colon; 63128e1390e688f721e13a9877d3c41884bf151db60Terence Haddock } 63228e1390e688f721e13a9877d3c41884bf151db60Terence Haddock } 63328e1390e688f721e13a9877d3c41884bf151db60Terence Haddock return serial_end; 63428e1390e688f721e13a9877d3c41884bf151db60Terence Haddock} 63528e1390e688f721e13a9877d3c41884bf151db60Terence Haddock 636dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int smart_socket_enqueue(asocket *s, apacket *p) 637dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 638dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned len; 639dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if ADB_HOST 640dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *service = NULL; 641dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char* serial = NULL; 642dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project transport_type ttype = kTransportAny; 643dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 644dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 645dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("SS(%d): enqueue %d\n", s->id, p->len); 646dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 647dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(s->pkt_first == 0) { 648dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->pkt_first = p; 649dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->pkt_last = p; 650dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 651dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if((s->pkt_first->len + p->len) > MAX_PAYLOAD) { 652dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("SS(%d): overflow\n", s->id); 653dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project put_apacket(p); 654dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto fail; 655dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 656dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 657dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project memcpy(s->pkt_first->data + s->pkt_first->len, 658dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->data, p->len); 659dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->pkt_first->len += p->len; 660dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project put_apacket(p); 661dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 662dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p = s->pkt_first; 663dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 664dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 665dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* don't bother if we can't decode the length */ 666dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(p->len < 4) return 0; 667dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 668dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len = unhex(p->data, 4); 669dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if((len < 1) || (len > 1024)) { 670dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("SS(%d): bad size (%d)\n", s->id, len); 671dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto fail; 672dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 673dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 674dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("SS(%d): len is %d\n", s->id, len ); 675dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* can't do anything until we have the full header */ 676dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if((len + 4) > p->len) { 677dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("SS(%d): waiting for %d more bytes\n", s->id, len+4 - p->len); 678dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 679dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 680dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 681dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->data[len + 4] = 0; 682dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 683dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("SS(%d): '%s'\n", s->id, (char*) (p->data + 4)); 684dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 685dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if ADB_HOST 686dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project service = (char *)p->data + 4; 687dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(!strncmp(service, "host-serial:", strlen("host-serial:"))) { 688dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char* serial_end; 689dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project service += strlen("host-serial:"); 690dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 69128e1390e688f721e13a9877d3c41884bf151db60Terence Haddock // serial number should follow "host:" and could be a host:port string. 69228e1390e688f721e13a9877d3c41884bf151db60Terence Haddock serial_end = skip_host_serial(service); 693dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (serial_end) { 694dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *serial_end = 0; // terminate string 695dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project serial = service; 696dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project service = serial_end + 1; 697dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 698dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (!strncmp(service, "host-usb:", strlen("host-usb:"))) { 699dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ttype = kTransportUsb; 700dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project service += strlen("host-usb:"); 701dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (!strncmp(service, "host-local:", strlen("host-local:"))) { 702dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ttype = kTransportLocal; 703dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project service += strlen("host-local:"); 704dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (!strncmp(service, "host:", strlen("host:"))) { 705dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ttype = kTransportAny; 706dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project service += strlen("host:"); 707dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 708dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project service = NULL; 709dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 710dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 711dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (service) { 712dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project asocket *s2; 713dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 714dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* some requests are handled immediately -- in that 715dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ** case the handle_host_request() routine has sent 716dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ** the OKAY or FAIL message and all we have to do 717dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ** is clean up. 718dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 719dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(handle_host_request(service, ttype, serial, s->peer->fd, s) == 0) { 720dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* XXX fail message? */ 721dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D( "SS(%d): handled host service '%s'\n", s->id, service ); 722dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto fail; 723dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 724dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!strncmp(service, "transport", strlen("transport"))) { 725dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D( "SS(%d): okay transport\n", s->id ); 726dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->len = 0; 727dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 728dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 729dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 730dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* try to find a local service with this name. 731dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ** if no such service exists, we'll fail out 732dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ** and tear down here. 733dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 734dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s2 = create_host_service_socket(service, serial); 735dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(s2 == 0) { 736dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D( "SS(%d): couldn't create host service '%s'\n", s->id, service ); 737dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sendfailmsg(s->peer->fd, "unknown host service"); 738dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto fail; 739dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 740dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 741dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* we've connected to a local host service, 742dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ** so we make our peer back into a regular 743dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ** local socket and bind it to the new local 744dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ** service socket, acknowledge the successful 745dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ** connection, and close this smart socket now 746dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ** that its work is done. 747dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 748dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_write(s->peer->fd, "OKAY", 4); 749dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 750dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->peer->ready = local_socket_ready; 751dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->peer->close = local_socket_close; 752dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->peer->peer = s2; 753dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s2->peer = s->peer; 754dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->peer = 0; 755dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D( "SS(%d): okay\n", s->id ); 756dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->close(s); 757dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 758dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* initial state is "ready" */ 759dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s2->ready(s2); 760dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 761dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 762dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else /* !ADB_HOST */ 763dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (s->transport == NULL) { 764dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char* error_string = "unknown failure"; 765dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->transport = acquire_one_transport (CS_ANY, 766dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project kTransportAny, NULL, &error_string); 767dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 768dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (s->transport == NULL) { 769dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sendfailmsg(s->peer->fd, error_string); 770dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto fail; 771dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 772dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 773dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 774dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 775dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(!(s->transport) || (s->transport->connection_state == CS_OFFLINE)) { 776dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* if there's no remote we fail the connection 777dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ** right here and terminate it 778dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 779dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sendfailmsg(s->peer->fd, "device offline (x)"); 780dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto fail; 781dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 782dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 783dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 784dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* instrument our peer to pass the success or fail 785dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ** message back once it connects or closes, then 786dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ** detach from it, request the connection, and 787dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ** tear down 788dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 789dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->peer->ready = local_socket_ready_notify; 790dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->peer->close = local_socket_close_notify; 791dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->peer->peer = 0; 792dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* give him our transport and upref it */ 793dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->peer->transport = s->transport; 794dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 795dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project connect_to_remote(s->peer, (char*) (p->data + 4)); 796dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->peer = 0; 797dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->close(s); 798dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 1; 799dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 800dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectfail: 801dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* we're going to close our peer as a side-effect, so 802dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ** return -1 to signal that state to the local socket 803dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ** who is enqueueing against us 804dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 805dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->close(s); 806dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 807dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 808dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 809dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void smart_socket_ready(asocket *s) 810dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 811dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("SS(%d): ready\n", s->id); 812dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 813dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 814dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void smart_socket_close(asocket *s) 815dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 816dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("SS(%d): closed\n", s->id); 817dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(s->pkt_first){ 818dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project put_apacket(s->pkt_first); 819dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 820dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(s->peer) { 821dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->peer->peer = 0; 822dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->peer->close(s->peer); 82349f1857dd8b64cdd57f28e965a1ff5fa0c2b0547Tom Marlin s->peer = 0; 824dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 825dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project free(s); 826dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 827dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 828dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectasocket *create_smart_socket(void (*action_cb)(asocket *s, const char *act)) 829dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 830dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("Creating smart socket \n"); 831dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project asocket *s = calloc(1, sizeof(asocket)); 832c419e2a210ad7e37a1f749f2ab4de7c7f95b90d7André Goddard Rosa if (s == NULL) fatal("cannot allocate socket"); 833dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->enqueue = smart_socket_enqueue; 834dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->ready = smart_socket_ready; 835dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->close = smart_socket_close; 836dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->extra = action_cb; 837dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 838dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("SS(%d): created %p\n", s->id, action_cb); 839dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return s; 840dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 841dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 842dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid smart_socket_action(asocket *s, const char *act) 843dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 844dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 845dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 846dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 847dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid connect_to_smartsocket(asocket *s) 848dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 849dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("Connecting to smart socket \n"); 850dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project asocket *ss = create_smart_socket(smart_socket_action); 851dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->peer = ss; 852dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ss->peer = s; 853dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->ready(s); 854dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 855