It seems like this should be a simple thing, but I can't find an example of it, and nothing I've read here seems to help.
I want my app to come up in general advertising mode and stay there, forever, until certain things happen. Then I want it to shut down to a reasonably low-power state (nothing running but timers) until a button is pressed, at which time it will wake up and start advertising again, and then stop again, etc.
But when I call sd_ble_gap_adv_stop()
, it returns a bad state error if it doesn't happen to be advertising at the moment (I assume that means between intervals), but if I ignore that error the program then fails with a timer memory error (trying to do an m_evt_schedule_func()
, which I assume is the next advertisement).
I guess what I really want is advertising always on, but in "IDLE" mode sometimes. But I don't see any way to do that with softdevice calls. Can sd_ble_gap_adv_start()
be called more than once with different parameters, maybe? Can I shutdown and restart the whole softdevice?
My startup code (using SDK 12.1) is:
void advertising_start()
{
ble_gap_conn_sec_mode_t sec_mode;
ble_gap_conn_params_t gap_conn_params = {
.min_conn_interval = MIN_CONN_INTERVAL,
.max_conn_interval = MAX_CONN_INTERVAL,
.slave_latency = SLAVE_LATENCY,
.conn_sup_timeout = CONN_SUP_TIMEOUT
};
ble_advdata_t adv_data = {
.name_type = BLE_ADVDATA_FULL_NAME,
.include_appearance = false,
.flags = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE
};
static ble_gap_adv_params_t adv_params = {
.type = BLE_GAP_ADV_TYPE_ADV_IND,
.p_peer_addr = NULL,
.fp = BLE_GAP_ADV_FP_ANY,
.interval = APP_ADV_INTERVAL, // 100 ms
.timeout = 0
};
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode);
APP_ERROR_CHECK(sd_ble_gap_device_name_set(&sec_mode,
(const uint8_t *)P.bt.device_name,
strlen(P.bt.device_name)));
APP_ERROR_CHECK(sd_ble_gap_ppcp_set(&gap_conn_params));
APP_ERROR_CHECK(ble_advdata_set(&adv_data, NULL));
APP_ERROR_CHECK(sd_ble_gap_adv_start(&adv_params));
}