OTA BLE and BLE SCAN at the same time, is it possible?

ivan.gerber
Posts: 11
Joined: Wed Apr 16, 2025 7:22 pm

OTA BLE and BLE SCAN at the same time, is it possible?

Postby ivan.gerber » Tue May 27, 2025 8:08 pm

Hello, I'm developing an esp-idf application for the ESP32-S3 module using platformio in VSCode.
I've tried the OTA BLE component succesfully, following the example from the https://github.com/espressif/esp-iot-so ... th/ble_ota repository.
It works very well, however I also want the ESP32-S3 module to be able to scan enviromental BLE advertisement to search for specifics UUID using GAP implementation.
This is the ble_scan code I'm using:

Code: Select all

#include "ble_scan.h"

#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "freertos/event_groups.h"
#include "esp_event.h"
#include "nvs_flash.h"
#include "esp_log.h"
#include "esp_nimble_hci.h"
#include "nimble/nimble_port.h"
#include "nimble/nimble_port_freertos.h"
#include "host/ble_hs.h"
#include "services/gap/ble_svc_gap.h"
#include "sdkconfig.h"

static const char *TAG = "BLE-SCAN";
uint8_t UUID_128_SEARCH[16] = {0x77, 0x77, 0x77, 0x2E, 0xAA, 0xAA, 0x6D, 0x63, 0x6E, 0x2E, 0x63, 0x6F, 0x6D, 0x00, 0x00, 0x06};
uint8_t ble_addr_type;

QueueHandle_t ble_scan_queue = NULL; // Queue to send specific uuid found events

// BLE event handling
static int ble_gap_event(struct ble_gap_event *event, void *arg)
{
    struct ble_hs_adv_fields fields;

    switch (event->type)
    {
    // NimBLE event discovery
        case BLE_GAP_EVENT_DISC:
        {
            //ESP_LOGI(TAG, "GAP EVENT DISCOVERY");
            ble_hs_adv_parse_fields(&fields, event->disc.data, event->disc.length_data);
            uint8_t search_uuid[16];
            if (event->disc.length_data < 25) return 0;
            memcpy(search_uuid, &event->disc.data[9], 16);
            bool uuid_detected = true;
            for (int i = 0; i < 16; i++)
            {
                if (search_uuid[i] != UUID_128_SEARCH[i])
                {
                    uuid_detected = false;
                    break;
                }
            }
            if (uuid_detected )
            {
                // ESP_LOGI(TAG, "UUID DETECTED MAC: %02X:%02X:%02X:%02X:%02X:%02X",
                //          event->disc.addr.val[5], event->disc.addr.val[4],
                //          event->disc.addr.val[3], event->disc.addr.val[2],
                //          event->disc.addr.val[1], event->disc.addr.val[0]);
                //Send to queue
                if (ble_scan_queue != NULL)
                {
                    uint8_t mac_device[6];
                    mac_device[0] = event->disc.addr.val[5];
                    mac_device[1] = event->disc.addr.val[4];
                    mac_device[2] = event->disc.addr.val[3];
                    mac_device[3] = event->disc.addr.val[2];
                    mac_device[4] = event->disc.addr.val[1];
                    mac_device[5] = event->disc.addr.val[0];
                    xQueueSend(ble_scan_queue, &mac_device, 0);
                }
            }
            break;
        }
        default:
        {
            break;
        }
    }
    return 0;
}

void ble_app_scan(void)
{
    ESP_LOGI(TAG, "Start scanning ...");

    struct ble_gap_disc_params disc_params;
    disc_params.filter_duplicates = 0;
    disc_params.passive = 0;
    disc_params.itvl = 0;
    disc_params.window = 0;
    disc_params.filter_policy = 0;
    disc_params.limited = 0;

    ble_gap_disc(ble_addr_type, BLE_HS_FOREVER, &disc_params, ble_gap_event, NULL);
}

// The application
void ble_app_on_sync(void)
{
    ble_hs_id_infer_auto(0, &ble_addr_type); // Determines the best address type automatically
    ble_app_scan();                          
}

// The infinite task
void host_task(void *param)
{
    nimble_port_run(); // This function will return only when nimble_port_stop() is executed
}

void ble_scan_task(void *queueOut)
{
    if (queueOut == NULL)
    {
        ESP_LOGE(TAG, "Queue is NULL");
        return;
    }
    ble_scan_queue = (QueueHandle_t)queueOut; // Set the queue for the event
    ESP_LOGI(TAG, "BLE Scan Task started");
    nvs_flash_init();                               // 1 - Initialize NVS flash using
    //esp_nimble_hci_and_controller_init();           // 2 - Initialize ESP controller
    nimble_port_init();                             // 3 - Initialize the controller stack
    ble_svc_gap_device_name_set("SSL-GPE-SCAN");    // 4 - Set device name characteristic
    ble_svc_gap_init();                             // 4 - Initialize GAP service
    ble_hs_cfg.sync_cb = ble_app_on_sync;           // 5 - Set application
    nimble_port_freertos_init(host_task);           // 6 - Set infinite task
}
Both BLE-OTA and BLE-SCAN use "NimBLE only" in the Menuconfing options.
My issue is that I can't make them to work side by side.
I'm starting to work on a workaround that stops the ble-scan part and "activates" the ble-ota implementation, but it's not a very good workaround...

Perhaps someone has an inside on making the BLE-OTA component work side by side with another BLE implementation, hope to find some guidance on this.

irahul
Espressif staff
Espressif staff
Posts: 57
Joined: Fri Jun 18, 2021 10:07 am

Re: OTA BLE and BLE SCAN at the same time, is it possible?

Postby irahul » Thu May 29, 2025 9:45 am

> My issue is that I can't make them to work side by side.

Can you elaborate on what is working or not working in more detail , so someone may have inputs .

There is a BT_NIMBLE_HOST_ALLOW_CONNECT_WITH_SCAN configuration, which allows scanning and connection happen at same time. May be you can try enabling it and check if it helps.

chegewara
Posts: 2505
Joined: Wed Jun 14, 2017 9:00 pm

Re: OTA BLE and BLE SCAN at the same time, is it possible?

Postby chegewara » Sat May 31, 2025 2:27 pm

Even if its possible it is strongly advised to not do it.
You have to remember that ble scan is occupying radio very strong, unless you setup window and interval with correct values to not.
Which means, when you do ble scan at the same time you do ble ota yor throughput will be smaller and OTA will take much longer.

ivan.gerber
Posts: 11
Joined: Wed Apr 16, 2025 7:22 pm

Re: OTA BLE and BLE SCAN at the same time, is it possible?

Postby ivan.gerber » Mon Jun 02, 2025 6:48 pm

Thank you both for your input.
I ended up having to scan for a specific UUID that works as a "here comes the OTA" message to deinitialize all the BLE-SCAN implementation. Once BLE-SCAN is stopped and everything is deinitialized, I start the BLE-OTA task.
It's a very silly solution, but it kind of works.

Who is online

Users browsing this forum: Baidu [Spider], Bing [Bot], Bytespider and 7 guests