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

#if MYNEWT_VAL(BLE_PERIODIC_ADV)
static SLIST_HEAD(, ble_hs_periodic_sync) g_ble_hs_periodic_sync_handles;
static struct os_mempool ble_hs_periodic_sync_pool;

static os_membuf_t ble_hs_psync_elem_mem[
    OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_MAX_PERIODIC_SYNCS),
                    sizeof (struct ble_hs_periodic_sync))
];

struct ble_hs_periodic_sync *
ble_hs_periodic_sync_alloc(void)
{
    struct ble_hs_periodic_sync *psync;

    psync = os_memblock_get(&ble_hs_periodic_sync_pool);
    if (psync) {
        memset(psync, 0, sizeof(*psync));
    }

    return psync;
}

void
ble_hs_periodic_sync_free(struct ble_hs_periodic_sync *psync)
{
    int rc;

    if (psync == NULL) {
        return;
    }

#if MYNEWT_VAL(BLE_HS_DEBUG)
    memset(psync, 0xff, sizeof *psync);
#endif
    rc = os_memblock_put(&ble_hs_periodic_sync_pool, psync);
    BLE_HS_DBG_ASSERT_EVAL(rc == 0);
}

void
ble_hs_periodic_sync_insert(struct ble_hs_periodic_sync *psync)
{
    BLE_HS_DBG_ASSERT(ble_hs_locked_by_cur_task());

    BLE_HS_DBG_ASSERT_EVAL(
                       ble_hs_periodic_sync_find_by_handle(psync->sync_handle) == NULL);

    SLIST_INSERT_HEAD(&g_ble_hs_periodic_sync_handles, psync, next);
}

void
ble_hs_periodic_sync_remove(struct ble_hs_periodic_sync *psync)
{
    BLE_HS_DBG_ASSERT(ble_hs_locked_by_cur_task());

    SLIST_REMOVE(&g_ble_hs_periodic_sync_handles, psync, ble_hs_periodic_sync,
                 next);
}

struct ble_hs_periodic_sync *
ble_hs_periodic_sync_find_by_handle(uint16_t sync_handle)
{
    struct ble_hs_periodic_sync *psync;

    BLE_HS_DBG_ASSERT(ble_hs_locked_by_cur_task());

    SLIST_FOREACH(psync, &g_ble_hs_periodic_sync_handles, next) {
        if (psync->sync_handle == sync_handle) {
            return psync;
        }
    }

    return NULL;
}

struct ble_hs_periodic_sync *
ble_hs_periodic_sync_find(const ble_addr_t *addr, uint8_t sid)
{
    struct ble_hs_periodic_sync *psync;

    BLE_HS_DBG_ASSERT(ble_hs_locked_by_cur_task());

    if (!addr) {
        return NULL;
    }

    SLIST_FOREACH(psync, &g_ble_hs_periodic_sync_handles, next) {
        if ((ble_addr_cmp(&psync->advertiser_addr, addr) == 0) &&
                (psync->adv_sid == sid)) {
            return psync;
        }
    }

    return NULL;
}

/**
 * Retrieves the first periodic discovery handle in the list.
 */
struct ble_hs_periodic_sync *
ble_hs_periodic_sync_first(void)
{
    struct ble_hs_periodic_sync *psync;

    ble_hs_lock();
    psync = SLIST_FIRST(&g_ble_hs_periodic_sync_handles);
    ble_hs_unlock();

    return psync;
}

int
ble_hs_periodic_sync_init(void)
{
    int rc;

    rc = os_mempool_init(&ble_hs_periodic_sync_pool,
                         MYNEWT_VAL(BLE_MAX_PERIODIC_SYNCS),
                         sizeof (struct ble_hs_periodic_sync),
                         ble_hs_psync_elem_mem, "ble_hs_periodic_disc_pool");
    if (rc != 0) {
        return BLE_HS_EOS;
    }

    SLIST_INIT(&g_ble_hs_periodic_sync_handles);

    return 0;
}
#endif
