/* * Handle a packet. Returns "false" if we encounter a connection-fatal error. */ static bool handlePacket(JdwpState* state) { JdwpNetState* netState = state->netState; const unsigned char* buf = netState->inputBuffer; JdwpReqHeader hdr; u4 length, id; u1 flags, cmdSet, cmd; //u2 error; bool reply; int dataLen; cmd = cmdSet = 0; // shut up gcc /*dumpPacket(netState->inputBuffer);*/ length = read4BE(&buf); id = read4BE(&buf); flags = read1(&buf); if ((flags & kJDWPFlagReply) != 0) { reply = true; /*error =*/ read2BE(&buf); } else { reply = false; cmdSet = read1(&buf); cmd = read1(&buf); } assert((int) length <= netState->inputCount); dataLen = length - (buf - netState->inputBuffer); if (!reply) { ExpandBuf* pReply = expandBufAlloc(); hdr.length = length; hdr.id = id; hdr.cmdSet = cmdSet; hdr.cmd = cmd; dvmJdwpProcessRequest(state, &hdr, buf, dataLen, pReply); if (expandBufGetLength(pReply) > 0) { ssize_t cc = netState->writePacket(pReply); if (cc != (ssize_t) expandBufGetLength(pReply)) { ALOGE("Failed sending reply to debugger: %s", strerror(errno)); expandBufFree(pReply); return false; } } else { ALOGW("No reply created for set=%d cmd=%d", cmdSet, cmd); } expandBufFree(pReply); } else { ALOGV("reply?!"); assert(false); } ALOGV("----------"); consumeBytes(netState, length); return true; }
/* * Send a request. * * The entire packet must be sent with a single write() call to avoid * threading issues. * * Returns "true" if it was sent successfully. */ static bool sendRequest(JdwpState* state, ExpandBuf* pReq) { JdwpNetState* netState = state->netState; int cc; /*dumpPacket(expandBufGetBuffer(pReq));*/ if (netState->clientSock < 0) { /* can happen with some DDMS events */ LOGV("NOT sending request -- no debugger is attached\n"); return false; } /* * TODO: we currently assume the write() will complete in one * go, which may not be safe for a network socket. We may need * to mutex this against handlePacket(). */ errno = 0; cc = write(netState->clientSock, expandBufGetBuffer(pReq), expandBufGetLength(pReq)); if (cc != (int) expandBufGetLength(pReq)) { LOGE("Failed sending req to debugger: %s (%d of %d)\n", strerror(errno), cc, (int) expandBufGetLength(pReq)); return false; } return true; }
/* * Send a request. * * The entire packet must be sent with a single write() call to avoid * threading issues. * * Returns "true" if it was sent successfully. */ static bool sendRequest(JdwpState* state, ExpandBuf* pReq) { JdwpNetState* netState = state->netState; /*dumpPacket(expandBufGetBuffer(pReq));*/ if (netState->clientSock < 0) { /* can happen with some DDMS events */ ALOGV("NOT sending request -- no debugger is attached"); return false; } errno = 0; ssize_t cc = netState->writePacket(pReq); if (cc != (ssize_t) expandBufGetLength(pReq)) { ALOGE("Failed sending req to debugger: %s (%d of %d)", strerror(errno), (int) cc, (int) expandBufGetLength(pReq)); return false; } return true; }
/* * Write the header into the buffer and send the packet off to the debugger. * * Takes ownership of "pReq" (currently discards it). */ static void eventFinish(JdwpState* state, ExpandBuf* pReq) { u1* buf = expandBufGetBuffer(pReq); set4BE(buf, expandBufGetLength(pReq)); set4BE(buf+4, dvmJdwpNextRequestSerial(state)); set1(buf+8, 0); /* flags */ set1(buf+9, kJdwpEventCommandSet); set1(buf+10, kJdwpCompositeCommand); dvmJdwpSendRequest(state, pReq); expandBufFree(pReq); }
/* * Handle a packet. Returns "false" if we encounter a connection-fatal error. */ static bool handlePacket(JdwpState* state) { JdwpNetState* netState = state->netState; const unsigned char* buf = netState->inputBuffer; JdwpReqHeader hdr; u4 length, id; u1 flags, cmdSet, cmd; u2 error; bool reply; int dataLen; cmd = cmdSet = 0; // shut up gcc /*dumpPacket(netState->inputBuffer);*/ length = read4BE(&buf); id = read4BE(&buf); flags = read1(&buf); if ((flags & kJDWPFlagReply) != 0) { reply = true; error = read2BE(&buf); } else { reply = false; cmdSet = read1(&buf); cmd = read1(&buf); } assert((int) length <= netState->inputCount); dataLen = length - (buf - netState->inputBuffer); if (!reply) { ExpandBuf* pReply = expandBufAlloc(); hdr.length = length; hdr.id = id; hdr.cmdSet = cmdSet; hdr.cmd = cmd; dvmJdwpProcessRequest(state, &hdr, buf, dataLen, pReply); if (expandBufGetLength(pReply) > 0) { int cc; /* * TODO: we currently assume the write() will complete in one * go, which may not be safe for a network socket. We may need * to mutex this against sendRequest(). */ cc = write(netState->clientSock, expandBufGetBuffer(pReply), expandBufGetLength(pReply)); if (cc != (int) expandBufGetLength(pReply)) { LOGE("Failed sending reply to debugger: %s\n", strerror(errno)); expandBufFree(pReply); return false; } } else { LOGW("No reply created for set=%d cmd=%d\n", cmdSet, cmd); } expandBufFree(pReply); } else { LOGV("reply?!\n"); assert(false); } LOGV("----------\n"); consumeBytes(netState, length); return true; }