123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814 |
- /**
- * Copyright (c) 2015 - 2020, Nordic Semiconductor ASA
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form, except as embedded into a Nordic
- * Semiconductor ASA integrated circuit in a product or a software update for
- * such product, must reproduce the above copyright notice, this list of
- * conditions and the following disclaimer in the documentation and/or other
- * materials provided with the distribution.
- *
- * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
- * contributors may be used to endorse or promote products derived from this
- * software without specific prior written permission.
- *
- * 4. This software, with or without modification, must only be used with a
- * Nordic Semiconductor ASA integrated circuit.
- *
- * 5. Any software provided in binary form under this license must not be reverse
- * engineered, decompiled, modified and/or disassembled.
- *
- * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
- #include "sdk_common.h"
- #if NRF_MODULE_ENABLED(BLE_ADVERTISING)
- #include "ble_advdata.h"
- #include "ble_advertising.h"
- #include "nrf_soc.h"
- #include "nrf_log.h"
- #include "sdk_errors.h"
- #include "nrf_sdh_ble.h"
- #define BLE_ADV_MODES (5) /**< Total number of possible advertising modes. */
- /**@brief Function for checking if the whitelist is in use.
- *
- * @param[in] p_advertising Advertising module instance.
- */
- static bool whitelist_has_entries(ble_advertising_t * const p_advertising)
- {
- return p_advertising->whitelist_in_use;
- }
- /**@brief Function for checking if an address is valid.
- *
- * @param[in] p_addr Pointer to a bluetooth address.
- */
- static bool addr_is_valid(uint8_t const * const p_addr)
- {
- for (uint32_t i = 0; i < BLE_GAP_ADDR_LEN; i++)
- {
- if (p_addr[i] != 0)
- {
- return true;
- }
- }
- return false;
- }
- /**@brief Function for checking the next advertising mode.
- *
- * @param[in] adv_mode Current advertising mode.
- */
- static ble_adv_mode_t adv_mode_next_get(ble_adv_mode_t adv_mode)
- {
- return (ble_adv_mode_t)((adv_mode + 1) % BLE_ADV_MODES);
- }
- /**@brief Function for handling the Connected event.
- *
- * @param[in] p_ble_evt Event received from the BLE stack.
- */
- static void on_connected(ble_advertising_t * const p_advertising, ble_evt_t const * p_ble_evt)
- {
- if (p_ble_evt->evt.gap_evt.params.connected.role == BLE_GAP_ROLE_PERIPH)
- {
- p_advertising->current_slave_link_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
- }
- }
- /**@brief Function for handling the Disconnected event.
- *
- * @param[in] p_advertising Advertising module instance.
- * @param[in] p_ble_evt Event received from the BLE stack.
- */
- static void on_disconnected(ble_advertising_t * const p_advertising, ble_evt_t const * p_ble_evt)
- {
- uint32_t ret;
- p_advertising->whitelist_temporarily_disabled = false;
- if (p_ble_evt->evt.gap_evt.conn_handle == p_advertising->current_slave_link_conn_handle &&
- p_advertising->adv_modes_config.ble_adv_on_disconnect_disabled == false)
- {
- ret = ble_advertising_start(p_advertising, BLE_ADV_MODE_DIRECTED_HIGH_DUTY);
- if ((ret != NRF_SUCCESS) && (p_advertising->error_handler != NULL))
- {
- p_advertising->error_handler(ret);
- }
- }
- }
- /**@brief Function for handling the Timeout event.
- *
- * @param[in] p_advertising Advertising module instance.
- * @param[in] p_ble_evt Event received from the BLE stack.
- */
- static void on_terminated(ble_advertising_t * const p_advertising, ble_evt_t const * p_ble_evt)
- {
- ret_code_t ret;
- if (p_ble_evt->header.evt_id != BLE_GAP_EVT_ADV_SET_TERMINATED)
- {
- // Nothing to do.
- return;
- }
- if ( p_ble_evt->evt.gap_evt.params.adv_set_terminated.reason == BLE_GAP_EVT_ADV_SET_TERMINATED_REASON_TIMEOUT
- ||p_ble_evt->evt.gap_evt.params.adv_set_terminated.reason == BLE_GAP_EVT_ADV_SET_TERMINATED_REASON_LIMIT_REACHED)
- {
- // Start advertising in the next mode.
- ret = ble_advertising_start(p_advertising, adv_mode_next_get(p_advertising->adv_mode_current));
- if ((ret != NRF_SUCCESS) && (p_advertising->error_handler != NULL))
- {
- p_advertising->error_handler(ret);
- }
- }
- }
- /**@brief Get the next available advertising mode.
- *
- * @param[in] p_advertising Advertising module instance.
- * @param[in] adv_mode Requested advertising mode.
- *
- * @returns adv_mode if possible, or the best available mode if not.
- */
- static ble_adv_mode_t adv_mode_next_avail_get(ble_advertising_t * const p_advertising,
- ble_adv_mode_t adv_mode)
- {
- bool peer_addr_is_valid = addr_is_valid(p_advertising->peer_address.addr);
- // If a mode is disabled, continue to the next mode.
- switch (adv_mode)
- {
- case BLE_ADV_MODE_DIRECTED_HIGH_DUTY:
- if ( (p_advertising->adv_modes_config.ble_adv_directed_high_duty_enabled)
- && (!p_advertising->adv_modes_config.ble_adv_extended_enabled)
- && (peer_addr_is_valid))
- {
- return BLE_ADV_MODE_DIRECTED_HIGH_DUTY;
- }
- // Fallthrough.
- case BLE_ADV_MODE_DIRECTED:
- if ((p_advertising->adv_modes_config.ble_adv_directed_enabled) && peer_addr_is_valid)
- {
- return BLE_ADV_MODE_DIRECTED;
- }
- // Fallthrough.
- case BLE_ADV_MODE_FAST:
- if (p_advertising->adv_modes_config.ble_adv_fast_enabled)
- {
- return BLE_ADV_MODE_FAST;
- }
- // Fallthrough.
- case BLE_ADV_MODE_SLOW:
- if (p_advertising->adv_modes_config.ble_adv_slow_enabled)
- {
- return BLE_ADV_MODE_SLOW;
- }
- // Fallthrough.
- default:
- return BLE_ADV_MODE_IDLE;
- }
- }
- /**@brief Function for starting high duty directed advertising.
- *
- * @param[in] p_advertising Advertising instance.
- * @param[out] p_adv_params Advertising parameters.
- *
- * @return NRF_SUCCESS
- */
- static ret_code_t set_adv_mode_directed_high_duty(ble_advertising_t * const p_advertising,
- ble_gap_adv_params_t * p_adv_params)
- {
- p_advertising->adv_evt = BLE_ADV_EVT_DIRECTED_HIGH_DUTY;
- p_advertising->p_adv_data = NULL;
- p_adv_params->p_peer_addr = &(p_advertising->peer_address);
- p_adv_params->interval = 0;
- p_adv_params->properties.type = BLE_GAP_ADV_TYPE_CONNECTABLE_NONSCANNABLE_DIRECTED_HIGH_DUTY_CYCLE;
- p_adv_params->duration = BLE_GAP_ADV_TIMEOUT_HIGH_DUTY_MAX;
- return NRF_SUCCESS;
- }
- /**@brief Function for starting directed slow advertising.
- *
- * @param[in] p_advertising Advertising module instance.
- * @param[out] p_adv_params Advertising parameters.
- *
- * @return NRF_SUCCESS
- */
- static ret_code_t set_adv_mode_directed(ble_advertising_t * const p_advertising,
- ble_gap_adv_params_t * p_adv_params)
- {
- p_advertising->adv_evt = BLE_ADV_EVT_DIRECTED;
- #if !defined (S112) && !defined(S312) && !defined(S113)
- if (p_advertising->adv_modes_config.ble_adv_extended_enabled)
- {
- p_adv_params->properties.type = BLE_GAP_ADV_TYPE_EXTENDED_CONNECTABLE_NONSCANNABLE_DIRECTED;
- }
- else
- {
- #endif // !defined (S112) && !defined(S312)
- p_adv_params->properties.type = BLE_GAP_ADV_TYPE_CONNECTABLE_NONSCANNABLE_DIRECTED;
- #if !defined (S112) && !defined(S312) && !defined(S113)
- }
- #endif // !defined (S112) && !defined(S312) && !defined(S113)
- p_adv_params->duration = p_advertising->adv_modes_config.ble_adv_directed_timeout;
- p_advertising->p_adv_data = NULL;
- p_adv_params->p_peer_addr = &p_advertising->peer_address;
- p_adv_params->interval = p_advertising->adv_modes_config.ble_adv_directed_interval;
- return NRF_SUCCESS;
- }
- /**@brief Function for indicating whether to use whitelist for advertising.
- *
- * @param[in] p_advertising Advertising module instance.
- *
- * @return Whether to use whitelist.
- */
- static bool use_whitelist(ble_advertising_t * const p_advertising)
- {
- return((p_advertising->adv_modes_config.ble_adv_whitelist_enabled) &&
- (!p_advertising->whitelist_temporarily_disabled) &&
- (whitelist_has_entries(p_advertising)));
- }
- /**@brief Function for setting new advertising flags in the advertising parameters.
- *
- * @param[in] p_advertising Advertising module instance.
- * @param[in] flags New flags.
- *
- * @return Any error from @ref sd_ble_gap_adv_set_configure.
- */
- static ret_code_t flags_set(ble_advertising_t * const p_advertising, uint8_t flags)
- {
- uint8_t * p_flags = ble_advdata_parse(p_advertising->adv_data.adv_data.p_data,
- p_advertising->adv_data.adv_data.len,
- BLE_GAP_AD_TYPE_FLAGS);
- if (p_flags != NULL)
- {
- *p_flags = flags;
- }
- return sd_ble_gap_adv_set_configure(&p_advertising->adv_handle, &p_advertising->adv_data, &p_advertising->adv_params);
- }
- /**@brief Function for starting fast advertising.
- *
- * @param[in] p_advertising Advertising module instance.
- * @param[out] p_adv_params Advertising parameters.
- *
- * @return NRF_SUCCESS or an error from @ref flags_set().
- */
- static ret_code_t set_adv_mode_fast(ble_advertising_t * const p_advertising,
- ble_gap_adv_params_t * p_adv_params)
- {
- ret_code_t ret;
- p_adv_params->interval = p_advertising->adv_modes_config.ble_adv_fast_interval;
- p_adv_params->duration = p_advertising->adv_modes_config.ble_adv_fast_timeout;
- #if !defined (S112) && !defined(S312) && !defined(S113)
- if (p_advertising->adv_modes_config.ble_adv_extended_enabled)
- {
- p_advertising->adv_params.properties.type = BLE_GAP_ADV_TYPE_EXTENDED_CONNECTABLE_NONSCANNABLE_UNDIRECTED;
- }
- else
- {
- #endif // !defined (S112) && !defined(S312) && !defined(S113)
- p_advertising->adv_params.properties.type = BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED;
- #if !defined (S112) && !defined(S312) && !defined(S113)
- }
- #endif // !defined (S112) && !defined(S312) && !defined(S113)
-
- if (use_whitelist(p_advertising))
- {
- p_adv_params->filter_policy = BLE_GAP_ADV_FP_FILTER_CONNREQ;
- // Set correct flags.
- ret = flags_set(p_advertising, BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED);
- VERIFY_SUCCESS(ret);
- p_advertising->adv_evt = BLE_ADV_EVT_FAST_WHITELIST;
- }
- else
- {
- p_advertising->adv_evt = BLE_ADV_EVT_FAST;
- }
- p_advertising->p_adv_data = &(p_advertising->adv_data);
- return NRF_SUCCESS;
- }
- /**@brief Function for starting slow advertising.
- *
- * @param[in] p_advertising Advertising module instance.
- * @param[out] p_adv_params Advertising parameters.
- *
- * @return NRF_SUCCESS or an error from @ref flags_set().
- */
- static ret_code_t set_adv_mode_slow(ble_advertising_t * const p_advertising,
- ble_gap_adv_params_t * p_adv_params)
- {
- ret_code_t ret;
- p_adv_params->interval = p_advertising->adv_modes_config.ble_adv_slow_interval;
- p_adv_params->duration = p_advertising->adv_modes_config.ble_adv_slow_timeout;
- #if !defined (S112) && !defined(S312) && !defined(S113)
- if (p_advertising->adv_modes_config.ble_adv_extended_enabled)
- {
- p_advertising->adv_params.properties.type = BLE_GAP_ADV_TYPE_EXTENDED_CONNECTABLE_NONSCANNABLE_UNDIRECTED;
- }
- else
- {
- #endif // !defined (S112) && !defined(S312) && !defined(S113)
- p_advertising->adv_params.properties.type = BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED;
- #if !defined (S112) && !defined(S312) && !defined(S113)
- }
- #endif // !defined (S112) && !defined(S312) && !defined(S113)
- if (use_whitelist(p_advertising))
- {
- p_adv_params->filter_policy = BLE_GAP_ADV_FP_FILTER_CONNREQ;
- // Set correct flags.
- ret = flags_set(p_advertising, BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED);
- VERIFY_SUCCESS(ret);
- p_advertising->adv_evt = BLE_ADV_EVT_SLOW_WHITELIST;
- }
- else
- {
- p_advertising->adv_evt = BLE_ADV_EVT_SLOW;
- }
- p_advertising->p_adv_data = &(p_advertising->adv_data);
- return NRF_SUCCESS;
- }
- /**@brief Function for checking if an advertising module configuration is legal.
- *
- * @details Advertising module can not be initialized if high duty directed advertising is used
- * together with extended advertising.
- *
- * @param[in] p_config Pointer to the configuration.
- *
- * @return True If the configuration is valid.
- * @return False If the configuration is invalid.
- */
- static bool config_is_valid(ble_adv_modes_config_t const * const p_config)
- {
- if ((p_config->ble_adv_directed_high_duty_enabled == true) &&
- (p_config->ble_adv_extended_enabled == true))
- {
- return false;
- }
- #if !defined (S140)
- else if ( p_config->ble_adv_primary_phy == BLE_GAP_PHY_CODED ||
- p_config->ble_adv_secondary_phy == BLE_GAP_PHY_CODED)
- {
- return false;
- }
- #endif // !defined (S140)
- else
- {
- return true;
- }
- }
- /**@brief Function for getting the maximum size of the advertising data buffer.
- *
- * @param[in] p_advertising Advertising module instance.
- *
- * @returns The maximum size of the advertising data buffer.
- */
- static uint16_t adv_set_data_size_max_get(ble_advertising_t const * const p_advertising)
- {
- uint16_t adv_set_data_size_max;
- if (p_advertising->adv_modes_config.ble_adv_extended_enabled == true)
- {
- #ifdef BLE_GAP_ADV_SET_DATA_SIZE_EXTENDED_CONNECTABLE_MAX_SUPPORTED
- adv_set_data_size_max = BLE_GAP_ADV_SET_DATA_SIZE_EXTENDED_CONNECTABLE_MAX_SUPPORTED;
- #else
- adv_set_data_size_max = BLE_GAP_ADV_SET_DATA_SIZE_MAX;
- #endif // BLE_GAP_ADV_SET_DATA_SIZE_EXTENDED_CONNECTABLE_MAX_SUPPORTED
- }
- else
- {
- adv_set_data_size_max = BLE_GAP_ADV_SET_DATA_SIZE_MAX;
- }
- return adv_set_data_size_max;
- }
- void ble_advertising_conn_cfg_tag_set(ble_advertising_t * const p_advertising,
- uint8_t ble_cfg_tag)
- {
- p_advertising->conn_cfg_tag = ble_cfg_tag;
- }
- uint32_t ble_advertising_init(ble_advertising_t * const p_advertising,
- ble_advertising_init_t const * const p_init)
- {
- uint32_t ret;
- if ((p_init == NULL) || (p_advertising == NULL))
- {
- return NRF_ERROR_NULL;
- }
- if (!config_is_valid(&p_init->config))
- {
- return NRF_ERROR_INVALID_PARAM;
- }
- p_advertising->adv_mode_current = BLE_ADV_MODE_IDLE;
- p_advertising->adv_modes_config = p_init->config;
- p_advertising->conn_cfg_tag = BLE_CONN_CFG_TAG_DEFAULT;
- p_advertising->evt_handler = p_init->evt_handler;
- p_advertising->error_handler = p_init->error_handler;
- p_advertising->current_slave_link_conn_handle = BLE_CONN_HANDLE_INVALID;
- p_advertising->p_adv_data = &p_advertising->adv_data;
- memset(&p_advertising->peer_address, 0, sizeof(p_advertising->peer_address));
- // Copy advertising data.
- if (!p_advertising->initialized)
- {
- p_advertising->adv_handle = BLE_GAP_ADV_SET_HANDLE_NOT_SET;
- }
- p_advertising->adv_data.adv_data.p_data = p_advertising->enc_advdata[0];
- p_advertising->adv_data.adv_data.len = adv_set_data_size_max_get(p_advertising);
- ret = ble_advdata_encode(&p_init->advdata, p_advertising->enc_advdata[0], &p_advertising->adv_data.adv_data.len);
- VERIFY_SUCCESS(ret);
- p_advertising->adv_data.scan_rsp_data.p_data = p_advertising->enc_scan_rsp_data[0];
- p_advertising->adv_data.scan_rsp_data.len = adv_set_data_size_max_get(p_advertising);
- ret = ble_advdata_encode(&p_init->srdata,
- p_advertising->adv_data.scan_rsp_data.p_data,
- &p_advertising->adv_data.scan_rsp_data.len);
- VERIFY_SUCCESS(ret);
- // Configure a initial advertising configuration. The advertising data and and advertising
- // parameters will be changed later when we call @ref ble_advertising_start, but must be set
- // to legal values here to define an advertising handle.
- p_advertising->adv_params.primary_phy = BLE_GAP_PHY_1MBPS;
- p_advertising->adv_params.duration = p_advertising->adv_modes_config.ble_adv_fast_timeout;
- p_advertising->adv_params.properties.type = BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED;
- p_advertising->adv_params.p_peer_addr = NULL;
- p_advertising->adv_params.filter_policy = BLE_GAP_ADV_FP_ANY;
- p_advertising->adv_params.interval = p_advertising->adv_modes_config.ble_adv_fast_interval;
- ret = sd_ble_gap_adv_set_configure(&p_advertising->adv_handle, NULL, &p_advertising->adv_params);
- VERIFY_SUCCESS(ret);
- p_advertising->initialized = true;
- return ret;
- }
- /**@brief Function for checking that a phy define value matches one of the valid phys from the SD.
- *
- * @param[in] PHY to be validated.
- *
- * @retval true If the PHY value is valid (1mbit, 2mbit, coded).
- * @retval false If the PHY value is invalid.
- */
- static bool phy_is_valid(uint32_t const * const p_phy)
- {
- if ((*p_phy) == BLE_GAP_PHY_1MBPS ||
- (*p_phy) == BLE_GAP_PHY_2MBPS
- #if defined (S140)
- || (*p_phy) == BLE_GAP_PHY_CODED
- #endif // !defined (S140)
- )
- {
- return true;
- }
- else
- {
- return false;
- }
- }
- uint32_t ble_advertising_start(ble_advertising_t * const p_advertising,
- ble_adv_mode_t advertising_mode)
- {
- uint32_t ret;
- if (p_advertising->initialized == false)
- {
- return NRF_ERROR_INVALID_STATE;
- }
- p_advertising->adv_mode_current = advertising_mode;
- memset(&p_advertising->peer_address, 0, sizeof(p_advertising->peer_address));
- if ( ((p_advertising->adv_modes_config.ble_adv_directed_high_duty_enabled) && (p_advertising->adv_mode_current == BLE_ADV_MODE_DIRECTED_HIGH_DUTY))
- ||((p_advertising->adv_modes_config.ble_adv_directed_enabled) && (p_advertising->adv_mode_current == BLE_ADV_MODE_DIRECTED_HIGH_DUTY))
- ||((p_advertising->adv_modes_config.ble_adv_directed_enabled) && (p_advertising->adv_mode_current == BLE_ADV_MODE_DIRECTED))
- )
- {
- if (p_advertising->evt_handler != NULL)
- {
- p_advertising->peer_addr_reply_expected = true;
- p_advertising->evt_handler(BLE_ADV_EVT_PEER_ADDR_REQUEST);
- }
- else
- {
- p_advertising->peer_addr_reply_expected = false;
- }
- }
- p_advertising->adv_mode_current = adv_mode_next_avail_get(p_advertising, advertising_mode);
- // Fetch the whitelist.
- if ((p_advertising->evt_handler != NULL) &&
- (p_advertising->adv_mode_current == BLE_ADV_MODE_FAST || p_advertising->adv_mode_current == BLE_ADV_MODE_SLOW) &&
- (p_advertising->adv_modes_config.ble_adv_whitelist_enabled) &&
- (!p_advertising->whitelist_temporarily_disabled))
- {
- p_advertising->whitelist_in_use = false;
- p_advertising->whitelist_reply_expected = true;
- p_advertising->evt_handler(BLE_ADV_EVT_WHITELIST_REQUEST);
- }
- else
- {
- p_advertising->whitelist_reply_expected = false;
- }
- // Initialize advertising parameters with default values.
- memset(&p_advertising->adv_params, 0, sizeof(p_advertising->adv_params));
-
- p_advertising->adv_params.scan_req_notification = 1;
- p_advertising->adv_params.properties.type = BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED;
- // Use 1MBIT as primary phy if no phy was selected.
- if (phy_is_valid(&p_advertising->adv_modes_config.ble_adv_primary_phy))
- {
- p_advertising->adv_params.primary_phy = p_advertising->adv_modes_config.ble_adv_primary_phy;
- }
- else
- {
- p_advertising->adv_params.primary_phy = BLE_GAP_PHY_1MBPS;
- }
- if (p_advertising->adv_modes_config.ble_adv_extended_enabled)
- {
- // Use 1MBIT as secondary phy if no phy was selected.
- if (phy_is_valid(&p_advertising->adv_modes_config.ble_adv_secondary_phy))
- {
- p_advertising->adv_params.secondary_phy = p_advertising->adv_modes_config.ble_adv_secondary_phy;
- }
- else
- {
- p_advertising->adv_params.secondary_phy = BLE_GAP_PHY_1MBPS;
- }
- }
- p_advertising->adv_params.filter_policy = BLE_GAP_ADV_FP_ANY;
- // Set advertising parameters and events according to selected advertising mode.
- switch (p_advertising->adv_mode_current)
- {
- case BLE_ADV_MODE_DIRECTED_HIGH_DUTY:
- ret = set_adv_mode_directed_high_duty(p_advertising, &p_advertising->adv_params);
- break;
- case BLE_ADV_MODE_DIRECTED:
- ret = set_adv_mode_directed(p_advertising, &p_advertising->adv_params);
- break;
- case BLE_ADV_MODE_FAST:
- ret = set_adv_mode_fast(p_advertising, &p_advertising->adv_params);
- break;
- case BLE_ADV_MODE_SLOW:
- ret = set_adv_mode_slow(p_advertising, &p_advertising->adv_params);
- break;
- case BLE_ADV_MODE_IDLE:
- p_advertising->adv_evt = BLE_ADV_EVT_IDLE;
- break;
- default:
- break;
- }
- if (p_advertising->adv_mode_current != BLE_ADV_MODE_IDLE)
- {
- ret = sd_ble_gap_adv_set_configure(&p_advertising->adv_handle, p_advertising->p_adv_data, &p_advertising->adv_params);
- if (ret != NRF_SUCCESS)
- {
- return ret;
- }
- ret = sd_ble_gap_adv_start(p_advertising->adv_handle, p_advertising->conn_cfg_tag);
- if (ret != NRF_SUCCESS)
- {
- return ret;
- }
- }
- if (p_advertising->evt_handler != NULL)
- {
- p_advertising->evt_handler(p_advertising->adv_evt);
- }
- return NRF_SUCCESS;
- }
- void ble_advertising_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context)
- {
- ble_advertising_t * p_advertising = (ble_advertising_t *)p_context;
- switch (p_ble_evt->header.evt_id)
- {
- case BLE_GAP_EVT_CONNECTED:
- on_connected(p_advertising, p_ble_evt);
- break;
- // Upon disconnection, whitelist will be activated and direct advertising is started.
- case BLE_GAP_EVT_DISCONNECTED:
- on_disconnected(p_advertising, p_ble_evt);
- break;
- // Upon terminated advertising (time-out), the next advertising mode is started.
- case BLE_GAP_EVT_ADV_SET_TERMINATED:
- on_terminated(p_advertising, p_ble_evt);
- break;
- default:
- break;
- }
- }
- uint32_t ble_advertising_peer_addr_reply(ble_advertising_t * const p_advertising,
- ble_gap_addr_t * p_peer_address)
- {
- if (!p_advertising->peer_addr_reply_expected)
- {
- return NRF_ERROR_INVALID_STATE;
- }
- p_advertising->peer_addr_reply_expected = false;
- memcpy(&p_advertising->peer_address, p_peer_address, sizeof(p_advertising->peer_address));
- return NRF_SUCCESS;
- }
- uint32_t ble_advertising_whitelist_reply(ble_advertising_t * const p_advertising,
- ble_gap_addr_t const * p_gap_addrs,
- uint32_t addr_cnt,
- ble_gap_irk_t const * p_gap_irks,
- uint32_t irk_cnt)
- {
- if (!p_advertising->whitelist_reply_expected)
- {
- return NRF_ERROR_INVALID_STATE;
- }
- p_advertising->whitelist_reply_expected = false;
- p_advertising->whitelist_in_use = ((addr_cnt > 0) || (irk_cnt > 0));
- return NRF_SUCCESS;
- }
- uint32_t ble_advertising_restart_without_whitelist(ble_advertising_t * const p_advertising)
- {
- ret_code_t ret;
- (void) sd_ble_gap_adv_stop(p_advertising->adv_handle);
- p_advertising->whitelist_temporarily_disabled = true;
- p_advertising->whitelist_in_use = false;
- p_advertising->adv_params.filter_policy = BLE_GAP_ADV_FP_ANY;
- // Set correct flags.
- ret = flags_set(p_advertising, BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE);
- VERIFY_SUCCESS(ret);
- ret = ble_advertising_start(p_advertising, p_advertising->adv_mode_current);
- if ((ret != NRF_SUCCESS) && (p_advertising->error_handler != NULL))
- {
- p_advertising->error_handler(ret);
- }
- return NRF_SUCCESS;
- }
- void ble_advertising_modes_config_set(ble_advertising_t * const p_advertising,
- ble_adv_modes_config_t const * const p_adv_modes_config)
- {
- p_advertising->adv_modes_config = *p_adv_modes_config;
- }
- ret_code_t ble_advertising_advdata_update(ble_advertising_t * const p_advertising,
- ble_advdata_t const * const p_advdata,
- ble_advdata_t const * const p_srdata)
- {
- VERIFY_PARAM_NOT_NULL(p_advertising);
- if (p_advertising->initialized == false)
- {
- return NRF_ERROR_INVALID_STATE;
- }
- if ((p_advdata == NULL) && (p_srdata == NULL))
- {
- return NRF_ERROR_NULL;
- }
- ble_gap_adv_data_t new_adv_data;
- memset(&new_adv_data, 0, sizeof(new_adv_data));
- if (p_advdata != NULL)
- {
- new_adv_data.adv_data.p_data =
- (p_advertising->p_adv_data->adv_data.p_data != p_advertising->enc_advdata[0]) ?
- p_advertising->enc_advdata[0] : p_advertising->enc_advdata[1];
- new_adv_data.adv_data.len = adv_set_data_size_max_get(p_advertising);
- ret_code_t ret = ble_advdata_encode(p_advdata,
- new_adv_data.adv_data.p_data,
- &new_adv_data.adv_data.len);
- VERIFY_SUCCESS(ret);
- }
- if (p_srdata != NULL)
- {
- new_adv_data.scan_rsp_data.p_data =
- (p_advertising->p_adv_data->scan_rsp_data.p_data != p_advertising->enc_scan_rsp_data[0]) ?
- p_advertising->enc_scan_rsp_data[0] : p_advertising->enc_scan_rsp_data[1];
- new_adv_data.scan_rsp_data.len = adv_set_data_size_max_get(p_advertising);
- ret_code_t ret = ble_advdata_encode(p_srdata,
- new_adv_data.scan_rsp_data.p_data,
- &new_adv_data.scan_rsp_data.len);
- VERIFY_SUCCESS(ret);
- }
- memcpy(&p_advertising->adv_data, &new_adv_data, sizeof(p_advertising->adv_data));
- p_advertising->p_adv_data = &p_advertising->adv_data;
- return sd_ble_gap_adv_set_configure(&p_advertising->adv_handle,
- p_advertising->p_adv_data,
- NULL);
- }
- #endif // NRF_MODULE_ENABLED(BLE_ADVERTISING)
|