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