Newer
Older
mbed-os / features / FEATURE_BLE / ble / gap / Types.h
/* mbed Microcontroller Library
 * Copyright (c) 2018 ARM Limited
 *
 * Licensed 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.
 */

#ifndef BLE_GAP_TYPES_H
#define BLE_GAP_TYPES_H

#include "ble/common/Duration.h"
#include "ble/common/Bounded.h"
#include "ble/SafeEnum.h"

namespace ble {

/**
 * @addtogroup ble
 * @{
 * @addtogroup gap
 * @{
 */

/* BLE units, using microseconds as the common denominator */

/**
 * Time interval between two advertisements.
 *
 * The duration is in unit of 625µs and ranges from 0x20 to 0xFFFFFF .
 *
 * @note before Bluetooth 5 range was 0x20 to 0xFFFF.
 */
typedef Duration<uint32_t, 625, Range<0x20, 0xFFFFFF> > adv_interval_t;

/**
 * Advertising process duration.
 *
 * The duration is in unit of 10ms and ranges from 0x0001 to 0xFFFF. The special
 * value 0x0000 means the advertising process never ends; it is accessible with
 * adv_duration_t::forever().
 */
typedef Duration<uint16_t, 10000, Range<0x00, 0xFFFF>, /* forever */ Value<uint16_t, 0x0000> > adv_duration_t;

/**
 * Scan process duration.
 *
 * The duration is in unit of 10ms and ranges from 0x0001 to 0xFFFF. The special
 * value 0x0000 means the scan process never ends; it is accessible with
 * scan_duration_t::forever().
 */
typedef Duration<uint16_t, 10000, Range<0x00, 0xFFFF>, /* forever */ Value<uint16_t, 0x0000> > scan_duration_t;

/**
 * Time interval between two scan processes.
 *
 * The duration is in unit of 1.28s and ranges from 0x0001 to 0xFFFF. The special
 * value 0x0000 is used to indicate that scan_period_t is not used.
 */
typedef Duration<uint16_t, 1280000, Range<0x00, 0xFFFF> > scan_period_t;

/**
 * Time interval between two scans.
 *
 * The duration is in unit of 625µs and ranges from 0x04 to 0xFFFF.
 */
typedef Duration<uint16_t, 625, Range<0x04, 0xFFFF> > scan_interval_t;

/**
 * Duration of a scan.
 *
 * The duration is in unit of 625µs and ranges from 0x04 to 0xFFFF.
 */
typedef Duration<uint16_t, 625, Range<0x04, 0xFFFF> > scan_window_t;

/**
 * Time interval between two connection events.
 *
 * The interval is in unit of 1.250 milliseconds and ranges from 0x06 to 0xC80.
 */
typedef Duration<uint16_t, 1250, Range<0x06, 0x0C80> > conn_interval_t;

/**
 * Time after which a connection is loss of devices have not exchanged data.
 *
 * The duration is in unit of 10 milliseconds and ranges from 0x0A to 0xC80.
 *
 * @note this time should be no larger than (1 + ConnLatency) * ConnIntervalMax * 2
 */
typedef Duration<uint16_t, 10000, Range<0x0A, 0x0C80> > supervision_timeout_t;

/**
 * Duration of a connection event.
 *
 * The duration is in unit of 625µs and ranges from 0x0 to 0xFFFF .
 */
typedef Duration<uint16_t, 625, Range<0, 0xFFFF> > conn_event_length_t;

/**
 * Time after which a periodic sync link is considered lost if the receiver hasn't
 * received anything from the advertiser.
 *
 * The duration is in unit of 10 milliseconds and ranges from 0x0A to 0x4000.
 */
typedef Duration<uint16_t, 10000, Range<0x0A, 0x4000> > sync_timeout_t;

/**
 * Interval between two periodic advertising events.
 *
 * The duration is in unit of 1.250ms and ranges from 0x06 to 0xFFFF.
 */
typedef Duration<uint16_t, 1250, Range<0x06, 0xFFFF> > periodic_interval_t;

/**
 * Number of connection events that can be skipped by the slave.
 *
 * It ranges from 0 to 0x1F3.
 */
typedef Bounded<uint16_t, 0, 0x01F3> slave_latency_t;

/**
 * Handle of an advertising set.
 *
 * @note Range of valid handle is comprised between 0x00 and 0xEF.
 */
typedef uint8_t advertising_handle_t;

/**
 * Handle of a sync representing a periodic advertiser.
 *
 * @note Range of valid handle is comprised between 0x0000 and 0xFFFF.
 */
typedef uint16_t periodic_sync_handle_t;

/**
 * Encapsulates the peripheral advertising modes.
 *
 * It determines how the device appears to other scanner and peripheral
 * devices in the scanning range.
 */
struct advertising_type_t : SafeEnum<advertising_type_t, uint8_t> {
    /// enumeration of advertising_type_t values
    enum type {
        /**
         * Device is connectable, scannable and doesn't expect connection from a
         * specific peer.
         * @note Cannot carry extended advertising payload, only legacy PDUs.
         * Use CONNECTABLE_NON_SCANNABLE_UNDIRECTED for non-legacy payload.
         *
         * @see Vol 3, Part C, Section 9.3.4 and Vol 6, Part B, Section 2.3.1.1.
         */
        CONNECTABLE_UNDIRECTED = 0x00,

        /**
         * Device is connectable and expects connection from a specific peer.
         * (3.75 ms or smaller Advertising Interval)
         * @see Vol 3, Part C, Section 9.3.3 and Vol 6, Part B, Section 2.3.1.2.
         */
        CONNECTABLE_DIRECTED = 0x01,

        /**
         * Device is scannable but not connectable.
         *
         * @see Vol 6, Part B, Section 2.3.1.4.
         */
        SCANNABLE_UNDIRECTED = 0x02,

        /**
         * Device is not connectable and not scannable.
         *
         * @see Vol 3, Part C, Section 9.3.2 and Vol 6, Part B, Section 2.3.1.3.
         */
        NON_CONNECTABLE_UNDIRECTED = 0x03,

        /**
         * Device is connectable and expects connection from a specific peer (sent at long user set intervals).
         */
        CONNECTABLE_DIRECTED_LOW_DUTY = 0x04,

        /**
         * Device is connectable, but not scannable and doesn't expect connection from a specific peer.
         * @note Only for use with extended advertising payload, will not allow legacy PDUs
         * (use CONNECTABLE_UNDIRECTED for legacy PDU).
         */
        CONNECTABLE_NON_SCANNABLE_UNDIRECTED = 0x05,

#if !defined(DOXYGEN_ONLY)
        // used by the PAL; naming in line with the the spec.
        ADV_IND = 0x00,
        ADV_DIRECT_IND = 0x01,
        ADV_SCAN_IND = 0x02,
        ADV_NONCONN_IND = 0x03,
        ADV_DIRECT_IND_LOW_DUTY_CYCLE = 0x04,
        ADV_NONSCAN_IND = 0x05
#endif
    };

    /**
     * Construct a new advertising_type_t value.
     *
     * @param value The value of the advertising_type_t created.
     */
    advertising_type_t(type value) : SafeEnum(value)
    {
    }
};


/** Used to indicate if the packet is complete and if it's truncated.
 */
struct advertising_data_status_t : SafeEnum<advertising_data_status_t, uint8_t> {
    /// enumeration of advertising_data_status_t values
    enum type {
        COMPLETE = 0x00, /// Advertising payload complete.
        INCOMPLETE_MORE_DATA = 0x01, /// Partial advertising payload, more to come.
        INCOMPLETE_DATA_TRUNCATED = 0x02 /// Advertising payload incomplete, and no more is coming.
    };

    /**
     * Construct a new advertising_data_status_t value.
     *
     * @param value The value of the advertising_data_status_t created.
     */
    advertising_data_status_t(type value) : SafeEnum(value)
    {
    }

#if !defined(DOXYGEN_ONLY)

    /**
     * Explicit constructor from a raw value.
     */
    explicit advertising_data_status_t(uint8_t raw_value) :
        SafeEnum(raw_value)
    {
    }

#endif

};

/** Properties of an advertising event.
 */
struct advertising_event_t {

private:
    // Implementation note: The object is constructed from the field Event_Type
    // of an LE Extended Advertising.
    // Indexes and functions of bits are defined in BLUETOOTH SPECIFICATION
    // Version 5.0 | Vol 2, Part E -
    // Section 7.7.65.13 LE Extended Advertising report Event
    enum {
        CONNECTABLE_BIT = 0,
        SCANNABLE_ADVERTISING_BIT = 1,
        DIRECTED_ADVERTISING_BIT = 2,
        SCAN_RESPONSE_BIT = 3,
        LEGACY_PDU_BIT = 4,
        DATA_STATUS_INDEX = 5,
        DATA_STATUS_MASK = 0x03
    };

public:

#if !defined(DOXYGEN_ONLY)

    /** Create based on a raw value.
     *
     * @param value
     */
    explicit advertising_event_t(uint8_t value) : value(value)
    {
    }

#endif

    /** Is advertising connectable.
     *
     * @return True if connectable.
     */
    bool connectable() const
    {
        return static_cast<bool>(value & (1 << CONNECTABLE_BIT));
    }

    /** Is advertising scannable.
     *
     * @return True if scannable
     */
    bool scannable_advertising() const
    {
        return static_cast<bool>(value & (1 << SCANNABLE_ADVERTISING_BIT));
    }

    /** Is advertising directed.
     *
     * @return True if directed.
     */
    bool directed_advertising() const
    {
        return static_cast<bool>(value & (1 << DIRECTED_ADVERTISING_BIT));
    }

    /** Is this a scan response.
     *
     * @return True if scan response.
     */
    bool scan_response() const
    {
        return static_cast<bool>(value & (1 << SCAN_RESPONSE_BIT));
    }

    /** Is this legacy advertising.
     *
     * @return True if legacy.
     */
    bool legacy_advertising() const
    {
        return static_cast<bool>(value & (1 << LEGACY_PDU_BIT));
    }

    /** Payload completeness status.
     *
     * @return @see advertising_data_status_t for details.
     */
    advertising_data_status_t data_status() const
    {
        return static_cast<advertising_data_status_t::type>(
            (value >> DATA_STATUS_INDEX) & DATA_STATUS_MASK
        );
    }

    /** Is payload complete.
     *
     * @return True if payload is coplete.
     */
    bool complete() const
    {
        return data_status() == advertising_data_status_t::COMPLETE;
    }

    /** Is there more data coming.
     *
     * @return True if more data coming.
     */
    bool more_data_to_come() const
    {
        return data_status() == advertising_data_status_t::INCOMPLETE_MORE_DATA;
    }

    /** Is the payload truncated.
     *
     * @return True if no more data coming.
     */
    bool truncated() const
    {
        return data_status() == advertising_data_status_t::INCOMPLETE_DATA_TRUNCATED;
    }

private:
    uint8_t value;
};

/**
 * Identify an advertising SID. Range: [0x00, 0x0F]
 */
typedef uint8_t advertising_sid_t;

/** Received signal strength. Range <-127, 20>.
 *  @note Special value 127 means RSSI is not available. */
typedef int8_t rssi_t;

/**
 * Describe the advertising power.
 *
 * Values between -127 and +126 are considered power values in dBm while
 * the special value 127 can be used as a wildcard to indicate that the host
 * has no preference or if the power information is not available.
 */
typedef int8_t advertising_power_t;

/**
 * Advertising policy filter modes.
 *
 * @see Bluetooth Core Specification 4.2 (Vol. 6), Part B, Section 4.3.2.
 */
struct advertising_filter_policy_t : SafeEnum<advertising_filter_policy_t, uint8_t> {
    /// enumeration of advertising_filter_policy_t values
    enum type {
        /**
         * Process connection and scan requests from all devices. The whitelist is
         * not used.
         */
        NO_FILTER = 0x00,

        /**
         * Process connection requests from all devices but filter out scan requests
         * of devices that are not in the whitelist.
         */
        FILTER_SCAN_REQUESTS = 0x01,

        /**
         * Process scan requests from all devices but filter out connection requests
         * of devices that are not in the whitelist.
         */
        FILTER_CONNECTION_REQUEST = 0x02,

        /**
         * Filter out scan or connection requests of devices that are not in the
         * whitelist.
         */
        FILTER_SCAN_AND_CONNECTION_REQUESTS = 0x03
    };

    /**
     * Construct a advertising_filter_policy_t.
     * @param value The value of the advertising_filter_policy_t created.
     */
    advertising_filter_policy_t(type value) : SafeEnum(value)
    {
    }
};

/**
 * Scanning policy filter mode.
 *
 * @see Bluetooth Core Specification 4.2 (Vol. 6), Part B, Section 4.3.3.
 */
struct scanning_filter_policy_t : SafeEnum<scanning_filter_policy_t, uint8_t> {
    /// enumeration of scanning_filter_policy_t values
    enum type {
        /**
        * Accept all advertising packets except directed advertising packets not
        * addressed to this device.
        */
        NO_FILTER = 0x00,

        /**
        * Accept only advertising packets from devices in the whitelist except
        * directed advertising packets not addressed to this device.
        */
        FILTER_ADVERTISING = 0x01,

        /**
         * Accept all advertising packets except directed advertising packets
         * where the initiator's identity address does not address this device.
         *
         * @note Directed advertising packets where the initiator's address is a
         * resolvable private address that cannot be resolved are also accepted.
         */
        NO_FILTER_INCLUDE_UNRESOLVABLE_DIRECTED = 2,

        /**
         * Accept all advertising packets except:
         * - Advertising packets where the advertiser's
         * identity address is not in the whitelist.
         * - Directed advertising packets where the initiator's identity address
         * does not address this device.
         *
         * @note Directed advertising packets where the initiator's address is a
         * resolvable private address that cannot be resolved are also accepted.
         */
        FILTER_ADVERTISING_INCLUDE_UNRESOLVABLE_DIRECTED = 3
    };

    /**
     * Construct a new instance of scanning_filter_policy_t.
     *
     * @param value The value of the scanning_filter_policy_t created.
     */
    scanning_filter_policy_t(type value) : SafeEnum(value)
    {
    }
};

/**
 * Filter policy that you can use during connection initiation.
 */
struct initiator_filter_policy_t : SafeEnum<initiator_filter_policy_t, uint8_t> {
    /// enumeration of initiator_filter_policy_t values.
    enum type {
        /**
        * The whitelist is not used to determine which advertiser to connect to.
        */
        NO_FILTER,

        /**
        * The whitelist is used to determine which advertiser to connect to.
        */
        USE_WHITE_LIST
    };

    /**
     * Construct a initiator_filter_policy_t.
     * @param value The value of the initiator_filter_policy_t.
     */
    initiator_filter_policy_t(type value) : SafeEnum(value)
    {
    }
};

/**
 * Scanning policy filter mode.
 *
 * @see Bluetooth Core Specification 4.2 (Vol. 6), Part B, Section 4.3.3.
 */
struct duplicates_filter_t : SafeEnum<duplicates_filter_t, uint8_t> {
    /// enumeration of duplicates_filter_t values
    enum type {
        /**
         * Disable duplicate filtering.
         */
        DISABLE,

        /**
         * Enable duplicate filtering.
         */
        ENABLE,

        /**
         * Enable duplicate filtering, and reset the cache periodically.
         */
        PERIODIC_RESET
    };

    /**
     * Construct a new duplicates_filter_t value.
     * @param value The value of the duplicates_filter_t created.
     */
    duplicates_filter_t(type value) : SafeEnum(value)
    {
    }
};

/**
 * Type used to model the own address used during the following GAP operations:
 * advertising, scanning and initiating
 */
struct own_address_type_t : SafeEnum<own_address_type_t, uint8_t> {
    /// enumeration of own_address_type_t values.
    enum type {
        /**
         * Use the public device address.
         */
        PUBLIC = 0x00,

        /**
         * Use the random device address.
         */
        RANDOM = 0x01,

        /**
         * Generated resolvable private address based on the local IRK from the
         * resolving list. Use the public address if no entry match in the resolving
         * list.
         */
        RESOLVABLE_PRIVATE_ADDRESS_PUBLIC_FALLBACK = 0x02,

        /**
         * Generated resolvable private address based on the local IRK from the
         * resolving list. Use the random address if no entry match in the resolving
         * list.
         */
        RESOLVABLE_PRIVATE_ADDRESS_RANDOM_FALLBACK = 0x03,
    };

    /**
     * Construct a new instance of own_address_type_t.
     * @param value The value of the own_address_type_t created.
     */
    own_address_type_t(type value) : SafeEnum(value)
    {
    }

    /**
     * Default initialization of own_address_type_t.
     */
    own_address_type_t() :
        SafeEnum<own_address_type_t, uint8_t>(PUBLIC) { }
};

/**
 * Type of an address to connect to.
 *
 * It is used to connect to a device directly with directed advertising.
 */
struct target_peer_address_type_t : SafeEnum<target_peer_address_type_t, uint8_t> {
    /// enumeration of target_peer_address_type_t values.
    enum type {
        PUBLIC = 0x00, /**< Public Device Address or Public Identity Address. */
        RANDOM = 0x01, /**< Random Device Address or Random (static) Identity Address. */
    };

    /**
     * Create a new target_peer_address_type_t.
     * @param value The value of the target_peer_address_type_t created.
     */
    target_peer_address_type_t(type value) : SafeEnum(value)
    {
    }
};

/**
 * Accuracy of the master clock.
 */
struct clock_accuracy_t : SafeEnum<clock_accuracy_t, uint8_t> {
    /// enumeration of clock_accuracy_t values.
    enum type {
        /**
         * 500 PPM
         */
        PPM_500 = 0x00,

        /**
         * 250 PPM
         */
        PPM_250 = 0x01,

        /**
         * 150 PPM
         */
        PPM_150 = 0x02,

        /**
         * 100 PPM
         */
        PPM_100 = 0x03,

        /**
         * 75 PPM
         */
        PPM_75 = 0x04,

        /**
         * 50 PPM
         */
        PPM_50 = 0x05,

        /**
         * 30 PPM
         */
        PPM_30 = 0x06,

        /**
         * 20 PPM
         */
        PPM_20 = 0x07
    };

    /** Get clock accuracy.
     *
     * @return Parts per million as a number.
     */
    uint16_t get_ppm()
    {
        switch (value()) {
            case PPM_500:
                return 500;
            case PPM_250:
                return 250;
            case PPM_150:
                return 150;
            case PPM_100:
                return 100;
            case PPM_75:
                return 75;
            case PPM_50:
                return 50;
            case PPM_30:
                return 30;
            case PPM_20:
                return 20;
            default:
                return 0;
        }
    }

    /**
     * Construct a new clock_accuracy_t value.
     * @param value The value of the clock_accuracy_t created.
     */
    clock_accuracy_t(type value) : SafeEnum(value)
    {
    }

#if !defined(DOXYGEN_ONLY)

    /**
     * Construct a new clock_accuracy_t value from a raw value.
     * @param raw_value The value of the clock accuracy.
     */
    explicit clock_accuracy_t(uint8_t raw_value) : SafeEnum(raw_value)
    {
    }

#endif
};

/**
 * Enumeration of GAP roles.
 *
 * @note The BLE API does not express the broadcaster and scanner roles.
 *
 * @attention A device can fulfill different roles concurrently.
 */
struct connection_role_t : SafeEnum<connection_role_t, uint8_t> {
    /** struct scoped enum wrapped by the class */
    enum type {
        /**
         * Central Role.
         *
         * The device can scan and initiate connection to peripherals. It
         * acts as the master when a connection is established.
         *
         * @note A central is a scanner.
         */
        CENTRAL = 0x00,

        /**
         * Peripheral Role.
         *
         * The device can advertise, and you can connect it by a central. It
         * acts as a slave when connected.
         *
         * @note A peripheral is a broadcaster.
         */
        PERIPHERAL = 0x01
    };

    /**
     * Construct a new instance of role_t.
     *
     * @param value The value of the role_t created.
     */
    connection_role_t(type value) : SafeEnum(value)
    {
    }

#if !defined(DOXYGEN_ONLY)

    /**
     * Explicit constructor from a raw value.
     * @param raw_value The role.
     */
    explicit connection_role_t(uint8_t raw_value) : SafeEnum(raw_value)
    {
    }

#endif
};

/**
 * Enumeration of disconnection reasons that should be transmited to the peer.
 */
struct local_disconnection_reason_t : SafeEnum<local_disconnection_reason_t, uint8_t> {
    /// enumeration of local_disconnection_reason_t values.
    enum type {
        /**
         * GAP or GATT failed to authenticate the peer.
         */
        AUTHENTICATION_FAILURE = 0x05,

        /**
         * Connection terminated by the user.
         */
        USER_TERMINATION = 0x13,

        /**
         * Connection termination due to low resources.
         */
        LOW_RESOURCES = 0x14,

        /**
         * Connection termination due to power off.
         */
        POWER_OFF = 0x15,

        /**
         * Remote feature not supported.
         */
        UNSUPPORTED_REMOTE_FEATURE = 0x1A,

        /**
         * Not possible to pai with a unit key.
         */
        PAIRING_WITH_UNIT_KEY_NOT_SUPPORTED = 0x29,

        /**
         * Connection parameters were unacceptable.
         */
        UNACCEPTABLE_CONNECTION_PARAMETERS = 0x3B
    };

    /**
     * Construct a new instance of disconnection_reason_t.
     *
     * @param value The value of the local_disconnection_reason_t created.
     */
    local_disconnection_reason_t(type value) : SafeEnum(value)
    {
    }
};


/**
 * Enumeration of disconnection reasons received in a disconnection event.
 */
struct disconnection_reason_t : SafeEnum<disconnection_reason_t, uint8_t> {
    /// enumeration of disconnection_reason_t values.
    enum type {
        /**
         * GAP or GATT failed to authenticate the peer.
         */
        AUTHENTICATION_FAILURE = 0x05,

        /**
         * The connection timed out.
         */
        CONNECTION_TIMEOUT = 0x08,

        /**
         * Connection terminated by the user.
         */
        REMOTE_USER_TERMINATED_CONNECTION = 0x13,

        /**
         * Remote device terminated connection due to low resources.
         */
        REMOTE_DEV_TERMINATION_DUE_TO_LOW_RESOURCES = 0x14,

        /**
         * Remote device terminated connection due to power off.
         */
        REMOTE_DEV_TERMINATION_DUE_TO_POWER_OFF = 0x15,

        /**
         * Indicate that the local user or the internal
         * Bluetooth subsystem terminated the connection.
         */
        LOCAL_HOST_TERMINATED_CONNECTION = 0x16,

        /**
         * Connection parameters were unacceptable.
         */
        UNACCEPTABLE_CONNECTION_PARAMETERS = 0x3B
    };

    /**
     * Construct a new instance of disconnection_reason_t.
     *
     * @param value The value of the disconnection_reason_t created.
     */
    disconnection_reason_t(type value) : SafeEnum(value)
    {
    }

#if !defined(DOXYGEN_ONLY)
    /**
     * Construct a new instance of disconnection_reason_t.
     *
     * @param value The value of the local_disconnection_reason_t created.
     *
     * @note This should only be used for casting raw values from HCI.
     */
    explicit disconnection_reason_t(uint8_t value) : SafeEnum(value)
    {
    }
};
#endif // !defined(DOXYGEN_ONLY)

/**
 * Privacy Configuration of the peripheral role.
 *
 * @note This configuration also applies to the broadcaster role configuration.
 */
struct peripheral_privacy_configuration_t {
    /**
     * Indicates if nonresolvable random address should be used when the
     * peripheral advertises nonconnectable packets.
     *
     * Resolvable random address continues to be used for connectable packets.
     */
    bool use_non_resolvable_random_address;

    /**
     * Resolution strategy for initiator resolvable addresses when a
     * connection request is received.
     */
    enum resolution_strategy_t {
        /**
         * Do not resolve the address of the initiator and accept the
         * connection request.
         */
        DO_NOT_RESOLVE,

        /**
         * If a bond is present in the secure database and the address
         * resolution fails, then reject the connection request with the error
         * code AUTHENTICATION_FAILLURE.
         */
        REJECT_NON_RESOLVED_ADDRESS,

        /**
         * Perform the pairing procedure if the initiator resolvable
         * address failed the resolution process.
         */
        PERFORM_PAIRING_PROCEDURE,

        /**
         * Perform the authentication procedure if the initiator resolvable
         * address failed the resolution process.
         */
        PERFORM_AUTHENTICATION_PROCEDURE
    };

    /**
     * Connection strategy to use when a connection request contains a
     * private resolvable address.
     */
    resolution_strategy_t resolution_strategy;
};

/**
 * Privacy configuration of the central role.
 *
 * @note This configuration is also used when the local device operates as
 * an observer.
 */
struct central_privacy_configuration_t {
    /**
     * Indicates if nonresolvable random address should be used when the
     * central or observer sends scan request packets.
     *
     * Resolvable random address continues to be used for connection requests.
     */
    bool use_non_resolvable_random_address;


    /**
     * Resolution strategy of resolvable addresses received in advertising
     * packets.
     */
    enum resolution_strategy_t {
        /**
         * Do not resolve the address received in advertising packets.
         */
        DO_NOT_RESOLVE,

        /**
         * Resolve the resolvable addresses in the advertising packet and
         * forward advertising packet to the application independently of
         * the address resolution procedure result.
         */
        RESOLVE_AND_FORWARD,

        /**
         * Filter out packets containing a resolvable address that cannot be resolved
         * by this device.
         *
         * @note Filtering is applied if the local device contains at least
         * one bond.
         */
        RESOLVE_AND_FILTER
    };

    /**
     * Resolution strategy applied to advertising packets received by the
     * local device.
     */
    resolution_strategy_t resolution_strategy;
};


/**
 * @}
 * @}
 */

} // namespace ble

#endif //BLE_GAP_TYPES_H