/*
 * 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 "host/ble_hs.h"
#include "ble_hs_priv.h"

/**
 * Allocates an mbuf for use by the nimble host.
 */
static struct os_mbuf *
ble_hs_mbuf_gen_pkt(uint16_t leading_space)
{
    struct os_mbuf *om;
    int rc;

    om = os_msys_get_pkthdr(0, 0);
    if (om == NULL) {
        return NULL;
    }

    if (om->om_omp->omp_databuf_len < leading_space) {
        rc = os_mbuf_free_chain(om);
        BLE_HS_DBG_ASSERT_EVAL(rc == 0);
        return NULL;
    }

    om->om_data += leading_space;

    return om;
}

/**
 * Allocates an mbuf with no leading space.
 *
 * @return                  An empty mbuf on success; null on memory
 *                              exhaustion.
 */
struct os_mbuf *
ble_hs_mbuf_bare_pkt(void)
{
    return ble_hs_mbuf_gen_pkt(0);
}

/**
 * Allocates an mbuf suitable for an HCI ACL data packet.
 *
 * @return                  An empty mbuf on success; null on memory
 *                              exhaustion.
 */
struct os_mbuf *
ble_hs_mbuf_acl_pkt(void)
{
    return ble_hs_mbuf_gen_pkt(BLE_HCI_DATA_HDR_SZ);
}

/**
 * Allocates an mbuf suitable for an L2CAP data packet.  The resulting packet
 * has sufficient leading space for:
 *     o ACL data header
 *     o L2CAP B-frame header
 *
 * @return                  An empty mbuf on success; null on memory
 *                              exhaustion.
 */
struct os_mbuf *
ble_hs_mbuf_l2cap_pkt(void)
{
    return ble_hs_mbuf_gen_pkt(BLE_HCI_DATA_HDR_SZ + BLE_L2CAP_HDR_SZ);
}

struct os_mbuf *
ble_hs_mbuf_att_pkt(void)
{
    /* Prepare write request and response are the larget ATT commands which
     * contain attribute data.
     */
     return ble_hs_mbuf_gen_pkt(BLE_HCI_DATA_HDR_SZ +
                                BLE_L2CAP_HDR_SZ +
                                BLE_ATT_PREP_WRITE_CMD_BASE_SZ);
}

struct os_mbuf *
ble_hs_mbuf_from_flat(const void *buf, uint16_t len)
{
    struct os_mbuf *om;
    int rc;

    om = ble_hs_mbuf_att_pkt();
    if (om == NULL) {
        return NULL;
    }

    rc = os_mbuf_copyinto(om, 0, buf, len);
    if (rc != 0) {
        os_mbuf_free_chain(om);
        return NULL;
    }

    return om;
}

int
ble_hs_mbuf_to_flat(const struct os_mbuf *om, void *flat, uint16_t max_len,
                    uint16_t *out_copy_len)
{
    uint16_t copy_len;
    int rc;

    if (OS_MBUF_PKTLEN(om) <= max_len) {
        copy_len = OS_MBUF_PKTLEN(om);
    } else {
        copy_len = max_len;
    }

    rc = os_mbuf_copydata(om, 0, copy_len, flat);
    if (rc != 0) {
        return BLE_HS_EUNKNOWN;
    }

    if (copy_len > max_len) {
        rc = BLE_HS_EMSGSIZE;
    } else {
        rc = 0;
    }

    if (out_copy_len != NULL) {
        *out_copy_len = copy_len;
    }
    return rc;
}

int
ble_hs_mbuf_pullup_base(struct os_mbuf **om, int base_len)
{
    if (OS_MBUF_PKTLEN(*om) < base_len) {
        return BLE_HS_EBADDATA;
    }

    *om = os_mbuf_pullup(*om, base_len);
    if (*om == NULL) {
        return BLE_HS_ENOMEM;
    }

    return 0;
}
