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

struct find_field_data {
    uint8_t type;
    const struct ble_hs_adv_field *field;
};

static ble_uuid16_t ble_hs_adv_uuids16[BLE_HS_ADV_MAX_FIELD_SZ / 2];
static ble_uuid32_t ble_hs_adv_uuids32[BLE_HS_ADV_MAX_FIELD_SZ / 4];
static ble_uuid128_t ble_hs_adv_uuids128[BLE_HS_ADV_MAX_FIELD_SZ / 16];

static int
ble_hs_adv_set_hdr(uint8_t type, uint8_t data_len, uint8_t max_len,
                   uint8_t *dst, uint8_t *dst_len, struct os_mbuf *om)
{
    int rc;

    if (om ) {
        data_len++;
        rc = os_mbuf_append(om, &data_len, sizeof(data_len));
        if (rc) {
            return rc;
        }

        return os_mbuf_append(om, &type, sizeof(type));
    }


    if (*dst_len + 2 + data_len > max_len) {
        return BLE_HS_EMSGSIZE;
    }

    dst[*dst_len] = data_len + 1;
    dst[*dst_len + 1] = type;

    *dst_len += 2;

    return 0;
}

static int
ble_hs_adv_set_flat_mbuf(uint8_t type, int data_len, const void *data,
                    uint8_t *dst, uint8_t *dst_len, uint8_t max_len,
                    struct os_mbuf *om)
{
    int rc;

    BLE_HS_DBG_ASSERT(data_len > 0);

    rc = ble_hs_adv_set_hdr(type, data_len, max_len, dst, dst_len, om);
    if (rc != 0) {
        return rc;
    }

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

    memcpy(dst + *dst_len, data, data_len);
    *dst_len += data_len;

    return 0;
}

int
ble_hs_adv_set_flat(uint8_t type, int data_len, const void *data,
                    uint8_t *dst, uint8_t *dst_len, uint8_t max_len)
{
#if !NIMBLE_BLE_ADVERTISE
    return BLE_HS_ENOTSUP;
#endif

    return ble_hs_adv_set_flat_mbuf(type, data_len, data, dst, dst_len, max_len,
                                    NULL);
}

static int
ble_hs_adv_set_array_uuid16(uint8_t type, uint8_t num_elems,
                            const ble_uuid16_t *elems, uint8_t *dst,
                            uint8_t *dst_len, uint8_t max_len,
                            struct os_mbuf *om)
{
    int rc;
    int i;

    rc = ble_hs_adv_set_hdr(type, num_elems * 2, max_len, dst,
                            dst_len, om);
    if (rc != 0) {
        return rc;
    }

    for (i = 0; i < num_elems; i++) {
        if (om) {
            rc = ble_uuid_to_mbuf(&elems[i].u, om);
            if (rc) {
                return rc;
            }
        } else {
            ble_uuid_flat(&elems[i].u, dst + *dst_len);
            *dst_len += 2;
        }
    }

    return 0;
}

static int
ble_hs_adv_set_array_uuid32(uint8_t type, uint8_t num_elems,
                            const ble_uuid32_t *elems, uint8_t *dst,
                            uint8_t *dst_len, uint8_t max_len,
                            struct os_mbuf *om)
{
    uint32_t uuid_le;
    int rc;
    int i;

    rc = ble_hs_adv_set_hdr(type, num_elems * 4, max_len, dst,
                            dst_len, om);
    if (rc != 0) {
        return rc;
    }

    for (i = 0; i < num_elems; i++) {
        /* We cannot use ble_uuid_flat here since it converts 32-bit UUIDs to
         * 128-bit as ATT requires. In AD, 32-bit UUID shall be written as an
         * actual 32-bit value.
         */
        if (om) {
            uuid_le = htole32(elems[i].value);
            rc = os_mbuf_append(om, &uuid_le, sizeof(uuid_le));
            if (rc) {
                return rc;
            }
        } else {
            put_le32(dst + *dst_len, elems[i].value);
            *dst_len += 4;
        }
    }

    return 0;
}

static int
ble_hs_adv_set_array_uuid128(uint8_t type, uint8_t num_elems,
                             const ble_uuid128_t *elems, uint8_t *dst,
                             uint8_t *dst_len, uint8_t max_len,
                             struct os_mbuf *om)
{
    int rc;
    int i;

    rc = ble_hs_adv_set_hdr(type, num_elems * 16, max_len, dst,
                            dst_len, om);
    if (rc != 0) {
        return rc;
    }

    for (i = 0; i < num_elems; i++) {
        if (om) {
            rc = ble_uuid_to_mbuf(&elems[i].u, om);
            if (rc) {
                return rc;
            }
        } else {
            ble_uuid_flat(&elems[i].u, dst + *dst_len);
            *dst_len += 16;
        }
    }

    return 0;
}

static int
ble_hs_adv_set_array16(uint8_t type, uint8_t num_elems, const uint16_t *elems,
                       uint8_t *dst, uint8_t *dst_len, uint8_t max_len,
                       struct os_mbuf *om)
{
    uint16_t tmp;
    int rc;
    int i;

    rc = ble_hs_adv_set_hdr(type, num_elems * sizeof *elems, max_len, dst,
                            dst_len, om);
    if (rc != 0) {
        return rc;
    }

    for (i = 0; i < num_elems; i++) {
        if (om) {
            tmp = htole16(elems[i]);
            rc = os_mbuf_append(om, &tmp, sizeof(tmp));
            if (rc) {
                return rc;
            }
        } else {
            put_le16(dst + *dst_len, elems[i]);
            *dst_len += sizeof elems[i];
        }
    }

    return 0;
}

static int
adv_set_fields(const struct ble_hs_adv_fields *adv_fields,
                      uint8_t *dst, uint8_t *dst_len, uint8_t max_len,
                      struct os_mbuf *om)
{
#if !NIMBLE_BLE_ADVERTISE
    return BLE_HS_ENOTSUP;
#endif

    uint8_t type;
    int8_t tx_pwr_lvl;
    int rc;

    if (dst_len) {
        *dst_len = 0;
    }

    /*** 0x01 - Flags. */
    /* The application has two options concerning the flags field:
     * 1. Don't include it in advertisements (flags == 0).
     * 2. Explicitly specify the value (flags != 0).
     *
     * Note: The CSS prohibits advertising a flags value of 0, so this method
     * of specifying option 1 vs. 2 is sound.
     */
    if (adv_fields->flags != 0) {
        rc = ble_hs_adv_set_flat_mbuf(BLE_HS_ADV_TYPE_FLAGS, 1,
                                      &adv_fields->flags, dst, dst_len,
                                      max_len, om);

        if (rc != 0) {
            return rc;
        }
    }

    /*** 0x02,0x03 - 16-bit service class UUIDs. */
    if (adv_fields->uuids16 != NULL && adv_fields->num_uuids16) {
        if (adv_fields->uuids16_is_complete) {
            type = BLE_HS_ADV_TYPE_COMP_UUIDS16;
        } else {
            type = BLE_HS_ADV_TYPE_INCOMP_UUIDS16;
        }

        rc = ble_hs_adv_set_array_uuid16(type, adv_fields->num_uuids16,
                                         adv_fields->uuids16, dst, dst_len,
                                         max_len, om);
        if (rc != 0) {
            return rc;
        }
    }

    /*** 0x04,0x05 - 32-bit service class UUIDs. */
    if (adv_fields->uuids32 != NULL && adv_fields->num_uuids32) {
        if (adv_fields->uuids32_is_complete) {
            type = BLE_HS_ADV_TYPE_COMP_UUIDS32;
        } else {
            type = BLE_HS_ADV_TYPE_INCOMP_UUIDS32;
        }

        rc = ble_hs_adv_set_array_uuid32(type, adv_fields->num_uuids32,
                                         adv_fields->uuids32, dst, dst_len,
                                         max_len, om);
        if (rc != 0) {
            return rc;
        }
    }

    /*** 0x06,0x07 - 128-bit service class UUIDs. */
    if (adv_fields->uuids128 != NULL && adv_fields->num_uuids128 > 0) {
        if (adv_fields->uuids128_is_complete) {
            type = BLE_HS_ADV_TYPE_COMP_UUIDS128;
        } else {
            type = BLE_HS_ADV_TYPE_INCOMP_UUIDS128;
        }

        rc = ble_hs_adv_set_array_uuid128(type, adv_fields->num_uuids128,
                                          adv_fields->uuids128, dst, dst_len,
                                          max_len, om);
        if (rc != 0) {
            return rc;
        }
    }

    /*** 0x08,0x09 - Local name. */
    if (adv_fields->name != NULL && adv_fields->name_len > 0) {
        if (adv_fields->name_is_complete) {
            type = BLE_HS_ADV_TYPE_COMP_NAME;
        } else {
            type = BLE_HS_ADV_TYPE_INCOMP_NAME;
        }

        rc = ble_hs_adv_set_flat_mbuf(type, adv_fields->name_len,
                                      adv_fields->name, dst, dst_len, max_len,
                                      om);
        if (rc != 0) {
            return rc;
        }
    }

    /*** 0x0a - Tx power level. */
    if (adv_fields->tx_pwr_lvl_is_present) {
        /* Read the power level from the controller if requested; otherwise use
         * the explicitly specified value.
         */
        if (adv_fields->tx_pwr_lvl == BLE_HS_ADV_TX_PWR_LVL_AUTO) {
            rc = ble_hs_hci_util_read_adv_tx_pwr(&tx_pwr_lvl);
            if (rc != 0) {
                return rc;
            }
        } else {
            tx_pwr_lvl = adv_fields->tx_pwr_lvl;
        }

        rc = ble_hs_adv_set_flat_mbuf(BLE_HS_ADV_TYPE_TX_PWR_LVL, 1,
                                      &tx_pwr_lvl, dst, dst_len, max_len, om);
        if (rc != 0) {
            return rc;
        }
    }

    /*** 0x12 - Slave connection interval range. */
    if (adv_fields->slave_itvl_range != NULL) {
        rc = ble_hs_adv_set_flat_mbuf(BLE_HS_ADV_TYPE_SLAVE_ITVL_RANGE,
                                      BLE_HS_ADV_SLAVE_ITVL_RANGE_LEN,
                                      adv_fields->slave_itvl_range, dst,
                                      dst_len, max_len, om);
        if (rc != 0) {
            return rc;
        }
    }

    /*** 0x16 - Service data - 16-bit UUID. */
    if (adv_fields->svc_data_uuid16 != NULL) {
        rc = ble_hs_adv_set_flat_mbuf(BLE_HS_ADV_TYPE_SVC_DATA_UUID16,
                                      adv_fields->svc_data_uuid16_len,
                                      adv_fields->svc_data_uuid16, dst, dst_len,
                                      max_len, om);
        if (rc != 0) {
            return rc;
        }
    }

    /*** 0x17 - Public target address. */
    if (adv_fields->public_tgt_addr != NULL &&
        adv_fields->num_public_tgt_addrs != 0) {

        rc = ble_hs_adv_set_flat_mbuf(BLE_HS_ADV_TYPE_PUBLIC_TGT_ADDR,
                                 BLE_HS_ADV_PUBLIC_TGT_ADDR_ENTRY_LEN *
                                     adv_fields->num_public_tgt_addrs,
                                 adv_fields->public_tgt_addr, dst, dst_len,
                                 max_len, om);
        if (rc != 0) {
            return rc;
        }
    }

    /*** 0x19 - Appearance. */
    if (adv_fields->appearance_is_present) {
        rc = ble_hs_adv_set_flat_mbuf(BLE_HS_ADV_TYPE_APPEARANCE,
                                      BLE_HS_ADV_APPEARANCE_LEN,
                                      &adv_fields->appearance, dst, dst_len,
                                      max_len, om);
        if (rc != 0) {
            return rc;
        }
    }

    /*** 0x1a - Advertising interval. */
    if (adv_fields->adv_itvl_is_present) {
        rc = ble_hs_adv_set_array16(BLE_HS_ADV_TYPE_ADV_ITVL, 1,
                                    &adv_fields->adv_itvl, dst, dst_len,
                                    max_len, om);
        if (rc != 0) {
            return rc;
        }
    }

    /*** 0x20 - Service data - 32-bit UUID. */
    if (adv_fields->svc_data_uuid32 != NULL) {
        rc = ble_hs_adv_set_flat_mbuf(BLE_HS_ADV_TYPE_SVC_DATA_UUID32,
                                     adv_fields->svc_data_uuid32_len,
                                     adv_fields->svc_data_uuid32, dst, dst_len,
                                     max_len, om);
        if (rc != 0) {
            return rc;
        }
    }

    /*** 0x21 - Service data - 128-bit UUID. */
    if (adv_fields->svc_data_uuid128 != NULL) {
        rc = ble_hs_adv_set_flat_mbuf(BLE_HS_ADV_TYPE_SVC_DATA_UUID128,
                                      adv_fields->svc_data_uuid128_len,
                                      adv_fields->svc_data_uuid128, dst,
                                      dst_len, max_len, om);
        if (rc != 0) {
            return rc;
        }
    }

    /*** 0x24 - URI. */
    if (adv_fields->uri != NULL) {
        rc = ble_hs_adv_set_flat_mbuf(BLE_HS_ADV_TYPE_URI, adv_fields->uri_len,
                                      adv_fields->uri, dst, dst_len, max_len,
                                      om);
        if (rc != 0) {
            return rc;
        }
    }

    /*** 0xff - Manufacturer specific data. */
    if (adv_fields->mfg_data != NULL) {
        rc = ble_hs_adv_set_flat_mbuf(BLE_HS_ADV_TYPE_MFG_DATA,
                                      adv_fields->mfg_data_len,
                                      adv_fields->mfg_data,
                                      dst, dst_len, max_len, om);
        if (rc != 0) {
            return rc;
        }
    }

    return 0;
}

/**
 * Converts a high-level set of fields to a byte buffer.
 *
 * @return                      0 on success; nonzero on failure.
 */
int
ble_hs_adv_set_fields(const struct ble_hs_adv_fields *adv_fields,
                      uint8_t *dst, uint8_t *dst_len, uint8_t max_len)
{
#if !NIMBLE_BLE_ADVERTISE
    return BLE_HS_ENOTSUP;
#endif

    return adv_set_fields(adv_fields, dst, dst_len, max_len, NULL);
}

int
ble_hs_adv_set_fields_mbuf(const struct ble_hs_adv_fields *adv_fields,
                           struct os_mbuf *om)
{
#if !NIMBLE_BLE_ADVERTISE
    return BLE_HS_ENOTSUP;
#endif
    return adv_set_fields(adv_fields, NULL, NULL, 0, om);
}

static int
ble_hs_adv_parse_uuids16(struct ble_hs_adv_fields *adv_fields,
                         const uint8_t *data, uint8_t data_len)
{
    ble_uuid_any_t uuid;
    int i;

    if (data_len % 2 != 0) {
        return BLE_HS_EBADDATA;
    }

    adv_fields->uuids16 = ble_hs_adv_uuids16;
    adv_fields->num_uuids16 = data_len / 2;

    for (i = 0; i < adv_fields->num_uuids16; i++) {
        ble_uuid_init_from_buf(&uuid, data + i * 2, 2);
        adv_fields->uuids16[i] = uuid.u16;
    }

    return 0;
}

static int
ble_hs_adv_parse_uuids32(struct ble_hs_adv_fields *adv_fields,
                         const uint8_t *data, uint8_t data_len)
{
    ble_uuid_any_t uuid;
    int i;

    if (data_len % 4 != 0) {
        return BLE_HS_EBADDATA;
    }

    adv_fields->uuids32 = ble_hs_adv_uuids32;
    adv_fields->num_uuids32 = data_len / 4;

    for (i = 0; i < adv_fields->num_uuids32; i++) {
        ble_uuid_init_from_buf(&uuid, data + i * 4, 4);
        adv_fields->uuids32[i] = uuid.u32;
    }

    return 0;
}

static int
ble_hs_adv_parse_uuids128(struct ble_hs_adv_fields *adv_fields,
                          const uint8_t *data, uint8_t data_len)
{
    ble_uuid_any_t uuid;
    int i;

    if (data_len % 16 != 0) {
        return BLE_HS_EBADDATA;
    }

    adv_fields->uuids128 = ble_hs_adv_uuids128;
    adv_fields->num_uuids128 = data_len / 16;

    for (i = 0; i < adv_fields->num_uuids128; i++) {
        ble_uuid_init_from_buf(&uuid, data + i * 16, 16);
        adv_fields->uuids128[i] = uuid.u128;
    }

    return 0;
}

static int
ble_hs_adv_parse_one_field(struct ble_hs_adv_fields *adv_fields,
                           uint8_t *total_len, uint8_t *src, uint8_t src_len)
{
    uint8_t data_len;
    uint8_t type;
    uint8_t *data;
    int rc;

    if (src_len < 1) {
        return BLE_HS_EMSGSIZE;
    }
    *total_len = src[0] + 1;

    if (src_len < *total_len) {
        return BLE_HS_EMSGSIZE;
    }

    type = src[1];
    data = src + 2;
    data_len = *total_len - 2;

    if (data_len > BLE_HS_ADV_MAX_FIELD_SZ) {
        return BLE_HS_EBADDATA;
    }

    switch (type) {
    case BLE_HS_ADV_TYPE_FLAGS:
        if (data_len != BLE_HS_ADV_FLAGS_LEN) {
            return BLE_HS_EBADDATA;
        }
        adv_fields->flags = *data;
        break;

    case BLE_HS_ADV_TYPE_INCOMP_UUIDS16:
        rc = ble_hs_adv_parse_uuids16(adv_fields, data, data_len);
        if (rc != 0) {
            return rc;
        }
        adv_fields->uuids16_is_complete = 0;
        break;

    case BLE_HS_ADV_TYPE_COMP_UUIDS16:
        rc = ble_hs_adv_parse_uuids16(adv_fields, data, data_len);
        if (rc != 0) {
            return rc;
        }
        adv_fields->uuids16_is_complete = 1;
        break;

    case BLE_HS_ADV_TYPE_INCOMP_UUIDS32:
        rc = ble_hs_adv_parse_uuids32(adv_fields, data, data_len);
        if (rc != 0) {
            return rc;
        }
        adv_fields->uuids16_is_complete = 0;
        break;

    case BLE_HS_ADV_TYPE_COMP_UUIDS32:
        rc = ble_hs_adv_parse_uuids32(adv_fields, data, data_len);
        if (rc != 0) {
            return rc;
        }
        adv_fields->uuids16_is_complete = 1;
        break;

    case BLE_HS_ADV_TYPE_INCOMP_UUIDS128:
        rc = ble_hs_adv_parse_uuids128(adv_fields, data, data_len);
        if (rc != 0) {
            return rc;
        }
        adv_fields->uuids128_is_complete = 0;
        break;

    case BLE_HS_ADV_TYPE_COMP_UUIDS128:
        rc = ble_hs_adv_parse_uuids128(adv_fields, data, data_len);
        if (rc != 0) {
            return rc;
        }
        adv_fields->uuids128_is_complete = 1;
        break;

    case BLE_HS_ADV_TYPE_INCOMP_NAME:
        adv_fields->name = data;
        adv_fields->name_len = data_len;
        adv_fields->name_is_complete = 0;
        break;

    case BLE_HS_ADV_TYPE_COMP_NAME:
        adv_fields->name = data;
        adv_fields->name_len = data_len;
        adv_fields->name_is_complete = 1;
        break;

    case BLE_HS_ADV_TYPE_TX_PWR_LVL:
        if (data_len != BLE_HS_ADV_TX_PWR_LVL_LEN) {
            return BLE_HS_EBADDATA;
        }
        adv_fields->tx_pwr_lvl = *data;
        adv_fields->tx_pwr_lvl_is_present = 1;
        break;

    case BLE_HS_ADV_TYPE_SLAVE_ITVL_RANGE:
        if (data_len != BLE_HS_ADV_SLAVE_ITVL_RANGE_LEN) {
            return BLE_HS_EBADDATA;
        }
        adv_fields->slave_itvl_range = data;
        break;

    case BLE_HS_ADV_TYPE_SVC_DATA_UUID16:
        if (data_len < BLE_HS_ADV_SVC_DATA_UUID16_MIN_LEN) {
            return BLE_HS_EBADDATA;
        }
        adv_fields->svc_data_uuid16 = data;
        adv_fields->svc_data_uuid16_len = data_len;
        break;

    case BLE_HS_ADV_TYPE_PUBLIC_TGT_ADDR:
        if (data_len % BLE_HS_ADV_PUBLIC_TGT_ADDR_ENTRY_LEN != 0) {
            return BLE_HS_EBADDATA;
        }
        adv_fields->public_tgt_addr = data;
        adv_fields->num_public_tgt_addrs =
            data_len / BLE_HS_ADV_PUBLIC_TGT_ADDR_ENTRY_LEN;
        break;

    case BLE_HS_ADV_TYPE_APPEARANCE:
        if (data_len != BLE_HS_ADV_APPEARANCE_LEN) {
            return BLE_HS_EBADDATA;
        }
        adv_fields->appearance = get_le16(data);
        adv_fields->appearance_is_present = 1;
        break;

    case BLE_HS_ADV_TYPE_ADV_ITVL:
        if (data_len != BLE_HS_ADV_ADV_ITVL_LEN) {
            return BLE_HS_EBADDATA;
        }
        adv_fields->adv_itvl = get_le16(data);
        adv_fields->adv_itvl_is_present = 1;
        break;

    case BLE_HS_ADV_TYPE_SVC_DATA_UUID32:
        if (data_len < BLE_HS_ADV_SVC_DATA_UUID32_MIN_LEN) {
            return BLE_HS_EBADDATA;
        }
        adv_fields->svc_data_uuid32 = data;
        adv_fields->svc_data_uuid32_len = data_len;
        break;

    case BLE_HS_ADV_TYPE_SVC_DATA_UUID128:
        if (data_len < BLE_HS_ADV_SVC_DATA_UUID128_MIN_LEN) {
            return BLE_HS_EBADDATA;
        }
        adv_fields->svc_data_uuid128 = data;
        adv_fields->svc_data_uuid128_len = data_len;
        break;

    case BLE_HS_ADV_TYPE_URI:
        adv_fields->uri = data;
        adv_fields->uri_len = data_len;
        break;

    case BLE_HS_ADV_TYPE_MFG_DATA:
        adv_fields->mfg_data = data;
        adv_fields->mfg_data_len = data_len;
        break;

    default:
        break;
    }

    return 0;
}

int
ble_hs_adv_parse_fields(struct ble_hs_adv_fields *adv_fields, uint8_t *src,
                        uint8_t src_len)
{
    uint8_t field_len;
    int rc;

    memset(adv_fields, 0, sizeof *adv_fields);

    while (src_len > 0) {
        rc = ble_hs_adv_parse_one_field(adv_fields, &field_len, src, src_len);
        if (rc != 0) {
            return rc;
        }

        src += field_len;
        src_len -= field_len;
    }

    return 0;
}

int
ble_hs_adv_parse(const uint8_t *data, uint8_t length,
                 ble_hs_adv_parse_func_t func, void *user_data)
{
    const struct ble_hs_adv_field *field;

    while (length > 1) {
        field = (const void *) data;

        if (field->length >= length) {
            return BLE_HS_EBADDATA;
        }

        if (func(field, user_data) == 0) {
            return 0;
        }

        length -= 1 + field->length;
        data += 1 + field->length;
    }

    return 0;
}

static int
find_field_func(const struct ble_hs_adv_field *field, void *user_data)
{
    struct find_field_data *ffd = user_data;

    if (field->type != ffd->type) {
        return BLE_HS_EAGAIN;
    }

    ffd->field = field;

    return 0;
}

int
ble_hs_adv_find_field(uint8_t type, const uint8_t *data, uint8_t length,
                      const struct ble_hs_adv_field **out)
{
    int rc;
    struct find_field_data ffd = {
            .type = type,
            .field = NULL,
    };

    rc = ble_hs_adv_parse(data, length, find_field_func, &ffd);
    if (rc != 0) {
        return rc;
    }

    if (!ffd.field) {
        return BLE_HS_ENOENT;
    }

    *out = ffd.field;

    return 0;
}
