/*
 * Copyright (C) 2008 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "jdwp/JdwpPriv.h"
#include "jdwp/JdwpHandler.h"
#include <sys/socket.h>
#include <sys/un.h>
#include <errno.h>
#include <unistd.h>
#include <cutils/sockets.h>

/*
 * The JDWP <-> ADB transport protocol is explained in detail
 * in system/core/adb/jdwp_service.c. Here's a summary.
 *
 * 1/ when the JDWP thread starts, it tries to connect to a Unix
 *    domain stream socket (@jdwp-control) that is opened by the
 *    ADB daemon.
 *
 * 2/ it then sends the current process PID as a string of 4 hexadecimal
 *    chars (no terminating zero)
 *
 * 3/ then, it uses recvmsg to receive file descriptors from the
 *    daemon. each incoming file descriptor is a pass-through to
 *    a given JDWP debugger, that can be used to read the usual
 *    JDWP-handshake, etc...
 */

#define kInputBufferSize    8192

#define kMagicHandshake     "JDWP-Handshake"
#define kMagicHandshakeLen  (sizeof(kMagicHandshake)-1)

#define kJdwpControlName    "\0jdwp-control"
#define kJdwpControlNameLen (sizeof(kJdwpControlName)-1)

struct JdwpNetState : public JdwpNetStateBase {
    int                 controlSock;
    bool                awaitingHandshake;
    bool                shuttingDown;
    int                 wakeFds[2];

    int                 inputCount;
    unsigned char       inputBuffer[kInputBufferSize];

    socklen_t           controlAddrLen;
    union {
        struct sockaddr_un  controlAddrUn;
        struct sockaddr     controlAddrPlain;
    } controlAddr;

    JdwpNetState()
    {
        controlSock = -1;
        awaitingHandshake = false;
        shuttingDown = false;
        wakeFds[0] = -1;
        wakeFds[1] = -1;

        inputCount = 0;

        controlAddr.controlAddrUn.sun_family = AF_UNIX;
        controlAddrLen = sizeof(controlAddr.controlAddrUn.sun_family) +
                kJdwpControlNameLen;
        memcpy(controlAddr.controlAddrUn.sun_path, kJdwpControlName,
                kJdwpControlNameLen);
    }
};

static void
adbStateFree( JdwpNetState*  netState )
{
    if (netState == NULL)
        return;

    if (netState->clientSock >= 0) {
        shutdown(netState->clientSock, SHUT_RDWR);
        close(netState->clientSock);
    }
    if (netState->controlSock >= 0) {
        shutdown(netState->controlSock, SHUT_RDWR);
        close(netState->controlSock);
    }
    if (netState->wakeFds[0] >= 0) {
        close(netState->wakeFds[0]);
        netState->wakeFds[0] = -1;
    }
    if (netState->wakeFds[1] >= 0) {
        close(netState->wakeFds[1]);
        netState->wakeFds[1] = -1;
    }

    delete netState;
}

/*
 * Do initial prep work, e.g. binding to ports and opening files.  This
 * runs in the main thread, before the JDWP thread starts, so it shouldn't
 * do anything that might block forever.
 */
static bool startup(struct JdwpState* state, const JdwpStartupParams* pParams)
{
    JdwpNetState*  netState;

    LOGV("ADB transport startup");

    state->netState = netState = new JdwpNetState;
    if (netState == NULL)
        return false;

    return true;
}

/*
 * Receive a file descriptor from ADB.  The fd can be used to communicate
 * directly with a debugger or DDMS.
 *
 * Returns the file descriptor on success.  On failure, returns -1 and
 * closes netState->controlSock.
 */
static int  receiveClientFd(JdwpNetState*  netState)
{
    struct msghdr    msg;
    struct cmsghdr*  cmsg;
    struct iovec     iov;
    char             dummy = '!';
    union {
        struct cmsghdr cm;
        char buffer[CMSG_SPACE(sizeof(int))];
    } cm_un;
    int              ret;

    iov.iov_base       = &dummy;
    iov.iov_len        = 1;
    msg.msg_name       = NULL;
    msg.msg_namelen    = 0;
    msg.msg_iov        = &iov;
    msg.msg_iovlen     = 1;
    msg.msg_flags      = 0;
    msg.msg_control    = cm_un.buffer;
    msg.msg_controllen = sizeof(cm_un.buffer);

    cmsg = CMSG_FIRSTHDR(&msg);
    cmsg->cmsg_len   = msg.msg_controllen;
    cmsg->cmsg_level = SOL_SOCKET;
    cmsg->cmsg_type  = SCM_RIGHTS;
    ((int*)(void*)CMSG_DATA(cmsg))[0] = -1;

    do {
        ret = recvmsg(netState->controlSock, &msg, 0);
    } while (ret < 0 && errno == EINTR);

    if (ret <= 0) {
        if (ret < 0) {
            LOGW("receiving file descriptor from ADB failed (socket %d): %s",
                 netState->controlSock, strerror(errno));
        } else {
            LOGD("adbd disconnected");
        }
        close(netState->controlSock);
        netState->controlSock = -1;
        return -1;
    }

    return ((int*)(void*)CMSG_DATA(cmsg))[0];
}

/*
 * Block forever, waiting for a debugger to connect to us.  Called from the
 * JDWP thread.
 *
 * This needs to un-block and return "false" if the VM is shutting down.  It
 * should return "true" when it successfully accepts a connection.
 */
static bool acceptConnection(struct JdwpState* state)
{
    JdwpNetState*  netState = state->netState;
    int retryCount = 0;

    /* first, ensure that we get a connection to the ADB daemon */

retry:
    if (netState->shuttingDown)
        return false;

    if (netState->controlSock < 0) {
        int        sleep_ms     = 500;
        const int  sleep_max_ms = 2*1000;
        char       buff[5];

        netState->controlSock = socket(PF_UNIX, SOCK_STREAM, 0);
        if (netState->controlSock < 0) {
            LOGE("Could not create ADB control socket:%s",
                 strerror(errno));
            return false;
        }

        if (pipe(netState->wakeFds) < 0) {
            LOGE("pipe failed");
            return false;
        }

        snprintf(buff, sizeof(buff), "%04x", getpid());
        buff[4] = 0;

        for (;;) {
            /*
             * If adbd isn't running, because USB debugging was disabled or
             * perhaps the system is restarting it for "adb root", the
             * connect() will fail.  We loop here forever waiting for it
             * to come back.
             *
             * Waking up and polling every couple of seconds is generally a
             * bad thing to do, but we only do this if the application is
             * debuggable *and* adbd isn't running.  Still, for the sake
             * of battery life, we should consider timing out and giving
             * up after a few minutes in case somebody ships an app with
             * the debuggable flag set.
             */
            int  ret = connect(netState->controlSock,
                               &netState->controlAddr.controlAddrPlain,
                               netState->controlAddrLen);
            if (!ret) {
                if (!socket_peer_is_trusted(netState->controlSock)) {
                    if (shutdown(netState->controlSock, SHUT_RDWR)) {
                        LOGE("trouble shutting down socket: %s", strerror(errno));
                    }
                    return false;
                }

                /* now try to send our pid to the ADB daemon */
                do {
                    ret = send( netState->controlSock, buff, 4, 0 );
                } while (ret < 0 && errno == EINTR);

                if (ret >= 0) {
                    LOGV("PID sent as '%.*s' to ADB", 4, buff);
                    break;
                }

                LOGE("Weird, can't send JDWP process pid to ADB: %s",
                     strerror(errno));
                return false;
            }
            LOGV("Can't connect to ADB control socket:%s",
                 strerror(errno));

            usleep( sleep_ms*1000 );

            sleep_ms += (sleep_ms >> 1);
            if (sleep_ms > sleep_max_ms)
                sleep_ms = sleep_max_ms;

            if (netState->shuttingDown)
                return false;
        }
    }

    LOGV("trying to receive file descriptor from ADB");
    /* now we can receive a client file descriptor */
    netState->clientSock = receiveClientFd(netState);
    if (netState->shuttingDown)
        return false;       // suppress logs and additional activity

    if (netState->clientSock < 0) {
        if (++retryCount > 5) {
            LOGE("adb connection max retries exceeded");
            return false;
        }
        goto retry;
    } else {
        LOGV("received file descriptor %d from ADB", netState->clientSock);
        netState->awaitingHandshake = 1;
        netState->inputCount = 0;
        return true;
    }
}

/*
 * Connect out to a debugger (for server=n).  Not required.
 */
static bool establishConnection(struct JdwpState* state)
{
    return false;
}

/*
 * Close a connection from a debugger (which may have already dropped us).
 * Only called from the JDWP thread.
 */
static void closeConnection(struct JdwpState* state)
{
    JdwpNetState* netState;

    assert(state != NULL && state->netState != NULL);

    netState = state->netState;
    if (netState->clientSock < 0)
        return;

    LOGV("+++ closed JDWP <-> ADB connection");

    close(netState->clientSock);
    netState->clientSock = -1;
}

/*
 * Close all network stuff, including the socket we use to listen for
 * new connections.
 *
 * May be called from a non-JDWP thread, e.g. when the VM is shutting down.
 */
static void adbStateShutdown(struct JdwpNetState* netState)
{
    int  controlSock;
    int  clientSock;

    if (netState == NULL)
        return;

    netState->shuttingDown = true;

    clientSock = netState->clientSock;
    if (clientSock >= 0) {
        shutdown(clientSock, SHUT_RDWR);
        netState->clientSock = -1;
    }

    controlSock = netState->controlSock;
    if (controlSock >= 0) {
        shutdown(controlSock, SHUT_RDWR);
        netState->controlSock = -1;
    }

    if (netState->wakeFds[1] >= 0) {
        LOGV("+++ writing to wakePipe");
        write(netState->wakeFds[1], "", 1);
    }
}

static void netShutdown(JdwpState* state)
{
    adbStateShutdown(state->netState);
}

/*
 * Free up anything we put in state->netState.  This is called after
 * "netShutdown", after the JDWP thread has stopped.
 */
static void netFree(struct JdwpState* state)
{
    JdwpNetState*  netState = state->netState;

    adbStateFree(netState);
}

/*
 * Is a debugger connected to us?
 */
static bool isConnected(struct JdwpState* state)
{
    return (state->netState != NULL   &&
            state->netState->clientSock >= 0);
}

/*
 * Are we still waiting for the JDWP handshake?
 */
static bool awaitingHandshake(struct JdwpState* state)
{
    return state->netState->awaitingHandshake;
}

/*
 * Figure out if we have a full packet in the buffer.
 */
static bool haveFullPacket(JdwpNetState* netState)
{
    long length;

    if (netState->awaitingHandshake)
        return (netState->inputCount >= (int) kMagicHandshakeLen);

    if (netState->inputCount < 4)
        return false;

    length = get4BE(netState->inputBuffer);
    return (netState->inputCount >= length);
}

/*
 * Consume bytes from the buffer.
 *
 * This would be more efficient with a circular buffer.  However, we're
 * usually only going to find one packet, which is trivial to handle.
 */
static void consumeBytes(JdwpNetState* netState, int count)
{
    assert(count > 0);
    assert(count <= netState->inputCount);

    if (count == netState->inputCount) {
        netState->inputCount = 0;
        return;
    }

    memmove(netState->inputBuffer, netState->inputBuffer + count,
        netState->inputCount - count);
    netState->inputCount -= count;
}

/*
 * 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

    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)) {
                LOGE("Failed sending reply to debugger: %s", strerror(errno));
                expandBufFree(pReply);
                return false;
            }
        } else {
            LOGW("No reply created for set=%d cmd=%d", cmdSet, cmd);
        }
        expandBufFree(pReply);
    } else {
        LOGV("reply?!");
        assert(false);
    }

    LOGV("----------");

    consumeBytes(netState, length);
    return true;
}

/*
 * Process incoming data.  If no data is available, this will block until
 * some arrives.
 *
 * If we get a full packet, handle it.
 *
 * To take some of the mystery out of life, we want to reject incoming
 * connections if we already have a debugger attached.  If we don't, the
 * debugger will just mysteriously hang until it times out.  We could just
 * close the listen socket, but there's a good chance we won't be able to
 * bind to the same port again, which would confuse utilities.
 *
 * Returns "false" on error (indicating that the connection has been severed),
 * "true" if things are still okay.
 */
static bool processIncoming(JdwpState* state)
{
    JdwpNetState* netState = state->netState;
    int readCount;

    assert(netState->clientSock >= 0);

    if (!haveFullPacket(netState)) {
        /* read some more, looping until we have data */
        errno = 0;
        while (1) {
            int selCount;
            fd_set readfds;
            int maxfd = -1;
            int fd;

            FD_ZERO(&readfds);

            /* configure fds; note these may get zapped by another thread */
            fd = netState->controlSock;
            if (fd >= 0) {
                FD_SET(fd, &readfds);
                if (maxfd < fd)
                    maxfd = fd;
            }
            fd = netState->clientSock;
            if (fd >= 0) {
                FD_SET(fd, &readfds);
                if (maxfd < fd)
                    maxfd = fd;
            }
            fd = netState->wakeFds[0];
            if (fd >= 0) {
                FD_SET(fd, &readfds);
                if (maxfd < fd)
                    maxfd = fd;
            } else {
                LOGI("NOTE: entering select w/o wakepipe");
            }

            if (maxfd < 0) {
                LOGV("+++ all fds are closed");
                return false;
            }

            /*
             * Select blocks until it sees activity on the file descriptors.
             * Closing the local file descriptor does not count as activity,
             * so we can't rely on that to wake us up (it works for read()
             * and accept(), but not select()).
             *
             * We can do one of three things: (1) send a signal and catch
             * EINTR, (2) open an additional fd ("wakePipe") and write to
             * it when it's time to exit, or (3) time out periodically and
             * re-issue the select.  We're currently using #2, as it's more
             * reliable than #1 and generally better than #3.  Wastes two fds.
             */
            selCount = select(maxfd+1, &readfds, NULL, NULL, NULL);
            if (selCount < 0) {
                if (errno == EINTR)
                    continue;
                LOGE("select failed: %s", strerror(errno));
                goto fail;
            }

            if (netState->wakeFds[0] >= 0 &&
                FD_ISSET(netState->wakeFds[0], &readfds))
            {
                LOGD("Got wake-up signal, bailing out of select");
                goto fail;
            }
            if (netState->controlSock >= 0 &&
                FD_ISSET(netState->controlSock, &readfds))
            {
                int  sock = receiveClientFd(netState);
                if (sock >= 0) {
                    LOGI("Ignoring second debugger -- accepting and dropping");
                    close(sock);
                } else {
                    assert(netState->controlSock < 0);
                    /*
                     * Remote side most likely went away, so our next read
                     * on netState->clientSock will fail and throw us out
                     * of the loop.
                     */
                }
            }
            if (netState->clientSock >= 0 &&
                FD_ISSET(netState->clientSock, &readfds))
            {
                readCount = read(netState->clientSock,
                                netState->inputBuffer + netState->inputCount,
                    sizeof(netState->inputBuffer) - netState->inputCount);
                if (readCount < 0) {
                    /* read failed */
                    if (errno != EINTR)
                        goto fail;
                    LOGD("+++ EINTR hit");
                    return true;
                } else if (readCount == 0) {
                    /* EOF hit -- far end went away */
                    LOGV("+++ peer disconnected");
                    goto fail;
                } else
                    break;
            }
        }

        netState->inputCount += readCount;
        if (!haveFullPacket(netState))
            return true;        /* still not there yet */
    }

    /*
     * Special-case the initial handshake.  For some bizarre reason we're
     * expected to emulate bad tty settings by echoing the request back
     * exactly as it was sent.  Note the handshake is always initiated by
     * the debugger, no matter who connects to whom.
     *
     * Other than this one case, the protocol [claims to be] stateless.
     */
    if (netState->awaitingHandshake) {
        int cc;

        if (memcmp(netState->inputBuffer,
                kMagicHandshake, kMagicHandshakeLen) != 0)
        {
            LOGE("ERROR: bad handshake '%.14s'", netState->inputBuffer);
            goto fail;
        }

        errno = 0;
        cc = write(netState->clientSock, netState->inputBuffer,
                kMagicHandshakeLen);
        if (cc != kMagicHandshakeLen) {
            LOGE("Failed writing handshake bytes: %s (%d of %d)",
                strerror(errno), cc, (int) kMagicHandshakeLen);
            goto fail;
        }

        consumeBytes(netState, kMagicHandshakeLen);
        netState->awaitingHandshake = false;
        LOGV("+++ handshake complete");
        return true;
    }

    /*
     * Handle this packet.
     */
    return handlePacket(state);

fail:
    closeConnection(state);
    return false;
}

/*
 * 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;

    if (netState->clientSock < 0) {
        /* can happen with some DDMS events */
        LOGV("NOT sending request -- no debugger is attached");
        return false;
    }

    errno = 0;

    ssize_t cc = netState->writePacket(pReq);

    if (cc != (ssize_t) expandBufGetLength(pReq)) {
        LOGE("Failed sending req to debugger: %s (%d of %d)",
            strerror(errno), (int) cc, (int) expandBufGetLength(pReq));
        return false;
    }

    return true;
}

/*
 * Send a request that was split into multiple buffers.
 *
 * The entire packet must be sent with a single writev() call to avoid
 * threading issues.
 *
 * Returns "true" if it was sent successfully.
 */
static bool sendBufferedRequest(JdwpState* state, const struct iovec* iov,
    int iovcnt)
{
    JdwpNetState* netState = state->netState;

    if (netState->clientSock < 0) {
        /* can happen with some DDMS events */
        LOGV("NOT sending request -- no debugger is attached");
        return false;
    }

    size_t expected = 0;
    int i;
    for (i = 0; i < iovcnt; i++)
        expected += iov[i].iov_len;

    ssize_t actual = netState->writeBufferedPacket(iov, iovcnt);

    if ((size_t)actual != expected) {
        LOGE("Failed sending b-req to debugger: %s (%d of %zu)",
            strerror(errno), (int) actual, expected);
        return false;
    }

    return true;
}


/*
 * Our functions.
 */
static const JdwpTransport socketTransport = {
    startup,
    acceptConnection,
    establishConnection,
    closeConnection,
    netShutdown,
    netFree,
    isConnected,
    awaitingHandshake,
    processIncoming,
    sendRequest,
    sendBufferedRequest
};

/*
 * Return our set.
 */
const JdwpTransport* dvmJdwpAndroidAdbTransport()
{
    return &socketTransport;
}
