/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 */

/*
 * Provides HCI transport over sockets. Either over
 * TCP sockets, or Linux bluetooth socket.
 *
 * E.g. to connect to TCP target, start in another window
 * socat -x PIPE:/dev/ttyACM1 TCP4-LISTEN:14433,fork,reuseaddr
 * When building this package, set BLE_SOCK_USE_TCP=1 and
 * BLE_SOCK_TCP_PORT controls the target port this transport
 * connects to.
 *
 * To use Linux Bluetooth sockets, create an interface:
 * sudo hciattach -r -n /dev/ttyUSB0 any 57600
 * And build this package with BLE_SOCK_USE_LINUX_BLUE=1,
 * BLE_SOCK_LINUX_DEV=<interface index of the target interface>
 *
 */
#include "syscfg/syscfg.h"

#include <assert.h>
#include <string.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/uio.h>
#include <unistd.h>
#include <sys/socket.h>

#if MYNEWT_VAL(BLE_SOCK_USE_TCP)
#include <sys/errno.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#endif

#if MYNEWT_VAL(BLE_SOCK_USE_LINUX_BLUE)
#include <sys/errno.h>
#define BTPROTO_HCI 1
#define HCI_CHANNEL_RAW		0
#define HCI_CHANNEL_USER	1
#define HCIDEVUP	_IOW('H', 201, int)
#define HCIDEVDOWN	_IOW('H', 202, int)
#define HCIDEVRESET	_IOW('H', 203, int)
#define HCIGETDEVLIST	_IOR('H', 210, int)

struct sockaddr_hci {
        sa_family_t    hci_family;
        unsigned short hci_dev;
        unsigned short hci_channel;
};
#endif

#include <fcntl.h>
#include <sys/ioctl.h>

#include "sysinit/sysinit.h"
#include "os/os.h"
#include "mem/mem.h"

#include "stats/stats.h"

/* BLE */
#include "nimble/ble.h"
#include "nimble/nimble_opt.h"
#include "nimble/hci_common.h"
#include "nimble/ble_hci_trans.h"
#include "socket/ble_hci_socket.h"

/***
 * NOTES:
 * The UART HCI transport doesn't use event buffer priorities.  All incoming
 * and outgoing events use buffers from the same pool.
 *
 * The "skip" definitions are here so that when buffers cannot be allocated,
 * the command or acl packets are simply skipped so that the HCI interface
 * does not lose synchronization and resets dont (necessarily) occur.
 */

STATS_SECT_START(hci_sock_stats)
    STATS_SECT_ENTRY(imsg)
    STATS_SECT_ENTRY(icmd)
    STATS_SECT_ENTRY(ievt)
    STATS_SECT_ENTRY(iacl)
    STATS_SECT_ENTRY(ibytes)
    STATS_SECT_ENTRY(ierr)
    STATS_SECT_ENTRY(imem)
    STATS_SECT_ENTRY(omsg)
    STATS_SECT_ENTRY(oacl)
    STATS_SECT_ENTRY(ocmd)
    STATS_SECT_ENTRY(oevt)
    STATS_SECT_ENTRY(obytes)
    STATS_SECT_ENTRY(oerr)
STATS_SECT_END

STATS_SECT_DECL(hci_sock_stats) hci_sock_stats;
STATS_NAME_START(hci_sock_stats)
    STATS_NAME(hci_sock_stats, imsg)
    STATS_NAME(hci_sock_stats, icmd)
    STATS_NAME(hci_sock_stats, ievt)
    STATS_NAME(hci_sock_stats, iacl)
    STATS_NAME(hci_sock_stats, ibytes)
    STATS_NAME(hci_sock_stats, ierr)
    STATS_NAME(hci_sock_stats, imem)
    STATS_NAME(hci_sock_stats, omsg)
    STATS_NAME(hci_sock_stats, oacl)
    STATS_NAME(hci_sock_stats, ocmd)
    STATS_NAME(hci_sock_stats, oevt)
    STATS_NAME(hci_sock_stats, obytes)
    STATS_NAME(hci_sock_stats, oerr)
STATS_NAME_END(hci_sock_stats)

/***
 * NOTES:
 * The "skip" definitions are here so that when buffers cannot be allocated,
 * the command or acl packets are simply skipped so that the HCI interface
 * does not lose synchronization and resets dont (necessarily) occur.
 */
#define BLE_HCI_UART_H4_NONE        0x00
#define BLE_HCI_UART_H4_CMD         0x01
#define BLE_HCI_UART_H4_ACL         0x02
#define BLE_HCI_UART_H4_SCO         0x03
#define BLE_HCI_UART_H4_EVT         0x04
#define BLE_HCI_UART_H4_SYNC_LOSS   0x80
#define BLE_HCI_UART_H4_SKIP_CMD    0x81
#define BLE_HCI_UART_H4_SKIP_ACL    0x82

#if MYNEWT

#define BLE_SOCK_STACK_SIZE         \
    OS_STACK_ALIGN(MYNEWT_VAL(BLE_SOCK_STACK_SIZE))

struct os_task ble_sock_task;

#endif

static struct os_mempool ble_hci_sock_evt_hi_pool;
static os_membuf_t ble_hci_sock_evt_hi_buf[
        OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_HCI_EVT_HI_BUF_COUNT),
                        MYNEWT_VAL(BLE_HCI_EVT_BUF_SIZE))
];

static struct os_mempool ble_hci_sock_evt_lo_pool;
static os_membuf_t ble_hci_sock_evt_lo_buf[
        OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_HCI_EVT_LO_BUF_COUNT),
                        MYNEWT_VAL(BLE_HCI_EVT_BUF_SIZE))
];

static struct os_mempool ble_hci_sock_cmd_pool;
static os_membuf_t ble_hci_sock_cmd_buf[
        OS_MEMPOOL_SIZE(1, BLE_HCI_TRANS_CMD_SZ)
];

static struct os_mempool ble_hci_sock_acl_pool;
static struct os_mbuf_pool ble_hci_sock_acl_mbuf_pool;

#define ACL_BLOCK_SIZE  OS_ALIGN(MYNEWT_VAL(BLE_ACL_BUF_SIZE) \
                                 + BLE_MBUF_MEMBLOCK_OVERHEAD \
                                 + BLE_HCI_DATA_HDR_SZ, OS_ALIGNMENT)
/*
 * The MBUF payload size must accommodate the HCI data header size plus the
 * maximum ACL data packet length. The ACL block size is the size of the
 * mbufs we will allocate.
 */

static os_membuf_t ble_hci_sock_acl_buf[
        OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_ACL_BUF_COUNT),
                        ACL_BLOCK_SIZE)
];

static ble_hci_trans_rx_cmd_fn *ble_hci_sock_rx_cmd_cb;
static void *ble_hci_sock_rx_cmd_arg;
static ble_hci_trans_rx_acl_fn *ble_hci_sock_rx_acl_cb;
static void *ble_hci_sock_rx_acl_arg;

static struct ble_hci_sock_state {
    int sock;
    struct ble_npl_eventq evq;
    struct ble_npl_event ev;
    struct ble_npl_callout timer;

    uint16_t rx_off;
    uint8_t rx_data[512];
} ble_hci_sock_state;

/**
 * Allocates a buffer (mbuf) for ACL operation.
 *
 * @return                      The allocated buffer on success;
 *                              NULL on buffer exhaustion.
 */
static struct os_mbuf *
ble_hci_trans_acl_buf_alloc(void)
{
    struct os_mbuf *m;

    /*
     * XXX: note that for host only there would be no need to allocate
     * a user header. Address this later.
     */
    m = os_mbuf_get_pkthdr(&ble_hci_sock_acl_mbuf_pool,
                           sizeof(struct ble_mbuf_hdr));
    return m;
}

static int
ble_hci_sock_acl_tx(struct os_mbuf *om)
{
    struct msghdr msg;
    struct iovec iov[8];
    int i;
    struct os_mbuf *m;
    uint8_t ch;

    memset(&msg, 0, sizeof(msg));
    memset(iov, 0, sizeof(iov));

    msg.msg_iov = iov;

    ch = BLE_HCI_UART_H4_ACL;
    iov[0].iov_len = 1;
    iov[0].iov_base = &ch;
    i = 1;
    for (m = om; m; m = SLIST_NEXT(m, om_next)) {
        iov[i].iov_base = m->om_data;
        iov[i].iov_len = m->om_len;
        i++;
    }
    msg.msg_iovlen = i;

    STATS_INC(hci_sock_stats, omsg);
    STATS_INC(hci_sock_stats, oacl);
    STATS_INCN(hci_sock_stats, obytes, OS_MBUF_PKTLEN(om) + 1);
    i = sendmsg(ble_hci_sock_state.sock, &msg, 0);
    os_mbuf_free_chain(om);
    if (i != OS_MBUF_PKTLEN(om) + 1) {
        if (i < 0) {
            dprintf(1, "sendmsg() failed : %d\n", errno);
        } else {
            dprintf(1, "sendmsg() partial write: %d\n", i);
        }
        STATS_INC(hci_sock_stats, oerr);
        return BLE_ERR_MEM_CAPACITY;
    }
    return 0;
}

static int
ble_hci_sock_cmdevt_tx(uint8_t *hci_ev, uint8_t h4_type)
{
    struct msghdr msg;
    struct iovec iov[8];
    int len;
    int i;
    uint8_t ch;

    memset(&msg, 0, sizeof(msg));
    memset(iov, 0, sizeof(iov));

    msg.msg_iov = iov;
    msg.msg_iovlen = 2;

    ch = h4_type;
    iov[0].iov_len = 1;
    iov[0].iov_base = &ch;
    iov[1].iov_base = hci_ev;
    if (h4_type == BLE_HCI_UART_H4_CMD) {
        len = BLE_HCI_CMD_HDR_LEN + hci_ev[2];
        STATS_INC(hci_sock_stats, ocmd);
    } else if (h4_type == BLE_HCI_UART_H4_EVT) {
        len = BLE_HCI_EVENT_HDR_LEN + hci_ev[1];
        STATS_INC(hci_sock_stats, oevt);
    } else {
        assert(0);
    }
    iov[1].iov_len = len;

    STATS_INC(hci_sock_stats, omsg);
    STATS_INCN(hci_sock_stats, obytes, len + 1);

    i = sendmsg(ble_hci_sock_state.sock, &msg, 0);
    ble_hci_trans_buf_free(hci_ev);
    if (i != len + 1) {
        if (i < 0) {
            dprintf(1, "sendmsg() failed : %d\n", errno);
        } else {
            dprintf(1, "sendmsg() partial write: %d\n", i);
        }
        STATS_INC(hci_sock_stats, oerr);
        return BLE_ERR_MEM_CAPACITY;
    }

    return 0;
}

static int
ble_hci_sock_rx_msg(void)
{
    struct ble_hci_sock_state *bhss;
    int len;
    struct os_mbuf *m;
    uint8_t *data;
    int sr;
    int rc;

    bhss = &ble_hci_sock_state;
    if (bhss->sock < 0) {
        return -1;
    }
    len = read(bhss->sock, bhss->rx_data + bhss->rx_off,
               sizeof(bhss->rx_data) - bhss->rx_off);
    if (len < 0) {
        return -2;
    }
    if (len == 0) {
        return -1;
    }
    bhss->rx_off += len;
    STATS_INCN(hci_sock_stats, ibytes, len);

    while (bhss->rx_off > 0) {
        switch (bhss->rx_data[0]) {
#if MYNEWT_VAL(BLE_DEVICE)
        case BLE_HCI_UART_H4_CMD:
            if (bhss->rx_off < BLE_HCI_CMD_HDR_LEN) {
                return -1;
            }
            len = 1 + BLE_HCI_CMD_HDR_LEN + bhss->rx_data[3];
            if (bhss->rx_off < len) {
                return -1;
            }
            STATS_INC(hci_sock_stats, imsg);
            STATS_INC(hci_sock_stats, icmd);
            data = ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_CMD);
            if (!data) {
                STATS_INC(hci_sock_stats, ierr);
                break;
            }
            memcpy(data, &bhss->rx_data[1], len - 1);
            OS_ENTER_CRITICAL(sr);
            rc = ble_hci_sock_rx_cmd_cb(data, ble_hci_sock_rx_cmd_arg);
            OS_EXIT_CRITICAL(sr);
            if (rc) {
                ble_hci_trans_buf_free(data);
                STATS_INC(hci_sock_stats, ierr);
                break;
            }
            break;
#endif
#if MYNEWT_VAL(BLE_HOST)
        case BLE_HCI_UART_H4_EVT:
            if (bhss->rx_off < BLE_HCI_EVENT_HDR_LEN) {
                return -1;
            }
            len = 1 + BLE_HCI_EVENT_HDR_LEN + bhss->rx_data[2];
            if (bhss->rx_off < len) {
                return -1;
            }
            STATS_INC(hci_sock_stats, imsg);
            STATS_INC(hci_sock_stats, ievt);
            data = ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI);
            if (!data) {
                STATS_INC(hci_sock_stats, ierr);
                break;
            }
            memcpy(data, &bhss->rx_data[1], len - 1);
            OS_ENTER_CRITICAL(sr);
            rc = ble_hci_sock_rx_cmd_cb(data, ble_hci_sock_rx_cmd_arg);
            OS_EXIT_CRITICAL(sr);
            if (rc) {
                ble_hci_trans_buf_free(data);
                STATS_INC(hci_sock_stats, ierr);
                return 0;
            }
            break;
#endif
        case BLE_HCI_UART_H4_ACL:
            if (bhss->rx_off < BLE_HCI_DATA_HDR_SZ) {
                return -1;
            }
            len = 1 + BLE_HCI_DATA_HDR_SZ + (bhss->rx_data[4] << 8) +
              bhss->rx_data[3];
            if (bhss->rx_off < len) {
                return -1;
            }
            STATS_INC(hci_sock_stats, imsg);
            STATS_INC(hci_sock_stats, iacl);
            m = ble_hci_trans_acl_buf_alloc();
            if (!m) {
                STATS_INC(hci_sock_stats, imem);
                break;
            }
            if (os_mbuf_append(m, &bhss->rx_data[1], len - 1)) {
                STATS_INC(hci_sock_stats, imem);
                os_mbuf_free_chain(m);
                break;
            }
            OS_ENTER_CRITICAL(sr);
            ble_hci_sock_rx_acl_cb(m, ble_hci_sock_rx_acl_arg);
            OS_EXIT_CRITICAL(sr);
            break;
        default:
            STATS_INC(hci_sock_stats, ierr);
            break;
        }
        memmove(bhss->rx_data, &bhss->rx_data[len], bhss->rx_off - len);
        bhss->rx_off -= len;
    }
    return 0;
}

static void
ble_hci_sock_rx_ev(struct ble_npl_event *ev)
{
    int rc;
    ble_npl_time_t timeout;

    rc = ble_hci_sock_rx_msg();
    if (rc == 0) {
        ble_npl_eventq_put(&ble_hci_sock_state.evq, &ble_hci_sock_state.ev);
    } else {
        rc = ble_npl_time_ms_to_ticks(10, &timeout);
        ble_npl_callout_reset(&ble_hci_sock_state.timer, timeout);
    }
}

#if MYNEWT_VAL(BLE_SOCK_USE_TCP)
static int
ble_hci_sock_config(void)
{
    struct ble_hci_sock_state *bhss = &ble_hci_sock_state;
    struct sockaddr_in sin;
    ble_npl_time_t timeout;
    int s;
    int rc;

    memset(&sin, 0, sizeof(sin));
    sin.sin_family = AF_INET;
    sin.sin_port = htons(MYNEWT_VAL(BLE_SOCK_TCP_PORT));
    sin.sin_addr.s_addr = inet_addr("127.0.0.1");
#ifdef MN_OSX
    sin.sin_len = sizeof(sin);
#endif

#if 0
    if (bhss->sock >= 0) {
        close(bhss->sock);
        bhss->sock = -1;
    }
#endif
    if (bhss->sock < 0) {
        s = socket(PF_INET, SOCK_STREAM, 0);
        if (s < 0) {
            goto err;
        }

        rc = connect(s, (struct sockaddr *)&sin, sizeof(sin));
        if (rc) {
            dprintf(1, "connect() failed: %d\n", errno);
            goto err;
        }

        rc = 1;

        rc = ioctl(s, FIONBIO, (char *)&rc);
        if (rc) {
            goto err;
        }
        bhss->sock = s;
    }
    rc = ble_npl_time_ms_to_ticks(10, &timeout);
    if (rc) {
        goto err;
    }
    ble_npl_callout_reset(&ble_hci_sock_state.timer, timeout);

    return 0;
err:
    if (s >= 0) {
        close(s);
    }
    return BLE_ERR_HW_FAIL;
}
#endif

#if MYNEWT_VAL(BLE_SOCK_USE_LINUX_BLUE)
static int
ble_hci_sock_config(void)
{
    struct sockaddr_hci shci;
    int s;
    int rc;
    ble_npl_time_t timeout;

    memset(&shci, 0, sizeof(shci));
    shci.hci_family = AF_BLUETOOTH;
    shci.hci_dev = MYNEWT_VAL(BLE_SOCK_LINUX_DEV);
    shci.hci_channel = HCI_CHANNEL_USER;

    if (ble_hci_sock_state.sock >= 0) {
        close(ble_hci_sock_state.sock);
        ble_hci_sock_state.sock = -1;
    }

    s = socket(PF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
    if (s < 0) {
        dprintf(1, "socket() failed %d\n", errno);
        goto err;
    }

    /* 
     * HCI User Channel requires exclusive access to the device.
     * The device has to be down at the time of binding.
     */
    ioctl(s, HCIDEVDOWN, shci.hci_dev);

    rc = bind(s, (struct sockaddr *)&shci, sizeof(shci));
    if (rc) {
        dprintf(1, "bind() failed %d\n", errno);
        goto err;
    }

    rc = 1;

    rc = ioctl(s, FIONBIO, (char *)&rc);
    if (rc) {
        goto err;
    }
    ble_hci_sock_state.sock = s;

    rc = ble_npl_time_ms_to_ticks(10, &timeout);
    if (rc) {
        goto err;
    }
    ble_npl_callout_reset(&ble_hci_sock_state.timer, timeout);

    return 0;
err:
    if (s >= 0) {
        close(s);
    }
    return BLE_ERR_HW_FAIL;
}
#endif
/**
 * Sends an HCI event from the controller to the host.
 *
 * @param cmd                   The HCI event to send.  This buffer must be
 *                                  allocated via ble_hci_trans_buf_alloc().
 *
 * @return                      0 on success;
 *                              A BLE_ERR_[...] error code on failure.
 */
int
ble_hci_trans_ll_evt_tx(uint8_t *cmd)
{
    return ble_hci_sock_cmdevt_tx(cmd, BLE_HCI_UART_H4_EVT);
}

/**
 * Sends ACL data from controller to host.
 *
 * @param om                    The ACL data packet to send.
 *
 * @return                      0 on success;
 *                              A BLE_ERR_[...] error code on failure.
 */
int
ble_hci_trans_ll_acl_tx(struct os_mbuf *om)
{
    return ble_hci_sock_acl_tx(om);
}

/**
 * Sends an HCI command from the host to the controller.
 *
 * @param cmd                   The HCI command to send.  This buffer must be
 *                                  allocated via ble_hci_trans_buf_alloc().
 *
 * @return                      0 on success;
 *                              A BLE_ERR_[...] error code on failure.
 */
int
ble_hci_trans_hs_cmd_tx(uint8_t *cmd)
{
    return ble_hci_sock_cmdevt_tx(cmd, BLE_HCI_UART_H4_CMD);
}

/**
 * Sends ACL data from host to controller.
 *
 * @param om                    The ACL data packet to send.
 *
 * @return                      0 on success;
 *                              A BLE_ERR_[...] error code on failure.
 */
int
ble_hci_trans_hs_acl_tx(struct os_mbuf *om)
{
    return ble_hci_sock_acl_tx(om);
}

/**
 * Configures the HCI transport to call the specified callback upon receiving
 * HCI packets from the controller.  This function should only be called by by
 * host.
 *
 * @param cmd_cb                The callback to execute upon receiving an HCI
 *                                  event.
 * @param cmd_arg               Optional argument to pass to the command
 *                                  callback.
 * @param acl_cb                The callback to execute upon receiving ACL
 *                                  data.
 * @param acl_arg               Optional argument to pass to the ACL
 *                                  callback.
 */
void
ble_hci_trans_cfg_hs(ble_hci_trans_rx_cmd_fn *cmd_cb,
                     void *cmd_arg,
                     ble_hci_trans_rx_acl_fn *acl_cb,
                     void *acl_arg)
{
    ble_hci_sock_rx_cmd_cb = cmd_cb;
    ble_hci_sock_rx_cmd_arg = cmd_arg;
    ble_hci_sock_rx_acl_cb = acl_cb;
    ble_hci_sock_rx_acl_arg = acl_arg;
}

/**
 * Configures the HCI transport to operate with a host.  The transport will
 * execute specified callbacks upon receiving HCI packets from the controller.
 *
 * @param cmd_cb                The callback to execute upon receiving an HCI
 *                                  event.
 * @param cmd_arg               Optional argument to pass to the command
 *                                  callback.
 * @param acl_cb                The callback to execute upon receiving ACL
 *                                  data.
 * @param acl_arg               Optional argument to pass to the ACL
 *                                  callback.
 */
void
ble_hci_trans_cfg_ll(ble_hci_trans_rx_cmd_fn *cmd_cb,
                     void *cmd_arg,
                     ble_hci_trans_rx_acl_fn *acl_cb,
                     void *acl_arg)
{
    ble_hci_sock_rx_cmd_cb = cmd_cb;
    ble_hci_sock_rx_cmd_arg = cmd_arg;
    ble_hci_sock_rx_acl_cb = acl_cb;
    ble_hci_sock_rx_acl_arg = acl_arg;
}

/**
 * Allocates a flat buffer of the specified type.
 *
 * @param type                  The type of buffer to allocate; one of the
 *                                  BLE_HCI_TRANS_BUF_[...] constants.
 *
 * @return                      The allocated buffer on success;
 *                              NULL on buffer exhaustion.
 */
uint8_t *
ble_hci_trans_buf_alloc(int type)
{
    uint8_t *buf;

    switch (type) {
    case BLE_HCI_TRANS_BUF_CMD:
        buf = os_memblock_get(&ble_hci_sock_cmd_pool);
        break;
    case BLE_HCI_TRANS_BUF_EVT_HI:
        buf = os_memblock_get(&ble_hci_sock_evt_hi_pool);
        if (buf == NULL) {
            /* If no high-priority event buffers remain, try to grab a
             * low-priority one.
             */
            buf = os_memblock_get(&ble_hci_sock_evt_lo_pool);
        }
        break;

    case BLE_HCI_TRANS_BUF_EVT_LO:
        buf = os_memblock_get(&ble_hci_sock_evt_lo_pool);
        break;

    default:
        assert(0);
        buf = NULL;
    }

    return buf;
}

/**
 * Frees the specified flat buffer.  The buffer must have been allocated via
 * ble_hci_trans_buf_alloc().
 *
 * @param buf                   The buffer to free.
 */
void
ble_hci_trans_buf_free(uint8_t *buf)
{
    int rc;

    /*
     * XXX: this may look a bit odd, but the controller uses the command
     * buffer to send back the command complete/status as an immediate
     * response to the command. This was done to insure that the controller
     * could always send back one of these events when a command was received.
     * Thus, we check to see which pool the buffer came from so we can free
     * it to the appropriate pool
     */
    if (os_memblock_from(&ble_hci_sock_evt_hi_pool, buf)) {
        rc = os_memblock_put(&ble_hci_sock_evt_hi_pool, buf);
        assert(rc == 0);
    } else if (os_memblock_from(&ble_hci_sock_evt_lo_pool, buf)) {
        rc = os_memblock_put(&ble_hci_sock_evt_lo_pool, buf);
        assert(rc == 0);
    } else {
        assert(os_memblock_from(&ble_hci_sock_cmd_pool, buf));
        rc = os_memblock_put(&ble_hci_sock_cmd_pool, buf);
        assert(rc == 0);
    }
}

/**
 * Resets the HCI UART transport to a clean state.  Frees all buffers and
 * reconfigures the UART.
 *
 * @return                      0 on success;
 *                              A BLE_ERR_[...] error code on failure.
 */
int
ble_hci_trans_reset(void)
{
    int rc;

    ble_npl_callout_stop(&ble_hci_sock_state.timer);

    /* Reopen the UART. */
    rc = ble_hci_sock_config();
    if (rc != 0) {
        dprintf(1, "Failure restarting socket HCI\n");
        return rc;
    }

    return 0;
}

void
ble_hci_sock_ack_handler(void *arg)
{
    while (1) {
        ble_npl_eventq_run(&ble_hci_sock_state.evq);
    }
}

static void
ble_hci_sock_init_task(void)
{
    ble_npl_eventq_init(&ble_hci_sock_state.evq);
    ble_npl_callout_stop(&ble_hci_sock_state.timer);
    ble_npl_callout_init(&ble_hci_sock_state.timer, &ble_hci_sock_state.evq,
                    ble_hci_sock_rx_ev, NULL);

#if MYNEWT
    {
        os_stack_t *pstack;

        pstack = malloc(sizeof(os_stack_t)*BLE_SOCK_STACK_SIZE);
        assert(pstack);
        os_task_init(&ble_sock_task, "hci_sock", ble_hci_sock_ack_handler, NULL,
                     MYNEWT_VAL(BLE_SOCK_TASK_PRIO), BLE_NPL_WAIT_FOREVER, pstack,
                     BLE_SOCK_STACK_SIZE);
    }
#else
/*
 * For non-Mynewt OS it is required that OS creates task for HCI SOCKET
 * to run ble_hci_sock_ack_handler.
 */

#endif

}

/**
 * Initializes the UART HCI transport module.
 *
 * @return                      0 on success;
 *                              A BLE_ERR_[...] error code on failure.
 */
void
ble_hci_sock_init(void)
{
    int rc;

    /* Ensure this function only gets called by sysinit. */
    SYSINIT_ASSERT_ACTIVE();

    memset(&ble_hci_sock_state, 0, sizeof(ble_hci_sock_state));
    ble_hci_sock_state.sock = -1;

    ble_hci_sock_init_task();
    ble_hci_sock_state.ev.ev_cb = ble_hci_sock_rx_ev;

    rc = os_mempool_init(&ble_hci_sock_acl_pool,
                         MYNEWT_VAL(BLE_ACL_BUF_COUNT),
                         ACL_BLOCK_SIZE,
                         ble_hci_sock_acl_buf,
                         "ble_hci_sock_acl_pool");
    SYSINIT_PANIC_ASSERT(rc == 0);

    rc = os_mbuf_pool_init(&ble_hci_sock_acl_mbuf_pool,
                           &ble_hci_sock_acl_pool,
                           ACL_BLOCK_SIZE,
                           MYNEWT_VAL(BLE_ACL_BUF_COUNT));
    SYSINIT_PANIC_ASSERT(rc == 0);

    /*
     * Create memory pool of HCI command buffers. NOTE: we currently dont
     * allow this to be configured. The controller will only allow one
     * outstanding command. We decided to keep this a pool in case we allow
     * allow the controller to handle more than one outstanding command.
     */
    rc = os_mempool_init(&ble_hci_sock_cmd_pool,
                         1,
                         BLE_HCI_TRANS_CMD_SZ,
                         &ble_hci_sock_cmd_buf,
                         "ble_hci_sock_cmd_pool");
    SYSINIT_PANIC_ASSERT(rc == 0);

    rc = os_mempool_init(&ble_hci_sock_evt_hi_pool,
                         MYNEWT_VAL(BLE_HCI_EVT_HI_BUF_COUNT),
                         MYNEWT_VAL(BLE_HCI_EVT_BUF_SIZE),
                         &ble_hci_sock_evt_hi_buf,
                         "ble_hci_sock_evt_hi_pool");
    SYSINIT_PANIC_ASSERT(rc == 0);

    rc = os_mempool_init(&ble_hci_sock_evt_lo_pool,
                         MYNEWT_VAL(BLE_HCI_EVT_LO_BUF_COUNT),
                         MYNEWT_VAL(BLE_HCI_EVT_BUF_SIZE),
                         ble_hci_sock_evt_lo_buf,
                         "ble_hci_sock_evt_lo_pool");
    SYSINIT_PANIC_ASSERT(rc == 0);

    rc = ble_hci_sock_config();
    SYSINIT_PANIC_ASSERT_MSG(rc == 0, "Failure configuring socket HCI");

    rc = stats_init_and_reg(STATS_HDR(hci_sock_stats),
                            STATS_SIZE_INIT_PARMS(hci_sock_stats, STATS_SIZE_32),
                            STATS_NAME_INIT_PARMS(hci_sock_stats), "hci_socket");
    SYSINIT_PANIC_ASSERT(rc == 0);
}
