uint32_t ble_advertising_start(ble_adv_mode_t advertising_mode) { uint32_t err_code; ble_gap_adv_params_t adv_params; m_adv_mode_current = advertising_mode; uint32_t count = 0; // Verify if there are any pending flash operations. If so, delay starting advertising until // the flash operations are complete. err_code = pstorage_access_status_get(&count); if (err_code == NRF_ERROR_INVALID_STATE) { // Pstorage is not initialized, i.e. not in use. count = 0; } else if (err_code != NRF_SUCCESS) { return err_code; } if (count != 0) { m_advertising_start_pending = true; return NRF_SUCCESS; } // Fetch the peer address. ble_advertising_peer_address_clear(); if ( ((m_adv_modes_config.ble_adv_directed_enabled) && m_adv_mode_current == BLE_ADV_MODE_DIRECTED) ||((m_adv_modes_config.ble_adv_directed_slow_enabled) && m_adv_mode_current == BLE_ADV_MODE_DIRECTED_SLOW)) { if (m_evt_handler != NULL) { m_peer_addr_reply_expected = true; m_evt_handler(BLE_ADV_EVT_PEER_ADDR_REQUEST); } else { m_peer_addr_reply_expected = false; } } // If a mode is disabled, continue to the next mode. I.e fast instead of direct, slow instead of fast, idle instead of slow. if ( (m_adv_mode_current == BLE_ADV_MODE_DIRECTED) &&(!m_adv_modes_config.ble_adv_directed_enabled || !peer_address_exists(m_peer_address.addr))) { m_adv_mode_current = BLE_ADV_MODE_DIRECTED_SLOW; } if ( (m_adv_mode_current == BLE_ADV_MODE_DIRECTED_SLOW) &&(!m_adv_modes_config.ble_adv_directed_slow_enabled || !peer_address_exists(m_peer_address.addr))) { m_adv_mode_current = BLE_ADV_MODE_FAST; } if (!m_adv_modes_config.ble_adv_fast_enabled && m_adv_mode_current == BLE_ADV_MODE_FAST) { m_adv_mode_current = BLE_ADV_MODE_SLOW; } if (!m_adv_modes_config.ble_adv_slow_enabled && m_adv_mode_current == BLE_ADV_MODE_SLOW) { m_adv_mode_current = BLE_ADV_MODE_IDLE; m_adv_evt = BLE_ADV_EVT_IDLE; } // Fetch the whitelist. if ( (m_evt_handler != NULL) && (m_adv_mode_current == BLE_ADV_MODE_FAST || m_adv_mode_current == BLE_ADV_MODE_SLOW) && (m_adv_modes_config.ble_adv_whitelist_enabled) && (!m_whitelist_temporarily_disabled)) { m_whitelist_reply_expected = true; m_evt_handler(BLE_ADV_EVT_WHITELIST_REQUEST); } else { m_whitelist_reply_expected = false; } // Initialize advertising parameters with default values. memset(&adv_params, 0, sizeof(adv_params)); adv_params.type = BLE_GAP_ADV_TYPE_ADV_IND; adv_params.p_peer_addr = NULL; adv_params.fp = BLE_GAP_ADV_FP_ANY; adv_params.p_whitelist = NULL; // Set advertising parameters and events according to selected advertising mode. switch (m_adv_mode_current) { case BLE_ADV_MODE_DIRECTED: LOG("[ADV]: Starting direct advertisement.\r\n"); adv_params.p_peer_addr = &m_peer_address; // Directed advertising. adv_params.type = BLE_GAP_ADV_TYPE_ADV_DIRECT_IND; adv_params.timeout = 0; adv_params.interval = 0; m_adv_evt = BLE_ADV_EVT_DIRECTED; break; case BLE_ADV_MODE_DIRECTED_SLOW: LOG("[ADV]: Starting direct advertisement.\r\n"); adv_params.p_peer_addr = &m_peer_address; // Directed advertising. adv_params.type = BLE_GAP_ADV_TYPE_ADV_DIRECT_IND; adv_params.timeout = m_adv_modes_config.ble_adv_directed_slow_timeout; adv_params.interval = m_adv_modes_config.ble_adv_directed_slow_interval; m_adv_evt = BLE_ADV_EVT_DIRECTED_SLOW; break; case BLE_ADV_MODE_FAST: adv_params.timeout = m_adv_modes_config.ble_adv_fast_timeout; adv_params.interval = m_adv_modes_config.ble_adv_fast_interval; if ( whitelist_has_entries(&m_whitelist) && m_adv_modes_config.ble_adv_whitelist_enabled && !m_whitelist_temporarily_disabled) { adv_params.fp = BLE_GAP_ADV_FP_FILTER_CONNREQ; adv_params.p_whitelist = &m_whitelist; m_advdata.flags = BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED; err_code = ble_advdata_set(&m_advdata, NULL); if(err_code != NRF_SUCCESS) { return err_code; } m_adv_evt = BLE_ADV_EVT_FAST_WHITELIST; LOG("[ADV]: Starting fast advertisement with whitelist.\r\n"); } else { m_adv_evt = BLE_ADV_EVT_FAST; LOG("[ADV]: Starting fast advertisement.\r\n"); } break; case BLE_ADV_MODE_SLOW: adv_params.interval = m_adv_modes_config.ble_adv_slow_interval; adv_params.timeout = m_adv_modes_config.ble_adv_slow_timeout; if ( whitelist_has_entries(&m_whitelist) && m_adv_modes_config.ble_adv_whitelist_enabled && !m_whitelist_temporarily_disabled) { adv_params.fp = BLE_GAP_ADV_FP_FILTER_CONNREQ; adv_params.p_whitelist = &m_whitelist; m_advdata.flags = BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED; err_code = ble_advdata_set(&m_advdata, NULL); if(err_code != NRF_SUCCESS) { return err_code; } m_adv_evt = BLE_ADV_EVT_SLOW_WHITELIST; LOG("[ADV]: Starting slow advertisement with whitelist.\r\n"); } else { m_adv_evt = BLE_ADV_EVT_SLOW; LOG("[ADV]: Starting slow advertisement.\r\n"); } break; default: break; } if (m_adv_mode_current != BLE_ADV_MODE_IDLE) { err_code = sd_ble_gap_adv_start(&adv_params); if(err_code != NRF_SUCCESS) { return err_code; } } if (m_evt_handler != NULL) { m_evt_handler(m_adv_evt); } return NRF_SUCCESS; }
uint32_t ble_advertising_init(ble_advdata_t const * p_advdata, ble_advdata_t const * p_srdata, ble_adv_modes_config_t const * p_config, ble_advertising_evt_handler_t const evt_handler, ble_advertising_error_handler_t const error_handler) { uint32_t err_code; if((p_advdata == NULL) || p_config == NULL) { return NRF_ERROR_NULL; } m_adv_mode_current = BLE_ADV_MODE_IDLE; m_evt_handler = evt_handler; m_error_handler = error_handler; m_adv_modes_config = *p_config; ble_advertising_peer_address_clear(); // Prepare Whitelist. Address and IRK double pointers point to allocated arrays. m_whitelist.pp_addrs = mp_whitelist_addr; m_whitelist.pp_irks = mp_whitelist_irk; // Copy and set advertising data. memset(&m_advdata, 0, sizeof(m_advdata)); // Copy advertising data. m_advdata.name_type = p_advdata->name_type; m_advdata.include_appearance = p_advdata->include_appearance; m_advdata.flags = p_advdata->flags; m_advdata.short_name_len = p_advdata->short_name_len; /* if(p_advdata->uuids_complete != NULL) { m_advdata.uuids_complete = p_advdata->uuids_complete; } */ m_advdata.uuids_complete = p_advdata->uuids_complete; m_advdata.uuids_more_available = p_advdata->uuids_more_available; m_advdata.uuids_solicited = p_advdata->uuids_solicited; if(p_advdata->p_manuf_specific_data != NULL) { m_advdata.p_manuf_specific_data = &m_manuf_specific_data; m_manuf_specific_data.data.p_data = m_manuf_data_array; m_advdata.p_manuf_specific_data->company_identifier = p_advdata->p_manuf_specific_data->company_identifier; m_advdata.p_manuf_specific_data->data.size = p_advdata->p_manuf_specific_data->data.size; for(uint32_t i = 0; i < m_advdata.p_manuf_specific_data->data.size; i++) { m_manuf_data_array[i] = p_advdata->p_manuf_specific_data->data.p_data[i]; } } if(p_advdata->p_service_data_array != NULL) { m_service_data.data.p_data = m_service_data_array; m_advdata.p_service_data_array = &m_service_data; m_advdata.p_service_data_array->data.p_data = m_service_data_array; m_advdata.p_service_data_array->data.size = p_advdata->p_service_data_array->data.size; m_advdata.p_service_data_array->service_uuid = p_advdata->p_service_data_array->service_uuid; for(uint32_t i = 0; i < m_advdata.p_service_data_array->data.size; i++) { m_service_data_array[i] = p_advdata->p_service_data_array->data.p_data[i]; } m_advdata.service_data_count = p_advdata->service_data_count; } if(p_advdata->p_slave_conn_int != NULL) { m_advdata.p_slave_conn_int = &m_slave_conn_int; m_advdata.p_slave_conn_int->max_conn_interval = p_advdata->p_slave_conn_int->max_conn_interval; m_advdata.p_slave_conn_int->min_conn_interval = p_advdata->p_slave_conn_int->min_conn_interval; } if(p_advdata->p_tx_power_level != NULL) { m_advdata.p_tx_power_level = &m_tx_power_level; m_advdata.p_tx_power_level = p_advdata->p_tx_power_level; } err_code = ble_advdata_set(&m_advdata, p_srdata); return err_code; }
uint32_t ess_advertising_start(void) { uint32_t err_code; ble_gap_adv_params_t adv_params; // m_adv_mode_current = advertising_mode; // Verify if there are any pending flash operations. If so, delay starting advertising until // the flash operations are complete. if(flash_access_in_progress()) { m_advertising_start_pending = true; return NRF_SUCCESS; } ADV_LOG("[ADV]: no flash operations in progress, prepare advertising.\r\n"); // Fetch the peer address. ble_advertising_peer_address_clear(); // if ( ((m_adv_modes_config.ble_adv_directed_enabled) && (m_adv_mode_current == BLE_ADV_MODE_DIRECTED)) // ||((m_adv_modes_config.ble_adv_directed_slow_enabled) && (m_adv_mode_current == BLE_ADV_MODE_DIRECTED)) // ||((m_adv_modes_config.ble_adv_directed_slow_enabled) && (m_adv_mode_current == BLE_ADV_MODE_DIRECTED_SLOW)) // ) // { // if (m_evt_handler != NULL) // { // m_peer_addr_reply_expected = true; // m_evt_handler(BLE_ADV_EVT_PEER_ADDR_REQUEST); // } // else // { // m_peer_addr_reply_expected = false; // } // } // If a mode is disabled, continue to the next mode. I.e fast instead of direct, slow instead of fast, idle instead of slow. // if ( (m_adv_mode_current == BLE_ADV_MODE_DIRECTED) // &&(!m_adv_modes_config.ble_adv_directed_enabled || !peer_address_exists(m_peer_address.addr))) // { // m_adv_mode_current = BLE_ADV_MODE_DIRECTED_SLOW; // } // if ( (m_adv_mode_current == BLE_ADV_MODE_DIRECTED_SLOW) // &&(!m_adv_modes_config.ble_adv_directed_slow_enabled || !peer_address_exists(m_peer_address.addr))) // { // m_adv_mode_current = BLE_ADV_MODE_FAST; // } // if (!m_adv_modes_config.ble_adv_fast_enabled && m_adv_mode_current == BLE_ADV_MODE_FAST) // { // m_adv_mode_current = BLE_ADV_MODE_SLOW; // } // if (!m_adv_modes_config.ble_adv_slow_enabled && m_adv_mode_current == BLE_ADV_MODE_SLOW) // { // m_adv_mode_current = BLE_ADV_MODE_IDLE; // m_adv_evt = BLE_ADV_EVT_IDLE; // } // Fetch the whitelist. if ( (m_evt_handler != NULL) // && (m_adv_mode_current == BLE_ADV_MODE_FAST || m_adv_mode_current == BLE_ADV_MODE_SLOW) // && (m_adv_modes_config.ble_adv_whitelist_enabled) // && (!m_whitelist_temporarily_disabled)) ) { // m_whitelist_reply_expected = true; m_evt_handler(ESS_ADV_EVT_WHITELIST_REQUEST); } else { // m_whitelist_reply_expected = false; } // Initialize advertising parameters with default values. memset(&adv_params, 0, sizeof(adv_params)); adv_params.type = BLE_GAP_ADV_TYPE_ADV_IND; adv_params.p_peer_addr = NULL; adv_params.fp = BLE_GAP_ADV_FP_ANY; adv_params.p_whitelist = NULL; // Set advertising parameters and events according to selected advertising mode. switch (m_adv_mode_current) { case ESS_ADV_MODE_1: ADV_LOG("[ADV]: AdvMode=1"); if (whitelist_has_entries(&m_whitelist)) { ADV_LOG(" +whitelist.\r\n"); adv_params.timeout = m_adv_modes_config.ess_adv_bonded_wl_on_timeout; adv_params.interval = m_adv_modes_config.ess_adv_bonded_wl_on_interval; adv_params.fp = BLE_GAP_ADV_FP_FILTER_CONNREQ; adv_params.p_whitelist = &m_whitelist; m_advdata.flags = BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED; err_code = ble_advdata_set(&m_advdata, NULL); VERIFY_SUCCESS(err_code); } else { ADV_LOG(" -whitelist.\r\n"); adv_params.timeout = m_adv_modes_config.ess_adv_unbonded_fast_timeout; adv_params.interval = m_adv_modes_config.ess_adv_unbonded_fast_interval; adv_params.fp = BLE_GAP_ADV_FP_ANY; adv_params.p_whitelist = NULL; m_advdata.flags = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE; err_code = ble_advdata_set(&m_advdata, NULL); VERIFY_SUCCESS(err_code); } m_adv_evt = ESS_ADV_EVT_MODE_1; break; case ESS_ADV_MODE_2: ADV_LOG("[ADV]: AdvMode=2.\r\n"); if (whitelist_has_entries(&m_whitelist)) { ADV_LOG(" +whitelist.\r\n"); adv_params.timeout = m_adv_modes_config.ess_adv_bonded_wl_off_fast_timeout; adv_params.interval = m_adv_modes_config.ess_adv_bonded_wl_off_fast_interval; adv_params.fp = BLE_GAP_ADV_FP_ANY; adv_params.p_whitelist = NULL; // m_advdata.flags = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE; err_code = ble_advdata_set(&m_advdata, NULL); VERIFY_SUCCESS(err_code); } else { ADV_LOG(" -whitelist.\r\n"); adv_params.timeout = m_adv_modes_config.ess_adv_unbonded_slow_timeout; adv_params.interval = m_adv_modes_config.ess_adv_unbonded_slow_interval; adv_params.fp = BLE_GAP_ADV_FP_ANY; adv_params.p_whitelist = NULL; m_advdata.flags = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE; err_code = ble_advdata_set(&m_advdata, NULL); VERIFY_SUCCESS(err_code); } m_adv_evt = ESS_ADV_EVT_MODE_2; break; case ESS_ADV_MODE_3: ADV_LOG("[ADV]: AdvMode=3.\r\n"); if (whitelist_has_entries(&m_whitelist)) { ADV_LOG(" +whitelist.\r\n"); adv_params.timeout = m_adv_modes_config.ess_adv_bonded_wl_off_slow_timeout; adv_params.interval = m_adv_modes_config.ess_adv_bonded_wl_off_slow_interval; adv_params.fp = BLE_GAP_ADV_FP_ANY; adv_params.p_whitelist = NULL; m_advdata.flags = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE; err_code = ble_advdata_set(&m_advdata, NULL); VERIFY_SUCCESS(err_code); m_adv_evt = ESS_ADV_EVT_MODE_3; } else { ADV_LOG(" -whitelist.\r\n"); m_adv_mode_current = ESS_ADV_MODE_IDLE; m_adv_evt = ESS_ADV_EVT_IDLE; } break; case ESS_ADV_MODE_IDLE: ADV_LOG("[ADV]: AdvMode=0.\r\n"); break; } // if (whitelist_has_entries(&m_whitelist)) { // ADV_LOG("[ADV]: Use whitelist.\r\n"); // if (m_adv_mode_current == ESS_ADV_MODE_UNBONDED_FAST) { // m_adv_mode_current = ESS_ADV_MODE_BONDED_WL_ON; // } // switch (m_adv_mode_current) { // case ESS_ADV_MODE_BONDED_WL_ON: // adv_params.timeout = m_adv_modes_config.ess_adv_bonded_wl_on_timeout; // adv_params.interval = m_adv_modes_config.ess_adv_bonded_wl_on_interval; // m_adv_evt = ESS_ADV_EVT_BONDED_WL_ON; // ADV_LOG("[ADV]: Starting bonded advertisement with whitelist.\r\n"); // break; // case ESS_ADV_MODE_BONDED_WL_OFF_FAST: // adv_params.timeout = m_adv_modes_config.ess_adv_bonded_wl_off_fast_timeout; // adv_params.interval = m_adv_modes_config.ess_adv_bonded_wl_off_fast_interval; // m_adv_evt = ESS_ADV_EVT_BONDED_WL_OFF_FAST; // ADV_LOG("[ADV]: Starting bonded fast advertisement without whitelist.\r\n"); // break; // case ESS_ADV_MODE_BONDED_WL_OFF_SLOW: // adv_params.timeout = m_adv_modes_config.ess_adv_bonded_wl_off_slow_timeout; // adv_params.interval = m_adv_modes_config.ess_adv_bonded_wl_off_slow_interval; // m_adv_evt = ESS_ADV_EVT_BONDED_WL_OFF_SLOW; // ADV_LOG("[ADV]: Starting bonded slow advertisement without whitelist.\r\n"); // break; // default: // break; // } // } else { // ADV_LOG("[ADV]: Do not use whitelist.\r\n"); // switch (m_adv_mode_current) { // case ESS_ADV_MODE_UNBONDED_FAST: // adv_params.timeout = m_adv_modes_config.ess_adv_unbonded_fast_timeout; // adv_params.interval = m_adv_modes_config.ess_adv_unbonded_fast_interval; // m_adv_evt = ESS_ADV_EVT_UNBONDED_FAST; // ADV_LOG("[ADV]: Starting unbonded fast advertisement.\r\n"); // break; // case ESS_ADV_MODE_UNBONDED_SLOW: // adv_params.timeout = m_adv_modes_config.ess_adv_unbonded_slow_timeout; // adv_params.interval = m_adv_modes_config.ess_adv_unbonded_slow_interval; // m_adv_evt = ESS_ADV_EVT_UNBONDED_SLOW; // ADV_LOG("[ADV]: Starting unbonded slow advertisement.\r\n"); // break; // default: // break; // } // } // switch (m_adv_mode_current) // { //// case BLE_ADV_MODE_DIRECTED: //// ADV_LOG("[ADV]: Starting direct advertisement.\r\n"); //// adv_params.p_peer_addr = &m_peer_address; // Directed advertising. //// adv_params.type = BLE_GAP_ADV_TYPE_ADV_DIRECT_IND; //// adv_params.timeout = 0; //// adv_params.interval = 0; //// m_adv_evt = BLE_ADV_EVT_DIRECTED; //// break; //// case BLE_ADV_MODE_DIRECTED_SLOW: //// ADV_LOG("[ADV]: Starting direct advertisement.\r\n"); //// adv_params.p_peer_addr = &m_peer_address; // Directed advertising. //// adv_params.type = BLE_GAP_ADV_TYPE_ADV_DIRECT_IND; //// adv_params.timeout = m_adv_modes_config.ble_adv_directed_slow_timeout; //// adv_params.interval = m_adv_modes_config.ble_adv_directed_slow_interval; //// m_adv_evt = BLE_ADV_EVT_DIRECTED_SLOW; //// break; //// case BLE_ADV_MODE_FAST: //// adv_params.timeout = m_adv_modes_config.ble_adv_fast_timeout; //// adv_params.interval = m_adv_modes_config.ble_adv_fast_interval; //// if ( whitelist_has_entries(&m_whitelist) //// && m_adv_modes_config.ble_adv_whitelist_enabled //// && !m_whitelist_temporarily_disabled) //// { //// adv_params.fp = BLE_GAP_ADV_FP_FILTER_CONNREQ; //// adv_params.p_whitelist = &m_whitelist; //// m_advdata.flags = BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED; //// err_code = ble_advdata_set(&m_advdata, NULL); //// VERIFY_SUCCESS(err_code); //// m_adv_evt = BLE_ADV_EVT_FAST_WHITELIST; //// ADV_LOG("[ADV]: Starting fast advertisement with whitelist.\r\n"); //// } //// else //// { //// m_adv_evt = BLE_ADV_EVT_FAST; //// ADV_LOG("[ADV]: Starting fast advertisement.\r\n"); //// } //// break; //// case BLE_ADV_MODE_SLOW: //// adv_params.interval = m_adv_modes_config.ble_adv_slow_interval; //// adv_params.timeout = m_adv_modes_config.ble_adv_slow_timeout; //// if ( whitelist_has_entries(&m_whitelist) //// && m_adv_modes_config.ble_adv_whitelist_enabled //// && !m_whitelist_temporarily_disabled) //// { //// adv_params.fp = BLE_GAP_ADV_FP_FILTER_CONNREQ; //// adv_params.p_whitelist = &m_whitelist; //// m_advdata.flags = BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED; //// err_code = ble_advdata_set(&m_advdata, NULL); //// VERIFY_SUCCESS(err_code); //// m_adv_evt = BLE_ADV_EVT_SLOW_WHITELIST; //// ADV_LOG("[ADV]: Starting slow advertisement with whitelist.\r\n"); //// } //// else //// { //// m_adv_evt = BLE_ADV_EVT_SLOW; //// ADV_LOG("[ADV]: Starting slow advertisement.\r\n"); //// } //// break; // case ESS_ADV_MODE_UNBONDED_FAST: // adv_params.timeout = m_adv_modes_config.ess_adv_unbonded_fast_timeout; // adv_params.interval = m_adv_modes_config.ess_adv_unbonded_fast_interval; //// if ( whitelist_has_entries(&m_whitelist) //// && m_adv_modes_config.ble_adv_whitelist_enabled //// && !m_whitelist_temporarily_disabled) //// { //// adv_params.fp = BLE_GAP_ADV_FP_FILTER_CONNREQ; //// adv_params.p_whitelist = &m_whitelist; //// m_advdata.flags = BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED; //// err_code = ble_advdata_set(&m_advdata, NULL); //// VERIFY_SUCCESS(err_code); //// m_adv_evt = BLE_ADV_EVT_FAST_WHITELIST; //// ADV_LOG("[ADV]: Starting fast advertisement with whitelist.\r\n"); //// } //// else //// { // m_adv_evt = BLE_ADV_EVT_FAST; // ADV_LOG("[ADV]: Starting fast advertisement.\r\n"); //// } //// break; // default: // break; // } if (m_adv_mode_current != ESS_ADV_MODE_IDLE) { ADV_LOG_PRINTF("[ADV]: Interval: %d\r\n", adv_params.interval); ADV_LOG_PRINTF("[ADV]: Timeout: %d\r\n", adv_params.timeout); err_code = sd_ble_gap_adv_start(&adv_params); VERIFY_SUCCESS(err_code); } if (m_evt_handler != NULL) { m_evt_handler(m_adv_evt); } return NRF_SUCCESS; }