-
Notifications
You must be signed in to change notification settings - Fork 7.6k
BLE Advertising: Redundancy betweeen AdvData and ScanResponseData #4158
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
https://github.com/espressif/arduino-esp32/blob/master/libraries/BLE/src/BLEAdvertising.h#L67 |
Hi @chegewara , thank you for pointing me to that possibility. Now, I tried disabling the scan response. It indeed avoids the crash but also has some disadvantages:
Furthermore, I have just done some more research into the advertisement topic:
Mainly because of the name truncation issue, I would keep the scan response enabled, and just avoid that some data types - specifically 'flags' and 'appearance' - appear in both, the advertisement, and the scan response. What do you think about this? |
There is few options, including changing code in library, to do this. I dont remember if its possible to use raw data, but you can for sure use advertisement data builder: |
For comparison, I have implemented three variants, all of which produce identical advertisement and scan response payload data:
From an application programmer's view I would prefer the first solution. But I also understand that changing the library might have some undesirable effects on existing programs. I think that as long as library users are aware of the problem and know which solutions there are, they can save a lot of time that it takes to analyse crashes. #include <Arduino.h>
#include <BLEDevice.h>
#include <BLEHIDDevice.h>
const char kDeviceName[] = "ESP32 Wireless Joystick";
/* Let (a modified version of) the BLE library define advertisement and scan response data. */
void setupAdvertisementA()
{
BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
pAdvertising->setAppearance(HID_GAMEPAD);
pAdvertising->start();
// Note: BLEAdvertising::start() has been modified so that there is no redundant
// data for 'Flags' and 'Appearance' in the scan response
}
/* Configure (unmodified) BLE library with custom advertisement and scan response data. */
void setupAdvertisementB()
{
BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
BLEAdvertisementData advData;
advData.setFlags(ESP_BLE_ADV_FLAG_GEN_DISC | ESP_BLE_ADV_FLAG_BREDR_NOT_SPT);
advData.setAppearance(ESP_BLE_APPEARANCE_HID_GAMEPAD);
// Note: BLEAdvertisementData has no dedicated function for 'Slave Connection Interval Range' (data type 0x12)
advData.addData(std::string({0x05, 0x12, 0x20, 0x00, 0x40, 0x00}));
pAdvertising->setAdvertisementData(advData);
BLEAdvertisementData scanResData;
scanResData.setName(kDeviceName);
// Note: BLEAdvertisementData has no dedicated function for 'Tx Power Level' (data type 0x0A)
scanResData.addData(std::string({0x02, 0x0A, 0x03}));
pAdvertising->setScanResponseData(scanResData);
pAdvertising->start();
}
/* Configure and start advertisement using the ESP-IDF library directly. */
void setupAdvertisementC()
{
esp_ble_adv_data_t advData{};
advData.min_interval = 0x20;
advData.max_interval = 0x40;
advData.appearance = ESP_BLE_APPEARANCE_HID_GAMEPAD;
advData.flag = (ESP_BLE_ADV_FLAG_GEN_DISC | ESP_BLE_ADV_FLAG_BREDR_NOT_SPT);
esp_ble_gap_config_adv_data(&advData);
esp_ble_adv_data_t scanResData{};
scanResData.set_scan_rsp = true;
scanResData.include_name = true;
scanResData.include_txpower = true;
esp_ble_gap_config_adv_data(&scanResData);
esp_ble_adv_params_t advParams{};
advParams.adv_int_min = 0x20;
advParams.adv_int_max = 0x40;
advParams.adv_type = ADV_TYPE_IND;
advParams.own_addr_type = BLE_ADDR_TYPE_PUBLIC;
advParams.channel_map = ADV_CHNL_ALL;
advParams.adv_filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY;
advParams.peer_addr_type = BLE_ADDR_TYPE_PUBLIC;
esp_ble_gap_start_advertising(&advParams);
}
|
I would like to submit a branch with changes in BLEAdvertising and a pull request. Could you tell me please, what I need to do to get write permissions? |
Nothing, just fork repo, make changes and create PR then i will eventually merge it. |
…luedroid Improved configuration of scan response data in 'BLEAdvertising' avoids the crash: - Added member variable 'm_scanRespData' to configure scan response differently from advertising data - Initialization of 'm_scanRespData' in BLEAdvertising constructor - Use of 'm_scanRespData' within BLEAdvertising::start() to configure the scan response - 'Flags' and 'Appearance' are cleared in the scan response data - With this fix, device names of up to 29 characters can be used without causing a crash.
Thanks a lot for your advice. I have followed the process that you described above. |
[STALE_SET] This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 14 days if no further activity occurs. Thank you for your contributions. |
[STALE_DEL] This stale issue has been automatically closed. Thank you for your contributions. |
…ing in Bluedroid (#4182) * Fix for issue #4158: Crash with stack trace originating in Bluedroid Improved configuration of scan response data in 'BLEAdvertising' avoids the crash: - Added member variable 'm_scanRespData' to configure scan response differently from advertising data - Initialization of 'm_scanRespData' in BLEAdvertising constructor - Use of 'm_scanRespData' within BLEAdvertising::start() to configure the scan response - 'Flags' and 'Appearance' are cleared in the scan response data - With this fix, device names of up to 29 characters can be used without causing a crash.
Hardware:
Board: M5StickC ESP32-PICO Mini IoT Development Kit
Core Installation version: v3.2.3-14-gd3e562907
IDE name: Platform.io (Espressif32 v1.12.4, Arduino)
Flash Frequency: 40 Mhz
PSRAM enabled: No
Upload Speed: 1500000 Baud
Computer OS: Windows 10
Description:
During the development of a custom BLE gamepad, I experienced crashes including a backtrace after calling BLEAdvertising::start().
A deeper analysis using the 'nRF Connect for Mobile' app revealed that
BLEAdvertising::start()
configures the advertisment data and the scan response data in such a way that the Bluetooth stack includes specific information, e.g. the appearance attribute, into both, the advertisment message and the scan response message.A crash occurs when the total payload size of the scan response message exceeds 31 bytes. The problem can be avoided by improving the configuration of the scan response data in
BLEAdvertising::start()
.I have included a more detailed description and solution outline below the debug messages.
Sketch:
Debug Messages:
Analysis of the Problem:
The scan response is configured by the following lines of code in BLEAdvertising.cpp:
m_advData.set_scan_rsp = true; m_advData.include_name = m_scanResp; m_advData.include_txpower = m_scanResp;
Therein,

m_advData
is the same struct that is used for the configuration of the advertisement data.Therefore, the attributes 'Flags (type: 0x01)' and 'Apperance (type: 0x19)' are contained in both messages. This can be seen in the following screenshot from the 'nRF Connect for Mobile' app:
Note: For taking the screenshot, I used a device name with 22 characters, so the payload of the scan response message is 31 bytes.
Solution Outline:
I suggest to configure the scan response message using a separate struct (not a copy of 'm_advData'), so that all fields are zero-initialized, and only the fields 'set_scan_rsp', 'include_name', and 'include_txpower' are set to 'true'. Thus the redundant attributes in the scan response message are eliminated, and a device name with up to 29 characters is possible without causing a crash. This can be seen in the following screenshot:

(Note: The Bluetooth LE stack includes the Tx power attribute in the scan response only if the device name has at most 26 characters.)With the proposed solution, there is no loss of information because the other attributes such as 'Appearance' are still transmitted in the advertisement message.
Please let me know if you would like me to provide my solution proposal in a source code branch.
The text was updated successfully, but these errors were encountered: