/*
 * 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 <string.h>
#include <errno.h>
#include "syscfg/syscfg.h"
#include "os/os.h"
#include "host/ble_hs_id.h"
#include "ble_hs_priv.h"

/** At least three channels required per connection (sig, att, sm). */
#define BLE_HS_CONN_MIN_CHANS       3

static SLIST_HEAD(, ble_hs_conn) ble_hs_conns;
static struct os_mempool ble_hs_conn_pool;

static os_membuf_t ble_hs_conn_elem_mem[
    OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_MAX_CONNECTIONS),
                    sizeof (struct ble_hs_conn))
];

static const uint8_t ble_hs_conn_null_addr[6];

int
ble_hs_conn_can_alloc(void)
{
#if !NIMBLE_BLE_CONNECT
    return 0;
#endif

    return ble_hs_conn_pool.mp_num_free >= 1 &&
           ble_l2cap_chan_pool.mp_num_free >= BLE_HS_CONN_MIN_CHANS &&
           ble_gatts_conn_can_alloc();
}

struct ble_l2cap_chan *
ble_hs_conn_chan_find_by_scid(struct ble_hs_conn *conn, uint16_t cid)
{
#if !NIMBLE_BLE_CONNECT
    return NULL;
#endif

    struct ble_l2cap_chan *chan;

    SLIST_FOREACH(chan, &conn->bhc_channels, next) {
        if (chan->scid == cid) {
            return chan;
        }
        if (chan->scid > cid) {
            return NULL;
        }
    }

    return NULL;
}

struct ble_l2cap_chan *
ble_hs_conn_chan_find_by_dcid(struct ble_hs_conn *conn, uint16_t cid)
{
#if !NIMBLE_BLE_CONNECT
    return NULL;
#endif

    struct ble_l2cap_chan *chan;

    SLIST_FOREACH(chan, &conn->bhc_channels, next) {
        if (chan->dcid == cid) {
            return chan;
        }
    }

    return NULL;
}

bool
ble_hs_conn_chan_exist(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan)
{
#if !NIMBLE_BLE_CONNECT
    return NULL;
#endif

    struct ble_l2cap_chan *tmp;

    SLIST_FOREACH(tmp, &conn->bhc_channels, next) {
        if (chan == tmp) {
            return true;
        }
    }

    return false;
}

int
ble_hs_conn_chan_insert(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan)
{
#if !NIMBLE_BLE_CONNECT
    return BLE_HS_ENOTSUP;
#endif

    struct ble_l2cap_chan *prev;
    struct ble_l2cap_chan *cur;

    prev = NULL;
    SLIST_FOREACH(cur, &conn->bhc_channels, next) {
        if (cur->scid == chan->scid) {
            return BLE_HS_EALREADY;
        }
        if (cur->scid > chan->scid) {
            break;
        }

        prev = cur;
    }

    if (prev == NULL) {
        SLIST_INSERT_HEAD(&conn->bhc_channels, chan, next);
    } else {
        SLIST_INSERT_AFTER(prev, chan, next);
    }

    return 0;
}

struct ble_hs_conn *
ble_hs_conn_alloc(uint16_t conn_handle)
{
#if !NIMBLE_BLE_CONNECT
    return NULL;
#endif

    struct ble_l2cap_chan *chan;
    struct ble_hs_conn *conn;
    int rc;

    conn = os_memblock_get(&ble_hs_conn_pool);
    if (conn == NULL) {
        goto err;
    }
    memset(conn, 0, sizeof *conn);
    conn->bhc_handle = conn_handle;

    SLIST_INIT(&conn->bhc_channels);

    chan = ble_att_create_chan(conn_handle);
    if (chan == NULL) {
        goto err;
    }
    rc = ble_hs_conn_chan_insert(conn, chan);
    if (rc != 0) {
        goto err;
    }

    chan = ble_l2cap_sig_create_chan(conn_handle);
    if (chan == NULL) {
        goto err;
    }
    rc = ble_hs_conn_chan_insert(conn, chan);
    if (rc != 0) {
        goto err;
    }

    /* Create the SM channel even if not configured. We need it to reject SM
     * messages.
     */
    chan = ble_sm_create_chan(conn_handle);
    if (chan == NULL) {
        goto err;
    }
    rc = ble_hs_conn_chan_insert(conn, chan);
    if (rc != 0) {
        goto err;
    }

    rc = ble_gatts_conn_init(&conn->bhc_gatt_svr);
    if (rc != 0) {
        goto err;
    }

    STAILQ_INIT(&conn->bhc_tx_q);
    STAILQ_INIT(&conn->att_tx_q);

    STATS_INC(ble_hs_stats, conn_create);

    return conn;

err:
    ble_hs_conn_free(conn);
    return NULL;
}

void
ble_hs_conn_delete_chan(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan)
{
    if (conn->bhc_rx_chan == chan) {
        conn->bhc_rx_chan = NULL;
    }

    SLIST_REMOVE(&conn->bhc_channels, chan, ble_l2cap_chan, next);
    ble_l2cap_chan_free(conn, chan);
}

void
ble_hs_conn_foreach(ble_hs_conn_foreach_fn *cb, void *arg)
{
    struct ble_hs_conn *conn;

    BLE_HS_DBG_ASSERT(ble_hs_locked_by_cur_task());

    SLIST_FOREACH(conn, &ble_hs_conns, bhc_next) {
        if (cb(conn, arg) != 0) {
            return;
        }
    }
}

void
ble_hs_conn_free(struct ble_hs_conn *conn)
{
#if !NIMBLE_BLE_CONNECT
    return;
#endif

    struct ble_l2cap_chan *chan;
    struct os_mbuf_pkthdr *omp;
    int rc;

    if (conn == NULL) {
        return;
    }

    ble_att_svr_prep_clear(&conn->bhc_att_svr.basc_prep_list);

    while ((chan = SLIST_FIRST(&conn->bhc_channels)) != NULL) {
        ble_hs_conn_delete_chan(conn, chan);
    }

    while ((omp = STAILQ_FIRST(&conn->bhc_tx_q)) != NULL) {
        STAILQ_REMOVE_HEAD(&conn->bhc_tx_q, omp_next);
        os_mbuf_free_chain(OS_MBUF_PKTHDR_TO_MBUF(omp));
    }

#if MYNEWT_VAL(BLE_HS_DEBUG)
    memset(conn, 0xff, sizeof *conn);
#endif
    rc = os_memblock_put(&ble_hs_conn_pool, conn);
    BLE_HS_DBG_ASSERT_EVAL(rc == 0);

    STATS_INC(ble_hs_stats, conn_delete);
}

void
ble_hs_conn_insert(struct ble_hs_conn *conn)
{
#if !NIMBLE_BLE_CONNECT
    return;
#endif

    BLE_HS_DBG_ASSERT(ble_hs_locked_by_cur_task());

    BLE_HS_DBG_ASSERT_EVAL(ble_hs_conn_find(conn->bhc_handle) == NULL);
    SLIST_INSERT_HEAD(&ble_hs_conns, conn, bhc_next);
}

void
ble_hs_conn_remove(struct ble_hs_conn *conn)
{
#if !NIMBLE_BLE_CONNECT
    return;
#endif

    BLE_HS_DBG_ASSERT(ble_hs_locked_by_cur_task());

    SLIST_REMOVE(&ble_hs_conns, conn, ble_hs_conn, bhc_next);
}

struct ble_hs_conn *
ble_hs_conn_find(uint16_t conn_handle)
{
#if !NIMBLE_BLE_CONNECT
    return NULL;
#endif

    struct ble_hs_conn *conn;

    BLE_HS_DBG_ASSERT(ble_hs_locked_by_cur_task());

    SLIST_FOREACH(conn, &ble_hs_conns, bhc_next) {
        if (conn->bhc_handle == conn_handle) {
            return conn;
        }
    }

    return NULL;
}

struct ble_hs_conn *
ble_hs_conn_find_assert(uint16_t conn_handle)
{
    struct ble_hs_conn *conn;

    conn = ble_hs_conn_find(conn_handle);
    BLE_HS_DBG_ASSERT(conn != NULL);

    return conn;
}

struct ble_hs_conn *
ble_hs_conn_find_by_addr(const ble_addr_t *addr)
{
#if !NIMBLE_BLE_CONNECT
    return NULL;
#endif

    struct ble_hs_conn *conn;
    struct ble_hs_conn_addrs addrs;

    BLE_HS_DBG_ASSERT(ble_hs_locked_by_cur_task());

    if (!addr) {
        return NULL;
    }

    SLIST_FOREACH(conn, &ble_hs_conns, bhc_next) {
        if (BLE_ADDR_IS_RPA(addr)) {
            if (ble_addr_cmp(&conn->bhc_peer_rpa_addr, addr) == 0) {
                return conn;
            }
        } else {
            if (ble_addr_cmp(&conn->bhc_peer_addr, addr) == 0) {
                return conn;
            }
            if (conn->bhc_peer_addr.type < BLE_OWN_ADDR_RPA_PUBLIC_DEFAULT) {
                continue;
            }
            /*If type 0x02 or 0x03 is used, let's double check if address is good */
            ble_hs_conn_addrs(conn, &addrs);
            if (ble_addr_cmp(&addrs.peer_id_addr, addr) == 0) {
                return conn;
            }
        }
    }

    return NULL;
}

struct ble_hs_conn *
ble_hs_conn_find_by_idx(int idx)
{
#if !NIMBLE_BLE_CONNECT
    return NULL;
#endif

    struct ble_hs_conn *conn;
    int i;

    BLE_HS_DBG_ASSERT(ble_hs_locked_by_cur_task());

    i = 0;
    SLIST_FOREACH(conn, &ble_hs_conns, bhc_next) {
        if (i == idx) {
            return conn;
        }

        i++;
    }

    return NULL;
}

int
ble_hs_conn_exists(uint16_t conn_handle)
{
#if !NIMBLE_BLE_CONNECT
    return 0;
#endif
    return ble_hs_conn_find(conn_handle) != NULL;
}

/**
 * Retrieves the first connection in the list.
 */
struct ble_hs_conn *
ble_hs_conn_first(void)
{
#if !NIMBLE_BLE_CONNECT
    return NULL;
#endif

    BLE_HS_DBG_ASSERT(ble_hs_locked_by_cur_task());
    return SLIST_FIRST(&ble_hs_conns);
}

void
ble_hs_conn_addrs(const struct ble_hs_conn *conn,
                  struct ble_hs_conn_addrs *addrs)
{
    const uint8_t *our_id_addr_val;
    int rc;

    /* Determine our address information. */
    addrs->our_id_addr.type =
        ble_hs_misc_own_addr_type_to_id(conn->bhc_our_addr_type);

#if MYNEWT_VAL(BLE_EXT_ADV)
    /* With EA enabled random address for slave connection is per advertising
     * instance and requires special handling here.
     */

    if (!(conn->bhc_flags & BLE_HS_CONN_F_MASTER) &&
            addrs->our_id_addr.type == BLE_ADDR_RANDOM) {
        our_id_addr_val = conn->bhc_our_rnd_addr;
    } else {
        rc = ble_hs_id_addr(addrs->our_id_addr.type, &our_id_addr_val, NULL);
        assert(rc == 0);
    }
#else
    rc = ble_hs_id_addr(addrs->our_id_addr.type, &our_id_addr_val, NULL);
    assert(rc == 0);
#endif

    memcpy(addrs->our_id_addr.val, our_id_addr_val, 6);

    if (memcmp(conn->bhc_our_rpa_addr.val, ble_hs_conn_null_addr, 6) == 0) {
        addrs->our_ota_addr = addrs->our_id_addr;
    } else {
        addrs->our_ota_addr = conn->bhc_our_rpa_addr;
    }

    /* Determine peer address information. */
    addrs->peer_id_addr = conn->bhc_peer_addr;
    addrs->peer_ota_addr = conn->bhc_peer_addr;
    switch (conn->bhc_peer_addr.type) {
    case BLE_ADDR_PUBLIC:
    case BLE_ADDR_RANDOM:
        break;

    case BLE_ADDR_PUBLIC_ID:
        addrs->peer_id_addr.type = BLE_ADDR_PUBLIC;
        addrs->peer_ota_addr = conn->bhc_peer_rpa_addr;
        break;

    case BLE_ADDR_RANDOM_ID:
        addrs->peer_id_addr.type = BLE_ADDR_RANDOM;
        addrs->peer_ota_addr = conn->bhc_peer_rpa_addr;
        break;

    default:
        BLE_HS_DBG_ASSERT(0);
        break;
    }
}

int32_t
ble_hs_conn_timer(void)
{
    /* If there are no timeouts configured, then there is nothing to check. */
#if MYNEWT_VAL(BLE_L2CAP_RX_FRAG_TIMEOUT) == 0 && \
    BLE_HS_ATT_SVR_QUEUED_WRITE_TMO == 0

    return BLE_HS_FOREVER;
#endif

    struct ble_hs_conn *conn;
    ble_npl_time_t now = ble_npl_time_get();
    int32_t next_exp_in = BLE_HS_FOREVER;
    int32_t next_exp_in_new;
    bool next_exp_in_updated;
    int32_t time_diff;

    ble_hs_lock();

    /* This loop performs one of two tasks:
     * 1. Determine if any connections need to be terminated due to timeout. If
     *    so connection is disconnected.
     * 2. Otherwise, determine when the next timeout will occur.
     */
    SLIST_FOREACH(conn, &ble_hs_conns, bhc_next) {
        if (!(conn->bhc_flags & BLE_HS_CONN_F_TERMINATING)) {
            next_exp_in_updated = false;

#if MYNEWT_VAL(BLE_L2CAP_RX_FRAG_TIMEOUT) != 0
            /* Check each connection's rx fragment timer.  If too much time
             * passes after a partial packet is received, the connection is
             * terminated.
             */
            if (conn->bhc_rx_chan != NULL) {
                time_diff = conn->bhc_rx_timeout - now;

                if (time_diff <= 0) {
                    /* ACL reassembly has timed out.*/
                    ble_gap_terminate_with_conn(conn, BLE_ERR_REM_USER_CONN_TERM);
                    continue;
                }

                /* Determine if this connection is the soonest to time out. */
                if (time_diff < next_exp_in) {
                    next_exp_in_new = time_diff;
                    next_exp_in_updated = true;
                }
            }
#endif

#if BLE_HS_ATT_SVR_QUEUED_WRITE_TMO
            /* Check each connection's rx queued write timer.  If too much
             * time passes after a prep write is received, the queue is
             * cleared.
             */
            time_diff = ble_att_svr_ticks_until_tmo(&conn->bhc_att_svr, now);
            if (time_diff <= 0) {
                /* Queued write has timed out.*/
                ble_gap_terminate_with_conn(conn, BLE_ERR_REM_USER_CONN_TERM);
                continue;
            }

            /* Determine if this connection is the soonest to time out. */
            if (time_diff < next_exp_in) {
                next_exp_in_new = time_diff;
                next_exp_in_updated = true;
            }
#endif

            if (next_exp_in_updated) {
                next_exp_in = next_exp_in_new;
            }
        }
    }

    ble_hs_unlock();

    return next_exp_in;
}

int
ble_hs_conn_init(void)
{
    int rc;

    rc = os_mempool_init(&ble_hs_conn_pool, MYNEWT_VAL(BLE_MAX_CONNECTIONS),
                         sizeof (struct ble_hs_conn),
                         ble_hs_conn_elem_mem, "ble_hs_conn_pool");
    if (rc != 0) {
        return BLE_HS_EOS;
    }

    SLIST_INIT(&ble_hs_conns);

    return 0;
}
