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

#include <inttypes.h>
#include "syscfg/syscfg.h"
#include "ble_hs_mbuf_priv.h"

#if MYNEWT_VAL(BLE_ISO)

#include "os/os_mbuf.h"
#include "host/ble_hs_log.h"
#include "host/ble_hs.h"
#include "host/ble_iso.h"
#include "nimble/hci_common.h"
#include "sys/queue.h"
#include "ble_hs_hci_priv.h"

struct ble_iso_big {
    SLIST_ENTRY(ble_iso_big) next;
    uint8_t handle;
    uint16_t max_pdu;
    uint8_t num_bis;
    uint16_t conn_handles[MYNEWT_VAL(BLE_MAX_BIS)];

    ble_iso_event_fn *cb;
    void *cb_arg;
};

static SLIST_HEAD(, ble_iso_big) ble_iso_bigs;
static struct os_mempool ble_iso_big_pool;
static os_membuf_t ble_iso_big_mem[
    OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_MAX_BIG), sizeof (struct ble_iso_big))];

static int
ble_iso_big_handle_set(struct ble_iso_big *big)
{
    static uint8_t free_handle;
    uint8_t i;

    /* Set next free handle */
    for (i = BLE_HCI_ISO_BIG_HANDLE_MIN; i < BLE_HCI_ISO_BIG_HANDLE_MAX; i++) {
        struct ble_iso_big *node = NULL;

        if (free_handle > BLE_HCI_ISO_BIG_HANDLE_MAX) {
            free_handle = BLE_HCI_ISO_BIG_HANDLE_MIN;
        }

        big->handle = free_handle++;

        SLIST_FOREACH(node, &ble_iso_bigs, next) {
            if (node->handle == big->handle) {
                break;
            }
        }

        if (node == NULL || node->handle != big->handle) {
            return 0;
        }
    }

    BLE_HS_DBG_ASSERT(0);

    return BLE_HS_EOS;
}

static struct ble_iso_big *
ble_iso_big_alloc(void)
{
    struct ble_iso_big *new_big;
    int rc;

    new_big = os_memblock_get(&ble_iso_big_pool);
    if (new_big == NULL) {
        BLE_HS_LOG_ERROR("No more memory in pool\n");
        /* Out of memory. */
        return NULL;
    }

    memset(new_big, 0, sizeof *new_big);

    rc = ble_iso_big_handle_set(new_big);
    if (rc != 0) {
        os_memblock_put(&ble_iso_big_pool, new_big);
        return NULL;
    }

    SLIST_INSERT_HEAD(&ble_iso_bigs, new_big, next);

    return new_big;
}

static struct ble_iso_big *
ble_iso_big_find_by_handle(uint8_t big_handle)
{
    struct ble_iso_big *big;

    SLIST_FOREACH(big, &ble_iso_bigs, next) {
        if (big->handle == big_handle) {
            return big;
        }
    }

    return NULL;
}

static int
ble_iso_big_free(struct ble_iso_big *big)
{
    SLIST_REMOVE(&ble_iso_bigs, big, ble_iso_big, next);
    os_memblock_put(&ble_iso_big_pool, big);
    return 0;
}

int
ble_iso_create_big(const struct ble_iso_create_big_params *create_params,
                   const struct ble_iso_big_params *big_params)
{
    struct ble_hci_le_create_big_cp cp = { 0 };
    struct ble_iso_big *big;

    cp.adv_handle = create_params->adv_handle;
    if (create_params->bis_cnt > MYNEWT_VAL(BLE_MAX_BIS)) {
        return BLE_HS_EINVAL;
    }

    big = ble_iso_big_alloc();
    if (big == NULL) {
        return BLE_HS_ENOMEM;
    }

    big->cb = create_params->cb;
    big->cb_arg = create_params->cb_arg;

    cp.num_bis = create_params->bis_cnt;
    put_le24(cp.sdu_interval, big_params->sdu_interval);
    cp.max_sdu = big_params->max_sdu;
    cp.max_transport_latency = big_params->max_transport_latency;
    cp.rtn = big_params->rtn;
    cp.phy = big_params->phy;
    cp.packing = big_params->packing;
    cp.framing = big_params->framing;
    cp.encryption = big_params->encryption;
    if (big_params->encryption) {
        memcpy(cp.broadcast_code, big_params->broadcast_code, 16);
    }

    return ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE,
                                        BLE_HCI_OCF_LE_CREATE_BIG),
                             &cp, sizeof(cp),NULL, 0);
}

int
ble_iso_terminate_big(uint8_t big_handle)
{
    struct ble_hci_le_terminate_big_cp cp;
    struct ble_iso_big *big;
    int rc;

    big = ble_iso_big_find_by_handle(big_handle);
    if (big == NULL) {
        BLE_HS_LOG_ERROR("No BIG with handle=%d\n", big_handle);
        return BLE_HS_ENOENT;
    }

    cp.big_handle = big->handle;
    cp.reason = BLE_ERR_CONN_TERM_LOCAL;

    rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE,
                                      BLE_HCI_OCF_LE_TERMINATE_BIG),
                           &cp, sizeof(cp),NULL, 0);

    return rc;
}

int
ble_iso_init(void)
{
    int rc;

    SLIST_INIT(&ble_iso_bigs);

    rc = os_mempool_init(&ble_iso_big_pool,
                         MYNEWT_VAL(BLE_MAX_BIG),
                         sizeof (struct ble_iso_big),
                         ble_iso_big_mem, "ble_iso_big_pool");
    SYSINIT_PANIC_ASSERT(rc == 0);

    return 0;
}

void
ble_iso_rx_create_big_complete(const struct ble_hci_ev_le_subev_create_big_complete *ev)
{
    struct ble_iso_event event;

    struct ble_iso_big *big;
    int i;

    big = ble_iso_big_find_by_handle(ev->big_handle);

    big->num_bis = ev->num_bis;

    for (i = 0; i < ev->num_bis; i++) {
        big->conn_handles[i] = ev->conn_handle[i];
    }

    big->max_pdu = ev->max_pdu;

    event.type = BLE_ISO_EVENT_BIG_CREATE_COMPLETE;
    event.big_created.desc.big_handle = ev->big_handle;
    event.big_created.desc.big_sync_delay = get_le24(ev->big_sync_delay);
    event.big_created.desc.transport_latency_big =
        get_le24(ev->transport_latency_big);
    event.big_created.desc.phy = ev->phy;
    event.big_created.desc.nse = ev->nse;
    event.big_created.desc.bn = ev->bn;
    event.big_created.desc.pto = ev->pto;
    event.big_created.desc.irc = ev->irc;
    event.big_created.desc.max_pdu = ev->max_pdu;
    event.big_created.desc.iso_interval = ev->iso_interval;
    event.big_created.desc.num_bis = ev->num_bis;
    memcpy(event.big_created.desc.conn_handle, ev->conn_handle,
           ev->num_bis * sizeof(uint16_t));

    if (big->cb != NULL) {
        big->cb(&event, big->cb_arg);
    }
}

void
ble_iso_rx_terminate_big_complete(const struct ble_hci_ev_le_subev_terminate_big_complete *ev)
{
    struct ble_iso_event event;
    struct ble_iso_big *big;

    big = ble_iso_big_find_by_handle(ev->big_handle);

    event.type = BLE_ISO_EVENT_BIG_TERMINATE_COMPLETE;
    event.big_terminated.big_handle = ev->big_handle;
    event.big_terminated.reason = ev->reason;

    if (big->cb != NULL) {
        big->cb(&event, big->cb_arg);
    }

    ble_iso_big_free(big);
}

static int
ble_iso_tx_complete(uint16_t conn_handle, const uint8_t *data,
                    uint16_t data_len)
{
    struct os_mbuf *om;
    int rc;

    om = ble_hs_mbuf_bare_pkt();
    if (!om) {
        return BLE_HS_ENOMEM;
    }

    os_mbuf_extend(om, 8);
    /* Connection_Handle, PB_Flag, TS_Flag */
    put_le16(&om->om_data[0],
             BLE_HCI_ISO_HANDLE(conn_handle, BLE_HCI_ISO_PB_COMPLETE, 0));
    /* Data_Total_Length = Data length + Packet_Sequence_Number placeholder */
    put_le16(&om->om_data[2], data_len + 4);
    /* Packet_Sequence_Number placeholder */
    put_le16(&om->om_data[4], 0);
    /* ISO_SDU_Length */
    put_le16(&om->om_data[6], data_len);

    rc = os_mbuf_append(om, data, data_len);
    if (rc) {
        return rc;
    }

    return ble_transport_to_ll_iso(om);
}

static int
ble_iso_tx_segmented(uint16_t conn_handle, const uint8_t *data,
                     uint16_t data_len)
{
    struct os_mbuf *om;
    uint16_t data_left = data_len;
    uint16_t packet_len;
    uint16_t offset = 0;
    uint8_t pb;
    int rc;

    while (data_left) {
        packet_len = min(MYNEWT_VAL(BLE_TRANSPORT_ISO_SIZE), data_left);
        if (data_left == data_len) {
            pb = BLE_HCI_ISO_PB_FIRST;
        } else if (packet_len == data_left) {
            pb = BLE_HCI_ISO_PB_LAST;
        } else {
            pb = BLE_HCI_ISO_PB_CONTINUATION;
        }

        om = ble_hs_mbuf_bare_pkt();
        if (!om) {
            return BLE_HS_ENOMEM;
        }

        os_mbuf_extend(om, pb == BLE_HCI_ISO_PB_FIRST ? 8: 4);

        /* Connection_Handle, PB_Flag, TS_Flag */
        put_le16(&om->om_data[0],
                 BLE_HCI_ISO_HANDLE(conn_handle, pb, 0));

        if (pb == BLE_HCI_ISO_PB_FIRST) {
            /* Data_Total_Length = Data length +
             * Packet_Sequence_Number placeholder*/
            put_le16(&om->om_data[2], packet_len + 4);

            /* Packet_Sequence_Number placeholder */
            put_le16(&om->om_data[8], 0);

            /* ISO_SDU_Length */
            put_le16(&om->om_data[10], packet_len);
        } else {
            put_le16(&om->om_data[2], packet_len);
        }

        rc = os_mbuf_append(om, data + offset, packet_len);
        if (rc) {
            return rc;
        }

        ble_transport_to_ll_iso(om);

        offset += packet_len;
        data_left -= packet_len;
    }

    return 0;
}

int
ble_iso_tx(uint16_t conn_handle, void *data, uint16_t data_len)
{
    int rc;

    if (data_len <= MYNEWT_VAL(BLE_TRANSPORT_ISO_SIZE)) {
        rc = ble_iso_tx_complete(conn_handle, data, data_len);
    } else {
        rc = ble_iso_tx_segmented(conn_handle, data, data_len);
    }

    return rc;
}
#endif
