Hi Nordic team,
I'm encountering a crash when attempting to stop BLE advertising using bt_le_adv_update_data() and bt_le_adv_stop() on the nRF5340. Below are the details:
Environment:
SoC: nRF5340
SDK: nrf connect SDK v2.6.1
Role: Peripheral
Toolchain: nRF Connect SDK v2.7.0
Issue Summary:
BLE advertising starts successfully via bt_le_adv_start().
However, when I attempt to update advertising with bt_le_adv_update_data() or bt_le_adv_stop()+bt_le_adv_start(), a hard fault occurs inside bt_hci_cmd_send_sync().
Minimal Reproduction Code:
#if defined(CONFIG_BT) /* * Static variables */ static struct bt_conn *s_p_conn; static struct bt_gatt_exchange_params s_exchange_params; /* Variable that holds callback for MTU negotiation */ static uint32_t s_adv_update_timer; static uint8_t s_adv_packet_raw[ADV_PACKET_LEN]; static uint8_t s_scan_rsp_raw[SCAN_RSP_LEN]; static bool s_is_advertising = false; /* Advertise Packet */ static struct bt_data s_adv_data[] = { BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)), BT_DATA(BT_DATA_MANUFACTURER_DATA, s_adv_packet_raw, ADV_PACKET_LEN), }; static struct bt_data s_scan_rsp_data[] = { BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)), BT_DATA(BT_DATA_MANUFACTURER_DATA, s_scan_rsp_raw, SCAN_RSP_LEN) }; /* Advertise Parameters */ static struct bt_le_adv_param *s_p_adv_param = BT_LE_ADV_PARAM( BT_LE_ADV_OPT_CONNECTABLE | BT_LE_ADV_OPT_USE_IDENTITY, BLE_MIN_ADV_INTERVAL, BLE_MAX_ADV_INTERVAL, NULL); /* * @fn blep_nrf_start_adv * @brief set advertise data from saved data */ static void blep_nrf_start_adv(void){ int err = 0; uint8_t adv_format = STANDARD_ADVERTISING; DBG_PRINT_INFO("BLE advertise start\n"); blep_nrf_set_adv_packet(adv_format); blep_nrf_set_scan_rsp_packet(); s_adv_update_timer = util_timer_create(false, blep_nrf_update_adv_packet); uint32_t adv_interval = 10000;//unit ms int rc = util_timer_start(s_adv_update_timer, adv_interval); if( rc < 0 ){ DBG_PRINT_FATAL(" - !! Fail to start timer\n"); } switch(adv_format){ case STANDARD_ADVERTISING: err = bt_le_adv_start(s_p_adv_param, s_adv_data, ARRAY_SIZE(s_adv_data), NULL, 0); DBG_PRINT_INFO("STANDARD ADV start\n"); break; case EXTENDED_ADVERTISING: break; case SENSOR_BROADCAST: // break; default: // break; } if(err < 0) { blep_nrf_print_error_no(BLEP_NRF_ERR_ADV_START, err); return; } s_is_advertising = true; } /** * @fn blep_nrf_set_adv_packet * @brief set advertise data * @param advertise_format advertise format */ static void blep_nrf_set_adv_packet(uint8_t advertise_format) { uint16_t param_len; rb_param_union_t *p_saved_param; memset(s_adv_packet_raw, 0x00, sizeof(s_adv_packet_raw)); s_adv_packet_raw[COMPANY_ID_OFFSET] = BLE_COMPANY_ID_CODE & 0xFF; s_adv_packet_raw[COMPANY_ID_OFFSET + 1] = (BLE_COMPANY_ID_CODE >> 8) & 0xFF; s_adv_packet_raw[FRAME_TYPE_OFFSET] = 0x01;//frame type switch(advertise_format){ case STANDARD_ADVERTISING: s_adv_packet_raw[ST_PRODUCT_ID_OFFSET] = 0xA1; s_adv_packet_raw[ST_FW_VER_OFFSET] = 0x00; util_byteorder_put_le16(v_bat, &s_adv_packet_raw[ST_BATTEY_OFFSET]); s_adv_packet_raw[ST_UPDATE_FLAG_OFFSET] = 0x01; s_adv_packet_raw[ST_TEMPERATURE_OFFSET] = 0x01;//get temp s_adv_packet_raw[ST_DEV_STATUS_OFFSET] = 0x01;//TODO need fix specification and RAM partetion s_adv_packet_raw[ST_ERR_STATUS_OFFSET] = 0x01; break; case EXTENDED_ADVERTISING: // break; case SENSOR_BROADCAST: // break; default: // break; } } /** * @fn blep_nrf_set_scan_rsp_packet * @brief set scan response data */ static void blep_nrf_set_scan_rsp_packet(void) { memset(s_scan_rsp_raw, 0x00, sizeof(s_scan_rsp_raw)); s_scan_rsp_raw[SR_LENGTH_OFFSET] = BLE_SCAN_RSP_LEN; s_scan_rsp_raw[SR_AD_TYPE_OFFSET] = BLE_SCAN_RSP_AD_TYPE; s_scan_rsp_raw[SR_COMPANY_ID_OFFSET] = (uint8_t)(BLE_COMPANY_ID_CODE & 0xFF); s_scan_rsp_raw[SR_COMPANY_ID_OFFSET + 1] = (uint8_t)((BLE_COMPANY_ID_CODE >> 8) & 0xFF);//util_byteorder_put_le16(BLE_COMPANY_ID_CODE, &s_scan_rsp_raw[SR_COMPANY_ID_OFFSET]); } /** * @fn blep_nrf_update_adv_packet * @brief set advertisement data and scan response data at advertise setting command * or timer. * @param advertise_format advertise format */ void blep_nrf_update_adv_packet(void) { uint16_t param_len; rb_param_adv_t *p_saved_param; int err = 0; err = bt_le_adv_stop(); if(err < 0) { blep_nrf_print_error_no(BLEP_NRF_ERR_ADV_START, err); return; } uint8_t adv_format = STANDARD_ADVERTISING; DBG_PRINT_INFO("update advertise packet\n"); blep_nrf_set_adv_packet(adv_format); blep_nrf_set_scan_rsp_packet(); if(!s_is_advertising) return; switch(adv_format){ case STANDARD_ADVERTISING: //err = bt_le_adv_update_data(s_adv_data, ARRAY_SIZE(s_adv_data), NULL, 0); err = bt_le_adv_start(s_p_adv_param, s_adv_data, ARRAY_SIZE(s_adv_data), NULL, 0); DBG_PRINT_INFO("STANDARD ADV re-start\n"); break; case EXTENDED_ADVERTISING: break; case SENSOR_BROADCAST: break; default: // break; } if(err < 0) { blep_nrf_print_error_no(BLEP_NRF_ERR_ADV_START, err); return; } } /** * @fn blep_nrf_print_error_no * @brief Print error number * @param err_num Error number * @param err_code Error code from API */ static void blep_nrf_print_error_no(uint16_t err_num, int err_code) { DBG_PRINT_ERROR("[blep_nrf] 0x%04x(%d)\n", err_num, err_code); } /** * @fn blep_nrf_init * @brief BLE stack initialization */ static void blep_nrf_init(void) { bt_addr_t addr; int err; bt_conn_cb_register(&s_conn_cb); err = bt_enable(NULL); if(err < 0) { blep_nrf_print_error_no(BLEP_NRF_ERR_BT_EN, err); return; } if(blep_nrf_get_addr(&addr)) { blep_nrf_set_addr(&addr); } err = bt_set_name(BLE_DEV_NAME); if(err < 0) { blep_nrf_print_error_no(BLEP_NRF_ERR_DEV_NAME, err); return; } blep_nrf_start_adv(); } #endif
What I Have Tried:
- Verified that advertising is active (s_is_advertising = true) before calling bt_le_adv_stop()&bt_le_adv_update_data()
- Checked that no connection exists (bt_conn_lookup_state_le() returns NULL)
- Used both bt_le_adv_update_data() and bt_le_adv_stop()+bt_le_adv_start() pattern
- Ensured bt_enable() completes successfully
Questions:
Am I using bt_le_adv_update_data() or bt_le_adv_stop() incorrectly?
Any guidance or similar experience would be greatly appreciated.
Thank you in advance!