BLE: can't receive Scan Response

v1nc3nt
Posts: 6
Joined: Sun Oct 15, 2017 7:47 am
Location: montpellier, france

BLE: can't receive Scan Response

Postby v1nc3nt » Sun Dec 24, 2017 10:29 am

Hey all!

Anyone around the esp32 world ever managed to RX a BLE scan response in an esp32?

I advertise using bluez and can receive in another bluez host: (btmon output while running hcitool lescan)

Code: Select all

> HCI Event: LE Meta Event (0x3e) plen 28                   #8 [hci0] 24.931439
      LE Advertising Report (0x02)
        Num reports: 1
        Event type: Scan response - SCAN_RSP (0x04)
        Address type: Public (0x00)
        Address: 00:C2:C6:D1:E8:44 (OUI 00-C2-C6)
        Data length: 9
        Name (complete): 60 c6 fd 3f 0a eb 03 03 ab
        RSSI: -57 dBm (0xc7)
        
...so I know my advertiser sends a scan response...


However, when I try to RX this type of event in an esp32: no luck. I'm able to receive regular scan result events but only of type ESP_BLE_EVT_CONN_ADV.

Here is my code:

Code: Select all

#include <stdint.h>
#include <string.h>
#include <stdbool.h>
#include <stdio.h>
#include "controller.h"
#include "driver/uart.h"

#include "bt.h"
#include "nvs_flash.h"
#include "esp_bt_device.h"
#include "esp_gap_ble_api.h"
#include "esp_bt_main.h"
#include "esp_system.h"
#include "btc_main.h"


static const char *MY_TAG = "BLE_PURE";

static esp_ble_scan_params_t ble_scan_params = {
    .scan_type              = BLE_SCAN_TYPE_ACTIVE,
    .own_addr_type          = BLE_ADDR_TYPE_PUBLIC,
    .scan_filter_policy     = BLE_SCAN_FILTER_ALLOW_ALL,
    .scan_interval          = 0x50,
    .scan_window            = 0x30
};



static void esp_gap_cb(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param)
{
	esp_err_t ret;
	uint8_t *adv_data = NULL;
	
	esp_ble_gap_cb_param_t *p_data = (esp_ble_gap_cb_param_t *) param;
	ESP_LOGI(MY_TAG, "We're in the cb func to the gap module, event = %x", event); //event types: see esp_gap_ble_api.h
	
	if (event == ESP_GAP_BLE_SCAN_RESULT_EVT) {		
				esp_log_buffer_hex(MY_TAG, param->scan_rst.bda, sizeof(esp_bd_addr_t)); //bdaddr
		ESP_LOGI(MY_TAG, "SCAN_RESULT_EVT of type %x", p_data->scan_rst.ble_evt_type); //****I always get 0 ESP_BLE_EVT_CONN_ADV and should get ESP_BLE_EVT_SCAN_RSP sometimes *****
		ESP_LOGI(MY_TAG, "adv_data_len = %i", p_data->scan_rst.adv_data_len);
		adv_data = p_data->scan_rst.ble_adv;
            printf("data: ");
            for (int j = 0; j < p_data->scan_rst.adv_data_len; j++) {
                printf("%02x ", adv_data[j]);
            }
            printf("\n");
	}
	
	if (event == ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT) {
		ESP_LOGI(MY_TAG, "it's a SCAN_PARAM_SET_COMPLETE_EVT");		
		ESP_LOGI(MY_TAG, "+++++++status = %i ", p_data->scan_param_cmpl.status); //esp_bt_status_t
		
		ret = esp_ble_gap_start_scanning(200); //duration in s
	}
	

	
}

void app_main()
{
    esp_err_t ret;
    
    
    esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();

    nvs_flash_init();
    ret = esp_bt_controller_init(&bt_cfg);
    if (ret) {
        ESP_LOGE(MY_TAG, "%s enable controller failed\n", __func__);
        return;
    }

    ret = esp_bt_controller_enable(ESP_BT_MODE_BTDM); //"Now only support BTDM" (components/bt/include/bt.h) donc si tu tentes BLE ça plante
    if (ret) {
        ESP_LOGE(MY_TAG, "%s enable controller failed\n", __func__);
        return;
    }

    ESP_LOGI(MY_TAG, "%s init bluetooth", __func__);
    ret = esp_bluedroid_init();
    if (ret) {
        ESP_LOGE(MY_TAG, "%s init bluetooth failed", __func__);
        return;
    }
    
    ret = esp_bluedroid_enable();
    if (ret) {
        ESP_LOGE(MY_TAG, "%s enable bluetooth failed\n", __func__);
        return;
    }
    
    //register the scan callback function to the gap module
    if ((ret = esp_ble_gap_register_callback(esp_gap_cb)) != ESP_OK) {
        ESP_LOGE(MY_TAG, "gap register error, error code = %x", ret);
        return;
    }
    
    
    ret = esp_ble_gap_set_scan_params(&ble_scan_params);
		ESP_LOGI(MY_TAG, "******set scan param returns = %i", ret); //will generate ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT 
}
...which outputs in make monitor:

Code: Select all

...
I (186338) BLE_PURE: We're in the cb func to the gap module, event = 3
I (186338) BLE_PURE: 00 c2 c6 d1 e8 44 
I (186338) BLE_PURE: SCAN_RESULT_EVT of type 0
I (186348) BLE_PURE: adv_data_len = 14
data: 01 02 03 04 05 06 07 0e cb 05 0c 20 00 80 
...
I ALWAYS get SCAN_RESULT_EVT of type 0 but should from time to time receive a scan result of type 4 (ESP_BLE_EVT_SCAN_RSP) ...

Any ideas???


Please help me esp32 lovers!!!! (and a merry XMAS!!) :roll:

User avatar
kolban
Posts: 1683
Joined: Mon Nov 16, 2015 4:43 pm
Location: Texas, USA

Re: BLE: can't receive Scan Response

Postby kolban » Sun Dec 24, 2017 4:11 pm

I've got a half answer for you that is good news and bad news. The good news is that in my apps I am able to receive BLE Scan Responses. All is well.

For those who may come to this thread and wonder what a Scan Response is ...

Imagine a BLE server advertising. It is broadcasting packets of fixed size that contain information about the server such that a client can learn what servers are out there and what they do. In the BLE specification there is the concept of a Scan Response. What this means (and it is all optional) that when a BLE client receives an advert, it knows the address of the advertising server. It can then turn around and send a request immediately to the server to say "Hey ... tell me more". This is called a Scan Request. The server, on receipt of the packet, will send a Scan Response directly to the address of the client which contains one more additional packet of information that presumably further describes the server. This packet is called a Scan Response.

Now, back to your question....

The ESP-IDF BLE APIs are great ... but there are lots of them, they are rich in function and they require the BLE programmer to perform a lot of state management. To try and solve that, we created C++ classes that encapsulate the majority of BLE functions and hide the complexities from the consumer. This means that the ESP-IDF APIs are a further abstraction removed.

The classes can be found here:

https://github.com/nkolban/esp32-snippe ... /cpp_utils

The reason I mention this is that we have been using these for so long that we have now (by and large) hidden from ourselves the utilization of the lowest level ESP-IDF APIs. However, the answers you seek may be found by examination of the source referenced above.
Free book on ESP32 available here: https://leanpub.com/kolban-ESP32

WiFive
Posts: 3529
Joined: Tue Dec 01, 2015 7:35 am

Re: BLE: can't receive Scan Response

Postby WiFive » Sun Dec 24, 2017 9:21 pm

kolban wrote:Imagine a BLE server advertising. It is broadcasting packets of fixed size that contain information about the server such that a client can learn what servers are out there and what they do. In the BLE specification there is the concept of a Scan Response. What this means (and it is all optional) that when a BLE client receives an advert, it knows the address of the advertising server. It can then turn around and send a request immediately to the server to say "Hey ... tell me more". This is called a Scan Request. The server, on receipt of the packet, will send a Scan Response directly to the address of the client which contains one more additional packet of information that presumably further describes the server. This packet is called a Scan Response.
Terminology! https://esp32.com/viewtopic.php?f=13&t=4026#p18150

v1nc3nt
Posts: 6
Joined: Sun Oct 15, 2017 7:47 am
Location: montpellier, france

Re: BLE: can't receive Scan Response

Postby v1nc3nt » Fri Dec 29, 2017 12:39 pm

Kolban, thank you very much for your answer, which I find highly valuable!

I'm gonna dig into the c++ code in january and eventually post here as soon as I get scan responses.

cheers

Vincent

v1nc3nt
Posts: 6
Joined: Sun Oct 15, 2017 7:47 am
Location: montpellier, france

Re: BLE: can't receive Scan Response

Postby v1nc3nt » Wed Jan 03, 2018 7:25 am

... turns out the answer is simple as ****....

When you read the definition of struct ble_scan_result_evt_param in esp_gap_ble_api.h: the array ble_adv[] is defined as:

Code: Select all

uint8_t  ble_adv[ESP_BLE_ADV_DATA_LEN_MAX + ESP_BLE_SCAN_RSP_DATA_LEN_MAX];     /*!< Received EIR */

... well, why do you think ESP_BLE_SCAN_RSP_DATA_LEN_MAX is part of the size, uhh???

...yes, you got it, because the scan response falls in this array, just after the adv data...

so the problem in my code above was not reading entirely the array:

for (int j = 0; j < p_data->scan_rst.adv_data_len; j++) //limited to adv_data_len, if I add the size of the scan_rsp, I can read it...


Happy new year everyone!!! 8-)

hyunwoo
Posts: 15
Joined: Tue May 04, 2021 6:54 am

Re: BLE: can't receive Scan Response

Postby hyunwoo » Fri May 07, 2021 5:33 am

How can I check sent scan request or got scan response?
I hope to see data of scan request packet. (It will be used for whitelist)

I analyzed (actually saw) the ESP-IDF bluetooth library, but there are only event callback & set status functions.
Also find 'btu_hcif_hdl_command_complete()' function. I think that means no way to check about scan request/response in ESP. (maybe use 'esp_vhci_host_send_packet()' function to get that status from bluetooth controller. Or I didn't found task function of that yet.

Would you advice about that for me?

Who is online

Users browsing this forum: Baidu [Spider], ESP_ondrej, Majestic-12 [Bot], wemaxon and 43 guests