JdwpAdb.cpp revision f6c387128427e121477c1b32ad35cdcaa5101ba3
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
132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic int  receiveClientFd(JdwpNetState*  netState)
133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    struct msghdr    msg;
135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    struct cmsghdr*  cmsg;
136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    struct iovec     iov;
137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    char             dummy = '!';
138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    union {
139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        struct cmsghdr cm;
140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        char buffer[CMSG_SPACE(sizeof(int))];
141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    } cm_un;
142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int              ret;
143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    iov.iov_base       = &dummy;
145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    iov.iov_len        = 1;
146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    msg.msg_name       = NULL;
147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    msg.msg_namelen    = 0;
148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    msg.msg_iov        = &iov;
149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    msg.msg_iovlen     = 1;
150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    msg.msg_flags      = 0;
151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    msg.msg_control    = cm_un.buffer;
152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    msg.msg_controllen = sizeof(cm_un.buffer);
153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    cmsg = CMSG_FIRSTHDR(&msg);
155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    cmsg->cmsg_len   = msg.msg_controllen;
156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    cmsg->cmsg_level = SOL_SOCKET;
157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    cmsg->cmsg_type  = SCM_RIGHTS;
158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    ((int*)CMSG_DATA(cmsg))[0] = -1;
159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    do {
161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ret = recvmsg(netState->controlSock, &msg, 0);
162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    } while (ret < 0 && errno == EINTR);
163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (ret < 0) {
165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGE("receiving file descriptor from ADB failed (socket %d): %s\n",
166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             netState->controlSock, strerror(errno));
167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return -1;
168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return ((int*)CMSG_DATA(cmsg))[0];
171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Block forever, waiting for a debugger to connect to us.  Called from the
175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * JDWP thread.
176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This needs to un-block and return "false" if the VM is shutting down.  It
178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * should return "true" when it successfully accepts a connection.
179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic bool acceptConnection(struct JdwpState* state)
181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    JdwpNetState*  netState = state->netState;
183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /* first, ensure that we get a connection to the ADB daemon */
185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (netState->controlSock < 0)
187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int        sleep_ms     = 500;
189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        const int  sleep_max_ms = 2*1000;
190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        char       buff[5];
191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        netState->controlSock = socket(PF_UNIX, SOCK_STREAM, 0);
193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (netState->controlSock < 0) {
194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            LOGE("Could not create ADB control socket:%s\n",
195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                 strerror(errno));
196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return false;
197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (pipe(netState->wakeFds) < 0) {
200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            LOGE("pipe failed");
201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return false;
202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        snprintf(buff, sizeof(buff), "%04x", getpid());
205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        buff[4] = 0;
206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (;;) {
208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            int  ret = connect(netState->controlSock,
209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                               &netState->controlAddr.controlAddrPlain,
210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                               netState->controlAddrLen);
211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (!ret) {
212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                /* now try to send our pid to the ADB daemon */
213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                do {
214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    ret = send( netState->controlSock, buff, 4, 0 );
215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                } while (ret < 0 && errno == EINTR);
216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if (ret >= 0) {
218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    LOGV("PID sent as '%.*s' to ADB\n", 4, buff);
219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    break;
220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                LOGE("Weird, can't send JDWP process pid to ADB: %s\n",
223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                     strerror(errno));
224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return false;
225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            LOGV("Can't connect to ADB control socket:%s\n",
227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                 strerror(errno));
228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            usleep( sleep_ms*1000 );
230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            sleep_ms += (sleep_ms >> 1);
232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (sleep_ms > sleep_max_ms)
233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                sleep_ms = sleep_max_ms;
234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    LOGV("trying to receive file descriptor from ADB\n");
238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /* now we can receive a client file descriptor */
239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    netState->clientSock = receiveClientFd(netState);
240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (netState->clientSock >= 0) {
241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGI("received file descriptor %d from ADB\n", netState->clientSock);
242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        netState->awaitingHandshake = 1;
243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        netState->inputCount = 0;
244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return (netState->clientSock >= 0);
246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Connect out to a debugger (for server=n).  Not required.
250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic bool establishConnection(struct JdwpState* state)
252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return false;
254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Close a connection from a debugger (which may have already dropped us).
258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Only called from the JDWP thread.
259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void closeConnection(struct JdwpState* state)
261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    JdwpNetState* netState;
263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(state != NULL && state->netState != NULL);
265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    netState = state->netState;
267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (netState->clientSock < 0)
268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return;
269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    LOGV("+++ closed JDWP <-> ADB connection\n");
271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    close(netState->clientSock);
273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    netState->clientSock = -1;
274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Close all network stuff, including the socket we use to listen for
278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * new connections.
279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * May be called from a non-JDWP thread, e.g. when the VM is shutting down.
281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void adbStateShutdown(struct JdwpNetState* netState)
283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int  controlSock;
285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int  clientSock;
286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (netState == NULL)
288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return;
289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    clientSock = netState->clientSock;
291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (clientSock >= 0) {
292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        shutdown(clientSock, SHUT_RDWR);
293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        netState->clientSock = -1;
294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    controlSock = netState->controlSock;
297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (controlSock >= 0) {
298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        shutdown(controlSock, SHUT_RDWR);
299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        netState->controlSock = -1;
300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (netState->wakeFds[1] >= 0) {
303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGV("+++ writing to wakePipe\n");
304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        (void) write(netState->wakeFds[1], "", 1);
305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void netShutdown(JdwpState* state)
309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    adbStateShutdown(state->netState);
311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Free up anything we put in state->netState.  This is called after
315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "netShutdown", after the JDWP thread has stopped.
316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void netFree(struct JdwpState* state)
318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    JdwpNetState*  netState = state->netState;
320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    adbStateFree(netState);
322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Is a debugger connected to us?
326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic bool isConnected(struct JdwpState* state)
328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return (state->netState != NULL   &&
330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            state->netState->clientSock >= 0);
331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Are we still waiting for the JDWP handshake?
335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic bool awaitingHandshake(struct JdwpState* state)
337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return state->netState->awaitingHandshake;
339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Figure out if we have a full packet in the buffer.
343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic bool haveFullPacket(JdwpNetState* netState)
345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    long length;
347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (netState->awaitingHandshake)
349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return (netState->inputCount >= (int) kMagicHandshakeLen);
350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (netState->inputCount < 4)
352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return false;
353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    length = get4BE(netState->inputBuffer);
355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return (netState->inputCount >= length);
356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Consume bytes from the buffer.
360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This would be more efficient with a circular buffer.  However, we're
362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * usually only going to find one packet, which is trivial to handle.
363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void consumeBytes(JdwpNetState* netState, int count)
365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(count > 0);
367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(count <= netState->inputCount);
368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (count == netState->inputCount) {
370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        netState->inputCount = 0;
371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return;
372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
373f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    memmove(netState->inputBuffer, netState->inputBuffer + count,
375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        netState->inputCount - count);
376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    netState->inputCount -= count;
377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Handle a packet.  Returns "false" if we encounter a connection-fatal error.
381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic bool handlePacket(JdwpState* state)
383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    JdwpNetState* netState = state->netState;
385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const unsigned char* buf = netState->inputBuffer;
386f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    JdwpReqHeader hdr;
387f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    u4 length, id;
388f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    u1 flags, cmdSet, cmd;
389f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    u2 error;
390f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    bool reply;
391f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int dataLen;
392f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
393f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    cmd = cmdSet = 0;       // shut up gcc
394f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
395f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*dumpPacket(netState->inputBuffer);*/
396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    length = read4BE(&buf);
398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    id = read4BE(&buf);
399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    flags = read1(&buf);
400f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if ((flags & kJDWPFlagReply) != 0) {
401f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        reply = true;
402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        error = read2BE(&buf);
403f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    } else {
404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        reply = false;
405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        cmdSet = read1(&buf);
406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        cmd = read1(&buf);
407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert((int) length <= netState->inputCount);
410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dataLen = length - (buf - netState->inputBuffer);
411f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
412f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (!reply) {
413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ExpandBuf* pReply = expandBufAlloc();
414f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
415f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        hdr.length = length;
416f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        hdr.id = id;
417f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        hdr.cmdSet = cmdSet;
418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        hdr.cmd = cmd;
419f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmJdwpProcessRequest(state, &hdr, buf, dataLen, pReply);
420f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (expandBufGetLength(pReply) > 0) {
421f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            int cc;
422f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
423f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            /*
424f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * TODO: we currently assume the write() will complete in one
425f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * go, which may not be safe for a network socket.  We may need
426f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * to mutex this against sendRequest().
427f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             */
428f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            cc = write(netState->clientSock, expandBufGetBuffer(pReply),
429f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    expandBufGetLength(pReply));
430f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (cc != (int) expandBufGetLength(pReply)) {
431f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                LOGE("Failed sending reply to debugger: %s\n", strerror(errno));
432f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                expandBufFree(pReply);
433f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return false;
434f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
435f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } else {
436f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            LOGW("No reply created for set=%d cmd=%d\n", cmdSet, cmd);
437f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
438f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        expandBufFree(pReply);
439f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    } else {
440f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGV("reply?!\n");
441f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(false);
442f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
443f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
444f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    LOGV("----------\n");
445f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
446f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    consumeBytes(netState, length);
447f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return true;
448f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
449f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
450f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
451f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Process incoming data.  If no data is available, this will block until
452f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * some arrives.
453f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
454f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If we get a full packet, handle it.
455f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
456f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * To take some of the mystery out of life, we want to reject incoming
457f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * connections if we already have a debugger attached.  If we don't, the
458f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * debugger will just mysteriously hang until it times out.  We could just
459f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * close the listen socket, but there's a good chance we won't be able to
460f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * bind to the same port again, which would confuse utilities.
461f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
462f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns "false" on error (indicating that the connection has been severed),
463f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "true" if things are still okay.
464f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
465f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic bool processIncoming(JdwpState* state)
466f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
467f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    JdwpNetState* netState = state->netState;
468f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int readCount;
469f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
470f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(netState->clientSock >= 0);
471f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
472f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (!haveFullPacket(netState)) {
473f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /* read some more, looping until we have data */
474f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        errno = 0;
475f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        while (1) {
476f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            int selCount;
477f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            fd_set readfds;
478f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            int maxfd = -1;
479f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            int fd;
480f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
481f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            FD_ZERO(&readfds);
482f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
483f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            /* configure fds; note these may get zapped by another thread */
484f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            fd = netState->controlSock;
485f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (fd >= 0) {
486f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                FD_SET(fd, &readfds);
487f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if (maxfd < fd)
488f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    maxfd = fd;
489f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
490f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            fd = netState->clientSock;
491f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (fd >= 0) {
492f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                FD_SET(fd, &readfds);
493f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if (maxfd < fd)
494f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    maxfd = fd;
495f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
496f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            fd = netState->wakeFds[0];
497f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (fd >= 0) {
498f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                FD_SET(fd, &readfds);
499f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if (maxfd < fd)
500f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    maxfd = fd;
501f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            } else {
502f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                LOGI("NOTE: entering select w/o wakepipe\n");
503f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
504f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
505f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (maxfd < 0) {
506f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                LOGV("+++ all fds are closed\n");
507f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return false;
508f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
509f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
510f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            /*
511f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * Select blocks until it sees activity on the file descriptors.
512f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * Closing the local file descriptor does not count as activity,
513f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * so we can't rely on that to wake us up (it works for read()
514f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * and accept(), but not select()).
515f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             *
516f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * We can do one of three things: (1) send a signal and catch
517f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * EINTR, (2) open an additional fd ("wakePipe") and write to
518f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * it when it's time to exit, or (3) time out periodically and
519f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * re-issue the select.  We're currently using #2, as it's more
520f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * reliable than #1 and generally better than #3.  Wastes two fds.
521f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             */
522f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            selCount = select(maxfd+1, &readfds, NULL, NULL, NULL);
523f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (selCount < 0) {
524f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if (errno == EINTR)
525f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    continue;
526f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                LOGE("select failed: %s\n", strerror(errno));
527f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                goto fail;
528f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
529f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
530f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (netState->wakeFds[0] >= 0 &&
531f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                FD_ISSET(netState->wakeFds[0], &readfds))
532f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            {
533f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                LOGD("Got wake-up signal, bailing out of select\n");
534f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                goto fail;
535f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
536f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (netState->controlSock >= 0 &&
537f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                FD_ISSET(netState->controlSock, &readfds))
538f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            {
539f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                LOGI("Ignoring second debugger -- accepting and dropping\n");
540f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                int  sock = receiveClientFd(netState);
541f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if (sock < 0)
542f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    LOGI("Weird -- client fd reception failed\n");
543f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                else
544f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    close(sock);
545f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
546f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (netState->clientSock >= 0 &&
547f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                FD_ISSET(netState->clientSock, &readfds))
548f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            {
549f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                readCount = read(netState->clientSock,
550f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                netState->inputBuffer + netState->inputCount,
551f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    sizeof(netState->inputBuffer) - netState->inputCount);
552f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if (readCount < 0) {
553f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    /* read failed */
554f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    if (errno != EINTR)
555f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        goto fail;
556f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    LOGD("+++ EINTR hit\n");
557f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    return true;
558f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                } else if (readCount == 0) {
559f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    /* EOF hit -- far end went away */
560f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    LOGD("+++ peer disconnected\n");
561f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    goto fail;
562f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                } else
563f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    break;
564f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
565f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
566f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
567f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        netState->inputCount += readCount;
568f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (!haveFullPacket(netState))
569f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return true;        /* still not there yet */
570f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
571f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
572f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*
573f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Special-case the initial handshake.  For some bizarre reason we're
574f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * expected to emulate bad tty settings by echoing the request back
575f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * exactly as it was sent.  Note the handshake is always initiated by
576f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * the debugger, no matter who connects to whom.
577f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
578f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Other than this one case, the protocol [claims to be] stateless.
579f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
580f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (netState->awaitingHandshake) {
581f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int cc;
582f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
583f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (memcmp(netState->inputBuffer,
584f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                kMagicHandshake, kMagicHandshakeLen) != 0)
585f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        {
586f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            LOGE("ERROR: bad handshake '%.14s'\n", netState->inputBuffer);
587f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            goto fail;
588f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
589f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
590f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        errno = 0;
591f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        cc = write(netState->clientSock, netState->inputBuffer,
592f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                kMagicHandshakeLen);
593f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (cc != kMagicHandshakeLen) {
594f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            LOGE("Failed writing handshake bytes: %s (%d of %d)\n",
595f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                strerror(errno), cc, (int) kMagicHandshakeLen);
596f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            goto fail;
597f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
598f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
599f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        consumeBytes(netState, kMagicHandshakeLen);
600f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        netState->awaitingHandshake = false;
601f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGV("+++ handshake complete\n");
602f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return true;
603f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
604f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
605f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*
606f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Handle this packet.
607f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
608f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return handlePacket(state);
609f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
610f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectfail:
611f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    closeConnection(state);
612f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return false;
613f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
614f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
615f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
616f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Send a request.
617f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
618f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The entire packet must be sent with a single write() call to avoid
619f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * threading issues.
620f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
621f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns "true" if it was sent successfully.
622f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
623f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic bool sendRequest(JdwpState* state, ExpandBuf* pReq)
624f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
625f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    JdwpNetState* netState = state->netState;
626f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int cc;
627f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
628f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /* dumpPacket(expandBufGetBuffer(pReq)); */
629f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (netState->clientSock < 0) {
630f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /* can happen with some DDMS events */
631f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGV("NOT sending request -- no debugger is attached\n");
632f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return false;
633f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
634f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
635f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*
636f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * TODO: we currently assume the write() will complete in one
637f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * go, which may not be safe for a network socket.  We may need
638f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * to mutex this against handlePacket().
639f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
640f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    errno = 0;
641f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    cc = write(netState->clientSock, expandBufGetBuffer(pReq),
642f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            expandBufGetLength(pReq));
643f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (cc != (int) expandBufGetLength(pReq)) {
644f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGE("Failed sending req to debugger: %s (%d of %d)\n",
645f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            strerror(errno), cc, (int) expandBufGetLength(pReq));
646f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return false;
647f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
648f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
649f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return true;
650f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
651f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
652f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
653f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
654f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Our functions.
655f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
656f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic const JdwpTransport socketTransport = {
657f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    startup,
658f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    acceptConnection,
659f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    establishConnection,
660f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    closeConnection,
661f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    netShutdown,
662f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    netFree,
663f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    isConnected,
664f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    awaitingHandshake,
665f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    processIncoming,
666f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    sendRequest
667f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project};
668f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
669f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
670f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Return our set.
671f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
672f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectconst JdwpTransport* dvmJdwpAndroidAdbTransport(void)
673f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
674f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return &socketTransport;
675f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
676f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
677