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