1d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine/* 2d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine * Copyright (C) 2011 The Android Open Source Project 3d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine * 4d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine * Licensed under the Apache License, Version 2.0 (the "License"); 5d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine * you may not use this file except in compliance with the License. 6d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine * You may obtain a copy of the License at 7d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine * 8d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine * http://www.apache.org/licenses/LICENSE-2.0 9d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine * 10d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine * Unless required by applicable law or agreed to in writing, software 11d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine * distributed under the License is distributed on an "AS IS" BASIS, 12d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine * See the License for the specific language governing permissions and 14d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine * limitations under the License. 15d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine */ 16d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine 17d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine#include "qemu-common.h" 18d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine#include "sockets.h" 19d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine#include "iolooper.h" 20d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine#include "android/async-utils.h" 21d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine#include "android/utils/debug.h" 22d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine#include "android/utils/list.h" 23d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine#include "android/utils/misc.h" 24d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine#include "android/adb-server.h" 25d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine 26d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine#define E(...) derror(__VA_ARGS__) 27d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine#define W(...) dwarning(__VA_ARGS__) 28d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine#define D(...) VERBOSE_PRINT(adbserver,__VA_ARGS__) 29d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine#define D_ACTIVE VERBOSE_CHECK(adbserver) 30d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine#define QB(b, s) quote_bytes((const char*)b, (s < 32) ? s : 32) 31d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine 32d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkinetypedef struct AdbServer AdbServer; 33d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkinetypedef struct AdbHost AdbHost; 34d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkinetypedef struct AdbGuest AdbGuest; 35d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine 36d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine/* ADB guest connection descriptor. */ 37d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkinestruct AdbGuest { 38d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine /* Entry in the list of pending or connected ADB guests. 39d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine * NOTE: This must be the first entry in the descriptor! */ 40d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine ACList list_entry; 41d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine /* Opaque pointer associated with the guest. */ 42d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine void* opaque; 43d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine /* ADB server for this guest. */ 44d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine AdbServer* adb_srv; 45d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine /* ADB host connected with this ADB guest. */ 46d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine AdbHost* adb_host; 47d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine /* Callback routines for the ADB guest. */ 48d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine AdbGuestRoutines* callbacks; 49d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine /* ADB guest connection status. If 0 indicates that ADB guest is not yet 50d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine * ready to receive data from the host. */ 51d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine int is_connected; 52d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine}; 53d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine 54d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine/* ADB host connection descriptor. */ 55d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkinestruct AdbHost { 56d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine /* Entry in the list of pending or connected ADB hosts. 57d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine * NOTE: This must be the first entry in the descriptor! */ 58d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine ACList list_entry; 59d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine /* ADB server for this host. */ 60d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine AdbServer* adb_srv; 61d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine /* ADB socket connected with the host. */ 62d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine int host_so; 63d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine /* I/O port for asynchronous I/O on the host socket. */ 64d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine LoopIo io[1]; 65d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine /* ADB guest connected with this ADB host. */ 66d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine AdbGuest* adb_guest; 67d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine /* Pending data to send to the guest when it is fully connected. */ 68d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine uint8_t* pending_data; 69d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine /* Size of the pending data buffer. */ 70d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine int pending_data_size; 71d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine /* Contains data that are pending to be sent to the host. */ 72d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine uint8_t* pending_send_buffer; 73d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine /* Number of bytes that are pending to be sent to the host. */ 74d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine int pending_send_data_size; 75d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine /* Size of the pending_send_buffer */ 76d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine int pending_send_buffer_size; 77d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine}; 78d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine 79d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine/* ADB server descriptor. */ 80d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkinestruct AdbServer { 81d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine /* ADB socket address. */ 82d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine SockAddress socket_address; 83d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine /* Looper for async I/O on ADB server socket. */ 84d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine Looper* looper; 85d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine /* I/O port for asynchronous I/O on ADB server socket. */ 86d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine LoopIo io[1]; 87d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine /* ADB port. */ 88d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine int port; 89d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine /* Server socket. */ 90d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine int so; 91d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine /* List of connected ADB hosts. */ 92d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine ACList adb_hosts; 93d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine /* List of connected ADB guests. */ 94d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine ACList adb_guests; 95d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine /* List of ADB hosts pending connection with ADB guest. */ 96d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine ACList pending_hosts; 97d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine /* List of ADB guests pending connection with ADB host. */ 98d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine ACList pending_guests; 99d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine}; 100d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine 101d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine/* One and only one ADB server instance. */ 102d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkinestatic AdbServer _adb_server; 103d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine/* ADB server initialization flag. */ 104d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkinestatic int _adb_server_initialized = 0; 105d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine 106d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine/******************************************************************************** 107d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine * ADB host API 108d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine *******************************************************************************/ 109d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine 110d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine/* Creates and initializes a new AdbHost instance. */ 111d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkinestatic AdbHost* 112d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine_adb_host_new(AdbServer* adb_srv) 113d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine{ 114d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine AdbHost* adb_host; 115d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine 116d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine ANEW0(adb_host); 117d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine alist_init(&adb_host->list_entry); 118d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine adb_host->adb_srv = adb_srv; 119d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine adb_host->host_so = -1; 120d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine 121d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine return adb_host; 122d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine} 123d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine 124d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine/* Frees AdbHost instance created with _adb_host_new routine. */ 125d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkinestatic void 126d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine_adb_host_free(AdbHost* adb_host) 127d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine{ 128d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine if (adb_host != NULL) { 129d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine /* At this point it must not be listed anywhere. */ 130d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine assert(alist_is_empty(&adb_host->list_entry)); 131d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine 132d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine /* Close the host socket. */ 133d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine if (adb_host->host_so >= 0) { 134d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine loopIo_done(adb_host->io); 135d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine socket_close(adb_host->host_so); 136d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine } 137d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine 138d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine /* Free pending data buffers. */ 139d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine if (adb_host->pending_data != NULL) { 140d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine free(adb_host->pending_data); 141d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine } 142d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine if (adb_host->pending_send_buffer != NULL) { 143d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine free(adb_host->pending_send_buffer); 144d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine } 145d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine 146d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine AFREE(adb_host); 147d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine } 148d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine} 149d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine 150d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkinestatic void 151d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine_adb_host_append_message(AdbHost* adb_host, const void* msg, int msglen) 152d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine{ 153d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine printf("Append %d bytes to ADB host buffer.\n", msglen); 154d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine 155d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine /* Make sure that buffer can contain the appending data. */ 156d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine if (adb_host->pending_send_buffer == NULL) { 157d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine adb_host->pending_send_buffer = (uint8_t*)malloc(msglen); 158d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine adb_host->pending_send_buffer_size = msglen; 159d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine } else if ((adb_host->pending_send_data_size + msglen) > 160d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine adb_host->pending_send_buffer_size) { 161d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine adb_host->pending_send_buffer = 162d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine (uint8_t*)realloc(adb_host->pending_send_buffer, 163d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine adb_host->pending_send_data_size + msglen); 164d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine adb_host->pending_send_buffer_size = 165d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine adb_host->pending_send_data_size + msglen; 166d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine } 167d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine 168d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine if (adb_host->pending_send_buffer == NULL) { 169d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine D("Unable to allocate %d bytes for pending ADB host data.", 170d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine adb_host->pending_send_data_size + msglen); 171d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine adb_host->pending_send_buffer_size = adb_host->pending_send_data_size = 0; 172d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine loopIo_dontWantWrite(adb_host->io); 173d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine return; 174d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine } 175d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine 176d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine memcpy(adb_host->pending_send_buffer + adb_host->pending_send_data_size, 177d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine msg, msglen); 178d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine loopIo_wantWrite(adb_host->io); 179d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine} 180d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine 181d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine/* Connects ADB host with ADB guest. */ 182d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkinestatic void 183d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine_adb_connect(AdbHost* adb_host, AdbGuest* adb_guest) 184d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine{ 185d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine D("Connecting ADB host %p(so=%d) with ADB guest %p(o=%p)", 186d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine adb_host, adb_host->host_so, adb_guest, adb_guest->opaque); 187d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine 188d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine adb_guest->adb_host = adb_host; 189d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine adb_host->adb_guest = adb_guest; 190d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine adb_guest->callbacks->on_connected(adb_guest->opaque, adb_guest); 191d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine} 192d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine 193d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine/* Callback invoked when ADB host socket gets disconnected. */ 194d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkinestatic void 195d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine_on_adb_host_disconnected(AdbHost* adb_host) 196d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine{ 197d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine AdbGuest* const adb_guest = adb_host->adb_guest; 198d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine 199d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine /* Notify the ADB guest that the host got disconnected. */ 200d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine if (adb_guest != NULL) { 201d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine D("Disconnecting ADB host %p(so=%d) from ADB guest %p(o=%p)", 202d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine adb_host, adb_host->host_so, adb_guest, adb_guest->opaque); 203d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine adb_host->adb_guest = NULL; 204d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine adb_guest->callbacks->on_disconnect(adb_guest->opaque, adb_guest); 205d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine adb_guest->adb_host = NULL; 206d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine } else { 207d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine D("Disconnecting ADB host %p(so=%d)", adb_host, adb_host->host_so); 208d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine } 209d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine 210d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine /* Destroy the host. */ 211d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine alist_remove(&adb_host->list_entry); 212d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine _adb_host_free(adb_host); 213d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine 214d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine /* Remove the guest from the list. */ 215d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine if (adb_guest != NULL) { 216d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine alist_remove(&adb_guest->list_entry); 217d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine } 218d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine} 219d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine 220d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine/* Read I/O callback on ADB host socket. */ 221d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkinestatic void 222d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine_on_adb_host_read(AdbHost* adb_host) 223d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine{ 224d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine char buff[4096]; 225d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine 226d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine /* Read data from the socket. */ 227d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine const int size = socket_recv(adb_host->host_so, buff, sizeof(buff)); 228d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine if (size < 0) { 229d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine D("Error while reading from ADB host %p(so=%d). Error: %s", 230d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine adb_host, adb_host->host_so, strerror(errno)); 231d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine } else if (size == 0) { 232d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine /* This is a "disconnect" condition. */ 233d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine _on_adb_host_disconnected(adb_host); 234d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine } else { 235d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine D("%s %d bytes received from ADB host %p(so=%d): %s", 236d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine adb_host->adb_guest ? "Transfer" : "Pend", size, adb_host, 237d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine adb_host->host_so, QB(buff, size)); 238d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine 239d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine /* Lets see if there is an ADB guest associated with this host, and it 240d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine * is ready to receive host data. */ 241d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine AdbGuest* const adb_guest = adb_host->adb_guest; 242d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine if (adb_guest != NULL && adb_guest->is_connected) { 243d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine /* Channel the data through... */ 244d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine adb_guest->callbacks->on_read(adb_guest->opaque, adb_guest, buff, size); 245d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine } else { 246d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine /* Pend the data for the upcoming guest connection. */ 247d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine if (adb_host->pending_data == NULL) { 248d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine adb_host->pending_data = malloc(size); 249d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine } else { 250d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine adb_host->pending_data = realloc(adb_host->pending_data, 251d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine adb_host->pending_data_size + size); 252d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine } 253d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine if (adb_host->pending_data != NULL) { 254d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine memcpy(adb_host->pending_data + adb_host->pending_data_size, 255d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine buff, size); 256d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine adb_host->pending_data_size += size; 257d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine } else { 258d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine D("Unable to (re)allocate %d bytes for pending ADB host data", 259d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine adb_host->pending_data_size + size); 260d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine } 261d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine } 262d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine } 263d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine} 264d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine 265d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine/* Write I/O callback on ADB host socket. */ 266d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkinestatic void 267d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine_on_adb_host_write(AdbHost* adb_host) 268d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine{ 269d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine while (adb_host->pending_send_data_size && adb_host->pending_send_buffer != NULL) { 270d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine const int sent = socket_send(adb_host->host_so, 271d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine adb_host->pending_send_buffer, 272d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine adb_host->pending_send_data_size); 273d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine if (sent < 0) { 274d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine if (errno == EWOULDBLOCK) { 275d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine /* Try again later. */ 276d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine return; 277d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine } else { 278d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine D("Unable to send pending data to the ADB host: %s", 279d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine strerror(errno)); 280d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine free(adb_host->pending_send_buffer); 281d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine adb_host->pending_send_buffer = NULL; 282d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine adb_host->pending_send_buffer_size = 0; 283d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine adb_host->pending_send_data_size = 0; 284d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine break; 285d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine } 286d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine } else if (sent == 0) { 287d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine /* Disconnect condition. */ 288d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine free(adb_host->pending_send_buffer); 289d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine adb_host->pending_send_buffer = NULL; 290d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine adb_host->pending_send_buffer_size = 0; 291d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine adb_host->pending_send_data_size = 0; 292d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine _on_adb_host_disconnected(adb_host); 293d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine break; 294d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine } else if (sent == adb_host->pending_send_data_size) { 295d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine free(adb_host->pending_send_buffer); 296d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine adb_host->pending_send_buffer = NULL; 297d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine adb_host->pending_send_buffer_size = 0; 298d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine adb_host->pending_send_data_size = 0; 299d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine } else { 300d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine adb_host->pending_send_data_size -= sent; 301d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine memmove(adb_host->pending_send_buffer, 302d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine adb_host->pending_send_buffer + sent, 303d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine adb_host->pending_send_data_size); 304d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine return; 305d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine } 306d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine } 307d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine 308d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine loopIo_dontWantWrite(adb_host->io); 309d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine} 310d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine 311d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine/* I/O callback on ADB host socket. */ 312d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkinestatic void 313d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine_on_adb_host_io(void* opaque, int fd, unsigned events) 314d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine{ 315d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine AdbHost* const adb_host = (AdbHost*)opaque; 316d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine assert(fd == adb_host->host_so); 317d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine 318d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine /* Dispatch I/O to read / write handlers. */ 319d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine if ((events & LOOP_IO_READ) != 0) { 320d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine _on_adb_host_read(adb_host); 321d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine } 322d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine if ((events & LOOP_IO_WRITE) != 0) { 323d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine _on_adb_host_write(adb_host); 324d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine } 325d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine} 326d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine 327d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine/******************************************************************************** 328d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine * ADB guest API 329d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine *******************************************************************************/ 330d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine 331d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine/* Creates and initializes a new AdbGuest instance. */ 332d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkinestatic AdbGuest* 333d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine_adb_guest_new(AdbServer* adb_srv) 334d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine{ 335d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine AdbGuest* adb_guest; 336d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine 337d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine ANEW0(adb_guest); 338d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine alist_init(&adb_guest->list_entry); 339d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine adb_guest->adb_srv = adb_srv; 340d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine 341d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine return adb_guest; 342d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine} 343d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine 344d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine/* Frees AdbGuest instance created with _adb_guest_new routine. */ 345d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkinestatic void 346d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine_adb_guest_free(AdbGuest* adb_guest) 347d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine{ 348d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine if (adb_guest != NULL) { 349d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine /* At this poin the guest must not be in any of the lists. */ 350d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine assert(alist_is_empty(&adb_guest->list_entry)); 351d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine AFREE(adb_guest); 352d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine } 353d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine} 354d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine 355d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine/******************************************************************************** 356d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine * ADB server internals 357d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine *******************************************************************************/ 358d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine 359d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine/* I/O callback on ADB server socket. */ 360d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkinestatic void 361d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine_on_server_socket_io(void* opaque, int fd, unsigned events) 362d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine{ 363d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine AdbHost* adb_host; 364d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine AdbGuest* adb_guest; 365d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine AdbServer* adb_srv = (AdbServer*)opaque; 366d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine assert(adb_srv->so == fd); 367d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine 368d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine /* Since this is a server socket, we only expect a connection I/O here. */ 369d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine if ((events & LOOP_IO_READ) == 0) { 370d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine D("Unexpected write I/O on ADB server socket"); 371d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine return; 372d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine } 373d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine 374d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine /* Create AdbHost instance for the new host connection. */ 375d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine adb_host = _adb_host_new(adb_srv); 376d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine 377d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine /* Accept the connection. */ 378d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine adb_host->host_so = socket_accept(fd, &adb_srv->socket_address); 379d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine if (adb_host->host_so < 0) { 380d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine D("Unable to accept ADB connection: %s", strerror(errno)); 381d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine _adb_host_free(adb_host); 382d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine return; 383d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine } 384d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine 385d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine /* Prepare for I/O on the host connection socket. */ 386d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine loopIo_init(adb_host->io, adb_srv->looper, adb_host->host_so, 387d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine _on_adb_host_io, adb_host); 388d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine 389d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine /* Lets see if there is an ADB guest waiting for a host connection. */ 390d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine adb_guest = (AdbGuest*)alist_remove_head(&adb_srv->pending_guests); 391d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine if (adb_guest != NULL) { 392d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine /* Tie up ADB host with the ADB guest. */ 393d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine alist_insert_tail(&adb_srv->adb_guests, &adb_guest->list_entry); 394d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine alist_insert_tail(&adb_srv->adb_hosts, &adb_host->list_entry); 395d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine _adb_connect(adb_host, adb_guest); 396d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine } else { 397d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine /* Pend this connection. */ 398d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine D("Pend ADB host %p(so=%d)", adb_host, adb_host->host_so); 399d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine alist_insert_tail(&adb_srv->pending_hosts, &adb_host->list_entry); 400d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine } 401d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine 402d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine /* Enable I/O on the host socket. */ 403d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine loopIo_wantRead(adb_host->io); 404d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine} 405d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine 406d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine/******************************************************************************** 407d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine * ADB server API 408d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine *******************************************************************************/ 409d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkineint 410d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkineadb_server_init(int port) 411d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine{ 412d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine if (!_adb_server_initialized) { 413d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine /* Initialize the descriptor. */ 414d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine memset(&_adb_server, 0, sizeof(_adb_server)); 415d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine alist_init(&_adb_server.adb_hosts); 416d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine alist_init(&_adb_server.adb_guests); 417d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine alist_init(&_adb_server.pending_hosts); 418d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine alist_init(&_adb_server.pending_guests); 419d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine _adb_server.port = port; 420d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine 421d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine /* Create looper for an async I/O on the server. */ 422d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine _adb_server.looper = looper_newCore(); 423d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine if (_adb_server.looper == NULL) { 424d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine E("Unable to create I/O looper for ADB server"); 425d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine return -1; 426d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine } 427d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine 428d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine /* Create loopback server socket for the ADB port. */ 429d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine sock_address_init_inet(&_adb_server.socket_address, 430d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine SOCK_ADDRESS_INET_LOOPBACK, port); 431d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine _adb_server.so = socket_loopback_server(port, SOCKET_STREAM); 432d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine if (_adb_server.so < 0) { 433d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine E("Unable to create ADB server socket: %s", strerror(errno)); 434d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine return -1; 435d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine } 436d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine 437d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine /* Prepare server socket for I/O */ 438d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine socket_set_nonblock(_adb_server.so); 439d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine loopIo_init(_adb_server.io, _adb_server.looper, _adb_server.so, 440d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine _on_server_socket_io, &_adb_server); 441d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine loopIo_wantRead(_adb_server.io); 442d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine 443d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine D("ADB server has been initialized for port %d. Socket: %d", 444d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine port, _adb_server.so); 445d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine 446d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine _adb_server_initialized = 1; 447d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine } 448d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine 449d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine return 0; 450d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine} 451d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine 452d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkineint 453d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkineadb_server_is_initialized(void) 454d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine{ 455d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine return _adb_server_initialized; 456d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine} 457d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine 458d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkinevoid* 459d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkineadb_server_register_guest(void* opaque, AdbGuestRoutines* callbacks) 460d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine{ 461d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine if (_adb_server_initialized) { 462d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine AdbHost* adb_host; 463d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine 464d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine /* Create and initialize ADB guest descriptor. */ 465d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine AdbGuest* const adb_guest = _adb_guest_new(&_adb_server); 466d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine adb_guest->opaque = opaque; 467d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine adb_guest->callbacks = callbacks; 468d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine 469d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine /* Lets see if there is a pending ADB host for the new guest. */ 470d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine adb_host = (AdbHost*)alist_remove_head(&_adb_server.pending_hosts); 471d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine if (adb_host != NULL) { 472d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine /* Tie up ADB host with the ADB guest. */ 473d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine alist_insert_tail(&_adb_server.adb_guests, &adb_guest->list_entry); 474d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine alist_insert_tail(&_adb_server.adb_hosts, &adb_host->list_entry); 475d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine _adb_connect(adb_host, adb_guest); 476d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine } else { 477d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine /* Host is not available. Pend this guest. */ 478d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine D("Pend ADB guest %p(o=%p)", adb_guest, adb_guest->opaque); 479d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine alist_insert_tail(&_adb_server.pending_guests, &adb_guest->list_entry); 480d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine } 481d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine 482d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine return adb_guest; 483d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine } else { 484d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine D("%s is called on an uninitialized ADB server.", __FUNCTION__); 485d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine return NULL; 486d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine } 487d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine} 488d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine 489d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkinevoid 490d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkineadb_server_complete_connection(void* opaque) 491d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine{ 492d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine AdbGuest* const adb_guest = (AdbGuest*)opaque; 493d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine AdbHost* const adb_host = adb_guest->adb_host; 494d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine 495d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine /* Mark the guest as fully connected and ready for the host data. */ 496d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine adb_guest->is_connected = 1; 497d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine 498d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine /* Lets see if there is a host data pending transmission to the guest. */ 499d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine if (adb_host->pending_data != NULL && adb_host->pending_data_size != 0) { 500d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine /* Send the pending data to the guest. */ 501d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine D("Pushing %d bytes of the pending ADB host data.", 502d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine adb_host->pending_data_size); 503d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine adb_guest->callbacks->on_read(adb_guest->opaque, adb_guest, 504d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine adb_host->pending_data, 505d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine adb_host->pending_data_size); 506d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine free(adb_host->pending_data); 507d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine adb_host->pending_data = NULL; 508d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine adb_host->pending_data_size = 0; 509d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine } 510d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine} 511d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine 512d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkinevoid 513d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkineadb_server_on_guest_message(void* opaque, const uint8_t* msg, int msglen) 514d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine{ 515d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine AdbGuest* const adb_guest = (AdbGuest*)opaque; 516d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine AdbHost* const adb_host = adb_guest->adb_host; 517d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine 518d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine if (adb_host != NULL) { 519d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine D("Sending %d bytes to the ADB host: %s", msglen, QB(msg, msglen)); 520d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine 521d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine /* Lets see if we can send the data immediatelly... */ 522d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine if (adb_host->pending_send_buffer == NULL) { 523d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine /* There are no data that are pending to be sent to the host. Do the 524d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine * direct send. */ 525d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine const int sent = socket_send(adb_host->host_so, msg, msglen); 526d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine if (sent < 0) { 527d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine if (errno == EWOULDBLOCK) { 528d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine } else { 529d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine D("Unable to send data to ADB host: %s", strerror(errno)); 530d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine } 531d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine } else if (sent == 0) { 532d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine /* Disconnect condition. */ 533d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine _on_adb_host_disconnected(adb_host); 534d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine } else if (sent < msglen) { 535d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine /* Couldn't send everything. Schedule write via I/O callback. */ 536d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine _adb_host_append_message(adb_host, msg + sent, msglen - sent); 537d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine } 538d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine } else { 539d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine /* There are data that are pending to be sent to the host. We need 540d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine * to append new data to the end of the pending data buffer. */ 541d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine _adb_host_append_message(adb_host, msg, msglen); 542d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine } 543d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine } else { 544d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine D("ADB host is disconneted and can't accept %d bytes in %s", 545d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine msglen, QB(msg, msglen)); 546d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine } 547d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine} 548d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine 549d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkinevoid 550d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkineadb_server_on_guest_closed(void* opaque) 551d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine{ 552d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine AdbGuest* const adb_guest = (AdbGuest*)opaque; 553d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine AdbHost* const adb_host = adb_guest->adb_host; 554d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine 555d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine /* Remove the guest from the list */ 556d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine if (!alist_is_empty(&adb_guest->list_entry)) { 557d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine alist_remove(&adb_guest->list_entry); 558d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine } 559d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine 560d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine /* Disassociate the host. */ 561d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine if (adb_host != NULL) { 562d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine if (!alist_is_empty(&adb_host->list_entry)) { 563d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine alist_remove(&adb_host->list_entry); 564d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine } 565d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine _adb_host_free(adb_host); 566d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine } 567d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine _adb_guest_free(adb_guest); 568d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine} 569