Skip to content
This repository has been archived by the owner on Apr 18, 2024. It is now read-only.

Fix/advertise buffers #191

Merged
merged 13 commits into from
Jan 30, 2019
1,917 changes: 980 additions & 937 deletions hex/nRF5_SDK_15.2.0_connectivity.patch

Large diffs are not rendered by default.

41 changes: 30 additions & 11 deletions include/common/internal/app_ble_gap.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ extern "C" {
#define SER_MAX_CONNECTIONS 8
#endif

#ifndef APP_BLE_GAP_ADV_BUF_COUNT
#define APP_BLE_GAP_ADV_BUF_COUNT 8 // Keep in sync with connectivity in SDK
#endif

/**@brief GAP connection - keyset mapping structure.
*
* @note This structure is used to map keysets to connection instances and store them in a static
Expand Down Expand Up @@ -117,7 +121,8 @@ void app_ble_gap_unset_current_adapter_id(const app_ble_gap_adapter_codec_contex
/**@brief Check if current adapter is set
* @param[in] codec_context Check if adapter GAP state is set for codec context
*/
uint32_t app_ble_gap_check_current_adapter_set(const app_ble_gap_adapter_codec_context_t codec_context);
uint32_t
app_ble_gap_check_current_adapter_set(const app_ble_gap_adapter_codec_context_t codec_context);

/**@brief Allocates the instance in m_app_keys_table[] for storage of encryption keys.
*
Expand Down Expand Up @@ -173,6 +178,19 @@ uint32_t app_ble_gap_sec_keys_update(const uint32_t index, const ble_gap_sec_key
uint32_t app_ble_gap_state_reset();

#if NRF_SD_BLE_API_VERSION >= 6

/**
* @brief Data structure to store advertising set data
*/
typedef struct
{
uint8_t adv_handle;
uint8_t *buf1;
uint8_t *buf2;
} adv_set_data_t;

void app_ble_gap_set_adv_data_set(uint8_t adv_handle, uint8_t *buf1, uint8_t *buf2);

/**
* @brief Stores buffer for adv report data.
*
Expand Down Expand Up @@ -218,25 +236,26 @@ uint32_t app_ble_gap_adv_set_unregister(uint8_t adv_handle, uint8_t **pp_adv_dat

/**
* @brief Register an advertisement buffer pointer
*
*
* @param[in] p_buf Advertisement buffer to create a pointer ID from
* @return -1 if there is no space left in buffer table, 0 of p_buf is nullptr, >0 with buffer location in buffer table
* @return -1 if there is no space left in buffer table, 0 of p_buf is nullptr, >0 with buffer
* location in buffer table
*/

int app_ble_gap_adv_buf_register(void * p_buf);

int app_ble_gap_adv_buf_register(void *p_buf);
int app_ble_gap_adv_buf_addr_unregister(void *p_buf);
/**
* @brief Unregister a buffer from advertisement buffer table
*
*
* Unregister a buffer from the buffer table (ble_gap_adv_buf_addr)
*
*
* @param[in] id buffer ID in the ble_gap_adv_buf_addr table
* @param[in] event_context true if EVENT context, false if it is in REQUEST_REPLOY context
*
* @return Buffer pointer from advertisement buffer table, except nullptr if id == 0 or if the context for the current adapter is not set
*/
*
* @return Buffer pointer from advertisement buffer table, except nullptr if id == 0 or if the
* context for the current adapter is not set
*/
void *app_ble_gap_adv_buf_unregister(const int id, bool event_context);
void app_ble_gap_adv_buf_addr_unregister(void * p_buf, bool event_context);

void app_ble_gap_scan_data_unset(bool free);

Expand Down
92 changes: 88 additions & 4 deletions src/common/app_ble_gap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@
*/
#include "app_ble_gap.h"
#include "nrf_error.h"
#include "ser_config.h"

#include <cstring>
#include <map>
Expand Down Expand Up @@ -70,7 +69,7 @@ typedef struct
// Buffer for scan data received
ble_data_t scan_data = {nullptr, 0};
int scan_data_id{0};
void *ble_gap_adv_buf_addr[BLE_GAP_ADV_SET_COUNT_MAX]{};
void *ble_gap_adv_buf_addr[APP_BLE_GAP_ADV_BUF_COUNT]{};
#endif // NRF_SD_BLE_API_VERSION >= 6
} adapter_ble_gap_state_t;

Expand Down Expand Up @@ -345,6 +344,8 @@ uint32_t app_ble_gap_state_reset()
}

#if NRF_SD_BLE_API_VERSION >= 6
static adv_set_data_t adv_set_data[] = {BLE_GAP_ADV_SET_HANDLE_NOT_SET, nullptr, nullptr};

uint32_t app_ble_gap_scan_data_set(ble_data_t const *p_data)
{
if (!app_ble_gap_check_current_adapter_set(REQUEST_REPLY_CODEC_CONTEXT))
Expand Down Expand Up @@ -463,7 +464,9 @@ int app_ble_gap_adv_buf_register(void *p_buf)
{
if (!app_ble_gap_check_current_adapter_set(REQUEST_REPLY_CODEC_CONTEXT))
{
std::cerr << "PROGRAM LOGIC ERROR: app_ble_gap_adv_buf_register not called from context REQUEST_REPLY_CODEC_CONTEXT, terminating" << std::endl;
std::cerr << "PROGRAM LOGIC ERROR: app_ble_gap_adv_buf_register not called from context "
"REQUEST_REPLY_CODEC_CONTEXT, terminating"
<< std::endl;
std::terminate();
}

Expand All @@ -482,7 +485,7 @@ int app_ble_gap_adv_buf_register(void *p_buf)
// store this new buffer pointer.
for (auto &addr : gap_state->ble_gap_adv_buf_addr)
{
if (addr == nullptr)
if ((addr == nullptr) || (addr == p_buf))
{
addr = p_buf;
return id;
Expand All @@ -498,6 +501,46 @@ int app_ble_gap_adv_buf_register(void *p_buf)
}
}

int app_ble_gap_adv_buf_addr_unregister(void *p_buf)
{
if (!app_ble_gap_check_current_adapter_set(REQUEST_REPLY_CODEC_CONTEXT))
{
std::cerr << "PROGRAM LOGIC ERROR: app_ble_gap_adv_buf_register not called from context "
"REQUEST_REPLY_CODEC_CONTEXT, terminating"
<< std::endl;
std::terminate();
}

if (p_buf == nullptr)
{
return 0;
}

try
{
const auto gap_state = adapters_gap_state.at(current_request_reply_context.adapter_id);

auto id = 1;

// Find available location in ble_gap_adv_buf_addr for
// store this new buffer pointer.
for (auto &addr : gap_state->ble_gap_adv_buf_addr)
{
if (addr == p_buf)
{
addr = nullptr;
return id;
}
}

return -1;
}
catch (const std::out_of_range &)
{
return -1;
}
}

void *app_ble_gap_adv_buf_unregister(const int id, const bool event_context)
{
if (!app_ble_gap_check_current_adapter_set(event_context ? EVENT_CODEC_CONTEXT
Expand All @@ -521,6 +564,47 @@ void *app_ble_gap_adv_buf_unregister(const int id, const bool event_context)
return ret;
}

void app_ble_gap_set_adv_data_set(uint8_t adv_handle, uint8_t *buf1, uint8_t *buf2)
{
if (adv_handle == BLE_GAP_ADV_SET_HANDLE_NOT_SET)
{
return;
}

for (int i = 0; i < BLE_GAP_ADV_SET_COUNT_MAX; i++)
{
if (adv_set_data[i].adv_handle == adv_handle)
{
/* If adv_set is already configured replace old buffers with new one. */
if (adv_set_data[i].buf1 != buf1)
{
app_ble_gap_adv_buf_addr_unregister(adv_set_data[i].buf1);
}

if (adv_set_data[i].buf2 != buf2)
{
app_ble_gap_adv_buf_addr_unregister(adv_set_data[i].buf2);
}

adv_set_data[i].buf1 = buf1;
adv_set_data[i].buf2 = buf2;

return;
}
}

for (int i = 0; i < BLE_GAP_ADV_SET_COUNT_MAX; i++)
{
if (adv_set_data[i].adv_handle == BLE_GAP_ADV_SET_HANDLE_NOT_SET)
{
adv_set_data[i].adv_handle = adv_handle;
adv_set_data[i].buf1 = buf1;
adv_set_data[i].buf2 = buf2;
return;
}
}
}

// Update the adapter gap state scan_data_id variable based on pointer received???
void app_ble_gap_scan_data_set(const uint8_t *p_scan_data)
{
Expand Down
2 changes: 1 addition & 1 deletion src/common/ble_common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ uint32_t encode_decode(adapter_t *adapter, const encode_function_t &encode_funct

if (decode_function)
{
rx_buffer = std::make_shared<std::vector<uint8_t>>(SER_HAL_TRANSPORT_MAX_PKT_SIZE );
rx_buffer = std::make_shared<std::vector<uint8_t>>(SER_HAL_TRANSPORT_MAX_PKT_SIZE);
}

// Create tx_buffer
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -459,6 +459,7 @@ uint32_t ble_gap_evt_connected_t_enc(void const * const p_void_struct,
SER_PUSH_uint8(&p_struct->role);
SER_PUSH_FIELD(&p_struct->conn_params, ble_gap_conn_params_t_enc);
#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION > 5
SER_PUSH_uint8(&p_struct->adv_handle);
SER_PUSH_FIELD(&p_struct->adv_data, ble_gap_adv_data_t_enc);
#endif

Expand All @@ -476,6 +477,7 @@ uint32_t ble_gap_evt_connected_t_dec(uint8_t const * const p_buf,
SER_PULL_uint8(&p_struct->role);
SER_PULL_FIELD(&p_struct->conn_params, ble_gap_conn_params_t_dec);
#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION > 5
SER_PULL_uint8(&p_struct->adv_handle);
SER_PULL_FIELD(&p_struct->adv_data, ble_gap_adv_data_t_dec);
#endif

Expand Down
12 changes: 9 additions & 3 deletions src/sd_api_v6/ble_gap_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,8 @@ uint32_t sd_ble_gap_adv_set_configure(adapter_t *adapter, uint8_t *p_adv_handle,
}
else
{
mp_out_params[0] = NULL;
mp_out_params[1] = NULL;
mp_out_params[0] = nullptr;
mp_out_params[1] = nullptr;
}

return ble_gap_adv_set_configure_req_enc(p_adv_handle, p_adv_data, p_adv_params, buffer,
Expand All @@ -86,7 +86,13 @@ uint32_t sd_ble_gap_adv_set_configure(adapter_t *adapter, uint8_t *p_adv_handle,

decode_function_t decode_function = [&](uint8_t *buffer, uint32_t length,
uint32_t *result) -> uint32_t {
return ble_gap_adv_set_configure_rsp_dec(buffer, length, p_adv_handle, result);
uint32_t err = ble_gap_adv_set_configure_rsp_dec(buffer, length, p_adv_handle, result);
if (err == 0)
{
app_ble_gap_set_adv_data_set(*p_adv_handle, (uint8_t *)mp_out_params[0],
(uint8_t *)mp_out_params[1]);
}
return err;
};

uint32_t err = gap_encode_decode(adapter, encode_function, decode_function);
Expand Down
63 changes: 38 additions & 25 deletions test/softdevice_api/testcase_advertising.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,34 +74,28 @@ TEST_CASE(CREATE_TEST_NAME_AND_TAGS(
SECTION("extended")
{
const auto maxLengthOfAdvData = testutil::ADV_DATA_BUFFER_SIZE;
const auto maxNumberOfAdvertisements = 20;
const auto advertisementNameLength = 40;
const auto advertisementSetId = 5;
const auto maxNumberOfAdvertisements = 100; // Random number of advertisements
const auto advertisementNameLength = 40; // Random advertisement name length
const auto advertisementSetId = 5; // Random advertisement set id

auto scanRequestCountOtherCentral = 0;
auto scanRequestCountThisCentral = 0;

std::vector<uint8_t> peripheralAdvNameBuffer(advertisementNameLength);
testutil::appendRandomAlphaNumeric(peripheralAdvNameBuffer, advertisementNameLength);
const std::string peripheralAdvName(peripheralAdvNameBuffer.begin(),
peripheralAdvNameBuffer.end());
std::string peripheralAdvName;
std::vector<uint8_t> randomData;

// Create advertising data and scan response data
std::vector<uint8_t> advertising;
std::vector<uint8_t> scanResponse;

testutil::appendAdvertisingName(scanResponse, peripheralAdvName);
std::vector<uint8_t> advertisingData;
std::vector<uint8_t> scanResponseData;

// Append max number of bytes in advertisement packet with manufacturer specific random data
// after the peripheral name
const auto remainingSpace =
maxLengthOfAdvData - scanResponse.size() - 2 /* length and AD type */;
std::vector<uint8_t> randomData;
const auto remainingSpace = maxLengthOfAdvData -
(advertisementNameLength + 2) /* AD header size */ -
2 /* AD header size manufacturer specific data */;

testutil::appendRandomData(randomData, remainingSpace);

scanResponse.reserve(maxLengthOfAdvData);
testutil::appendManufacturerSpecificData(scanResponse, randomData, true);
testutil::createRandomAdvertisingData(scanResponseData, peripheralAdvName, randomData,
advertisementNameLength, remainingSpace);

// Instantiate an adapter to use as BLE Central in the test
auto c = std::make_shared<testutil::AdapterWrapper>(
Expand All @@ -110,8 +104,8 @@ TEST_CASE(CREATE_TEST_NAME_AND_TAGS(

// Instantiated an adapter to use as BLE Peripheral in the test
auto p = std::make_shared<testutil::AdapterWrapper>(
testutil::Peripheral, peripheral.port, env.baudRate, env.mtu, env.retransmissionInterval,
env.responseTimeout);
testutil::Peripheral, peripheral.port, env.baudRate, env.mtu,
env.retransmissionInterval, env.responseTimeout);

REQUIRE(sd_rpc_log_handler_severity_filter_set(c->unwrap(), env.driverLogLevel) ==
NRF_SUCCESS);
Expand Down Expand Up @@ -156,6 +150,25 @@ TEST_CASE(CREATE_TEST_NAME_AND_TAGS(
error = true;
return true;
}

// Change advertising data in peripheral
scanResponseData.clear();
testutil::createRandomAdvertisingData(
scanResponseData, peripheralAdvName, randomData);
NRF_LOG(c->role() << " Changing advertisement data in BLE_GAP_EVT_ADV_REPORT");

const auto err_code = p->changeAdvertisingData(
std::vector<uint8_t>(), scanResponseData);

if (err_code != NRF_SUCCESS)
{
NRF_LOG(c->role() << " Error changing advertising data "
<< testutil::asText(
gapEvent->params.adv_report.peer_addr)
<< ", " << testutil::errorToString(err_code));
error = true;
return true;
}
}
}
}
Expand Down Expand Up @@ -252,12 +265,12 @@ TEST_CASE(CREATE_TEST_NAME_AND_TAGS(
std::vector<uint8_t> manufacturerSpecificData;
const auto advReport = setTerminated.adv_data;

std::vector<uint8_t> advData;
std::vector<uint8_t> scan_rsp_data;
const auto data = advReport.scan_rsp_data.p_data;
const auto dataLength = advReport.scan_rsp_data.len;
advData.assign(data, data + dataLength);
scan_rsp_data.assign(data, data + dataLength);

if (scanResponse != advData)
if (scanResponseData != scan_rsp_data)
{
NRF_LOG(p->role() << " BLE_GAP_EVT_ADV_SET_TERMINATED: Advertisement "
"buffers set in sd_ble_gap_adv_set_configure does "
Expand Down Expand Up @@ -298,8 +311,8 @@ TEST_CASE(CREATE_TEST_NAME_AND_TAGS(
REQUIRE(c->configure() == NRF_SUCCESS);
REQUIRE(p->configure() == NRF_SUCCESS);

REQUIRE(p->setupAdvertising({}, // advertising data
scanResponse, // scan response data
REQUIRE(p->setupAdvertising(advertisingData, // advertising data
scanResponseData, // scan response data
40, // interval
0, // duration
false, // connectable
Expand Down
Loading