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