JdwpAdb.cpp revision 305efe65f9083b88562ce823bde6df027a2ff71e
1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * you may not use this file except in compliance with the License. 6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * You may obtain a copy of the License at 7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * See the License for the specific language governing permissions and 14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * limitations under the License. 15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include "jdwp/JdwpPriv.h" 17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include "jdwp/JdwpHandler.h" 18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <sys/socket.h> 19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <sys/un.h> 20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <errno.h> 21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <unistd.h> 22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* the JDWP <-> ADB transport protocol is explained in details 24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * in //device/tools/adb/jdwp_service.c, here's a summary. 25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1/ when the JDWP thread starts, it tries to connect to a Unix 27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * domain stream socket (@jdwp-control) that is opened by the 28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * ADB daemon. 29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 2/ it then sends the current process PID as a string of 4 hexadecimal 31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * chars (no terminating zero) 32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 3/ then, it uses recvmsg to receive file descriptors from the 34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * daemon. each incoming file descriptor is a pass-through to 35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * a given JDWP debugger, that can be used to read the usual 36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * JDWP-handshake, etc... 37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define kInputBufferSize 8192 41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define kMagicHandshake "JDWP-Handshake" 43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define kMagicHandshakeLen (sizeof(kMagicHandshake)-1) 44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define kJdwpControlName "\0jdwp-control" 46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define kJdwpControlNameLen (sizeof(kJdwpControlName)-1) 47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstruct JdwpNetState { 49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int controlSock; 50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int clientSock; 51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bool awaitingHandshake; 52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int wakeFds[2]; 53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int inputCount; 55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unsigned char inputBuffer[kInputBufferSize]; 56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project socklen_t controlAddrLen; 58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project union { 59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project struct sockaddr_un controlAddrUn; 60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project struct sockaddr controlAddrPlain; 61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } controlAddr; 62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}; 63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void 65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectadbStateFree( JdwpNetState* netState ) 66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (netState == NULL) 68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return; 69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (netState->clientSock >= 0) { 71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project shutdown(netState->clientSock, SHUT_RDWR); 72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project close(netState->clientSock); 73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (netState->controlSock >= 0) { 75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project shutdown(netState->controlSock, SHUT_RDWR); 76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project close(netState->controlSock); 77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (netState->wakeFds[0] >= 0) { 79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project close(netState->wakeFds[0]); 80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project netState->wakeFds[0] = -1; 81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (netState->wakeFds[1] >= 0) { 83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project close(netState->wakeFds[1]); 84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project netState->wakeFds[1] = -1; 85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(netState); 88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic JdwpNetState* 92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectadbStateAlloc(void) 93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project JdwpNetState* netState = calloc(sizeof(*netState),1); 95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project netState->controlSock = -1; 97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project netState->clientSock = -1; 98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project netState->controlAddr.controlAddrUn.sun_family = AF_UNIX; 100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project netState->controlAddrLen = 101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sizeof(netState->controlAddr.controlAddrUn.sun_family) + 102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kJdwpControlNameLen; 103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project memcpy(netState->controlAddr.controlAddrUn.sun_path, 105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kJdwpControlName, kJdwpControlNameLen); 106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project netState->wakeFds[0] = -1; 108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project netState->wakeFds[1] = -1; 109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return netState; 111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Do initial prep work, e.g. binding to ports and opening files. This 116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * runs in the main thread, before the JDWP thread starts, so it shouldn't 117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * do anything that might block forever. 118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic bool startup(struct JdwpState* state, const JdwpStartupParams* pParams) 120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project JdwpNetState* netState; 122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGV("ADB transport startup\n"); 124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project state->netState = netState = adbStateAlloc(); 126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (netState == NULL) 127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 132305efe65f9083b88562ce823bde6df027a2ff71eAndy McFadden/* 133305efe65f9083b88562ce823bde6df027a2ff71eAndy McFadden * Receive a file descriptor from ADB. The fd can be used to communicate 134305efe65f9083b88562ce823bde6df027a2ff71eAndy McFadden * directly with a debugger or DDMS. 135305efe65f9083b88562ce823bde6df027a2ff71eAndy McFadden * 136305efe65f9083b88562ce823bde6df027a2ff71eAndy McFadden * Returns the file descriptor on success, -1 on call failure. If ADB 137305efe65f9083b88562ce823bde6df027a2ff71eAndy McFadden * went away, this closes netState->controlSock and returns -2. 138305efe65f9083b88562ce823bde6df027a2ff71eAndy McFadden */ 139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic int receiveClientFd(JdwpNetState* netState) 140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project struct msghdr msg; 142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project struct cmsghdr* cmsg; 143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project struct iovec iov; 144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char dummy = '!'; 145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project union { 146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project struct cmsghdr cm; 147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char buffer[CMSG_SPACE(sizeof(int))]; 148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } cm_un; 149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int ret; 150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project iov.iov_base = &dummy; 152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project iov.iov_len = 1; 153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project msg.msg_name = NULL; 154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project msg.msg_namelen = 0; 155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project msg.msg_iov = &iov; 156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project msg.msg_iovlen = 1; 157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project msg.msg_flags = 0; 158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project msg.msg_control = cm_un.buffer; 159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project msg.msg_controllen = sizeof(cm_un.buffer); 160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project cmsg = CMSG_FIRSTHDR(&msg); 162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project cmsg->cmsg_len = msg.msg_controllen; 163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project cmsg->cmsg_level = SOL_SOCKET; 164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project cmsg->cmsg_type = SCM_RIGHTS; 165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ((int*)CMSG_DATA(cmsg))[0] = -1; 166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project do { 168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ret = recvmsg(netState->controlSock, &msg, 0); 169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } while (ret < 0 && errno == EINTR); 170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (ret < 0) { 172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGE("receiving file descriptor from ADB failed (socket %d): %s\n", 173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project netState->controlSock, strerror(errno)); 174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 175305efe65f9083b88562ce823bde6df027a2ff71eAndy McFadden } else if (ret == 0) { 176305efe65f9083b88562ce823bde6df027a2ff71eAndy McFadden close(netState->controlSock); 177305efe65f9083b88562ce823bde6df027a2ff71eAndy McFadden netState->controlSock = -1; 178305efe65f9083b88562ce823bde6df027a2ff71eAndy McFadden return -2; 179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return ((int*)CMSG_DATA(cmsg))[0]; 182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Block forever, waiting for a debugger to connect to us. Called from the 186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * JDWP thread. 187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This needs to un-block and return "false" if the VM is shutting down. It 189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * should return "true" when it successfully accepts a connection. 190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic bool acceptConnection(struct JdwpState* state) 192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project JdwpNetState* netState = state->netState; 194305efe65f9083b88562ce823bde6df027a2ff71eAndy McFadden int retryCount = 0; 195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* first, ensure that we get a connection to the ADB daemon */ 197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 198305efe65f9083b88562ce823bde6df027a2ff71eAndy McFaddenretry: 199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (netState->controlSock < 0) 200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int sleep_ms = 500; 202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const int sleep_max_ms = 2*1000; 203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char buff[5]; 204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project netState->controlSock = socket(PF_UNIX, SOCK_STREAM, 0); 206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (netState->controlSock < 0) { 207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGE("Could not create ADB control socket:%s\n", 208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project strerror(errno)); 209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pipe(netState->wakeFds) < 0) { 213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGE("pipe failed"); 214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project snprintf(buff, sizeof(buff), "%04x", getpid()); 218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project buff[4] = 0; 219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (;;) { 221305efe65f9083b88562ce823bde6df027a2ff71eAndy McFadden /* 222305efe65f9083b88562ce823bde6df027a2ff71eAndy McFadden * If adbd isn't running, because USB debugging was disabled or 223305efe65f9083b88562ce823bde6df027a2ff71eAndy McFadden * perhaps the system is restarting it for "adb root", the 224305efe65f9083b88562ce823bde6df027a2ff71eAndy McFadden * connect() will fail. We loop here forever waiting for it 225305efe65f9083b88562ce823bde6df027a2ff71eAndy McFadden * to come back. 226305efe65f9083b88562ce823bde6df027a2ff71eAndy McFadden * 227305efe65f9083b88562ce823bde6df027a2ff71eAndy McFadden * Waking up and polling every couple of seconds is generally a 228305efe65f9083b88562ce823bde6df027a2ff71eAndy McFadden * bad thing to do, but we only do this if the application is 229305efe65f9083b88562ce823bde6df027a2ff71eAndy McFadden * debuggable *and* adbd isn't running. Still, for the sake 230305efe65f9083b88562ce823bde6df027a2ff71eAndy McFadden * of battery life, we should consider timing out and giving 231305efe65f9083b88562ce823bde6df027a2ff71eAndy McFadden * up after a few minutes in case somebody ships an app with 232305efe65f9083b88562ce823bde6df027a2ff71eAndy McFadden * the debuggable flag set. 233305efe65f9083b88562ce823bde6df027a2ff71eAndy McFadden */ 234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int ret = connect(netState->controlSock, 235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project &netState->controlAddr.controlAddrPlain, 236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project netState->controlAddrLen); 237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!ret) { 238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* now try to send our pid to the ADB daemon */ 239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project do { 240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ret = send( netState->controlSock, buff, 4, 0 ); 241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } while (ret < 0 && errno == EINTR); 242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (ret >= 0) { 244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGV("PID sent as '%.*s' to ADB\n", 4, buff); 245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGE("Weird, can't send JDWP process pid to ADB: %s\n", 249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project strerror(errno)); 250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGV("Can't connect to ADB control socket:%s\n", 253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project strerror(errno)); 254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project usleep( sleep_ms*1000 ); 256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sleep_ms += (sleep_ms >> 1); 258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (sleep_ms > sleep_max_ms) 259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sleep_ms = sleep_max_ms; 260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGV("trying to receive file descriptor from ADB\n"); 264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* now we can receive a client file descriptor */ 265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project netState->clientSock = receiveClientFd(netState); 266305efe65f9083b88562ce823bde6df027a2ff71eAndy McFadden if (netState->clientSock == -1) { 267305efe65f9083b88562ce823bde6df027a2ff71eAndy McFadden return false; 268305efe65f9083b88562ce823bde6df027a2ff71eAndy McFadden } else if (netState->clientSock == -2) { 269305efe65f9083b88562ce823bde6df027a2ff71eAndy McFadden LOGD("adbd dropped us; retrying connection\n"); 270305efe65f9083b88562ce823bde6df027a2ff71eAndy McFadden assert(netState->controlSock < 0); 271305efe65f9083b88562ce823bde6df027a2ff71eAndy McFadden if (++retryCount > 5) { 272305efe65f9083b88562ce823bde6df027a2ff71eAndy McFadden /* shouldn't be possible, but we check it just in case */ 273305efe65f9083b88562ce823bde6df027a2ff71eAndy McFadden LOGE("max retries exceeded\n"); 274305efe65f9083b88562ce823bde6df027a2ff71eAndy McFadden return false; 275305efe65f9083b88562ce823bde6df027a2ff71eAndy McFadden } 276305efe65f9083b88562ce823bde6df027a2ff71eAndy McFadden goto retry; 277305efe65f9083b88562ce823bde6df027a2ff71eAndy McFadden } else { 278305efe65f9083b88562ce823bde6df027a2ff71eAndy McFadden LOGV("received file descriptor %d from ADB\n", netState->clientSock); 279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project netState->awaitingHandshake = 1; 280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project netState->inputCount = 0; 281305efe65f9083b88562ce823bde6df027a2ff71eAndy McFadden return true; 282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Connect out to a debugger (for server=n). Not required. 287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic bool establishConnection(struct JdwpState* state) 289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Close a connection from a debugger (which may have already dropped us). 295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Only called from the JDWP thread. 296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void closeConnection(struct JdwpState* state) 298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project JdwpNetState* netState; 300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(state != NULL && state->netState != NULL); 302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project netState = state->netState; 304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (netState->clientSock < 0) 305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return; 306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGV("+++ closed JDWP <-> ADB connection\n"); 308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project close(netState->clientSock); 310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project netState->clientSock = -1; 311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Close all network stuff, including the socket we use to listen for 315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * new connections. 316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * May be called from a non-JDWP thread, e.g. when the VM is shutting down. 318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void adbStateShutdown(struct JdwpNetState* netState) 320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int controlSock; 322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int clientSock; 323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (netState == NULL) 325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return; 326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project clientSock = netState->clientSock; 328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (clientSock >= 0) { 329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project shutdown(clientSock, SHUT_RDWR); 330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project netState->clientSock = -1; 331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project controlSock = netState->controlSock; 334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (controlSock >= 0) { 335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project shutdown(controlSock, SHUT_RDWR); 336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project netState->controlSock = -1; 337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (netState->wakeFds[1] >= 0) { 340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGV("+++ writing to wakePipe\n"); 341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (void) write(netState->wakeFds[1], "", 1); 342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void netShutdown(JdwpState* state) 346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project adbStateShutdown(state->netState); 348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Free up anything we put in state->netState. This is called after 352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "netShutdown", after the JDWP thread has stopped. 353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void netFree(struct JdwpState* state) 355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project JdwpNetState* netState = state->netState; 357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project adbStateFree(netState); 359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Is a debugger connected to us? 363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic bool isConnected(struct JdwpState* state) 365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (state->netState != NULL && 367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project state->netState->clientSock >= 0); 368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Are we still waiting for the JDWP handshake? 372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 373f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic bool awaitingHandshake(struct JdwpState* state) 374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return state->netState->awaitingHandshake; 376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Figure out if we have a full packet in the buffer. 380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic bool haveFullPacket(JdwpNetState* netState) 382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project long length; 384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (netState->awaitingHandshake) 386f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (netState->inputCount >= (int) kMagicHandshakeLen); 387f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 388f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (netState->inputCount < 4) 389f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 390f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 391f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project length = get4BE(netState->inputBuffer); 392f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (netState->inputCount >= length); 393f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 394f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 395f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Consume bytes from the buffer. 397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This would be more efficient with a circular buffer. However, we're 399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * usually only going to find one packet, which is trivial to handle. 400f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 401f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void consumeBytes(JdwpNetState* netState, int count) 402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 403f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(count > 0); 404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(count <= netState->inputCount); 405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (count == netState->inputCount) { 407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project netState->inputCount = 0; 408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return; 409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 411f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project memmove(netState->inputBuffer, netState->inputBuffer + count, 412f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project netState->inputCount - count); 413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project netState->inputCount -= count; 414f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 415f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 416f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 417f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Handle a packet. Returns "false" if we encounter a connection-fatal error. 418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 419f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic bool handlePacket(JdwpState* state) 420f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 421f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project JdwpNetState* netState = state->netState; 422f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const unsigned char* buf = netState->inputBuffer; 423f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project JdwpReqHeader hdr; 424f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u4 length, id; 425f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u1 flags, cmdSet, cmd; 426f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u2 error; 427f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bool reply; 428f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int dataLen; 429f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 430f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project cmd = cmdSet = 0; // shut up gcc 431f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 432f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /*dumpPacket(netState->inputBuffer);*/ 433f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 434f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project length = read4BE(&buf); 435f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project id = read4BE(&buf); 436f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project flags = read1(&buf); 437f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((flags & kJDWPFlagReply) != 0) { 438f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project reply = true; 439f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project error = read2BE(&buf); 440f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 441f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project reply = false; 442f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project cmdSet = read1(&buf); 443f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project cmd = read1(&buf); 444f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 445f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 446f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert((int) length <= netState->inputCount); 447f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dataLen = length - (buf - netState->inputBuffer); 448f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 449f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!reply) { 450f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ExpandBuf* pReply = expandBufAlloc(); 451f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 452f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hdr.length = length; 453f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hdr.id = id; 454f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hdr.cmdSet = cmdSet; 455f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hdr.cmd = cmd; 456f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmJdwpProcessRequest(state, &hdr, buf, dataLen, pReply); 457f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (expandBufGetLength(pReply) > 0) { 458f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int cc; 459f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 460f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 461f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * TODO: we currently assume the write() will complete in one 462f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * go, which may not be safe for a network socket. We may need 463f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * to mutex this against sendRequest(). 464f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 465f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project cc = write(netState->clientSock, expandBufGetBuffer(pReply), 466f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expandBufGetLength(pReply)); 467f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (cc != (int) expandBufGetLength(pReply)) { 468f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGE("Failed sending reply to debugger: %s\n", strerror(errno)); 469f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expandBufFree(pReply); 470f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 471f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 472f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 473f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGW("No reply created for set=%d cmd=%d\n", cmdSet, cmd); 474f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 475f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expandBufFree(pReply); 476f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 477f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGV("reply?!\n"); 478f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(false); 479f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 480f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 481f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGV("----------\n"); 482f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 483f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project consumeBytes(netState, length); 484f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 485f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 486f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 487f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 488f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Process incoming data. If no data is available, this will block until 489f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * some arrives. 490f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 491f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If we get a full packet, handle it. 492f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 493f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * To take some of the mystery out of life, we want to reject incoming 494f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * connections if we already have a debugger attached. If we don't, the 495f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * debugger will just mysteriously hang until it times out. We could just 496f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * close the listen socket, but there's a good chance we won't be able to 497f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * bind to the same port again, which would confuse utilities. 498f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 499f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns "false" on error (indicating that the connection has been severed), 500f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "true" if things are still okay. 501f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 502f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic bool processIncoming(JdwpState* state) 503f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 504f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project JdwpNetState* netState = state->netState; 505f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int readCount; 506f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 507f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(netState->clientSock >= 0); 508f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 509f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!haveFullPacket(netState)) { 510f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* read some more, looping until we have data */ 511f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project errno = 0; 512f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (1) { 513f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int selCount; 514f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fd_set readfds; 515f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int maxfd = -1; 516f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int fd; 517f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 518f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project FD_ZERO(&readfds); 519f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 520f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* configure fds; note these may get zapped by another thread */ 521f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fd = netState->controlSock; 522f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (fd >= 0) { 523f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project FD_SET(fd, &readfds); 524f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (maxfd < fd) 525f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project maxfd = fd; 526f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 527f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fd = netState->clientSock; 528f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (fd >= 0) { 529f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project FD_SET(fd, &readfds); 530f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (maxfd < fd) 531f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project maxfd = fd; 532f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 533f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fd = netState->wakeFds[0]; 534f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (fd >= 0) { 535f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project FD_SET(fd, &readfds); 536f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (maxfd < fd) 537f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project maxfd = fd; 538f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 539f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGI("NOTE: entering select w/o wakepipe\n"); 540f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 541f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 542f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (maxfd < 0) { 543f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGV("+++ all fds are closed\n"); 544f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 545f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 546f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 547f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 548f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Select blocks until it sees activity on the file descriptors. 549f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Closing the local file descriptor does not count as activity, 550f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * so we can't rely on that to wake us up (it works for read() 551f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * and accept(), but not select()). 552f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 553f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We can do one of three things: (1) send a signal and catch 554f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * EINTR, (2) open an additional fd ("wakePipe") and write to 555f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * it when it's time to exit, or (3) time out periodically and 556f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * re-issue the select. We're currently using #2, as it's more 557f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * reliable than #1 and generally better than #3. Wastes two fds. 558f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 559f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project selCount = select(maxfd+1, &readfds, NULL, NULL, NULL); 560f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (selCount < 0) { 561f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (errno == EINTR) 562f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project continue; 563f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGE("select failed: %s\n", strerror(errno)); 564f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto fail; 565f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 566f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 567f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (netState->wakeFds[0] >= 0 && 568f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project FD_ISSET(netState->wakeFds[0], &readfds)) 569f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 570f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGD("Got wake-up signal, bailing out of select\n"); 571f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto fail; 572f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 573f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (netState->controlSock >= 0 && 574f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project FD_ISSET(netState->controlSock, &readfds)) 575f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 576f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGI("Ignoring second debugger -- accepting and dropping\n"); 577f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int sock = receiveClientFd(netState); 578305efe65f9083b88562ce823bde6df027a2ff71eAndy McFadden if (sock >= 0) 579f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project close(sock); 580f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 581f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (netState->clientSock >= 0 && 582f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project FD_ISSET(netState->clientSock, &readfds)) 583f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 584f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project readCount = read(netState->clientSock, 585f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project netState->inputBuffer + netState->inputCount, 586f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sizeof(netState->inputBuffer) - netState->inputCount); 587f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (readCount < 0) { 588f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* read failed */ 589f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (errno != EINTR) 590f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto fail; 591f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGD("+++ EINTR hit\n"); 592f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 593f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (readCount == 0) { 594f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* EOF hit -- far end went away */ 595305efe65f9083b88562ce823bde6df027a2ff71eAndy McFadden LOGV("+++ peer disconnected\n"); 596f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto fail; 597f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else 598f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 599f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 600f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 601f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 602f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project netState->inputCount += readCount; 603f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!haveFullPacket(netState)) 604f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; /* still not there yet */ 605f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 606f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 607f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 608f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Special-case the initial handshake. For some bizarre reason we're 609f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * expected to emulate bad tty settings by echoing the request back 610f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * exactly as it was sent. Note the handshake is always initiated by 611f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the debugger, no matter who connects to whom. 612f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 613f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Other than this one case, the protocol [claims to be] stateless. 614f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 615f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (netState->awaitingHandshake) { 616f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int cc; 617f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 618f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (memcmp(netState->inputBuffer, 619f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kMagicHandshake, kMagicHandshakeLen) != 0) 620f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 621f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGE("ERROR: bad handshake '%.14s'\n", netState->inputBuffer); 622f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto fail; 623f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 624f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 625f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project errno = 0; 626f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project cc = write(netState->clientSock, netState->inputBuffer, 627f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kMagicHandshakeLen); 628f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (cc != kMagicHandshakeLen) { 629f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGE("Failed writing handshake bytes: %s (%d of %d)\n", 630f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project strerror(errno), cc, (int) kMagicHandshakeLen); 631f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto fail; 632f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 633f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 634f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project consumeBytes(netState, kMagicHandshakeLen); 635f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project netState->awaitingHandshake = false; 636f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGV("+++ handshake complete\n"); 637f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 638f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 639f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 640f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 641f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Handle this packet. 642f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 643f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return handlePacket(state); 644f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 645f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectfail: 646f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project closeConnection(state); 647f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 648f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 649f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 650f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 651f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Send a request. 652f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 653f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The entire packet must be sent with a single write() call to avoid 654f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * threading issues. 655f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 656f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns "true" if it was sent successfully. 657f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 658f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic bool sendRequest(JdwpState* state, ExpandBuf* pReq) 659f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 660f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project JdwpNetState* netState = state->netState; 661f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int cc; 662f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 663f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* dumpPacket(expandBufGetBuffer(pReq)); */ 664f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (netState->clientSock < 0) { 665f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* can happen with some DDMS events */ 666f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGV("NOT sending request -- no debugger is attached\n"); 667f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 668f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 669f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 670f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 671f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * TODO: we currently assume the write() will complete in one 672f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * go, which may not be safe for a network socket. We may need 673f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * to mutex this against handlePacket(). 674f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 675f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project errno = 0; 676f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project cc = write(netState->clientSock, expandBufGetBuffer(pReq), 677f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expandBufGetLength(pReq)); 678f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (cc != (int) expandBufGetLength(pReq)) { 679f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGE("Failed sending req to debugger: %s (%d of %d)\n", 680f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project strerror(errno), cc, (int) expandBufGetLength(pReq)); 681f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 682f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 683f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 684f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 685f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 686f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 687f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 688f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 689f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Our functions. 690f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 691f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic const JdwpTransport socketTransport = { 692f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project startup, 693f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project acceptConnection, 694f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project establishConnection, 695f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project closeConnection, 696f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project netShutdown, 697f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project netFree, 698f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project isConnected, 699f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project awaitingHandshake, 700f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project processIncoming, 701f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sendRequest 702f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}; 703f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 704f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 705f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Return our set. 706f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 707f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectconst JdwpTransport* dvmJdwpAndroidAdbTransport(void) 708f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 709f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return &socketTransport; 710f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 711f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 712