/*
* Copyright (C) 2014 Samsung System LSI
* Copyright (C) 2013 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 <hardware/bluetooth.h>
#include <hardware/bt_sock.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <pthread.h>

#define LOG_TAG "BTIF_SOCK"
#include "osi/include/allocator.h"
#include "btif_common.h"
#include "btif_util.h"

#include "bta_api.h"
#include "btif_sock_thread.h"
#include "btif_sock_sdp.h"
#include "btif_sock_util.h"
#include "btif_sock_l2cap.h"
#include "l2cdefs.h"

#include "bt_target.h"
#include "gki.h"
#include "hcimsgs.h"
#include "sdp_api.h"
#include "btu.h"
#include "btm_api.h"
#include "btm_int.h"
#include "bta_jv_api.h"
#include "bta_jv_co.h"
#include "port_api.h"
#include "l2c_api.h"

#include <cutils/log.h>
#include <hardware/bluetooth.h>
#define asrt(s) if (!(s)) APPL_TRACE_ERROR("## %s assert %s failed at line:%d ##",__FUNCTION__, \
        #s, __LINE__)

static pthread_mutex_t slot_lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;


struct packet {
    struct packet *next, *prev;
    uint32_t len;
    uint8_t *data;
};

typedef struct l2cap_socket {

    struct l2cap_socket   *prev;                 //link to prev list item
    struct l2cap_socket   *next;                 //link to next list item
    bt_bdaddr_t            addr;                 //other side's address
    char                   name[256];            //user-friendly name of the service
    uint32_t               id;                   //just a tag to find this struct
    int                    handle;               //handle from lower layers
    unsigned               security;             //security flags
    int                    channel;              //channel (fixed_chan) or PSM (!fixed_chan)
    int                    our_fd;               //fd from our side
    int                    app_fd;               //fd from app's side

    unsigned               bytes_buffered;
    struct packet         *first_packet;         //fist packet to be delivered to app
    struct packet         *last_packet;          //last packet to be delivered to app

    BUFFER_Q               incoming_que;         //data that came in but has not yet been read
    unsigned               fixed_chan       :1;  //fixed channel (or psm?)
    unsigned               server           :1;  //is a server? (or connecting?)
    unsigned               connected        :1;  //is connected?
    unsigned               outgoing_congest :1;  //should we hold?
    unsigned               server_psm_sent  :1;  //The server shall only send PSM once.
}l2cap_socket;

static bt_status_t btSock_start_l2cap_server_l(l2cap_socket *sock);

static pthread_mutex_t state_lock;

l2cap_socket *socks = NULL;
static int pth = -1;

static void btsock_l2cap_cbk(tBTA_JV_EVT event, tBTA_JV *p_data, void *user_data);

/* TODO: Consider to remove this buffer, as we have a buffer in l2cap as well, and we risk
 *       a buffer overflow with this implementation if the socket data is not read from
 *       JAVA for a while. In such a case we should use flow control to tell the sender to
 *       back off.
 *       BUT remember we need to avoid blocking the BTA task execution - hence we cannot
 *       directly write to the socket.
 *       we should be able to change to store the data pointer here, and just wait
 *       confirming the l2cap_ind until we have more space in the buffer. */

/* returns FALSE if none - caller must free "data" memory when done with it */
static char packet_get_head_l(l2cap_socket *sock, uint8_t **data, uint32_t *len)
{
    struct packet *p = sock->first_packet;

    if (!p)
        return FALSE;

    if (data)
        *data = sock->first_packet->data;
    if (len)
        *len = sock->first_packet->len;
    sock->first_packet = p->next;
    if (sock->first_packet)
        sock->first_packet->prev = NULL;
    else
        sock->last_packet = NULL;

    if(len)
        sock->bytes_buffered -= *len;

    osi_free(p);

    return TRUE;
}

static struct packet *packet_alloc(const uint8_t *data, uint32_t len)
{
    struct packet *p = osi_calloc(sizeof(*p));
    uint8_t *buf = osi_malloc(len);

    if (p && buf) {

        p->data = buf;
        p->len = len;
        memcpy(p->data, data, len);
        return p;

    } else if (p)
       osi_free(p);
    else if (buf)
       osi_free(buf);

    return NULL;
}

/* makes a copy of the data, returns TRUE on success */
static char packet_put_head_l(l2cap_socket *sock, const void *data, uint32_t len)
{
    struct packet *p = packet_alloc((const uint8_t*)data, len);

    /*
     * We do not check size limits here since this is used to undo "getting" a
     * packet that the user read incompletely. That is to say the packet was
     * already in the queue. We do check thos elimits in packet_put_tail_l() since
     * that function is used to put new data into the queue.
     */

    if (!p)
        return FALSE;

    p->prev = NULL;
    p->next = sock->first_packet;
    sock->first_packet = p;
    if (p->next)
        p->next->prev = p;
    else
        sock->last_packet = p;

    sock->bytes_buffered += len;

    return TRUE;
}

/* makes a copy of the data, returns TRUE on success */
static char packet_put_tail_l(l2cap_socket *sock, const void *data, uint32_t len)
{
    struct packet *p = packet_alloc((const uint8_t*)data, len);

    if (sock->bytes_buffered >= L2CAP_MAX_RX_BUFFER) {
        ALOGE("packet_put_tail_l: buffer overflow");
        return FALSE;
    }

    if (!p) {
        ALOGE("packet_put_tail_l: unable to allocate packet...");
        return FALSE;
    }

    p->next = NULL;
    p->prev = sock->last_packet;
    sock->last_packet = p;
    if (p->prev)
        p->prev->next = p;
    else
        sock->first_packet = p;

    sock->bytes_buffered += len;

    return TRUE;
}

static inline void bd_copy(UINT8* dest, UINT8* src, BOOLEAN swap)
{
    if (swap) {
        int i;
        for (i =0; i < 6 ;i++)
            dest[i]= src[5-i];
    }
    else memcpy(dest, src, 6);
}

static char is_inited(void)
{
    char ret;


    pthread_mutex_lock(&state_lock);
    ret = pth != -1;
    pthread_mutex_unlock(&state_lock);

    return ret;
}

/* only call with mutex taken */
static l2cap_socket *btsock_l2cap_find_by_id_l(uint32_t id)
{
    l2cap_socket *sock = socks;

    while (sock && sock->id != id)
        sock = sock->next;

    return sock;
}

static void btsock_l2cap_free_l(l2cap_socket *sock)
{
    uint8_t *buf;
    l2cap_socket *t = socks;

    while(t && t != sock)
        t = t->next;

    if (!t) /* prever double-frees */
        return;

    if (sock->next)
        sock->next->prev = sock->prev;

    if (sock->prev)
        sock->prev->next = sock->next;
    else
        socks = sock->next;

    shutdown(sock->our_fd, SHUT_RDWR);
    close(sock->our_fd);
    if (sock->app_fd != -1) {
        close(sock->app_fd);
    } else {
        APPL_TRACE_ERROR("SOCK_LIST: free(id = %d) - NO app_fd!", sock->id);
    }

    while (packet_get_head_l(sock, &buf, NULL))
        osi_free(buf);

    //lower-level close() should be idempotent... so let's call it and see...
    // Only call if we are non server connections
    if (sock->handle && (sock->server == FALSE)) {
        if (sock->fixed_chan)
            BTA_JvL2capCloseLE(sock->handle);
        else
            BTA_JvL2capClose(sock->handle);
    }
    if ((sock->channel >= 0) && (sock->server == TRUE)) {
        if (sock->fixed_chan) {
            BTA_JvFreeChannel(sock->channel, BTA_JV_CONN_TYPE_L2CAP_LE);
        } else {
            BTA_JvFreeChannel(sock->channel, BTA_JV_CONN_TYPE_L2CAP);
        }
    }

    APPL_TRACE_DEBUG("SOCK_LIST: free(id = %d)", sock->id);
    osi_free(sock);
}

static void btsock_l2cap_free(l2cap_socket *sock)
{
    pthread_mutex_lock(&state_lock);
    btsock_l2cap_free_l(sock);
    pthread_mutex_unlock(&state_lock);
}

static l2cap_socket *btsock_l2cap_alloc_l(const char *name, const bt_bdaddr_t *addr,
        char is_server, int flags)
{
    l2cap_socket *sock;
    unsigned security = 0;
    int fds[2];

    if (flags & BTSOCK_FLAG_ENCRYPT)
        security |= is_server ? BTM_SEC_IN_ENCRYPT : BTM_SEC_OUT_ENCRYPT;
    if (flags & BTSOCK_FLAG_AUTH)
        security |= is_server ? BTM_SEC_IN_AUTHENTICATE : BTM_SEC_OUT_AUTHENTICATE;
    if (flags & BTSOCK_FLAG_AUTH_MITM)
        security |= is_server ? BTM_SEC_IN_MITM : BTM_SEC_OUT_MITM;
    if (flags & BTSOCK_FLAG_AUTH_16_DIGIT)
        security |= BTM_SEC_IN_MIN_16_DIGIT_PIN;

    sock = osi_calloc(sizeof(*sock));
    if (!sock) {
        APPL_TRACE_ERROR("alloc failed");
        goto fail_alloc;
    }

    if (socketpair(AF_LOCAL, SOCK_SEQPACKET, 0, fds)) {
        APPL_TRACE_ERROR("socketpair failed, errno:%d", errno);
        goto fail_sockpair;
    }

    sock->our_fd = fds[0];
    sock->app_fd = fds[1];
    sock->security = security;
    sock->server = is_server;
    sock->connected = FALSE;
    sock->handle = 0;
    sock->server_psm_sent = FALSE;

    if (name)
        strncpy(sock->name, name, sizeof(sock->name) - 1);
    if (addr)
        sock->addr = *addr;

    sock->first_packet = NULL;
    sock->last_packet = NULL;

    sock->next = socks;
    sock->prev = NULL;
    if (socks)
        socks->prev = sock;
    sock->id = (socks ? socks->id : 0) + 1;
    socks = sock;
    /* paranoia cap on: verify no ID duplicates due to overflow and fix as needed */
    while (1) {
        l2cap_socket *t;
        t = socks->next;
        while (t && t->id != sock->id) {
            t = t->next;
        }
        if (!t && sock->id) /* non-zeor handle is unique -> we're done */
            break;
        /* if we're here, we found a duplicate */
        if (!++sock->id) /* no zero IDs allowed */
            sock->id++;
    }
    APPL_TRACE_DEBUG("SOCK_LIST: alloc(id = %d)", sock->id);
    return sock;

fail_sockpair:
    osi_free(sock);

fail_alloc:
    return NULL;
}

static l2cap_socket *btsock_l2cap_alloc(const char *name, const bt_bdaddr_t *addr,
        char is_server, int flags)
{
    l2cap_socket *ret;

    pthread_mutex_lock(&state_lock);
    ret = btsock_l2cap_alloc_l(name, addr, is_server, flags);
    pthread_mutex_unlock(&state_lock);

    return ret;
}

bt_status_t btsock_l2cap_init(int handle)
{
    APPL_TRACE_DEBUG("btsock_l2cap_init...");
    pthread_mutex_lock(&state_lock);
    pth = handle;
    socks = NULL;
    pthread_mutex_unlock(&state_lock);

    return BT_STATUS_SUCCESS;
}

bt_status_t btsock_l2cap_cleanup()
{
    pthread_mutex_lock(&state_lock);
    pth = -1;
    while (socks)
        btsock_l2cap_free_l(socks);
    pthread_mutex_unlock(&state_lock);

    return BT_STATUS_SUCCESS;
}

static inline BOOLEAN send_app_psm_or_chan_l(l2cap_socket *sock)
{
    return sock_send_all(sock->our_fd, (const uint8_t*)&sock->channel, sizeof(sock->channel))
            == sizeof(sock->channel);
}

static BOOLEAN send_app_connect_signal(int fd, const bt_bdaddr_t* addr,
        int channel, int status, int send_fd, int tx_mtu)
{
    sock_connect_signal_t cs;
    cs.size = sizeof(cs);
    cs.bd_addr = *addr;
    cs.channel = channel;
    cs.status = status;
    cs.max_rx_packet_size = L2CAP_MAX_SDU_LENGTH;
    cs.max_tx_packet_size = tx_mtu;
    if (send_fd != -1) {
        if (sock_send_fd(fd, (const uint8_t*)&cs, sizeof(cs), send_fd) == sizeof(cs))
            return TRUE;
        else APPL_TRACE_ERROR("sock_send_fd failed, fd:%d, send_fd:%d", fd, send_fd);
    } else if (sock_send_all(fd, (const uint8_t*)&cs, sizeof(cs)) == sizeof(cs)) {
        return TRUE;
    }
    return FALSE;
}

static void on_srv_l2cap_listen_started(tBTA_JV_L2CAP_START *p_start, uint32_t id)
{
    l2cap_socket *sock;

    pthread_mutex_lock(&state_lock);
    sock = btsock_l2cap_find_by_id_l(id);
    if (sock) {
        if (p_start->status != BTA_JV_SUCCESS) {
            APPL_TRACE_ERROR("Error starting l2cap_listen - status: 0x%04x", p_start->status);
            btsock_l2cap_free_l(sock);
        }
        else {
            sock->handle = p_start->handle;
            APPL_TRACE_DEBUG("on_srv_l2cap_listen_started() sock->handle =%d id:%d",
                    sock->handle, sock->id);
            if(sock->server_psm_sent == FALSE) {
                if (!send_app_psm_or_chan_l(sock)) {
                    //closed
                    APPL_TRACE_DEBUG("send_app_psm() failed, close rs->id:%d", sock->id);
                    btsock_l2cap_free_l(sock);
                } else {
                    sock->server_psm_sent = TRUE;
                }
            }
        }
    }
    pthread_mutex_unlock(&state_lock);
}

static void on_cl_l2cap_init(tBTA_JV_L2CAP_CL_INIT *p_init, uint32_t id)
{
    l2cap_socket *sock;

    pthread_mutex_lock(&state_lock);
    sock = btsock_l2cap_find_by_id_l(id);
    if (sock) {
        if (p_init->status != BTA_JV_SUCCESS) {
            btsock_l2cap_free_l(sock);
        } else {
            sock->handle = p_init->handle;
        }
    }
    pthread_mutex_unlock(&state_lock);
}

/**
 * Here we allocate a new sock instance to mimic the BluetoothSocket. The socket will be a clone
 * of the sock representing the BluetoothServerSocket.
 * */
static void on_srv_l2cap_psm_connect_l(tBTA_JV_L2CAP_OPEN *p_open, l2cap_socket *sock)
{
    l2cap_socket *accept_rs;
    uint32_t new_listen_id;

    // Mutex locked by caller
    accept_rs = btsock_l2cap_alloc_l(sock->name, (const bt_bdaddr_t*)p_open->rem_bda, FALSE, 0);
    accept_rs->connected = TRUE;
    accept_rs->security = sock->security;
    accept_rs->fixed_chan = sock->fixed_chan;
    accept_rs->channel = sock->channel;
    accept_rs->handle = sock->handle;
    sock->handle = -1; /* We should no longer associate this handle with the server socket */

    /* Swap IDs to hand over the GAP connection to the accepted socket, and start a new server on
       the newly create socket ID. */
    new_listen_id = accept_rs->id;
    accept_rs->id = sock->id;
    sock->id = new_listen_id;

    if (accept_rs) {
        //start monitor the socket
        btsock_thread_add_fd(pth, sock->our_fd, BTSOCK_L2CAP, SOCK_THREAD_FD_EXCEPTION, sock->id);
        btsock_thread_add_fd(pth, accept_rs->our_fd, BTSOCK_L2CAP, SOCK_THREAD_FD_RD,
                accept_rs->id);
        APPL_TRACE_DEBUG("sending connect signal & app fd: %d to app server to accept() the"
                " connection", accept_rs->app_fd);
        APPL_TRACE_DEBUG("server fd:%d, scn:%d", sock->our_fd, sock->channel);
        send_app_connect_signal(sock->our_fd, &accept_rs->addr, sock->channel, 0,
                accept_rs->app_fd, p_open->tx_mtu);
        accept_rs->app_fd = -1; // The fd is closed after sent to app in send_app_connect_signal()
                                // But for some reason we still leak a FD - either the server socket
                                // one or the accept socket one.
        if(btSock_start_l2cap_server_l(sock) != BT_STATUS_SUCCESS) {
            btsock_l2cap_free_l(sock);
        }
    }
}

static void on_srv_l2cap_le_connect_l(tBTA_JV_L2CAP_LE_OPEN *p_open, l2cap_socket *sock)
{
    l2cap_socket *accept_rs;
    uint32_t new_listen_id;

    // mutex locked by caller
    accept_rs = btsock_l2cap_alloc_l(sock->name, (const bt_bdaddr_t*)p_open->rem_bda, FALSE, 0);
    if (accept_rs) {

        //swap IDs
        new_listen_id = accept_rs->id;
        accept_rs->id = sock->id;
        sock->id = new_listen_id;

        accept_rs->handle = p_open->handle;
        accept_rs->connected = TRUE;
        accept_rs->security = sock->security;
        accept_rs->fixed_chan = sock->fixed_chan;
        accept_rs->channel = sock->channel;

        //if we do not set a callback, this socket will be dropped */
        *(p_open->p_p_cback) = (void*)btsock_l2cap_cbk;
        *(p_open->p_user_data) = (void*)accept_rs->id;

        //start monitor the socket
        btsock_thread_add_fd(pth, sock->our_fd, BTSOCK_L2CAP, SOCK_THREAD_FD_EXCEPTION, sock->id);
        btsock_thread_add_fd(pth, accept_rs->our_fd, BTSOCK_L2CAP, SOCK_THREAD_FD_RD,
                accept_rs->id);
        APPL_TRACE_DEBUG("sending connect signal & app fd:%dto app server to accept() the"
                " connection", accept_rs->app_fd);
        APPL_TRACE_DEBUG("server fd:%d, scn:%d", sock->our_fd, sock->channel);
        send_app_connect_signal(sock->our_fd, &accept_rs->addr, sock->channel, 0,
                accept_rs->app_fd, p_open->tx_mtu);
        accept_rs->app_fd = -1; //the fd is closed after sent to app
    }
}

static void on_cl_l2cap_psm_connect_l(tBTA_JV_L2CAP_OPEN *p_open, l2cap_socket *sock)
{
    bd_copy(sock->addr.address, p_open->rem_bda, 0);

    if (!send_app_psm_or_chan_l(sock)) {
        APPL_TRACE_ERROR("send_app_psm_or_chan_l failed");
        return;
    }

    if (send_app_connect_signal(sock->our_fd, &sock->addr, sock->channel, 0, -1, p_open->tx_mtu)) {
        //start monitoring the socketpair to get call back when app writing data
        APPL_TRACE_DEBUG("on_l2cap_connect_ind, connect signal sent, slot id:%d, psm:%d,"
                " server:%d", sock->id, sock->channel, sock->server);
        btsock_thread_add_fd(pth, sock->our_fd, BTSOCK_L2CAP, SOCK_THREAD_FD_RD, sock->id);
        sock->connected = TRUE;
    }
    else APPL_TRACE_ERROR("send_app_connect_signal failed");
}

static void on_cl_l2cap_le_connect_l(tBTA_JV_L2CAP_LE_OPEN *p_open, l2cap_socket *sock)
{
    bd_copy(sock->addr.address, p_open->rem_bda, 0);

    if (!send_app_psm_or_chan_l(sock)) {
        APPL_TRACE_ERROR("send_app_psm_or_chan_l failed");
        return;
    }

    if (send_app_connect_signal(sock->our_fd, &sock->addr, sock->channel, 0, -1, p_open->tx_mtu)) {
        //start monitoring the socketpair to get call back when app writing data
        APPL_TRACE_DEBUG("on_l2cap_connect_ind, connect signal sent, slot id:%d, Chan:%d,"
                " server:%d", sock->id, sock->channel, sock->server);
        btsock_thread_add_fd(pth, sock->our_fd, BTSOCK_L2CAP, SOCK_THREAD_FD_RD, sock->id);
        sock->connected = TRUE;
    }
    else APPL_TRACE_ERROR("send_app_connect_signal failed");
}

static void on_l2cap_connect(tBTA_JV *p_data, uint32_t id)
{
    l2cap_socket *sock;
    tBTA_JV_L2CAP_OPEN *psm_open = &p_data->l2c_open;
    tBTA_JV_L2CAP_LE_OPEN *le_open = &p_data->l2c_le_open;

    pthread_mutex_lock(&state_lock);
    sock = btsock_l2cap_find_by_id_l(id);
    if (!sock) {
        APPL_TRACE_ERROR("on_l2cap_connect on unknown socket");
    } else {
        if (sock->fixed_chan && le_open->status == BTA_JV_SUCCESS) {
            if (!sock->server)
                on_cl_l2cap_le_connect_l(le_open, sock);
            else
                on_srv_l2cap_le_connect_l(le_open, sock);
        } else if (!sock->fixed_chan && psm_open->status == BTA_JV_SUCCESS) {
            if (!sock->server)
                on_cl_l2cap_psm_connect_l(psm_open, sock);
            else
                on_srv_l2cap_psm_connect_l(psm_open, sock);
        }
        else
            btsock_l2cap_free_l(sock);
    }
    pthread_mutex_unlock(&state_lock);
}

static void on_l2cap_close(tBTA_JV_L2CAP_CLOSE * p_close, uint32_t id)
{
    l2cap_socket *sock;

    pthread_mutex_lock(&state_lock);
    sock = btsock_l2cap_find_by_id_l(id);
    if (sock) {
        APPL_TRACE_DEBUG("on_l2cap_close, slot id:%d, fd:%d, %s:%d, server:%d",
                sock->id, sock->our_fd, sock->fixed_chan ? "fixed_chan" : "PSM",
                sock->channel, sock->server);
        sock->handle = 0;
        // TODO: This does not seem to be called...
        // I'm not sure if this will be called for non-server sockets?
        if(!sock->fixed_chan && (sock->server == TRUE)) {
            BTA_JvFreeChannel(sock->channel, BTA_JV_CONN_TYPE_L2CAP);
        }
        btsock_l2cap_free_l(sock);
    }
    pthread_mutex_unlock(&state_lock);
}

static void on_l2cap_outgoing_congest(tBTA_JV_L2CAP_CONG *p, uint32_t id)
{
    l2cap_socket *sock;

    pthread_mutex_lock(&state_lock);
    sock = btsock_l2cap_find_by_id_l(id);
    if (sock) {
        sock->outgoing_congest = p->cong ? 1 : 0;
        //mointer the fd for any outgoing data
        if (!sock->outgoing_congest) {
            APPL_TRACE_DEBUG("on_l2cap_outgoing_congest: adding fd to btsock_thread...");
            btsock_thread_add_fd(pth, sock->our_fd, BTSOCK_L2CAP, SOCK_THREAD_FD_RD, sock->id);

        }
    }
    pthread_mutex_unlock(&state_lock);
}

static void on_l2cap_write_done(void* req_id, uint32_t id)
{
    l2cap_socket *sock;

    if (req_id != NULL) {
        osi_free(req_id); //free the buffer
    }

    pthread_mutex_lock(&state_lock);
    sock = btsock_l2cap_find_by_id_l(id);
    if (sock && !sock->outgoing_congest) {
        //monitor the fd for any outgoing data
        APPL_TRACE_DEBUG("on_l2cap_write_done: adding fd to btsock_thread...");
        btsock_thread_add_fd(pth, sock->our_fd, BTSOCK_L2CAP, SOCK_THREAD_FD_RD, sock->id);
    }
    pthread_mutex_unlock(&state_lock);
}

static void on_l2cap_write_fixed_done(void* req_id, uint32_t id)
{
    l2cap_socket *sock;

    if (req_id != NULL) {
        osi_free(req_id); //free the buffer
    }

    pthread_mutex_lock(&state_lock);
    sock = btsock_l2cap_find_by_id_l(id);
    if (sock && !sock->outgoing_congest) {
        //monitor the fd for any outgoing data
        btsock_thread_add_fd(pth, sock->our_fd, BTSOCK_L2CAP, SOCK_THREAD_FD_RD, sock->id);
    }
    pthread_mutex_unlock(&state_lock);
}



static void on_l2cap_data_ind(tBTA_JV *evt, uint32_t id)
{
    l2cap_socket *sock;

    pthread_mutex_lock(&state_lock);
    sock = btsock_l2cap_find_by_id_l(id);
    if (sock) {
        if (sock->fixed_chan) { /* we do these differently */

            tBTA_JV_LE_DATA_IND *p_le_data_ind = &evt->le_data_ind;
            BT_HDR *p_buf = p_le_data_ind->p_buf;
            uint8_t *data = (uint8_t*)(p_buf + 1) + p_buf->offset;

            if (packet_put_tail_l(sock, data, p_buf->len))
                btsock_thread_add_fd(pth, sock->our_fd, BTSOCK_L2CAP, SOCK_THREAD_FD_WR, sock->id);
            else {//connection must be dropped
                APPL_TRACE_DEBUG("on_l2cap_data_ind() unable to push data to socket - closing"
                        " fixed channel");
                BTA_JvL2capCloseLE(sock->handle);
                btsock_l2cap_free_l(sock);
            }

        } else {

            tBTA_JV_DATA_IND *p_data_ind = &evt->data_ind;
            UINT8 buffer[L2CAP_MAX_SDU_LENGTH];
            UINT32  count;

            if (BTA_JvL2capReady(sock->handle, &count) == BTA_JV_SUCCESS) {
                if (BTA_JvL2capRead(sock->handle, sock->id, buffer, count) == BTA_JV_SUCCESS) {
                    if (packet_put_tail_l(sock, buffer, count))
                        btsock_thread_add_fd(pth, sock->our_fd, BTSOCK_L2CAP, SOCK_THREAD_FD_WR,
                                sock->id);
                    else {//connection must be dropped
                        APPL_TRACE_DEBUG("on_l2cap_data_ind() unable to push data to socket"
                                " - closing channel");
                        BTA_JvL2capClose(sock->handle);
                        btsock_l2cap_free_l(sock);
                    }
                }
            }
        }
    }
    pthread_mutex_unlock(&state_lock);
}

static void btsock_l2cap_cbk(tBTA_JV_EVT event, tBTA_JV *p_data, void *user_data)
{
    int rc;

    switch (event) {
    case BTA_JV_L2CAP_START_EVT:
        on_srv_l2cap_listen_started(&p_data->l2c_start, (uint32_t)user_data);
        break;

    case BTA_JV_L2CAP_CL_INIT_EVT:
        on_cl_l2cap_init(&p_data->l2c_cl_init, (uint32_t)user_data);
        break;

    case BTA_JV_L2CAP_OPEN_EVT:
        on_l2cap_connect(p_data, (uint32_t)user_data);
        BTA_JvSetPmProfile(p_data->l2c_open.handle,BTA_JV_PM_ID_1,BTA_JV_CONN_OPEN);
        break;

    case BTA_JV_L2CAP_CLOSE_EVT:
        APPL_TRACE_DEBUG("BTA_JV_L2CAP_CLOSE_EVT: user_data:%d", (uint32_t)user_data);
        on_l2cap_close(&p_data->l2c_close, (uint32_t)user_data);
        break;

    case BTA_JV_L2CAP_DATA_IND_EVT:
        on_l2cap_data_ind(p_data, (uint32_t)user_data);
        APPL_TRACE_DEBUG("BTA_JV_L2CAP_DATA_IND_EVT");
        break;

    case BTA_JV_L2CAP_READ_EVT:
        APPL_TRACE_DEBUG("BTA_JV_L2CAP_READ_EVT not used");
        break;

    case BTA_JV_L2CAP_RECEIVE_EVT:
        APPL_TRACE_DEBUG("BTA_JV_L2CAP_RECEIVE_EVT not used");
        break;

    case BTA_JV_L2CAP_WRITE_EVT:
        APPL_TRACE_DEBUG("BTA_JV_L2CAP_WRITE_EVT id: %d", (int)user_data);
        on_l2cap_write_done((void*)p_data->l2c_write.req_id, (uint32_t)user_data);
        break;

    case BTA_JV_L2CAP_WRITE_FIXED_EVT:
        APPL_TRACE_DEBUG("BTA_JV_L2CAP_WRITE_FIXED_EVT id: %d", (int)user_data);
        on_l2cap_write_fixed_done((void*)p_data->l2c_write_fixed.req_id, (uint32_t)user_data);
        break;

    case BTA_JV_L2CAP_CONG_EVT:
        on_l2cap_outgoing_congest(&p_data->l2c_cong, (uint32_t)user_data);
        break;

    default:
        APPL_TRACE_ERROR("unhandled event %d, slot id:%d", event, (uint32_t)user_data);
        break;
    }
}

/* L2CAP default options for OBEX socket connections */
const tL2CAP_FCR_OPTS obex_l2c_fcr_opts_def =
{
    L2CAP_FCR_ERTM_MODE,            /* Mandatory for OBEX over l2cap */
    OBX_FCR_OPT_TX_WINDOW_SIZE_BR_EDR,/* Tx window size */
    OBX_FCR_OPT_MAX_TX_B4_DISCNT,   /* Maximum transmissions before disconnecting */
    OBX_FCR_OPT_RETX_TOUT,          /* Retransmission timeout (2 secs) */
    OBX_FCR_OPT_MONITOR_TOUT,       /* Monitor timeout (12 secs) */
    OBX_FCR_OPT_MAX_PDU_SIZE        /* MPS segment size */
};
const tL2CAP_ERTM_INFO obex_l2c_etm_opt =
{
        L2CAP_FCR_ERTM_MODE,            /* Mandatory for OBEX over l2cap */
        L2CAP_FCR_CHAN_OPT_ERTM,        /* Mandatory for OBEX over l2cap */
        OBX_USER_RX_POOL_ID,
        OBX_USER_TX_POOL_ID,
        OBX_FCR_RX_POOL_ID,
        OBX_FCR_TX_POOL_ID
};

/**
 * When using a dynamic PSM, a PSM allocation is requested from btsock_l2cap_listen_or_connect().
 * The PSM allocation event is refeived in the JV-callback - currently located in RFC-code -
 * and this function is called with the newly allocated PSM.
 */
void on_l2cap_psm_assigned(int id, int psm) {
    l2cap_socket *sock;
    /* Setup ETM settings:
     *  mtu will be set below */
    pthread_mutex_lock(&state_lock);
    sock = btsock_l2cap_find_by_id_l(id);
    sock->channel = psm;

    if(btSock_start_l2cap_server_l(sock) != BT_STATUS_SUCCESS) {
        btsock_l2cap_free_l(sock);
    }

    pthread_mutex_unlock(&state_lock);

}

static bt_status_t btSock_start_l2cap_server_l(l2cap_socket *sock) {
    tL2CAP_CFG_INFO cfg;
    bt_status_t stat = BT_STATUS_SUCCESS;
    /* Setup ETM settings:
     *  mtu will be set below */
    memset(&cfg, 0, sizeof(tL2CAP_CFG_INFO));

    cfg.fcr_present = TRUE;
    cfg.fcr = obex_l2c_fcr_opts_def;

    if (sock->fixed_chan) {

        if (BTA_JvL2capStartServerLE(sock->security, 0, NULL, sock->channel,
                L2CAP_DEFAULT_MTU, NULL, btsock_l2cap_cbk, (void*)sock->id)
                != BTA_JV_SUCCESS)
            stat = BT_STATUS_FAIL;

    } else {
        /* If we have a channel specified in the request, just start the server,
         * else we request a PSM and start the server after we receive a PSM. */
        if(sock->channel < 0) {
            if(BTA_JvGetChannelId(BTA_JV_CONN_TYPE_L2CAP, (void*)sock->id, 0)
                    != BTA_JV_SUCCESS)
                stat = BT_STATUS_FAIL;
        } else {
            if (BTA_JvL2capStartServer(sock->security, 0, &obex_l2c_etm_opt,
                    sock->channel, L2CAP_MAX_SDU_LENGTH, &cfg, btsock_l2cap_cbk, (void*)sock->id)
                    != BTA_JV_SUCCESS)
                stat = BT_STATUS_FAIL;
        }
    }
    return stat;
}

static bt_status_t btsock_l2cap_listen_or_connect(const char *name, const bt_bdaddr_t *addr,
        int channel, int* sock_fd, int flags, char listen)
{
    bt_status_t stat;
    int fixed_chan = 1;
    l2cap_socket *sock;
    tL2CAP_CFG_INFO cfg;

    if (!sock_fd)
        return BT_STATUS_PARM_INVALID;

    if(channel < 0) {
        // We need to auto assign a PSM
        fixed_chan = 0;
    } else {
        fixed_chan = (channel & L2CAP_MASK_FIXED_CHANNEL) != 0;
        channel &=~ L2CAP_MASK_FIXED_CHANNEL;
    }

    if (!is_inited())
        return BT_STATUS_NOT_READY;

    // TODO: This is kind of bad to lock here, but it is needed for the current design.
    pthread_mutex_lock(&state_lock);

    sock = btsock_l2cap_alloc_l(name, addr, listen, flags);
    if (!sock)
        return BT_STATUS_NOMEM;

    sock->fixed_chan = fixed_chan;
    sock->channel = channel;

    stat = BT_STATUS_SUCCESS;

    /* Setup ETM settings:
     *  mtu will be set below */
    memset(&cfg, 0, sizeof(tL2CAP_CFG_INFO));

    cfg.fcr_present = TRUE;
    cfg.fcr = obex_l2c_fcr_opts_def;

    /* "role" is never initialized in rfcomm code */
    if (listen) {
        stat = btSock_start_l2cap_server_l(sock);
    } else {
        if (fixed_chan) {
            if (BTA_JvL2capConnectLE(sock->security, 0, NULL, channel,
                    L2CAP_DEFAULT_MTU, NULL, sock->addr.address, btsock_l2cap_cbk,
                    (void*)sock->id) != BTA_JV_SUCCESS)
                stat = BT_STATUS_FAIL;

        } else {
            if (BTA_JvL2capConnect(sock->security, 0, &obex_l2c_etm_opt,
                    channel, L2CAP_MAX_SDU_LENGTH, &cfg, sock->addr.address,
                    btsock_l2cap_cbk, (void*)sock->id) != BTA_JV_SUCCESS)
                stat = BT_STATUS_FAIL;
        }
    }

    if (stat == BT_STATUS_SUCCESS) {
        *sock_fd = sock->app_fd;
        /* We pass the FD to JAVA, but since it runs in another process, we need to also close
         * it in native, either straight away, as done when accepting an incoming connection,
         * or when doing cleanup after this socket */
        sock->app_fd = -1;  /*This leaks the file descriptor. The FD should be closed in
                              JAVA but it apparently do not work */
        btsock_thread_add_fd(pth, sock->our_fd, BTSOCK_L2CAP, SOCK_THREAD_FD_EXCEPTION,
                sock->id);
    } else {
       btsock_l2cap_free_l(sock);
    }
    pthread_mutex_unlock(&state_lock);

    return stat;
}

bt_status_t btsock_l2cap_listen(const char* name, int channel, int* sock_fd, int flags)
{
    return btsock_l2cap_listen_or_connect(name, NULL, channel, sock_fd, flags, 1);
}

bt_status_t btsock_l2cap_connect(const bt_bdaddr_t *bd_addr, int channel, int* sock_fd, int flags)
{
    return btsock_l2cap_listen_or_connect(NULL, bd_addr, channel, sock_fd, flags, 0);
}

/* return TRUE if we have more to send and should wait for user readiness, FALSE else
 * (for example: unrecoverable error or no data)
 */
static BOOLEAN flush_incoming_que_on_wr_signal_l(l2cap_socket *sock)
{
    uint8_t *buf;
    uint32_t len;

    while (packet_get_head_l(sock, &buf, &len)) {
        int sent = send(sock->our_fd, buf, len, MSG_DONTWAIT);

        if (sent == (signed)len)
            osi_free(buf);
        else if (sent >= 0) {
            packet_put_head_l(sock, buf + sent, len - sent);
            osi_free(buf);
            if (!sent) /* special case if other end not keeping up */
                return TRUE;
        }
        else {
            packet_put_head_l(sock, buf, len);
            osi_free(buf);
            return errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN;
        }
    }

    return FALSE;
}

void btsock_l2cap_signaled(int fd, int flags, uint32_t user_id)
{
    l2cap_socket *sock;
    char drop_it = FALSE;

    /* We use MSG_DONTWAIT when sending data to JAVA, hence it can be accepted to hold the lock. */
    pthread_mutex_lock(&state_lock);
    sock = btsock_l2cap_find_by_id_l(user_id);
    if (sock) {
        if ((flags & SOCK_THREAD_FD_RD) && !sock->server) {
            //app sending data
            if (sock->connected) {
                int size = 0;

                if (!(flags & SOCK_THREAD_FD_EXCEPTION) || (ioctl(sock->our_fd, FIONREAD, &size)
                        == 0 && size)) {
                    uint8_t *buffer = osi_malloc(L2CAP_MAX_SDU_LENGTH);
                    //uint8_t *buffer = (uint8_t*)GKI_getbuf(L2CAP_MAX_SDU_LENGTH);
                    /* Apparently we hijack the req_id (UINT32) to pass the pointer to the buffer to
                     * the write complete callback, which call a free... wonder if this works on a
                     * 64 bit platform? */
                    if (buffer != NULL) {
                        /* The socket is created with SOCK_SEQPACKET, hence we read one message at
                         * the time. The maximum size of a message is allocated to ensure data is
                         * not lost. This is okay to do as Android uses virtual memory, hence even
                         * if we only use a fraction of the memory it should not block for others
                         * to use the memory. As the definition of ioctl(FIONREAD) do not clearly
                         * define what value will be returned if multiple messages are written to
                         * the socket before any message is read from the socket, we could
                         * potentially risk to allocate way more memory than needed. One of the use
                         * cases for this socket is obex where multiple 64kbyte messages are
                         * typically written to the socket in a tight loop, hence we risk the ioctl
                         * will return the total amount of data in the buffer, which could be
                         * multiple 64kbyte chunks.
                         * UPDATE: As bluedroid cannot handle 64kbyte buffers, the size is reduced
                         * to around 8kbyte - and using malloc for buffer allocation here seems to
                         * be wrong
                         * UPDATE: Since we are responsible for freeing the buffer in the
                         * write_complete_ind, it is OK to use malloc. */

                        int count = recv(fd, buffer, L2CAP_MAX_SDU_LENGTH,
                                MSG_NOSIGNAL | MSG_DONTWAIT);
                        APPL_TRACE_DEBUG("btsock_l2cap_signaled - %d bytes received from socket",
                                count);
                        if (sock->fixed_chan) {
                            if(BTA_JvL2capWriteFixed(sock->channel, (BD_ADDR*)&sock->addr,
                                    (UINT32)buffer, btsock_l2cap_cbk, buffer, count,
                                    (void *)user_id) != BTA_JV_SUCCESS) {
                                // On fail, free the buffer
                                on_l2cap_write_fixed_done(buffer, user_id);
                            }
                        } else {
                            if(BTA_JvL2capWrite(sock->handle, (UINT32)buffer, buffer, count,
                                    (void *)user_id) != BTA_JV_SUCCESS) {
                                // On fail, free the buffer
                                on_l2cap_write_done(buffer, user_id);
                            }
                        }
                    } else {
                        // This cannot happen.
                        APPL_TRACE_ERROR("Unable to allocate memory for data packet from JAVA...")
                    }
                }
            } else
                drop_it = TRUE;
        }
        if (flags & SOCK_THREAD_FD_WR) {
            //app is ready to receive more data, tell stack to enable the data flow
            if (flush_incoming_que_on_wr_signal_l(sock) && sock->connected)
                btsock_thread_add_fd(pth, sock->our_fd, BTSOCK_L2CAP, SOCK_THREAD_FD_WR, sock->id);
        }
        if (drop_it || (flags & SOCK_THREAD_FD_EXCEPTION)) {
            int size = 0;
            if (drop_it || ioctl(sock->our_fd, FIONREAD, &size) != 0 || size == 0)
                btsock_l2cap_free_l(sock);
        }
    }
    pthread_mutex_unlock(&state_lock);
}



