Skip to content

Commit

Permalink
for SD>5 use static buffers for advertising and scan response data
Browse files Browse the repository at this point in the history
S140 6.1.x and up no longer makes its own copy of advertising data, provided buffers need to be valid all the time, also any change needs new set of buffers (otherwise it fails with NRF_ERROR_INVALID_STATE)
  • Loading branch information
fanoush committed May 10, 2023
1 parent 25226e5 commit a6c4118
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 36 deletions.
1 change: 1 addition & 0 deletions libs/bluetooth/bluetooth.h
Expand Up @@ -227,6 +227,7 @@ void jsble_restart_softdevice(JsVar *jsFunction);

uint32_t jsble_advertising_start();
uint32_t jsble_advertising_update_advdata(char *dPtr, unsigned int dLen);
uint32_t jsble_advertising_update_scanresponse(char *dPtr, unsigned int dLen);
void jsble_advertising_stop();

/** Is BLE connected to any device at all? */
Expand Down
20 changes: 1 addition & 19 deletions libs/bluetooth/jswrap_bluetooth.c
Expand Up @@ -1164,25 +1164,7 @@ void jswrap_ble_setScanResponse(JsVar *data) {
jsvObjectSetOrRemoveChild(execInfo.hiddenRoot, BLE_NAME_SCAN_RESPONSE_DATA, data);

#ifdef NRF5X
#if NRF_SD_BLE_API_VERSION<5
err_code = sd_ble_gap_adv_data_set(NULL, 0, (uint8_t *)respPtr, respLen);
#else
extern uint8_t m_adv_handle;
// Get existing advertising data as on SDK15 we have to be able to re-supply this
// when changing the scan response
JsVar *advData = jswrap_ble_getCurrentAdvertisingData();
JSV_GET_AS_CHAR_ARRAY(advPtr, advLen, advData);

ble_gap_adv_data_t d;
d.adv_data.p_data = (uint8_t *)advPtr;
d.adv_data.len = advLen;
d.scan_rsp_data.p_data = (uint8_t *)respPtr;
d.scan_rsp_data.len = respLen;
if (bleStatus & BLE_IS_ADVERTISING) sd_ble_gap_adv_stop(m_adv_handle);
err_code = sd_ble_gap_adv_set_configure(&m_adv_handle, &d, NULL);
if (bleStatus & BLE_IS_ADVERTISING) sd_ble_gap_adv_start(m_adv_handle, APP_BLE_CONN_CFG_TAG);
jsvUnLock(advData);
#endif
err_code=jsble_advertising_update_scanresponse((uint8_t *)respPtr, respLen);
#else
err_code = 0xDEAD;
jsiConsolePrintf("FIXME\n");
Expand Down
74 changes: 57 additions & 17 deletions targets/nrf5x/bluetooth.c
Expand Up @@ -2419,6 +2419,13 @@ void jsble_setup_advdata(ble_advdata_t *advdata) {
advdata->flags = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;
}

#if NRF_SD_BLE_API_VERSION>5
static ble_gap_adv_data_t m_ble_gap_adv_data;
// SoftDevice >= 6.1.0 needs this as static buffers
static uint8_t m_adv_data[BLE_GAP_ADV_SET_DATA_SIZE_MAX];
static uint8_t m_scan_rsp_data[BLE_GAP_ADV_SET_DATA_SIZE_MAX]; // 31
#endif

uint32_t jsble_advertising_start() {
// try not to call from IRQ as we might want to allocate JsVars
if (bleStatus & BLE_IS_ADVERTISING) return 0;
Expand Down Expand Up @@ -2524,16 +2531,18 @@ uint32_t jsble_advertising_start() {

//jsiConsolePrintf("adv_data_set %d %d\n", advPtr, advLen);
#if NRF_SD_BLE_API_VERSION>5
ble_gap_adv_data_t d;
memset(&d, 0, sizeof(d));
d.adv_data.p_data = (uint8_t*)advPtr;
d.adv_data.len = advLen;
advLen=MIN(advLen,BLE_GAP_ADV_SET_DATA_SIZE_MAX);
memset(&m_ble_gap_adv_data, 0, sizeof(m_ble_gap_adv_data));
memcpy(m_adv_data, advPtr, advLen);
m_ble_gap_adv_data.adv_data.p_data = m_adv_data;
m_ble_gap_adv_data.adv_data.len = advLen;
if (!non_scannable) {
d.scan_rsp_data.p_data = m_enc_scan_response_data;
d.scan_rsp_data.len = m_enc_scan_response_data_len;
memcpy(m_scan_rsp_data, m_enc_scan_response_data, m_enc_scan_response_data_len);
m_ble_gap_adv_data.scan_rsp_data.p_data = m_scan_rsp_data;
m_ble_gap_adv_data.scan_rsp_data.len = m_enc_scan_response_data_len;
}

err_code = sd_ble_gap_adv_set_configure(&m_adv_handle, &d, &adv_params);
err_code = sd_ble_gap_adv_set_configure(&m_adv_handle, &m_ble_gap_adv_data, &adv_params);
jsble_check_error(err_code);
if (!err_code) {
jsble_check_error(sd_ble_gap_tx_power_set(BLE_GAP_TX_POWER_ROLE_ADV, m_adv_handle, m_tx_power));
Expand All @@ -2559,21 +2568,52 @@ uint32_t jsble_advertising_start() {
return err_code;
}

uint32_t jsble_advertising_update_advdata(char *dPtr, unsigned int dLen) {
uint32_t jsble_advertising_update(char *advPtr, unsigned int advLen,char *rspPtr, unsigned int rspLen) {
#if NRF_SD_BLE_API_VERSION>5
ble_gap_adv_data_t d;
d.adv_data.p_data = (uint8_t *)dPtr;
d.adv_data.len = dLen;
d.scan_rsp_data.p_data = NULL;
d.scan_rsp_data.len = 0;

// TODO: scan_rsp_data? Does not setting this remove it?
return sd_ble_gap_adv_set_configure(&m_adv_handle, &d, NULL);
// first we need to switch away from our static live advertising data buffers
// otherwise we would get NRF_ERROR_INVALID_STATE from sd_ble_gap_adv_set_configure
ble_gap_adv_data_t tmp;
uint8_t tmp_adv_data[BLE_GAP_ADV_SET_DATA_SIZE_MAX];
uint8_t tmp_scan_rsp_data[BLE_GAP_ADV_SET_DATA_SIZE_MAX];

tmp.adv_data.len = m_ble_gap_adv_data.adv_data.len;
if (tmp.adv_data.len){
memcpy(tmp_adv_data, m_adv_data, tmp.adv_data.len);
tmp.adv_data.p_data = tmp_adv_data;
} else tmp.adv_data.p_data = NULL;

tmp.scan_rsp_data.len = m_ble_gap_adv_data.scan_rsp_data.len;
if (tmp.scan_rsp_data.len){
memcpy(tmp_scan_rsp_data, m_scan_rsp_data, tmp.scan_rsp_data.len);
tmp.scan_rsp_data.p_data = tmp_scan_rsp_data;
} else tmp.scan_rsp_data.p_data = NULL;

sd_ble_gap_adv_set_configure(&m_adv_handle, &tmp, NULL);

// now we can modify data and switch back to it
if (advLen){
advLen=MIN(advLen,BLE_GAP_ADV_SET_DATA_SIZE_MAX);
memcpy(m_adv_data,advPtr,advLen);
m_ble_gap_adv_data.adv_data.len = advLen;
}
if (rspLen){
rspLen=MIN(rspLen,BLE_GAP_ADV_SET_DATA_SIZE_MAX);
memcpy(m_scan_rsp_data, rspPtr, rspLen);
m_ble_gap_adv_data.scan_rsp_data.len = rspLen;
}
return sd_ble_gap_adv_set_configure(&m_adv_handle, &m_ble_gap_adv_data, NULL);
#else
return sd_ble_gap_adv_data_set((uint8_t *)dPtr, dLen, NULL, 0);
return sd_ble_gap_adv_data_set((uint8_t *)advPtr, advLen, (uint8_t *)rspPtr, rspLen);
#endif
}

uint32_t jsble_advertising_update_advdata(char *dPtr, unsigned int dLen) {
return jsble_advertising_update(dPtr,dLen,NULL,0);
}
uint32_t jsble_advertising_update_scanresponse(char *dPtr, unsigned int dLen) {
return jsble_advertising_update(NULL,0,dPtr,dLen);
}

void jsble_advertising_stop() {
if (!(bleStatus & BLE_IS_ADVERTISING)) return;
#if NRF_SD_BLE_API_VERSION > 5
Expand Down

0 comments on commit a6c4118

Please sign in to comment.