#include <hardware/bluetooth.h>
#include <hardware/bt_sock.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <pthread.h>
#include <fcntl.h>
#include <errno.h>
#include <poll.h>
#include <stdlib.h>
#include <string.h>
#include "aapiSocket.h"
#include "rfcomm.h"
#include "config.h"
#include "aapi.h"
#include "hci.h"
#include "sdp.h"
#include "log.h"
#include "sg.h"
#include "mt.h"


struct aapiSock {
    struct aapiSock *prev;
    struct aapiSock *next;
    btsock_type_t type;
    int fd, java_fd;
    struct bt_addr peer;
    union {
        struct {
            union { /* listening sockets have no rfc_conn_t */
                rfc_conn_t conn;
                uint32_t sdpHandle;
            };
            uint8_t state;
            uint8_t chNum;
            sg bufRx;
            sg bufTx;
        } rfc;
    };
};

struct appiSockListener {
    struct appiSockListener *next;
    uint32_t sdpHandle;
    uint8_t uuid[16];
};

#define RFC_SOCK_STATE_LISTENING       1
#define RFC_SOCK_STATE_AUTOACCEPTING   2 /* we allocated an instance but it is not yet openened by rfcomm */
#define RFC_SOCK_STATE_ESTABLISHED     3 /* it is open */
#define RFC_SOCK_STATE_AAPI_CLOSED     4 /* aapi closed, waiting for RFCOMM confirmation */
#define RFC_SOCK_STATE_RFC_CLOSED      5 /* rfc closed, waiting for aapi confirmation */
#define RFC_SOCK_STATE_RFC_STOP_LISTEN 6 /* someone else stopped listening for us */


#define WORKER_MSG_SOCK_ADD            0
#define WORKER_MSG_FD_CAN_RX           1 /* our user may now RX data */
#define WORKER_MSG_FD_CAN_TX           2 /* our user may now TX data */
#define WORKER_MSG_FD_CANNOT_RX        3
#define WORKER_MSG_FD_CANNOT_TX        4
#define WORKER_MSG_SOCK_DEL            5 /* delete this socket */
#define WORKER_MSG_QUIT                6 /* TODO: currently unused */

/* our state */
static struct aapiSock *mSocks = NULL;
static pthread_mutex_t mSocksLock = PTHREAD_MUTEX_INITIALIZER;
static pthread_t mWorker;
static int mWorkerPipe = -1;
static bool mSocksUp;
static bool mSocksWantUp;
static struct appiSockListener *mListeners = NULL;


/* fwd decls */
static void aapiSockFree(struct aapiSock* sock);
static void aapiSockWorkerMsgSend(uint8_t msg, void *aux);



/*
 * FUNCTION: aapiWorker
 * USE:      The worker thread for aapi.sock
 * PARAMS:   pipe - actually an int - the pipe we listen to to wake up
 * RETURN:   NONE
 * NOTES:
 */
static void *aapiSockWorker(void *pipe)
{
    uint32_t i, arrSz = 16/* a nice starting number */, arrNum = 1;
    struct aapiSock **socks = NULL;
    struct pollfd *fds = NULL;
    bool quit = false;
    uint8_t rdbuf[4096]; /* we read from java using this */

    fds = malloc(sizeof(struct pollfd) * arrSz);
    if (!fds) {
        loge("Failed to alloc fds\n");
        return NULL;
    }

    socks = malloc(sizeof(struct aapiSock*) * arrSz);
    if (!socks) {
        loge("Failed to alloc socks\n");
        free(fds);
        return NULL;
    }
    fds[0].fd = (int)(uintptr_t)pipe;
    fds[0].events = POLLIN;


    while (!quit) {
        int ret;
        for (i = 0; i < arrNum; i++)
            fds[i].revents = 0;

        do {
            ret = poll(fds, arrNum, -1);
        } while (ret == -1 && errno == EINTR);

        if (fds[0].revents & POLLIN) {
            uint8_t msg;
            struct aapiSock *sock;

            r_read(fds[0].fd, &msg, sizeof(msg));
            r_read(fds[0].fd, &sock, sizeof(sock));
            switch (msg) {
            case WORKER_MSG_SOCK_ADD:
                if (arrNum == arrSz) {
                    uint32_t newArrSz = arrSz + 16; /* we grow 16 at a time */
                    struct pollfd *newFds = realloc(fds, sizeof(struct pollfd) * newArrSz);
                    struct aapiSock **newSocks = realloc(socks, sizeof(struct aapiSock*) * newArrSz);

                    if (newFds)
                        fds = newFds;
                    if (newSocks)
                        socks = newSocks;
                    if (!newFds || !newSocks) {
                        logw("Failed to resize structs to add new sock\n");
                        break;
                    }
                    arrSz = newArrSz;
                }
                socks[arrNum] = sock;
                fds[arrNum].fd = sock->fd;
                fds[arrNum].events = POLLERR | POLLNVAL | POLLHUP;
                fds[arrNum].revents = 0;
                arrNum++;
                break;
            case WORKER_MSG_FD_CAN_RX:
            case WORKER_MSG_FD_CAN_TX:
            case WORKER_MSG_FD_CANNOT_RX:
            case WORKER_MSG_FD_CANNOT_TX:
            case WORKER_MSG_SOCK_DEL:
                for (i = 0; i < arrNum && socks[i] != sock; i++);
                if (i == arrNum) {
                    logw("worker(%u) called with unknown sock\n", msg);
                    break;
                }
                if (msg == WORKER_MSG_FD_CAN_RX)
                    fds[i].events |= POLLOUT;
                else if (msg == WORKER_MSG_FD_CAN_TX)
                    fds[i].events |= POLLIN;
                else if (msg == WORKER_MSG_FD_CANNOT_RX)
                    fds[i].events &=~ POLLOUT;
                else if (msg == WORKER_MSG_FD_CANNOT_TX)
                    fds[i].events &=~ POLLIN;
                else {
                    memcpy(fds + i, fds + arrNum - 1, sizeof(struct pollfd));
                    socks[i] = socks[arrNum - 1];
                    arrNum--;
                    pthread_mutex_lock(&mSocksLock);
                    aapiSockFree(sock);
                    pthread_mutex_unlock(&mSocksLock);
                }
                break;
            case WORKER_MSG_QUIT:
                quit = true;
                logd("AAPI.sock worker exiting\n");
                break;
            default:
                loge("Unknown AAPI.worker command %u\n", msg);
                break;
            }
        }
        for (i = 1; i < arrNum; i++) {
            uint32_t done;
            void *iter;

            if (fds[i].revents & (POLLERR | POLLNVAL | POLLHUP)) {
                logd("fd %d (sock %d) in state %u failed with error %d -> deleting\n", fds[i].fd, i, socks[i]->rfc.state, fds[i].revents);
                aapiSockWorkerMsgSend(WORKER_MSG_SOCK_DEL, socks[i]);
                continue;
            }

            if (!(fds[i].events & fds[i].revents))
                continue;

            if (fds[i].revents & POLLIN) { /* java has sent us data */
                int32_t txRet;
                while(1) {
                    ssize_t now;

                    if (sgLength(socks[i]->rfc.bufTx) >= AAPI_RFC_MAX_BUF) {
                        fds[i].events &=~ POLLIN; /* no buffer space - stop reading */
                        logd("TX throttled in socks api\n");
                        break;
                    }
                    now = read(fds[i].fd, rdbuf, sizeof(rdbuf));
                    if (now <= 0)
                        break;
                    if (!sgConcatBackCopy(socks[i]->rfc.bufTx, rdbuf, now))
                        loge("Failed to concat read data. TX data will be lost\n");
                    if (now != sizeof(rdbuf))
                        break;
                }
                txRet = rfcTx(socks[i]->rfc.conn, socks[i]->rfc.bufTx);
                if (txRet == RFC_TX_RET_ENTIRE_SENT) {
                    socks[i]->rfc.bufTx = sgNew();
                    if (!socks[i]->rfc.bufTx) {
                        loge("Failed to alloc new TX sg for conn. Closing\n");
                        aapiSockWorkerMsgSend(WORKER_MSG_SOCK_DEL, socks[i]);
                    }
                } else if (txRet == RFC_TX_RET_STOP_SENDING) {
                    fds[i].events &=~ POLLIN; /* no buffer space - stop reading */
                    logd("TX throttled in rfc\n");
                } else if (txRet == RFC_TX_RET_NO_SUCH_CONN || txRet == RFC_TX_RET_ERROR) {
                    loge("Rfc sock error %d. Closing\n", txRet);
                    aapiSockWorkerMsgSend(WORKER_MSG_SOCK_DEL, socks[i]);
                }
            }
            if (fds[i].revents & POLLOUT) { /* java is ready for data */
                pthread_mutex_lock(&mSocksLock);
                for (done = 0, iter = sgIterStart(socks[i]->rfc.bufRx); iter; iter = sgIterAdvance(iter)) {
                    ssize_t now = write(fds[i].fd, sgIterCurData(iter), sgIterCurLen(iter));
                    if (now <= 0)
                        break;
                    done += now;
                    if ((unsigned)now < sgIterCurLen(iter))
                        break;
                }
                sgTruncFront(socks[i]->rfc.bufRx, done);
                if (sgLength(socks[i]->rfc.bufRx) < AAPI_RFC_MAX_BUF)
                    rfcFlow(socks[i]->rfc.conn, false);
                if (!sgLength(socks[i]->rfc.bufRx))
                    fds[i].events &=~ POLLOUT; /* if we have no more to give, do not bother caring if java can read */
                pthread_mutex_unlock(&mSocksLock);
            }
        }
    }
    pthread_mutex_lock(&mSocksLock);
    for (i = 1; i < arrNum; i++)
        aapiSockFree(socks[i]);
    pthread_mutex_unlock(&mSocksLock);
    close((int)(uintptr_t)pipe);

    free(fds);
    free(socks);
    return NULL;
}

/*
 * FUNCTION: aapiSockDoInit
 * USE:      Init aapi.sock worker thread & pipes
 * PARAMS:   NONE
 * RETURN:   NONE
 * NOTES:
 */
static void aapiSockDoInit(void)
{
    int pipes[2];

    if (pipe(pipes))
        return;

    if (pthread_create(&mWorker, NULL, aapiSockWorker, (void*)(uintptr_t)pipes[0])) {
        close(pipes[0]);
        close(pipes[1]);
        return;
    }
    mWorkerPipe = pipes[1];
    mSocksUp = true;
    mSocksWantUp = false;
}

/*
 * FUNCTION: aapiSockWorkerMsgSend
 * USE:      Wake up aapi.sock worker with a message
 * PARAMS:   msg - the message
 *           aux - additional data for said message
 * RETURN:   NONE
 * NOTES:
 */
static void aapiSockWorkerMsgSend(uint8_t msg, void *aux)
{
    uint8_t t = msg;

    r_write(mWorkerPipe, &t, 1);
    r_write(mWorkerPipe, &aux, sizeof(void*));
}

/*
 * FUNCTION: aapiSockAlloc
 * USE:      Create a sock struct and link it into the list
 * PARAMS:   type - socket type (as per bt iface)
 *           sockType - local socket type (for linux kernel, SOCK_STREAM/SOCK_DGRAM)
 * RETURN:   sock struct or NULL on error
 * NOTES:    call with mSocksLock held
 */
static struct aapiSock* aapiSockAlloc(btsock_type_t type, int sockType)
{
    struct aapiSock *sock = calloc(1, sizeof(struct aapiSock));
    int socks[2], ret;

    if (!sock)
        return NULL;

    ret = socketpair(AF_LOCAL, sockType, 0, socks);
    if (ret) {
        free(sock);
        return NULL;
    }

    fcntl(socks[0], F_SETFL, O_NONBLOCK | fcntl(socks[0], F_GETFL));

    sock->type = type;
    sock->fd = socks[0];
    sock->java_fd = socks[1];
    sock->next = mSocks;
    if (mSocks)
        mSocks->prev = sock;
    mSocks = sock;

    return sock;
}

/*
 * FUNCTION: aapiSockAllocRfc
 * USE:      Create an RFC sock struct and link it into the list
 * PARAMS:   chNum - the chNum to save in the sock
 *           state - the state to put it into
 * RETURN:   sock struct or NULL on error
 * NOTES:    call with mSocksLock held
 */
static struct aapiSock* aapiSockAllocRfc(uint8_t chNum, uint8_t state)
{
    struct aapiSock *sock = NULL;

    sg bufTx = sgNew();
    sg bufRx = sgNew();

    if (!bufTx && ! bufRx) {
        if (bufTx)
            sgFree(bufTx);
        if (bufRx)
            sgFree(bufRx);
        return NULL;
    }

    sock = aapiSockAlloc(BTSOCK_RFCOMM, SOCK_STREAM);
    if (sock) {
        sock->rfc.chNum = chNum;
        sock->rfc.state = state;
        sock->rfc.bufTx = bufTx;
        sock->rfc.bufRx = bufRx;
    } else {
        sgFree(bufTx);
        sgFree(bufRx);
    }

    return sock;
}

/*
 * FUNCTION: aapiSockFree
 * USE:      Free a socket struct
 * PARAMS:   sock - the socket struct
 * RETURN:   NONE
 * NOTES:    call with mSocksLock held
 */
static void aapiSockFree(struct aapiSock* sock)
{
    shutdown(sock->fd, SHUT_RDWR);
    close(sock->fd);

    if (sock->java_fd != -1)
        close(sock->java_fd);

    if (sock->prev)
        sock->prev->next = sock->next;
    else
        mSocks = sock->next;
    if (sock->next)
        sock->next->prev = sock->prev;
    switch (sock->type) {
    case BTSOCK_RFCOMM:
        if (sock->rfc.bufTx)
            sgFree(sock->rfc.bufTx);
        sock->rfc.bufTx = NULL;
        if (sock->rfc.bufRx)
            sgFree(sock->rfc.bufRx);
        sock->rfc.bufTx = NULL;
        if (sock->rfc.state == RFC_SOCK_STATE_LISTENING) {
            struct appiSockListener *sl, *p = NULL;
            for (sl = mListeners; sl && sl->sdpHandle != sock->rfc.sdpHandle; p = sl, sl = sl->next);
            if (!sl)
                logw("Failed to find listener object for closed listening socket\n");
            else {
                if (p)
                    p->next = sl->next;
                else
                    mListeners = sl->next;
                free(sl);
            }
            rfcStopListen(sock->rfc.chNum);
            sdpServiceDescriptorDel(sock->rfc.sdpHandle);
        } else if (sock->rfc.state == RFC_SOCK_STATE_RFC_STOP_LISTEN) {
            /* nothing to do here */
        } else if (sock->rfc.conn)
            rfcClose(sock->rfc.conn);
        if (sock->rfc.state == RFC_SOCK_STATE_RFC_CLOSED || sock->rfc.state == RFC_SOCK_STATE_RFC_STOP_LISTEN || sock->rfc.state == RFC_SOCK_STATE_LISTENING)
            free(sock);
        else
            sock->rfc.state = RFC_SOCK_STATE_AAPI_CLOSED;
        break;
    default:
        logw("Unknown socket type %u on close\n", sock->type);
        break;
    }
}

static bool aapiSockNotifyOfConnReq(struct aapiSock *srvSock, struct aapiSock *newSock)
{
    sock_connect_signal_t sig = {.size = sizeof(sock_connect_signal_t), .channel = srvSock->rfc.chNum, .status = 0, };
    uint8_t *sigBuf  = (uint8_t*)&sig;
    char cmsgBuf[CMSG_SPACE(1)] = {0,};
    int ret, len = sizeof(sig);
    struct cmsghdr *cmsg;
    struct msghdr msg = {0,};

    memcpy(sig.bd_addr.address, newSock->peer.addr, sizeof(sig.bd_addr.address));


    msg.msg_control = cmsgBuf;
    msg.msg_controllen = sizeof(cmsgBuf);
    cmsg = CMSG_FIRSTHDR(&msg);
    cmsg->cmsg_level = SOL_SOCKET;
    cmsg->cmsg_type = SCM_RIGHTS;
    cmsg->cmsg_len = CMSG_LEN(sizeof(newSock->java_fd));
    memcpy(CMSG_DATA(cmsg), &newSock->java_fd, sizeof(newSock->java_fd));

    while (len) {
        struct iovec ovec = {0,};

        ovec.iov_base = sigBuf;
        ovec.iov_len = len;

        msg.msg_iov = &ovec;
        msg.msg_iovlen = 1;

        do {
            ret = sendmsg(srvSock->fd, &msg, MSG_NOSIGNAL);
        } while (ret < 0 && errno == EINTR);

        if (ret == -1) {
            logd("sendmsg err: %d\n", errno);
            return false;
        }

        sigBuf += ret;
        len -= ret;

        memset(&msg, 0, sizeof(msg));
    }
    close(newSock->java_fd);
    newSock->java_fd = -1;

    return true;
}

/*
 * FUNCTION: aapiSockRfcListenAlloc
 * USE:      Called when a remote device tries to connect to our listening RFC socket
 * PARAMS:   userData - our socket
 *           peerAddr - the peer address
 *           chNum - the chNum
 * RETURN:   bt_status_t
 * NOTES:
 */
static void* aapiSockRfcListenAlloc(void *userData, const struct bt_addr *peerAddr, uint8_t chNum)
{
    /* we have no way to ask user to accept or not, so we accept for the user, and sort it out later */
    struct aapiSock *srvSock = (struct aapiSock*)userData;
    struct aapiSock *newSock;

    logd("Connection to "ADDRFMT"[%u] alloc\n", ADDRCONV(*peerAddr), chNum);

    pthread_mutex_lock(&mSocksLock);
    newSock = aapiSockAllocRfc(chNum, RFC_SOCK_STATE_AUTOACCEPTING);

    if (!newSock)
        goto out;

    logd("aapi sock alloc ch %u\n", chNum);
    srvSock->rfc.chNum = chNum; /* in case we get here before aapiSockListen() finishes */

    memcpy(&newSock->peer, peerAddr, sizeof(newSock->peer));
    if (!aapiSockNotifyOfConnReq(srvSock, newSock)) {
        loge("Failed to notify of new connection - closing server socket too\n");
        aapiSockFree(newSock);
        aapiSockWorkerMsgSend(WORKER_MSG_SOCK_DEL, srvSock);
        newSock = NULL;
    }

out:
    pthread_mutex_unlock(&mSocksLock);
    return newSock;
}

/*
 * FUNCTION: aapiSockRfcListenEvt
 * USE:      Called when an even arises on an RFC connection
 * PARAMS:   userData - unused
 *           instance - our socket
 *           evt - what happened
 *           s - the data
 * RETURN:   NONE
 * NOTES:
 */
static void aapiSockRfcListenEvt(void *userData, void *instance, uint8_t evt, sg s)
{
    struct aapiSock *sock = (struct aapiSock*)instance;

    logd("aapi sock evt %u ch %u\n", evt, sock->rfc.chNum);
    pthread_mutex_lock(&mSocksLock);

    switch (evt) {
    case RFC_EVT_OPEN:
        logd("Connection to "ADDRFMT"[%u] open\n", ADDRCONV(sock->peer), sock->rfc.chNum);
        if (sock->rfc.state != RFC_SOCK_STATE_AUTOACCEPTING)
            logw("Weird socket state %u on rfc open\n", sock->rfc.state);
        sock->rfc.state = RFC_SOCK_STATE_ESTABLISHED;
        sgSerialize(s, 0, sizeof(sock->rfc.conn), &sock->rfc.conn);
        sgFree(s);
        aapiSockWorkerMsgSend(WORKER_MSG_SOCK_ADD, sock);
        aapiSockWorkerMsgSend(WORKER_MSG_FD_CAN_TX, sock);
        break;
    case RFC_EVT_RX:
        if (sock->rfc.state != RFC_SOCK_STATE_ESTABLISHED) {
            logw("Dropping data for non-established socket in state %u\n", sock->rfc.state);
            sgFree(s);
        } else {
            sgConcat(sock->rfc.bufRx, s);
            if (sgLength(sock->rfc.bufRx) >= AAPI_RFC_MAX_BUF)
                rfcFlow(sock->rfc.conn, true);
            aapiSockWorkerMsgSend(WORKER_MSG_FD_CAN_RX, sock);
        }
        break;
    case RFC_EVT_MAY_SEND:
        logd("TX unthrottled in rfc\n");
        aapiSockWorkerMsgSend(WORKER_MSG_FD_CAN_TX, sock);
        break;
    case RFC_EVT_CLOSE:
        logd("Connection to "ADDRFMT"[%u] closed\n", ADDRCONV(sock->peer), sock->rfc.chNum);
        sock->rfc.conn = 0;
        if (sock->rfc.state == RFC_SOCK_STATE_AAPI_CLOSED)
            free(sock);
        else {
            sock->rfc.state = RFC_SOCK_STATE_RFC_CLOSED;
            aapiSockWorkerMsgSend(WORKER_MSG_SOCK_DEL, sock);
        }
    }
    pthread_mutex_unlock(&mSocksLock);
}

/*
 * FUNCTION: aapiSockListen
 * USE:      Listen for connections from a peer on a socket
 * PARAMS:   type - socket type
 *           serviceName - service name to advertise
 *           serviceUuid - service uuid to advertise
 *           channel - channel number
 *           sockFdP - store socket's FD here
 *           flags - other relevant flags
 * RETURN:   bt_status_t
 * NOTES:
 */
static bt_status_t aapiSockListen(btsock_type_t type, const char* serviceName, const uint8_t* serviceUuid, int channel, int* sockFdP, int flags)
{
    bt_status_t ret = BT_STATUS_FAIL;
    struct appiSockListener *sl = NULL, *p;
    struct aapiSock* sock;
    bool linkIn = true;
    uint8_t ch;


    pthread_mutex_lock(&mSocksLock);
    if (!mSocksUp) {
        logw("Refusing sock listen when socks not up\n");
        goto out;
    }

    for (p = NULL, sl = mListeners; sl && memcmp(sl->uuid, serviceUuid, sizeof(sl->uuid)); p = sl, sl = sl->next);
    if (sl) {
        logw("Sock listen when identical listener exists -> deleting old\n");
        for (sock = mSocks; sock; sock = sock->next) {
            if (sock->rfc.state != RFC_SOCK_STATE_LISTENING)
                continue;
            if (sock->rfc.sdpHandle == sl->sdpHandle)
                break;
        }
        if (sock) {
            logd("Previous identical socket found\n");
            sock->rfc.state = RFC_SOCK_STATE_RFC_STOP_LISTEN;
            rfcStopListen(sock->rfc.chNum);
            sock->rfc.chNum = 0;
            sdpServiceDescriptorDel(sl->sdpHandle);
            sock->rfc.sdpHandle = 0;
            aapiSockWorkerMsgSend(WORKER_MSG_SOCK_DEL, sock);
        } else {
            logw("Failed to find previous listening socket. SDP likely to be leaked->auto-freeing\n");
            sdpServiceDescriptorDel(sl->sdpHandle);
        }
        linkIn = false;
    } else
        sl = malloc(sizeof(struct appiSockListener));
    if (sl)
        memcpy(sl->uuid, serviceUuid, sizeof(sl->uuid));
    else {
        loge("Failed to alloc a listener record\n");
        goto out;
    }

    logd("AAPI.sock: listen(%u,'%s',%d,%u)\n", type, serviceName, channel, flags);

    if (type != BTSOCK_RFCOMM) {
        logw("Refusing non-RFCOMM sockets for now\n");
        goto out;
    }

    if (channel == -1) /* magic number! */
        ch = RFC_CHNUM_REQ_ANY;
    else if (channel < RFC_FIRST_CHAN || channel >= RFC_NUM_CHANS + RFC_FIRST_CHAN) {
        logw("Refusing RFCOMM listen on invalid channel %d\n", channel);
        goto out;
    } else ch = channel;

    sock = aapiSockAllocRfc(ch, RFC_SOCK_STATE_LISTENING); /* yes, "ch" might be RFC_CHNUM_REQ_ANY here. this is actually ok */
    if (!sock)
        goto out;

    ch = rfcListen(ch, aapiSockRfcListenAlloc, aapiSockRfcListenEvt, sock);
    if (!ch) {
        logw("Failed to RFC listen\n");
        goto out_sockfree;
    }

    sock->rfc.chNum = ch;
    logd("RFC ch %u opened for listening with name '%s'\n", ch, serviceName);

    /* XXX: this makes me feel dirty all over, but sadly andriod api demands this be sent as an int and in native byte order... */
    channel = ch; /* send the channel ID to java */
    if (!sgConcatBackCopy(sock->rfc.bufRx, &channel ,sizeof(channel))) {
        loge("Failed to enqueue channel number for java\n");
        goto out_stoplisten;
    }

    sock->rfc.sdpHandle = rfcAddSdpRecord(serviceUuid, ch, serviceName);
    logd("sock %p has atate %u and fd %u with sdp handle 0x%08x\n", sock, sock->rfc.state, sock->fd, sock->rfc.sdpHandle);
    if (!sock->rfc.sdpHandle) {
        loge("Failed to add SDP record\n");
        goto out_stoplisten;
    }

    sl->sdpHandle = sock->rfc.sdpHandle;
    if (linkIn) {
        sl->next = mListeners;
        mListeners = sl;
    }

    *sockFdP = sock->java_fd;
    sock->java_fd = -1;
    aapiSockWorkerMsgSend(WORKER_MSG_SOCK_ADD, sock);
    aapiSockWorkerMsgSend(WORKER_MSG_FD_CAN_RX, sock);
    ret = BT_STATUS_SUCCESS;
    goto out;

out_stoplisten:
    rfcStopListen(ch);

out_sockfree:
    aapiSockFree(sock);
out:
    pthread_mutex_unlock(&mSocksLock);
    return ret;
}

/*
 * FUNCTION: aapiSockConnect
 * USE:      Try to connect to a peer's matching listening socket
 * PARAMS:   bd_addr - peer address
 *           type - socket type
 *           uuid - service uuid
 *           channel - channel number
 *           sockFdP - store socket's FD here
 *           flags - other relevant flags
 * RETURN:   bt_status_t
 * NOTES:
 */
static bt_status_t aapiSockConnect(const bt_bdaddr_t *bd_addr, btsock_type_t type, const uint8_t* uuid, int channel, int* sockFdP, int flags)
{
    bt_status_t ret = BT_STATUS_FAIL;

    logd("AAPI.sock: connect(%02X:%02X:%02X:%02X:%02X:%02X,%u,%d,%u)\n",
         bd_addr->address[5], bd_addr->address[4], bd_addr->address[3], bd_addr->address[2], bd_addr->address[1], bd_addr->address[0],
         type, channel, flags);

    pthread_mutex_lock(&mSocksLock);
    if (!mSocksUp) {
        pthread_mutex_unlock(&mSocksLock);
        logw("Refusing sock connect when socks not up\n");
        goto out;
    }
    pthread_mutex_unlock(&mSocksLock);

    if (type != BTSOCK_RFCOMM) {
        logw("Refusing non-RFCOMM sockets for now\n");
        goto out;
    }

    if (channel != -1 && (channel < RFC_FIRST_CHAN || channel >= RFC_NUM_CHANS + RFC_FIRST_CHAN)) {
        logw("Refusing RFCOMM connect on invalid channel %d\n", channel);
        goto out;
    }

    //TODO

out:
    return ret;
}


/*
 * FUNCTION: aapiGetProfileIfaceSockets
 * USE:      Try to connect to a peer's matching listening socket
 * PARAMS:   bd_addr - peer address
 *           type - socket type
 *           uuid - service uuid
 *           channel - channel number
 *           sockFdP - store socket's FD here
 *           flags - other relevant flags
 * RETURN:   bt_status_t
 * NOTES:
 */
const void* aapiGetProfileIfaceSockets(void)
{
    static const btsock_interface_t sockIface = {
        .size = sizeof(btsock_interface_t),
        .listen = aapiSockListen,
        .connect = aapiSockConnect,
    };

    pthread_mutex_lock(&mSocksLock);
    if (mSocksUp)
        logd("socks up again\n");
    else if (!aapiIsStackUp())
        mSocksWantUp = true;
    else
        aapiSockDoInit();

    pthread_mutex_unlock(&mSocksLock);

    return &sockIface;
}

/*
 * FUNCTION: aapiSocketNotifStackState
 * USE:      Stack uses this to tell us of stack up/down state changes
 * PARAMS:   up - true if stack is now up, false else
 * RETURN:   NONE
 * NOTES:
 */
void aapiSocketNotifStackState(bool up)
{
    pthread_mutex_lock(&mSocksLock);
    if (up && !mSocksUp && mSocksWantUp) {
        logd("socks coming up now\n");
        aapiSockDoInit();
        pthread_mutex_unlock(&mSocksLock);
    } else if (!up) {
        mSocksWantUp = false;
        while (mListeners) {
            struct appiSockListener *sl = mListeners;
            mListeners = mListeners->next;
            free(sl);
        }
        pthread_mutex_unlock(&mSocksLock);
        if(mSocksUp) {
            aapiSockWorkerMsgSend(WORKER_MSG_QUIT, NULL);
            pthread_join(mWorker, NULL);
            close(mWorkerPipe);
        }
        mSocksUp = false;
    }
}









