/* mbed Microcontroller Library * Copyright (c) 2006-2020 ARM Limited * * SPDX-License-Identifier: Apache-2.0 * * 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 IMPL_GAP_GAP_H #define IMPL_GAP_GAP_H #include "ble/common/CallChainOfFunctionPointersWithContext.h" #include #include "drivers/LowPowerTimeout.h" #include "drivers/LowPowerTicker.h" #include "platform/mbed_error.h" #include "ble/common/BLERoles.h" #include "ble/common/BLETypes.h" #include "ble/gap/AdvertisingDataBuilder.h" #include "ble/gap/AdvertisingDataSimpleBuilder.h" #include "ble/gap/ConnectionParameters.h" #include "ble/gap/ScanParameters.h" #include "ble/gap/AdvertisingParameters.h" #include "ble/gap/Events.h" #include "source/pal/PalGap.h" #include "source/pal/PalConnectionMonitor.h" #include "source/pal/PalEventQueue.h" #include "source/generic/PrivateAddressController.h" #include "ble/Gap.h" namespace ble { class PalGenericAccessService; class PalSecurityManager; class PalGap; class PalEventQueue; namespace impl { class BLEInstanceBase; class Gap : public ble::PalConnectionMonitor, public PalGapEventHandler #if BLE_FEATURE_PRIVACY , public PrivateAddressController::EventHandler #endif //BLE_FEATURE_PRIVACY { friend PalConnectionMonitor; friend PalGapEventHandler; friend PalGap; friend impl::BLEInstanceBase; using EventHandler = ::ble::Gap::EventHandler; using GapShutdownCallback_t = ::ble::Gap::GapShutdownCallback_t; using GapShutdownCallbackChain_t = ::ble::Gap::GapShutdownCallbackChain_t ; public: using PreferredConnectionParams_t = ::ble::Gap::PreferredConnectionParams_t ; #if BLE_FEATURE_PRIVACY #if BLE_ROLE_BROADCASTER /** * Default peripheral privacy configuration. */ static const peripheral_privacy_configuration_t default_peripheral_privacy_configuration; #endif // BLE_ROLE_BROADCASTER #if BLE_ROLE_OBSERVER /** * Default peripheral privacy configuration. */ static const central_privacy_configuration_t default_central_privacy_configuration; #endif // BLE_ROLE_OBSERVER #endif // BLE_FEATURE_PRIVACY public: void setEventHandler(EventHandler *handler); bool isFeatureSupported(controller_supported_features_t feature); /* advertising */ #if BLE_ROLE_BROADCASTER uint8_t getMaxAdvertisingSetNumber(); uint16_t getMaxAdvertisingDataLength(); uint16_t getMaxConnectableAdvertisingDataLength(); uint16_t getMaxActiveSetAdvertisingDataLength(); #if BLE_FEATURE_EXTENDED_ADVERTISING ble_error_t createAdvertisingSet( advertising_handle_t *handle, const AdvertisingParameters ¶meters ); ble_error_t destroyAdvertisingSet(advertising_handle_t handle); #endif // BLE_FEATURE_EXTENDED_ADVERTISING ble_error_t setAdvertisingParameters( advertising_handle_t handle, const AdvertisingParameters ¶ms ); ble_error_t setAdvertisingPayload( advertising_handle_t handle, mbed::Span payload ); ble_error_t setAdvertisingScanResponse( advertising_handle_t handle, mbed::Span response ); ble_error_t startAdvertising( advertising_handle_t handle, adv_duration_t maxDuration = adv_duration_t::forever(), uint8_t maxEvents = 0 ); ble_error_t stopAdvertising(advertising_handle_t handle); bool isAdvertisingActive(advertising_handle_t handle); #endif // BLE_ROLE_BROADCASTER #if BLE_ROLE_BROADCASTER #if BLE_FEATURE_PERIODIC_ADVERTISING ble_error_t setPeriodicAdvertisingParameters( advertising_handle_t handle, periodic_interval_t periodicAdvertisingIntervalMin, periodic_interval_t periodicAdvertisingIntervalMax, bool advertiseTxPower = true ); ble_error_t setPeriodicAdvertisingPayload( advertising_handle_t handle, mbed::Span payload ); ble_error_t startPeriodicAdvertising(advertising_handle_t handle); ble_error_t stopPeriodicAdvertising(advertising_handle_t handle); bool isPeriodicAdvertisingActive(advertising_handle_t handle); #endif // BLE_ROLE_BROADCASTER #endif // BLE_FEATURE_PERIODIC_ADVERTISING /* scanning */ #if BLE_ROLE_OBSERVER ble_error_t setScanParameters(const ScanParameters ¶ms); ble_error_t startScan( scan_duration_t duration = scan_duration_t::forever(), duplicates_filter_t filtering = duplicates_filter_t::DISABLE, scan_period_t period = scan_period_t(0) ); ble_error_t initiate_scan(); ble_error_t stopScan(); #endif // BLE_ROLE_OBSERVER #if BLE_ROLE_OBSERVER #if BLE_FEATURE_PERIODIC_ADVERTISING ble_error_t createSync( peer_address_type_t peerAddressType, const address_t &peerAddress, uint8_t sid, slave_latency_t maxPacketSkip, sync_timeout_t timeout ); ble_error_t createSync( slave_latency_t maxPacketSkip, sync_timeout_t timeout ); ble_error_t cancelCreateSync(); ble_error_t terminateSync(periodic_sync_handle_t handle); ble_error_t addDeviceToPeriodicAdvertiserList( peer_address_type_t peerAddressType, const address_t &peerAddress, advertising_sid_t sid ); ble_error_t removeDeviceFromPeriodicAdvertiserList( peer_address_type_t peerAddressType, const address_t &peerAddress, advertising_sid_t sid ); ble_error_t clearPeriodicAdvertiserList(); uint8_t getMaxPeriodicAdvertiserListSize(); #endif // BLE_ROLE_OBSERVER #endif // BLE_FEATURE_PERIODIC_ADVERTISING #if BLE_ROLE_CENTRAL ble_error_t connect( peer_address_type_t peerAddressType, const address_t &peerAddress, const ConnectionParameters &connectionParams ); ble_error_t cancelConnect(); #endif // BLE_ROLE_CENTRAL #if BLE_FEATURE_CONNECTABLE ble_error_t updateConnectionParameters( connection_handle_t connectionHandle, conn_interval_t minConnectionInterval, conn_interval_t maxConnectionInterval, slave_latency_t slaveLatency, supervision_timeout_t supervision_timeout, conn_event_length_t minConnectionEventLength = conn_event_length_t(0), conn_event_length_t maxConnectionEventLength = conn_event_length_t(0) ); ble_error_t manageConnectionParametersUpdateRequest( bool userManageConnectionUpdateRequest ); ble_error_t acceptConnectionParametersUpdate( connection_handle_t connectionHandle, conn_interval_t minConnectionInterval, conn_interval_t maxConnectionInterval, slave_latency_t slaveLatency, supervision_timeout_t supervision_timeout, conn_event_length_t minConnectionEventLength = conn_event_length_t(0), conn_event_length_t maxConnectionEventLength = conn_event_length_t(0) ); ble_error_t rejectConnectionParametersUpdate( connection_handle_t connectionHandle ); ble_error_t disconnect( connection_handle_t connectionHandle, local_disconnection_reason_t reason ); #endif // BLE_FEATURE_CONNECTABLE #if BLE_FEATURE_PHY_MANAGEMENT ble_error_t readPhy(connection_handle_t connection); ble_error_t setPreferredPhys( const phy_set_t *txPhys, const phy_set_t *rxPhys ); ble_error_t setPhy( connection_handle_t connection, const phy_set_t *txPhys, const phy_set_t *rxPhys, coded_symbol_per_bit_t codedSymbol ); #endif // BLE_FEATURE_PHY_MANAGEMENT #if BLE_FEATURE_PRIVACY ble_error_t enablePrivacy(bool enable); #if BLE_ROLE_BROADCASTER ble_error_t setPeripheralPrivacyConfiguration( const peripheral_privacy_configuration_t *configuration ); ble_error_t getPeripheralPrivacyConfiguration( peripheral_privacy_configuration_t *configuration ); #endif // BLE_ROLE_BROADCASTER #if BLE_ROLE_OBSERVER ble_error_t setCentralPrivacyConfiguration( const central_privacy_configuration_t *configuration ); ble_error_t getCentralPrivacyConfiguration( central_privacy_configuration_t *configuration ); #endif // BLE_ROLE_OBSERVER #endif // BLE_FEATURE_PRIVACY #if BLE_FEATURE_WHITELIST uint8_t getMaxWhitelistSize() const; ble_error_t getWhitelist(whitelist_t &whitelist) const; ble_error_t setWhitelist(const whitelist_t &whitelist); #endif // BLE_FEATURE_WHITELIST ble_error_t getAddress( own_address_type_t &typeP, address_t &address ); static ble_error_t getRandomAddressType( ble::address_t address, ble::random_address_type_t *addressType ); ble_error_t reset(); void onShutdown(const GapShutdownCallback_t &callback); GapShutdownCallbackChain_t &onShutdown(); #if !defined(DOXYGEN_ONLY) /* * API reserved for the controller driver to set the random static address. * Setting a new random static address while the controller is operating is * forbidden by the Bluetooth specification. */ ble_error_t setRandomStaticAddress(const ble::address_t &address); ble::address_t getRandomStaticAddress(); #endif // !defined(DOXYGEN_ONLY) /* ===================================================================== */ /* private implementation follows */ private: /** List in random order */ template class EventList { public: EventList() { }; ~EventList() { for (IndexType i = 0; i < _current_size; ++i) { delete _pointers[i]; } }; /** Add event to the list. List takes ownership of memory. * * @param event List will point to this event. * @return False if list full. */ bool push(EventType *event) { if (_current_size < MAX_EVENTS) { _pointers[_current_size] = event; _current_size++; return true; } return false; }; /** Take one entry of the list. Transfers ownership to caller. * * @return The event return. Memory belongs to caller. */ EventType* pop() { MBED_ASSERT(_current_size); if (!_current_size) { return nullptr; } EventType* event_returned = _pointers[_current_index]; _current_size--; if (_current_size != _current_index) { _pointers[_current_index] = _pointers[_current_size]; } else { _current_index = 0; } return event_returned; }; /** Return pointer to the first element that fulfills the passed in condition and remove the entry * that was pointing to the item. Transfers ownership to caller. * * @param compare_func The condition that is checked for all the items. * @return First element that fulfills the passed in condition or nullptr if no such item found. */ EventType* pop(mbed::Callback compare_func) { for (IndexType i = 0; i < _current_size ; ++i) { if (compare_func(*_pointers[_current_index])) { return pop(); } increment_current_index(); } return nullptr; } /** Return pointer to the first element that fulfills the passed in condition and remove the entry * that was pointing to the item. Takes and returns number of failed matches allowing to speed up search. * Transfers ownership to caller. * * @note Calls must be consecutive - any call to pop or find will invalidate the search. * * @param compare_func The condition that is checked for all the items. * @param events_not_matching Pointer to the number of items already searched but not matching. * This is updated in the method. * @return First element that fulfills the passed in condition or nullptr if no such item found. */ EventType* continue_pop(mbed::Callback compare_func, IndexType *events_not_matching) { _current_index = *events_not_matching; for (IndexType i = *events_not_matching; i < _current_size ; ++i) { if (compare_func(*_pointers[_current_index])) { return pop(); } (*events_not_matching)++; increment_current_index(); } return nullptr; } /** Return pointer to the first element that fulfills the passed in condition. Does not remove item from list. * * @param compare_func The condition that is checked for all the items. * @return First element that fulfills the passed in condition or nullptr if no such item found. */ EventType* find(mbed::Callback compare_func) { for (IndexType i = 0; i < _current_size ; ++i) { if (compare_func(*_pointers[_current_index])) { return _pointers[_current_index]; } increment_current_index(); } return nullptr; } /** Return number of events stored. * * @return Number of events stored. */ IndexType get_size() { return _current_size; } private: void increment_current_index() { _current_index++; if (_current_index == _current_size) { _current_index = 0; } } private: EventType* _pointers[MAX_EVENTS]; IndexType _current_size = 0; /* this helps us find the event faster */ IndexType _current_index = 0; }; #if BLE_FEATURE_PRIVACY && BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION class PendingAdvertisingReportEvent { public: PendingAdvertisingReportEvent( const AdvertisingReportEvent& event_to_copy ) : event(event_to_copy) { /* copy the data to the buffer */ const mbed::Span payload = event_to_copy.getPayload(); if (payload.size()) { advertising_data_buffer = new(std::nothrow) uint8_t[payload.size()]; if (advertising_data_buffer) { memcpy(advertising_data_buffer, payload.data(), payload.size()); /* set the payload to our local copy of the data */ event.setAdvertisingData(mbed::make_Span(advertising_data_buffer, payload.size())); } } }; ~PendingAdvertisingReportEvent() { delete[] advertising_data_buffer; } bool is_valid() { return advertising_data_buffer || (event.getPayload().size() == 0); } AdvertisingReportEvent& get_pending_event() { return event; } private: AdvertisingReportEvent event; uint8_t *advertising_data_buffer = nullptr; }; #endif // BLE_FEATURE_PRIVACY && BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION private: /* Disallow copy and assignment. */ Gap(const Gap &); Gap &operator=(const Gap &); Gap( ble::PalEventQueue &event_queue, ble::PalGap &pal_gap, ble::PalGenericAccessService &generic_access_service #if BLE_FEATURE_PRIVACY , ble::PrivateAddressController &private_address_controller #endif // BLE_FEATURE_PRIVACY ); ~Gap(); #if BLE_ROLE_BROADCASTER ble_error_t setAdvertisingData( advertising_handle_t handle, Span payload, bool minimiseFragmentation, bool scan_response ); void on_advertising_timeout(); void process_advertising_timeout(); #endif // BLE_ROLE_BROADCASTER void on_gap_event_received(const GapEvent &e); #if BLE_ROLE_OBSERVER void on_advertising_report(const GapAdvertisingReportEvent &e); #endif // BLE_ROLE_OBSERVER #if BLE_FEATURE_CONNECTABLE void on_connection_complete(const GapConnectionCompleteEvent &e); void on_disconnection_complete(const GapDisconnectionCompleteEvent &e); void on_connection_parameter_request( const GapRemoteConnectionParameterRequestEvent &e ); void on_connection_update(const GapConnectionUpdateEvent &e); #endif // BLE_FEATURE_CONNECTABLE void on_unexpected_error(const GapUnexpectedErrorEvent &e); enum AddressUseType_t { CENTRAL_CONNECTION, CENTRAL_SCAN, PERIPHERAL_CONNECTABLE, PERIPHERAL_NON_CONNECTABLE }; own_address_type_t get_own_address_type(AddressUseType_t address_use_type); #if BLE_FEATURE_WHITELIST bool initialize_whitelist() const; #endif // BLE_FEATURE_WHITELIST #if BLE_FEATURE_PRIVACY && !BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION ble_error_t update_ll_address_resolution_setting(); #endif // BLE_FEATURE_PRIVACY && !BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION #if BLE_ROLE_BROADCASTER #if BLE_FEATURE_EXTENDED_ADVERTISING ble_error_t setExtendedAdvertisingParameters( advertising_handle_t handle, const AdvertisingParameters ¶meters ); #endif // BLE_FEATURE_EXTENDED_ADVERTISING #endif // BLE_ROLE_BROADCASTER bool is_extended_advertising_available(); #if BLE_ROLE_BROADCASTER #if BLE_FEATURE_EXTENDED_ADVERTISING ble_error_t prepare_legacy_advertising_set(const AdvertisingParameters& parameters); #endif // BLE_FEATURE_EXTENDED_ADVERTISING #endif // BLE_ROLE_BROADCASTER #if BLE_FEATURE_CONNECTABLE /** Call the internal handlers that report to the security manager and GATT * that a connection has been established. * * @param report Connection event */ void report_internal_connection_complete(const ConnectionCompleteEvent& report); /** Pass the connection complete event to the application. This may involve privacy resolution. * * @param report Event to be passed to the user application. */ void signal_connection_complete(ConnectionCompleteEvent& report); #if BLE_FEATURE_PRIVACY /** * Apply the privacy policies when the local peripheral is connected. * @param event The connection event * @return true if the policy process has been successful and false if the * it fails meaning the process connection shouldn't continue. */ bool apply_peripheral_privacy_connection_policy( const ConnectionCompleteEvent &event ); #endif // BLE_FEATURE_PRIVACY #if BLE_FEATURE_PRIVACY && BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION /** Pass the connection complete event to the application after privacy resolution completed. * * @param event Event to be passed to the user application. * @param identity_address_type Address type of the identity address. * @param identity_address Address resolved by private address resolution, nullptr if no identity found. */ void conclude_signal_connection_complete_after_address_resolution( ConnectionCompleteEvent &event, target_peer_address_type_t identity_address_type, const address_t *identity_address ); #endif // BLE_FEATURE_PRIVACY && BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION #endif // BLE_FEATURE_CONNECTABLE #if BLE_ROLE_OBSERVER /** Pass the advertising report to the application. This may involve privacy resolution. * * @param report Report to be passed to the user application. */ void signal_advertising_report(AdvertisingReportEvent& report); #if BLE_FEATURE_PRIVACY && BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION /** Pass the advertising report to the application after privacy resolution completed. * * @param event Event to be passed to the user application. * @param identity_address_type Address type of the identity address. * @param identity_address Address resolved by private address resolution, nullptr if no identity found. */ void conclude_signal_advertising_report_after_address_resolution( AdvertisingReportEvent &event, target_peer_address_type_t identity_address_type, const address_t *identity_address ); #endif // BLE_FEATURE_PRIVACY && BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION #endif // BLE_ROLE_OBSERVER /* implements PalGap::EventHandler */ private: #if BLE_FEATURE_PHY_MANAGEMENT void on_read_phy( hci_error_code_t hci_status, connection_handle_t connection_handle, phy_t tx_phy, phy_t rx_phy ) override; #endif // BLE_FEATURE_PHY_MANAGEMENT #if BLE_FEATURE_CONNECTABLE void on_data_length_change( connection_handle_t connection_handle, uint16_t tx_size, uint16_t rx_size ) override; #endif #if BLE_FEATURE_PHY_MANAGEMENT void on_phy_update_complete( hci_error_code_t hci_status, connection_handle_t connection_handle, phy_t tx_phy, phy_t rx_phy ) override; #endif // BLE_FEATURE_PHY_MANAGEMENT #if BLE_ROLE_OBSERVER #if BLE_FEATURE_EXTENDED_ADVERTISING void on_extended_advertising_report( advertising_event_t event_type, const connection_peer_address_type_t *address_type, const ble::address_t &address, phy_t primary_phy, const phy_t *secondary_phy, advertising_sid_t advertising_sid, advertising_power_t tx_power, rssi_t rssi, uint16_t periodic_advertising_interval, direct_address_type_t direct_address_type, const ble::address_t &direct_address, uint8_t data_length, const uint8_t *data ) override; #endif // BLE_FEATURE_EXTENDED_ADVERTISING #if BLE_FEATURE_PERIODIC_ADVERTISING void on_periodic_advertising_sync_established( hci_error_code_t error, sync_handle_t sync_handle, advertising_sid_t advertising_sid, connection_peer_address_type_t advertiser_address_type, const ble::address_t &advertiser_address, phy_t advertiser_phy, uint16_t periodic_advertising_interval, clock_accuracy_t clock_accuracy ) override; void on_periodic_advertising_report( sync_handle_t sync_handle, advertising_power_t tx_power, rssi_t rssi, advertising_data_status_t data_status, uint8_t data_length, const uint8_t *data ) override; void on_periodic_advertising_sync_loss(sync_handle_t sync_handle) override; #endif // BLE_FEATURE_PERIODIC_ADVERTISING #endif // BLE_ROLE_OBSERVER #if BLE_ROLE_BROADCASTER void on_legacy_advertising_started() override; void on_legacy_advertising_stopped() override; #if BLE_FEATURE_EXTENDED_ADVERTISING void on_advertising_set_started(const mbed::Span& handles) override; void on_advertising_set_terminated( hci_error_code_t status, advertising_handle_t advertising_handle, connection_handle_t connection_handle, uint8_t number_of_completed_extended_advertising_events ) override; void on_scan_request_received( advertising_handle_t advertising_handle, connection_peer_address_type_t scanner_address_type, const ble::address_t &address ) override; #endif // BLE_FEATURE_EXTENDED_ADVERTISING #endif // BLE_ROLE_BROADCASTER #if BLE_FEATURE_CONNECTABLE void on_connection_update_complete( hci_error_code_t status, connection_handle_t connection_handle, uint16_t connection_interval, uint16_t connection_latency, uint16_t supervision_timeout ) override; void on_remote_connection_parameter( connection_handle_t connection_handle, uint16_t connection_interval_min, uint16_t connection_interval_max, uint16_t connection_latency, uint16_t supervision_timeout ) override; #endif // BLE_FEATURE_CONNECTABLE #if BLE_ROLE_OBSERVER void on_scan_started(bool success) override; void on_scan_stopped(bool success) override; void on_scan_timeout() override; void process_legacy_scan_timeout(); #endif // BLE_ROLE_OBSERVER #if BLE_FEATURE_PRIVACY /* Implement PrivateAddressController::EventHandler */ private: void on_resolvable_private_addresses_generated(const address_t &address) final; void on_non_resolvable_private_addresses_generated(const address_t &address) final; void on_private_address_generated(bool connectable); #if BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION void on_address_resolution_completed( const address_t &peer_resolvable_address, bool resolved, target_peer_address_type_t identity_address_type, const address_t &identity_address ) final; #endif // BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION #endif // BLE_FEATURE_PRIVACY private: bool is_advertising() const; bool is_radio_active() const; void update_advertising_set_connectable_attribute( advertising_handle_t handle, const AdvertisingParameters& parameters ); enum class controller_operation_t { scanning, advertising, initiating }; const address_t *get_random_address(controller_operation_t operation, size_t advertising_set = 0); #if BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION void connecting_to_host_resolved_address_failed(bool inform_user = true); #endif // BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION private: /** * Callchain containing all registered callback handlers for shutdown * events. */ GapShutdownCallbackChain_t shutdownCallChain; /** * Event handler provided by the application. */ ble::Gap::EventHandler *_event_handler; #if BLE_FEATURE_PRIVACY && BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION #if BLE_ROLE_OBSERVER EventList _reports_pending_address_resolution; #endif // BLE_ROLE_OBSERVER #if BLE_FEATURE_CONNECTABLE EventList _connections_pending_address_resolution; #endif // BLE_FEATURE_CONNECTABLE #endif // BLE_FEATURE_PRIVACY && BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION PalEventQueue &_event_queue; PalGap &_pal_gap; PalGenericAccessService &_gap_service; #if BLE_FEATURE_PRIVACY PrivateAddressController &_private_address_controller; #endif // BLE_FEATURE_PRIVACY ble::own_address_type_t _address_type; initiator_policy_t _initiator_policy_mode; scanning_filter_policy_t _scanning_filter_policy; advertising_filter_policy_t _advertising_filter_policy; mutable whitelist_t _whitelist; bool _privacy_enabled; #if BLE_FEATURE_PRIVACY bool _privacy_initialization_pending = false; #if BLE_ROLE_PERIPHERAL peripheral_privacy_configuration_t _peripheral_privacy_configuration; #endif // BLE_ROLE_PERIPHERAL #if BLE_ROLE_OBSERVER central_privacy_configuration_t _central_privacy_configuration; #endif //BLE_ROLE_OBSERVER #endif // BLE_FEATURE_PRIVACY ble::address_t _random_static_identity_address; enum class ScanState : uint8_t { idle, scan, pending_scan, pending_stop_scan }; ScanState _scan_state = ScanState::idle; scan_duration_t _scan_requested_duration = scan_duration_t::forever(); duplicates_filter_t _scan_requested_filtering = duplicates_filter_t::DISABLE; scan_period_t _scan_requested_period = scan_period_t(0); bool _scan_requested = false; #if BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION enum class ConnectionToHostResolvedAddressState : uint8_t { idle, scan, connect }; ble::address_t _connect_to_host_resolved_address; peer_address_type_t _connect_to_host_resolved_address_type = peer_address_type_t::ANONYMOUS; ConnectionToHostResolvedAddressState _connect_to_host_resolved_address_state = ConnectionToHostResolvedAddressState::idle; ConnectionParameters *_connect_to_host_resolved_address_parameters = nullptr; #endif // BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION mbed::LowPowerTimeout _advertising_timeout; mbed::LowPowerTimeout _scan_timeout; mbed::LowPowerTicker _address_rotation_ticker; bool _initiating = false; template struct BitArray { BitArray() : data() { } bool get(size_t index) const { position p(index); return (data[p.byte_index] >> p.bit_index) & 0x01; } void set(size_t index) { position p(index); data[p.byte_index] |= (0x01 << p.bit_index); } void clear(size_t index) { position p(index); data[p.byte_index] &= ~(0x01 << p.bit_index); } void clear() { for (size_t i = 0; i < (bit_size / 8 + 1); ++i) { data[i] = 0; } } private: struct position { position(size_t bit_number) : byte_index(bit_number / 8), bit_index(bit_number % 8) { } size_t byte_index; uint8_t bit_index; }; uint8_t data[bit_size / 8 + 1]; }; BitArray _existing_sets; BitArray _active_sets; BitArray _active_periodic_sets; BitArray _connectable_payload_size_exceeded; BitArray _set_is_connectable; BitArray _pending_sets; BitArray _address_refresh_sets; BitArray _interruptible_sets; BitArray _adv_started_from_refresh; bool _user_manage_connection_parameter_requests : 1; }; } // namespace impl } // namespace ble #endif //IMPL_GAP_GAP_H