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 */ 16d53c7efac74f2c690a86871f160a0f36fbc069efDan Bornstein 17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include "jdwp/JdwpPriv.h" 18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include "jdwp/JdwpHandler.h" 19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <sys/socket.h> 20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <sys/un.h> 21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <errno.h> 22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <unistd.h> 23d53c7efac74f2c690a86871f160a0f36fbc069efDan Bornstein#include <cutils/sockets.h> 24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 25d53c7efac74f2c690a86871f160a0f36fbc069efDan Bornstein/* 26d53c7efac74f2c690a86871f160a0f36fbc069efDan Bornstein * The JDWP <-> ADB transport protocol is explained in detail 27d53c7efac74f2c690a86871f160a0f36fbc069efDan Bornstein * in system/core/adb/jdwp_service.c. Here's a summary. 28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1/ when the JDWP thread starts, it tries to connect to a Unix 30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * domain stream socket (@jdwp-control) that is opened by the 31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * ADB daemon. 32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 2/ it then sends the current process PID as a string of 4 hexadecimal 34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * chars (no terminating zero) 35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 3/ then, it uses recvmsg to receive file descriptors from the 37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * daemon. each incoming file descriptor is a pass-through to 38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * a given JDWP debugger, that can be used to read the usual 39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * JDWP-handshake, etc... 40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define kInputBufferSize 8192 43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define kMagicHandshake "JDWP-Handshake" 45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define kMagicHandshakeLen (sizeof(kMagicHandshake)-1) 46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define kJdwpControlName "\0jdwp-control" 48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define kJdwpControlNameLen (sizeof(kJdwpControlName)-1) 49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 50128689844fda7f9287cc7494ec357397b6d59576jeffhaostruct JdwpNetState : public JdwpNetStateBase { 51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int controlSock; 52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bool awaitingHandshake; 53201a6b569b3820047bfe6dc22b793e646dd7eec2Andy McFadden bool shuttingDown; 54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int wakeFds[2]; 55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int inputCount; 57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unsigned char inputBuffer[kInputBufferSize]; 58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project socklen_t controlAddrLen; 60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project union { 61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project struct sockaddr_un controlAddrUn; 62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project struct sockaddr controlAddrPlain; 63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } controlAddr; 64128689844fda7f9287cc7494ec357397b6d59576jeffhao 65128689844fda7f9287cc7494ec357397b6d59576jeffhao JdwpNetState() 66128689844fda7f9287cc7494ec357397b6d59576jeffhao { 67128689844fda7f9287cc7494ec357397b6d59576jeffhao controlSock = -1; 68128689844fda7f9287cc7494ec357397b6d59576jeffhao awaitingHandshake = false; 69128689844fda7f9287cc7494ec357397b6d59576jeffhao shuttingDown = false; 70128689844fda7f9287cc7494ec357397b6d59576jeffhao wakeFds[0] = -1; 71128689844fda7f9287cc7494ec357397b6d59576jeffhao wakeFds[1] = -1; 72128689844fda7f9287cc7494ec357397b6d59576jeffhao 73128689844fda7f9287cc7494ec357397b6d59576jeffhao inputCount = 0; 74128689844fda7f9287cc7494ec357397b6d59576jeffhao 75128689844fda7f9287cc7494ec357397b6d59576jeffhao controlAddr.controlAddrUn.sun_family = AF_UNIX; 76128689844fda7f9287cc7494ec357397b6d59576jeffhao controlAddrLen = sizeof(controlAddr.controlAddrUn.sun_family) + 77128689844fda7f9287cc7494ec357397b6d59576jeffhao kJdwpControlNameLen; 78128689844fda7f9287cc7494ec357397b6d59576jeffhao memcpy(controlAddr.controlAddrUn.sun_path, kJdwpControlName, 79128689844fda7f9287cc7494ec357397b6d59576jeffhao kJdwpControlNameLen); 80128689844fda7f9287cc7494ec357397b6d59576jeffhao } 81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}; 82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void 84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectadbStateFree( JdwpNetState* netState ) 85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (netState == NULL) 87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return; 88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (netState->clientSock >= 0) { 90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project shutdown(netState->clientSock, SHUT_RDWR); 91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project close(netState->clientSock); 92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (netState->controlSock >= 0) { 94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project shutdown(netState->controlSock, SHUT_RDWR); 95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project close(netState->controlSock); 96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (netState->wakeFds[0] >= 0) { 98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project close(netState->wakeFds[0]); 99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project netState->wakeFds[0] = -1; 100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (netState->wakeFds[1] >= 0) { 102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project close(netState->wakeFds[1]); 103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project netState->wakeFds[1] = -1; 104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 106128689844fda7f9287cc7494ec357397b6d59576jeffhao delete netState; 107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Do initial prep work, e.g. binding to ports and opening files. This 111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * runs in the main thread, before the JDWP thread starts, so it shouldn't 112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * do anything that might block forever. 113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic bool startup(struct JdwpState* state, const JdwpStartupParams* pParams) 115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project JdwpNetState* netState; 117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 11892c1f6f1b4249e4e379452ee7b49f027052bf4ceSteve Block ALOGV("ADB transport startup"); 119de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 120128689844fda7f9287cc7494ec357397b6d59576jeffhao state->netState = netState = new JdwpNetState; 121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (netState == NULL) 122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 127305efe65f9083b88562ce823bde6df027a2ff71eAndy McFadden/* 128305efe65f9083b88562ce823bde6df027a2ff71eAndy McFadden * Receive a file descriptor from ADB. The fd can be used to communicate 129305efe65f9083b88562ce823bde6df027a2ff71eAndy McFadden * directly with a debugger or DDMS. 130305efe65f9083b88562ce823bde6df027a2ff71eAndy McFadden * 1316196d15e42f317a8075f0d8b8c92b0c69736d037Andy McFadden * Returns the file descriptor on success. On failure, returns -1 and 1326196d15e42f317a8075f0d8b8c92b0c69736d037Andy McFadden * closes netState->controlSock. 133305efe65f9083b88562ce823bde6df027a2ff71eAndy McFadden */ 134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic int receiveClientFd(JdwpNetState* netState) 135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project struct msghdr msg; 137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project struct cmsghdr* cmsg; 138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project struct iovec iov; 139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char dummy = '!'; 140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project union { 141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project struct cmsghdr cm; 142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char buffer[CMSG_SPACE(sizeof(int))]; 143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } cm_un; 144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int ret; 145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project iov.iov_base = &dummy; 147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project iov.iov_len = 1; 148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project msg.msg_name = NULL; 149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project msg.msg_namelen = 0; 150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project msg.msg_iov = &iov; 151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project msg.msg_iovlen = 1; 152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project msg.msg_flags = 0; 153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project msg.msg_control = cm_un.buffer; 154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project msg.msg_controllen = sizeof(cm_un.buffer); 155de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project cmsg = CMSG_FIRSTHDR(&msg); 157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project cmsg->cmsg_len = msg.msg_controllen; 158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project cmsg->cmsg_level = SOL_SOCKET; 159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project cmsg->cmsg_type = SCM_RIGHTS; 160d5c36b9040bd26a81219a7f399513526f9b46324Carl Shapiro ((int*)(void*)CMSG_DATA(cmsg))[0] = -1; 161de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project do { 163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ret = recvmsg(netState->controlSock, &msg, 0); 164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } while (ret < 0 && errno == EINTR); 165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1666196d15e42f317a8075f0d8b8c92b0c69736d037Andy McFadden if (ret <= 0) { 1676196d15e42f317a8075f0d8b8c92b0c69736d037Andy McFadden if (ret < 0) { 168e8e1ddccd616e8226b7cc1e4e9fdb327429249e8Steve Block ALOGW("receiving file descriptor from ADB failed (socket %d): %s", 1696196d15e42f317a8075f0d8b8c92b0c69736d037Andy McFadden netState->controlSock, strerror(errno)); 1706196d15e42f317a8075f0d8b8c92b0c69736d037Andy McFadden } 171305efe65f9083b88562ce823bde6df027a2ff71eAndy McFadden close(netState->controlSock); 172305efe65f9083b88562ce823bde6df027a2ff71eAndy McFadden netState->controlSock = -1; 1736196d15e42f317a8075f0d8b8c92b0c69736d037Andy McFadden return -1; 174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 176d5c36b9040bd26a81219a7f399513526f9b46324Carl Shapiro return ((int*)(void*)CMSG_DATA(cmsg))[0]; 177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Block forever, waiting for a debugger to connect to us. Called from the 181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * JDWP thread. 182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This needs to un-block and return "false" if the VM is shutting down. It 184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * should return "true" when it successfully accepts a connection. 185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic bool acceptConnection(struct JdwpState* state) 187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project JdwpNetState* netState = state->netState; 189305efe65f9083b88562ce823bde6df027a2ff71eAndy McFadden int retryCount = 0; 190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* first, ensure that we get a connection to the ADB daemon */ 192de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 193305efe65f9083b88562ce823bde6df027a2ff71eAndy McFaddenretry: 194201a6b569b3820047bfe6dc22b793e646dd7eec2Andy McFadden if (netState->shuttingDown) 195201a6b569b3820047bfe6dc22b793e646dd7eec2Andy McFadden return false; 196201a6b569b3820047bfe6dc22b793e646dd7eec2Andy McFadden 197201a6b569b3820047bfe6dc22b793e646dd7eec2Andy McFadden if (netState->controlSock < 0) { 198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int sleep_ms = 500; 199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const int sleep_max_ms = 2*1000; 200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char buff[5]; 201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project netState->controlSock = socket(PF_UNIX, SOCK_STREAM, 0); 203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (netState->controlSock < 0) { 204c1a4ab9c313d8a3d12007f2dbef7b5a6fa4ac2efSteve Block ALOGE("Could not create ADB control socket:%s", 205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project strerror(errno)); 206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pipe(netState->wakeFds) < 0) { 210c1a4ab9c313d8a3d12007f2dbef7b5a6fa4ac2efSteve Block ALOGE("pipe failed"); 211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project snprintf(buff, sizeof(buff), "%04x", getpid()); 215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project buff[4] = 0; 216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (;;) { 218305efe65f9083b88562ce823bde6df027a2ff71eAndy McFadden /* 219305efe65f9083b88562ce823bde6df027a2ff71eAndy McFadden * If adbd isn't running, because USB debugging was disabled or 220305efe65f9083b88562ce823bde6df027a2ff71eAndy McFadden * perhaps the system is restarting it for "adb root", the 221305efe65f9083b88562ce823bde6df027a2ff71eAndy McFadden * connect() will fail. We loop here forever waiting for it 222305efe65f9083b88562ce823bde6df027a2ff71eAndy McFadden * to come back. 223305efe65f9083b88562ce823bde6df027a2ff71eAndy McFadden * 224305efe65f9083b88562ce823bde6df027a2ff71eAndy McFadden * Waking up and polling every couple of seconds is generally a 225305efe65f9083b88562ce823bde6df027a2ff71eAndy McFadden * bad thing to do, but we only do this if the application is 226305efe65f9083b88562ce823bde6df027a2ff71eAndy McFadden * debuggable *and* adbd isn't running. Still, for the sake 227305efe65f9083b88562ce823bde6df027a2ff71eAndy McFadden * of battery life, we should consider timing out and giving 228305efe65f9083b88562ce823bde6df027a2ff71eAndy McFadden * up after a few minutes in case somebody ships an app with 229305efe65f9083b88562ce823bde6df027a2ff71eAndy McFadden * the debuggable flag set. 230305efe65f9083b88562ce823bde6df027a2ff71eAndy McFadden */ 231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int ret = connect(netState->controlSock, 232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project &netState->controlAddr.controlAddrPlain, 233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project netState->controlAddrLen); 234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!ret) { 235d53c7efac74f2c690a86871f160a0f36fbc069efDan Bornstein if (!socket_peer_is_trusted(netState->controlSock)) { 236d53c7efac74f2c690a86871f160a0f36fbc069efDan Bornstein if (shutdown(netState->controlSock, SHUT_RDWR)) { 237c1a4ab9c313d8a3d12007f2dbef7b5a6fa4ac2efSteve Block ALOGE("trouble shutting down socket: %s", strerror(errno)); 238d53c7efac74f2c690a86871f160a0f36fbc069efDan Bornstein } 239d53c7efac74f2c690a86871f160a0f36fbc069efDan Bornstein return false; 240d53c7efac74f2c690a86871f160a0f36fbc069efDan Bornstein } 241d53c7efac74f2c690a86871f160a0f36fbc069efDan Bornstein 242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* now try to send our pid to the ADB daemon */ 243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project do { 244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ret = send( netState->controlSock, buff, 4, 0 ); 245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } while (ret < 0 && errno == EINTR); 246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (ret >= 0) { 24892c1f6f1b4249e4e379452ee7b49f027052bf4ceSteve Block ALOGV("PID sent as '%.*s' to ADB", 4, buff); 249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 252c1a4ab9c313d8a3d12007f2dbef7b5a6fa4ac2efSteve Block ALOGE("Weird, can't send JDWP process pid to ADB: %s", 253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project strerror(errno)); 254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 25692c1f6f1b4249e4e379452ee7b49f027052bf4ceSteve Block ALOGV("Can't connect to ADB control socket:%s", 257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project strerror(errno)); 258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project usleep( sleep_ms*1000 ); 260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sleep_ms += (sleep_ms >> 1); 262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (sleep_ms > sleep_max_ms) 263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sleep_ms = sleep_max_ms; 26429527c9db5fcaac8ae4c567304d8b7160110214bBrett Chabot 26529527c9db5fcaac8ae4c567304d8b7160110214bBrett Chabot if (netState->shuttingDown) 26629527c9db5fcaac8ae4c567304d8b7160110214bBrett Chabot return false; 267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 27092c1f6f1b4249e4e379452ee7b49f027052bf4ceSteve Block ALOGV("trying to receive file descriptor from ADB"); 271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* now we can receive a client file descriptor */ 272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project netState->clientSock = receiveClientFd(netState); 273201a6b569b3820047bfe6dc22b793e646dd7eec2Andy McFadden if (netState->shuttingDown) 274201a6b569b3820047bfe6dc22b793e646dd7eec2Andy McFadden return false; // suppress logs and additional activity 275201a6b569b3820047bfe6dc22b793e646dd7eec2Andy McFadden 2766196d15e42f317a8075f0d8b8c92b0c69736d037Andy McFadden if (netState->clientSock < 0) { 277305efe65f9083b88562ce823bde6df027a2ff71eAndy McFadden if (++retryCount > 5) { 278c1a4ab9c313d8a3d12007f2dbef7b5a6fa4ac2efSteve Block ALOGE("adb connection max retries exceeded"); 279305efe65f9083b88562ce823bde6df027a2ff71eAndy McFadden return false; 280305efe65f9083b88562ce823bde6df027a2ff71eAndy McFadden } 281305efe65f9083b88562ce823bde6df027a2ff71eAndy McFadden goto retry; 282305efe65f9083b88562ce823bde6df027a2ff71eAndy McFadden } else { 28392c1f6f1b4249e4e379452ee7b49f027052bf4ceSteve Block ALOGV("received file descriptor %d from ADB", netState->clientSock); 284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project netState->awaitingHandshake = 1; 285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project netState->inputCount = 0; 286305efe65f9083b88562ce823bde6df027a2ff71eAndy McFadden return true; 287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Connect out to a debugger (for server=n). Not required. 292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic bool establishConnection(struct JdwpState* state) 294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Close a connection from a debugger (which may have already dropped us). 300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Only called from the JDWP thread. 301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void closeConnection(struct JdwpState* state) 303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project JdwpNetState* netState; 305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(state != NULL && state->netState != NULL); 307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project netState = state->netState; 309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (netState->clientSock < 0) 310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return; 311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 31292c1f6f1b4249e4e379452ee7b49f027052bf4ceSteve Block ALOGV("+++ closed JDWP <-> ADB connection"); 313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project close(netState->clientSock); 315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project netState->clientSock = -1; 316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Close all network stuff, including the socket we use to listen for 320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * new connections. 321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * May be called from a non-JDWP thread, e.g. when the VM is shutting down. 323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void adbStateShutdown(struct JdwpNetState* netState) 325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int controlSock; 327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int clientSock; 328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (netState == NULL) 330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return; 331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 332201a6b569b3820047bfe6dc22b793e646dd7eec2Andy McFadden netState->shuttingDown = true; 333201a6b569b3820047bfe6dc22b793e646dd7eec2Andy McFadden 334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project clientSock = netState->clientSock; 335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (clientSock >= 0) { 336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project shutdown(clientSock, SHUT_RDWR); 337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project netState->clientSock = -1; 338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project controlSock = netState->controlSock; 341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (controlSock >= 0) { 342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project shutdown(controlSock, SHUT_RDWR); 343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project netState->controlSock = -1; 344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 345de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (netState->wakeFds[1] >= 0) { 34792c1f6f1b4249e4e379452ee7b49f027052bf4ceSteve Block ALOGV("+++ writing to wakePipe"); 348b680ae3140a789f182c26abf8df9645f7744113aElliott Hughes TEMP_FAILURE_RETRY(write(netState->wakeFds[1], "", 1)); 349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void netShutdown(JdwpState* state) 353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project adbStateShutdown(state->netState); 355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Free up anything we put in state->netState. This is called after 359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "netShutdown", after the JDWP thread has stopped. 360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void netFree(struct JdwpState* state) 362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project JdwpNetState* netState = state->netState; 364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project adbStateFree(netState); 366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Is a debugger connected to us? 370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic bool isConnected(struct JdwpState* state) 372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 373f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (state->netState != NULL && 374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project state->netState->clientSock >= 0); 375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Are we still waiting for the JDWP handshake? 379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic bool awaitingHandshake(struct JdwpState* state) 381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return state->netState->awaitingHandshake; 383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 386f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Figure out if we have a full packet in the buffer. 387f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 388f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic bool haveFullPacket(JdwpNetState* netState) 389f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 390f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project long length; 391f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 392f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (netState->awaitingHandshake) 393f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (netState->inputCount >= (int) kMagicHandshakeLen); 394f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 395f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (netState->inputCount < 4) 396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project length = get4BE(netState->inputBuffer); 399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (netState->inputCount >= length); 400f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 401f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 403f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Consume bytes from the buffer. 404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This would be more efficient with a circular buffer. However, we're 406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * usually only going to find one packet, which is trivial to handle. 407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void consumeBytes(JdwpNetState* netState, int count) 409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(count > 0); 411f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(count <= netState->inputCount); 412f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (count == netState->inputCount) { 414f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project netState->inputCount = 0; 415f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return; 416f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 417f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project memmove(netState->inputBuffer, netState->inputBuffer + count, 419f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project netState->inputCount - count); 420f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project netState->inputCount -= count; 421f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 422f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 423f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 424f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Handle a packet. Returns "false" if we encounter a connection-fatal error. 425f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 426f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic bool handlePacket(JdwpState* state) 427f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 428f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project JdwpNetState* netState = state->netState; 429f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const unsigned char* buf = netState->inputBuffer; 430f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project JdwpReqHeader hdr; 431f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u4 length, id; 432f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u1 flags, cmdSet, cmd; 433f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u2 error; 434f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bool reply; 435f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int dataLen; 436f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 437f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project cmd = cmdSet = 0; // shut up gcc 438f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 439f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project length = read4BE(&buf); 440f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project id = read4BE(&buf); 441f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project flags = read1(&buf); 442f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((flags & kJDWPFlagReply) != 0) { 443f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project reply = true; 444f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project error = read2BE(&buf); 445f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 446f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project reply = false; 447f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project cmdSet = read1(&buf); 448f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project cmd = read1(&buf); 449f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 450f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 451f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert((int) length <= netState->inputCount); 452f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dataLen = length - (buf - netState->inputBuffer); 453f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 454f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!reply) { 455f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ExpandBuf* pReply = expandBufAlloc(); 456f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 457f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hdr.length = length; 458f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hdr.id = id; 459f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hdr.cmdSet = cmdSet; 460f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hdr.cmd = cmd; 461f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmJdwpProcessRequest(state, &hdr, buf, dataLen, pReply); 462f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (expandBufGetLength(pReply) > 0) { 463128689844fda7f9287cc7494ec357397b6d59576jeffhao ssize_t cc = netState->writePacket(pReply); 464f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 465128689844fda7f9287cc7494ec357397b6d59576jeffhao if (cc != (ssize_t) expandBufGetLength(pReply)) { 466c1a4ab9c313d8a3d12007f2dbef7b5a6fa4ac2efSteve Block ALOGE("Failed sending reply to debugger: %s", strerror(errno)); 467f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expandBufFree(pReply); 468f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 469f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 470f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 471e8e1ddccd616e8226b7cc1e4e9fdb327429249e8Steve Block ALOGW("No reply created for set=%d cmd=%d", cmdSet, cmd); 472f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 473f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expandBufFree(pReply); 474f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 47592c1f6f1b4249e4e379452ee7b49f027052bf4ceSteve Block ALOGV("reply?!"); 476f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(false); 477f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 478f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 47992c1f6f1b4249e4e379452ee7b49f027052bf4ceSteve Block ALOGV("----------"); 480f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 481f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project consumeBytes(netState, length); 482f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 483f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 484f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 485f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 486f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Process incoming data. If no data is available, this will block until 487f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * some arrives. 488f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 489f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If we get a full packet, handle it. 490f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 491f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * To take some of the mystery out of life, we want to reject incoming 492f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * connections if we already have a debugger attached. If we don't, the 493f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * debugger will just mysteriously hang until it times out. We could just 494f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * close the listen socket, but there's a good chance we won't be able to 495f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * bind to the same port again, which would confuse utilities. 496f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 497f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns "false" on error (indicating that the connection has been severed), 498f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "true" if things are still okay. 499f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 500f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic bool processIncoming(JdwpState* state) 501f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 502f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project JdwpNetState* netState = state->netState; 503f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int readCount; 504f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 505f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(netState->clientSock >= 0); 506f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 507f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!haveFullPacket(netState)) { 508f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* read some more, looping until we have data */ 509f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project errno = 0; 510f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (1) { 511f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int selCount; 512f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fd_set readfds; 513f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int maxfd = -1; 514f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int fd; 515f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 516f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project FD_ZERO(&readfds); 517f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 518f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* configure fds; note these may get zapped by another thread */ 519f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fd = netState->controlSock; 520f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (fd >= 0) { 521f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project FD_SET(fd, &readfds); 522f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (maxfd < fd) 523f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project maxfd = fd; 524f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 525f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fd = netState->clientSock; 526f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (fd >= 0) { 527f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project FD_SET(fd, &readfds); 528f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (maxfd < fd) 529f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project maxfd = fd; 530f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 531f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fd = netState->wakeFds[0]; 532f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (fd >= 0) { 533f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project FD_SET(fd, &readfds); 534f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (maxfd < fd) 535f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project maxfd = fd; 536f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 5374308417beec548c2b2c06ecec4f7f4a965b09fb2Steve Block ALOGI("NOTE: entering select w/o wakepipe"); 538f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 539f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 540f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (maxfd < 0) { 54192c1f6f1b4249e4e379452ee7b49f027052bf4ceSteve Block ALOGV("+++ all fds are closed"); 542f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 543f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 544f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 545f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 546f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Select blocks until it sees activity on the file descriptors. 547f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Closing the local file descriptor does not count as activity, 548f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * so we can't rely on that to wake us up (it works for read() 549f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * and accept(), but not select()). 550f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 551f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We can do one of three things: (1) send a signal and catch 552f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * EINTR, (2) open an additional fd ("wakePipe") and write to 553f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * it when it's time to exit, or (3) time out periodically and 554f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * re-issue the select. We're currently using #2, as it's more 555f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * reliable than #1 and generally better than #3. Wastes two fds. 556f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 557f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project selCount = select(maxfd+1, &readfds, NULL, NULL, NULL); 558f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (selCount < 0) { 559f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (errno == EINTR) 560f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project continue; 561c1a4ab9c313d8a3d12007f2dbef7b5a6fa4ac2efSteve Block ALOGE("select failed: %s", strerror(errno)); 562f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto fail; 563f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 564f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 565f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (netState->wakeFds[0] >= 0 && 566f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project FD_ISSET(netState->wakeFds[0], &readfds)) 567f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 568062bf509a77fce9dfcb7e7b2e401cf2a124d83d5Steve Block ALOGD("Got wake-up signal, bailing out of select"); 569f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto fail; 570f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 571f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (netState->controlSock >= 0 && 572f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project FD_ISSET(netState->controlSock, &readfds)) 573f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 574f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int sock = receiveClientFd(netState); 5756196d15e42f317a8075f0d8b8c92b0c69736d037Andy McFadden if (sock >= 0) { 5764308417beec548c2b2c06ecec4f7f4a965b09fb2Steve Block ALOGI("Ignoring second debugger -- accepting and dropping"); 577f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project close(sock); 5786196d15e42f317a8075f0d8b8c92b0c69736d037Andy McFadden } else { 5796196d15e42f317a8075f0d8b8c92b0c69736d037Andy McFadden assert(netState->controlSock < 0); 5806196d15e42f317a8075f0d8b8c92b0c69736d037Andy McFadden /* 5816196d15e42f317a8075f0d8b8c92b0c69736d037Andy McFadden * Remote side most likely went away, so our next read 5826196d15e42f317a8075f0d8b8c92b0c69736d037Andy McFadden * on netState->clientSock will fail and throw us out 5836196d15e42f317a8075f0d8b8c92b0c69736d037Andy McFadden * of the loop. 5846196d15e42f317a8075f0d8b8c92b0c69736d037Andy McFadden */ 5856196d15e42f317a8075f0d8b8c92b0c69736d037Andy McFadden } 586f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 587f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (netState->clientSock >= 0 && 588f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project FD_ISSET(netState->clientSock, &readfds)) 589f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 590f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project readCount = read(netState->clientSock, 591f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project netState->inputBuffer + netState->inputCount, 592f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sizeof(netState->inputBuffer) - netState->inputCount); 593f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (readCount < 0) { 594f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* read failed */ 595f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (errno != EINTR) 596f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto fail; 597062bf509a77fce9dfcb7e7b2e401cf2a124d83d5Steve Block ALOGD("+++ EINTR hit"); 598f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 599f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (readCount == 0) { 600f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* EOF hit -- far end went away */ 60192c1f6f1b4249e4e379452ee7b49f027052bf4ceSteve Block ALOGV("+++ peer disconnected"); 602f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto fail; 603f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else 604f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 605f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 606f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 607f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 608f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project netState->inputCount += readCount; 609f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!haveFullPacket(netState)) 610f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; /* still not there yet */ 611f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 612f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 613f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 614f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Special-case the initial handshake. For some bizarre reason we're 615f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * expected to emulate bad tty settings by echoing the request back 616f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * exactly as it was sent. Note the handshake is always initiated by 617f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the debugger, no matter who connects to whom. 618f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 619f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Other than this one case, the protocol [claims to be] stateless. 620f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 621f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (netState->awaitingHandshake) { 622f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int cc; 623f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 624f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (memcmp(netState->inputBuffer, 625f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kMagicHandshake, kMagicHandshakeLen) != 0) 626f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 627c1a4ab9c313d8a3d12007f2dbef7b5a6fa4ac2efSteve Block ALOGE("ERROR: bad handshake '%.14s'", netState->inputBuffer); 628f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto fail; 629f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 630f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 631f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project errno = 0; 632b680ae3140a789f182c26abf8df9645f7744113aElliott Hughes cc = TEMP_FAILURE_RETRY(write(netState->clientSock, netState->inputBuffer, 633b680ae3140a789f182c26abf8df9645f7744113aElliott Hughes kMagicHandshakeLen)); 634f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (cc != kMagicHandshakeLen) { 635c1a4ab9c313d8a3d12007f2dbef7b5a6fa4ac2efSteve Block ALOGE("Failed writing handshake bytes: %s (%d of %d)", 636f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project strerror(errno), cc, (int) kMagicHandshakeLen); 637f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto fail; 638f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 639f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 640f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project consumeBytes(netState, kMagicHandshakeLen); 641f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project netState->awaitingHandshake = false; 64292c1f6f1b4249e4e379452ee7b49f027052bf4ceSteve Block ALOGV("+++ handshake complete"); 643f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 644f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 645f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 646f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 647f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Handle this packet. 648f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 649f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return handlePacket(state); 650f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 651f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectfail: 652f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project closeConnection(state); 653f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 654f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 655f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 656f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 657f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Send a request. 658f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 659f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The entire packet must be sent with a single write() call to avoid 660f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * threading issues. 661f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 662f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns "true" if it was sent successfully. 663f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 664f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic bool sendRequest(JdwpState* state, ExpandBuf* pReq) 665f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 666f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project JdwpNetState* netState = state->netState; 667f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 668f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (netState->clientSock < 0) { 669f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* can happen with some DDMS events */ 67092c1f6f1b4249e4e379452ee7b49f027052bf4ceSteve Block ALOGV("NOT sending request -- no debugger is attached"); 671f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 672f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 673f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 674f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project errno = 0; 675128689844fda7f9287cc7494ec357397b6d59576jeffhao 676128689844fda7f9287cc7494ec357397b6d59576jeffhao ssize_t cc = netState->writePacket(pReq); 677128689844fda7f9287cc7494ec357397b6d59576jeffhao 678128689844fda7f9287cc7494ec357397b6d59576jeffhao if (cc != (ssize_t) expandBufGetLength(pReq)) { 679c1a4ab9c313d8a3d12007f2dbef7b5a6fa4ac2efSteve Block ALOGE("Failed sending req to debugger: %s (%d of %d)", 680128689844fda7f9287cc7494ec357397b6d59576jeffhao strerror(errno), (int) 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 6875442d46fe1d0645d786a289c1143e830a6699b14Andy McFadden/* 6880171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFadden * Send a request that was split into multiple buffers. 6895442d46fe1d0645d786a289c1143e830a6699b14Andy McFadden * 6905442d46fe1d0645d786a289c1143e830a6699b14Andy McFadden * The entire packet must be sent with a single writev() call to avoid 6915442d46fe1d0645d786a289c1143e830a6699b14Andy McFadden * threading issues. 6925442d46fe1d0645d786a289c1143e830a6699b14Andy McFadden * 6935442d46fe1d0645d786a289c1143e830a6699b14Andy McFadden * Returns "true" if it was sent successfully. 6945442d46fe1d0645d786a289c1143e830a6699b14Andy McFadden */ 6950171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFaddenstatic bool sendBufferedRequest(JdwpState* state, const struct iovec* iov, 6960171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFadden int iovcnt) 6975442d46fe1d0645d786a289c1143e830a6699b14Andy McFadden{ 6985442d46fe1d0645d786a289c1143e830a6699b14Andy McFadden JdwpNetState* netState = state->netState; 6995442d46fe1d0645d786a289c1143e830a6699b14Andy McFadden 7005442d46fe1d0645d786a289c1143e830a6699b14Andy McFadden if (netState->clientSock < 0) { 7015442d46fe1d0645d786a289c1143e830a6699b14Andy McFadden /* can happen with some DDMS events */ 70292c1f6f1b4249e4e379452ee7b49f027052bf4ceSteve Block ALOGV("NOT sending request -- no debugger is attached"); 7035442d46fe1d0645d786a289c1143e830a6699b14Andy McFadden return false; 7045442d46fe1d0645d786a289c1143e830a6699b14Andy McFadden } 7055442d46fe1d0645d786a289c1143e830a6699b14Andy McFadden 7060171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFadden size_t expected = 0; 7070171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFadden int i; 7080171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFadden for (i = 0; i < iovcnt; i++) 7090171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFadden expected += iov[i].iov_len; 7105442d46fe1d0645d786a289c1143e830a6699b14Andy McFadden 711128689844fda7f9287cc7494ec357397b6d59576jeffhao ssize_t actual = netState->writeBufferedPacket(iov, iovcnt); 712128689844fda7f9287cc7494ec357397b6d59576jeffhao 7130171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFadden if ((size_t)actual != expected) { 714c1a4ab9c313d8a3d12007f2dbef7b5a6fa4ac2efSteve Block ALOGE("Failed sending b-req to debugger: %s (%d of %zu)", 7150171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFadden strerror(errno), (int) actual, expected); 7165442d46fe1d0645d786a289c1143e830a6699b14Andy McFadden return false; 7175442d46fe1d0645d786a289c1143e830a6699b14Andy McFadden } 7185442d46fe1d0645d786a289c1143e830a6699b14Andy McFadden 7195442d46fe1d0645d786a289c1143e830a6699b14Andy McFadden return true; 7205442d46fe1d0645d786a289c1143e830a6699b14Andy McFadden} 7215442d46fe1d0645d786a289c1143e830a6699b14Andy McFadden 722f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 723f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 724f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Our functions. 725f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 726f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic const JdwpTransport socketTransport = { 727f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project startup, 728f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project acceptConnection, 729f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project establishConnection, 730f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project closeConnection, 731f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project netShutdown, 732f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project netFree, 733f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project isConnected, 734f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project awaitingHandshake, 735f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project processIncoming, 7365442d46fe1d0645d786a289c1143e830a6699b14Andy McFadden sendRequest, 7375442d46fe1d0645d786a289c1143e830a6699b14Andy McFadden sendBufferedRequest 738f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}; 739f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 740f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 741f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Return our set. 742f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 7431e1433e78f560a01744e870c19c162ab88df9dc1Carl Shapiroconst JdwpTransport* dvmJdwpAndroidAdbTransport() 744f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 745f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return &socketTransport; 746f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 747