Classic bluetooth discovery

sharky
Posts: 1
Joined: Mon Mar 05, 2018 2:47 pm

Classic bluetooth discovery

Postby sharky » Mon Mar 05, 2018 9:16 pm

Hello there,

I am currently trying to create a bluetooth discovery that sends all the found devices (SSID and RSSI) via MQTT to my local MQTT broker.
So for the first step I took the example code and removed most code I though I would not need so that I got a simple Bluetooth-Scanner.
The problem I am currently facing is, that I find other devices that are in discovery mode but as soon as a device is not discoverable anymore (iPhone for example after turning off the screen) the device is also no more visible in my scanner.

Does someone have an idea how I would be able to also find devices that are not directly discoverable?

Here the code I am currently using:

Code: Select all

/*
   This example code is in the Public Domain (or CC0 licensed, at your option.)

   Unless required by applicable law or agreed to in writing, this
   software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
   CONDITIONS OF ANY KIND, either express or implied.
*/



/****************************************************************************
*
* This file is for Classic Bluetooth device and service discovery Demo.
*
****************************************************************************/

#include <stdint.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "nvs.h"
#include "nvs_flash.h"
#include "esp_system.h"
#include "esp_log.h"
#include "esp_bt.h"
#include "esp_bt_main.h"
#include "esp_bt_device.h"
#include "esp_gap_bt_api.h"

#define GAP_TAG          "GAP"

char btSsid[10000];

typedef enum {
    APP_GAP_STATE_IDLE = 0,
    APP_GAP_STATE_DEVICE_DISCOVERING,
    APP_GAP_STATE_DEVICE_DISCOVER_COMPLETE,
    APP_GAP_STATE_SERVICE_DISCOVERING,
    APP_GAP_STATE_SERVICE_DISCOVER_COMPLETE,
} app_gap_state_t;

typedef struct {
    bool dev_found;
    uint8_t bdname_len;
    uint8_t eir_len;
    uint8_t rssi;
    uint32_t cod;
    uint8_t eir[ESP_BT_GAP_EIR_DATA_LEN];
    uint8_t bdname[ESP_BT_GAP_MAX_BDNAME_LEN + 1];
    esp_bd_addr_t bda;
    app_gap_state_t state;
} app_gap_cb_t;

static app_gap_cb_t m_dev_info;
int isStarted = 0;

static char *bda2str(esp_bd_addr_t bda, char *str, size_t size)
{
    if (bda == NULL || str == NULL || size < 18) {
        return NULL;
    }

    uint8_t *p = bda;
    sprintf(str, "%02x:%02x:%02x:%02x:%02x:%02x",
            p[0], p[1], p[2], p[3], p[4], p[5]);
    return str;
}

static void update_device_info(esp_bt_gap_cb_param_t *param)
{
    char bda_str[18];
    uint32_t cod = 0;
    int32_t rssi = -129; /* invalid value */
    esp_bt_gap_dev_prop_t *p;

    //ESP_LOGI(GAP_TAG, "Device found: %s", bda2str(param->disc_res.bda, bda_str, 18));
    bda2str(param->disc_res.bda, bda_str, 18);
    for (int i = 0; i < param->disc_res.num_prop; i++) {
        p = param->disc_res.prop + i;
        switch (p->type) {
        case ESP_BT_GAP_DEV_PROP_COD:
            cod = *(uint32_t *)(p->val);
            //ESP_LOGI(GAP_TAG, "--Class of Device: 0x%x", cod);
            break;
        case ESP_BT_GAP_DEV_PROP_RSSI:
            rssi = *(int8_t *)(p->val);
            //ESP_LOGI(GAP_TAG, "--RSSI: %d", rssi);
            break;
        case ESP_BT_GAP_DEV_PROP_BDNAME:
        default:
            break;
        }
    }

    //Add the information to the char array

    char *s;

    // this will just output the length which is to expect
    int length = snprintf( NULL, 0, "%d", rssi );

    char* rssiValueAsString = malloc( length + 1 );// one more for 0-terminator
    snprintf( rssiValueAsString, length + 1, "%d", rssi );

    s = strstr(btSsid, bda_str);      // search for string "hassasin" in buff
    if (s == NULL)                     // if successful then s now points at "hassasin"
    {
        strcat(btSsid, bda_str);
        strcat(btSsid, ":");
        strcat(btSsid, rssiValueAsString);
        strcat(btSsid, ";");
    }
}

void bt_app_gap_init(void)
{
    app_gap_cb_t *p_dev = &m_dev_info;
    memset(p_dev, 0, sizeof(app_gap_cb_t));
}

void bt_app_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *param)
{
    app_gap_cb_t *p_dev = &m_dev_info;

    switch (event) {
    case ESP_BT_GAP_DISC_RES_EVT: {
        update_device_info(param);
        break;
    }
    case ESP_BT_GAP_DISC_STATE_CHANGED_EVT: {
        if (param->disc_st_chg.state == ESP_BT_GAP_DISCOVERY_STOPPED && isStarted == 1) {
            ESP_LOGI(GAP_TAG, "Devices found: %s", btSsid);
            ESP_LOGI(GAP_TAG, "Device discovery stopped.");

            //Release memory
            esp_bt_gap_cancel_discovery();
            esp_bt_controller_mem_release(ESP_BT_MODE_BTDM);

            //Clear the char array
            memset(btSsid, 0, sizeof(btSsid));

            /* Start another discovery */
            esp_bt_gap_start_discovery(ESP_BT_INQ_MODE_GENERAL_INQUIRY, 1, 0);
            isStarted = 0;
        } else if (param->disc_st_chg.state == ESP_BT_GAP_DISCOVERY_STARTED) {
            ESP_LOGI(GAP_TAG, "Discovery started.");
            isStarted = 1;
        }
        break;
    }
    case ESP_BT_GAP_RMT_SRVC_REC_EVT:
    default: {
        ESP_LOGI(GAP_TAG, "event: %d", event);
        break;
    }
    }
    return;
}

void bt_app_gap_start_up(void)
{
    /* register GAP callback function */
    esp_bt_gap_register_callback(bt_app_gap_cb);

    /* inititialize device information and status */
    app_gap_cb_t *p_dev = &m_dev_info;
    memset(p_dev, 0, sizeof(app_gap_cb_t));

    /* start to discover nearby Bluetooth devices */
    p_dev->state = APP_GAP_STATE_DEVICE_DISCOVERING;
    esp_bt_gap_start_discovery(ESP_BT_INQ_MODE_LIMITED_INQIURY, 1, 0);
}

void app_main()
{
    /* Initialize NVS — it is used to store PHY calibration data */
    esp_err_t ret = nvs_flash_init();
    if (ret == ESP_ERR_NVS_NO_FREE_PAGES) {
        ESP_ERROR_CHECK(nvs_flash_erase());
        ret = nvs_flash_init();
    }
    ESP_ERROR_CHECK( ret );

    esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
    if (esp_bt_controller_init(&bt_cfg) != ESP_OK) {
        ESP_LOGE(GAP_TAG, "%s initialize controller failed\n", __func__);
        return;
    }

    if (esp_bt_controller_enable(ESP_BT_MODE_CLASSIC_BT) != ESP_OK) {
        ESP_LOGE(GAP_TAG, "%s enable controller failed\n", __func__);
        return;
    }

    if (esp_bluedroid_init() != ESP_OK) {
        ESP_LOGE(GAP_TAG, "%s initialize bluedroid failed\n", __func__);
        return;
    }

    if (esp_bluedroid_enable() != ESP_OK) {
        ESP_LOGE(GAP_TAG, "%s enable bluedroid failed\n", __func__);
        return;
    }

    bt_app_gap_start_up();
}

Best regards
Max

zdoucha
Posts: 2
Joined: Tue Nov 06, 2018 7:55 pm

Re: Classic bluetooth discovery

Postby zdoucha » Tue Nov 06, 2018 7:58 pm

Hello, I'm working on a projet:
i have an arduino uno and 2 BT modules (HC-05 & HM-10)

I should be able via (arduino+ Bluetooth module) to discover all nearby smartphones (android & ios) then to notify them (send message or picture) but without installing any app or doing any config on those smartphones (only bluetooth should be activated on them).

The HC-05 doesn't support the AT+DISC command and the BLE HM-10 discover only BLE devices (no smartphone discovered)

Is there any way to do this using this hardware?
Does the esp32 able to do it?
thanks for advance :)

blueMoodBHD
Posts: 7
Joined: Wed Nov 07, 2018 3:47 am

Re: Classic bluetooth discovery

Postby blueMoodBHD » Wed Nov 07, 2018 6:32 am

Hi sharky,
If a classic BT device want to discover others, it will sent a inquiry. Then the device which is in inquiry scan mode will response it. So, if a device is no-discoverable (not in inquiry scan), will not find by others.

blueMoodBHD
Posts: 7
Joined: Wed Nov 07, 2018 3:47 am

Re: Classic bluetooth discovery

Postby blueMoodBHD » Wed Nov 07, 2018 6:57 am

Hi zdoucha,
esp32 could discover all nearby smartphones(android & ios, bluetooth should be activated on them and discoverable), it also could pair and connect to smartphones.
Smartphones send file with OBject EXchange protocol, we do not support it, now. But we can send message to smartphones by other protocol, and smartphones will get it with some apps.

zdoucha
Posts: 2
Joined: Tue Nov 06, 2018 7:55 pm

Re: Classic bluetooth discovery

Postby zdoucha » Fri Nov 09, 2018 1:53 pm

Hi blueMoodBHD,

thank you for your reply :)

When you said "we can send message to smartphones by other protocol, and smartphones will get it with some apps." which protocols are used for ?

blueMoodBHD
Posts: 7
Joined: Wed Nov 07, 2018 3:47 am

Re: Classic bluetooth discovery

Postby blueMoodBHD » Tue Nov 13, 2018 2:10 am

Hi zdoucha,
We can send any message by SPP(Serial Port Profile), or send an audio stream by HFP(Hands-free Profile).

rexxnyc
Posts: 1
Joined: Thu Aug 01, 2019 1:48 pm

Re: Classic bluetooth discovery

Postby rexxnyc » Thu Aug 01, 2019 1:55 pm

1) found a couple bugs/typos - I can post if you are still interested in this.
2) more generally - what environment are you working in? and did you get results?
I'm just using Arduino IDE and got pretty far despite limited knowledge of ...everything.
thanks,Eric

brentlinger
Posts: 1
Joined: Thu Aug 08, 2019 6:30 pm

Re: Classic bluetooth discovery

Postby brentlinger » Thu Aug 08, 2019 6:33 pm

Hello, Im struggling with doing the same thing.


Hello, Im interested in creating some kind of presence detection sensor with an ESP32 and scanning for bluetooth devices.
Looking to do something similar to the following
https://www.instructables.com/id/ESP32- ... -Detector/

The dilemma is that for iPhones and apple products that doesn't work because they are not beaconing.
eg;
BLEScan can't find all Bluetooth devices around me
https://github.com/nkolban/esp32-snippets/issues/578

instead it seems I need to do Classic bluetooth discovery
I can easily find if an iphone is present via bluetooth and get its rssi strength without pairing from my linux computer
eg:Bluetooth distance sensing - phone etc without pairing
https://www.raspberrypi.org/forums/view ... hp?t=47466

Im struggling trying to determine how to emulate the same thing I can do on my linux machine on an ESP32.
Is it just not possible or perhaps Ive not yet been able to find a workable example

some searching and it seems this is a common question and the ESP32 just cant do this as of yet?
https://www.reddit.com/r/esp32/comments ... h_classic/
Ive found some people explaining its possible but found no working examples
https://www.reddit.com/r/esp32/comments ... _rpi_does/

ggenovese
Posts: 1
Joined: Mon Sep 09, 2019 10:12 am

Re: Classic bluetooth discovery

Postby ggenovese » Mon Sep 09, 2019 10:14 am

Hi,
I'm interested in the topic too.

I'm investigating the library at https://github.com/espressif/arduino-es ... include/bt

Any news about working library or code?

Bests,
G.

andreas.liebenberg
Posts: 1
Joined: Thu Jul 22, 2021 12:28 pm

Re: Classic bluetooth discovery

Postby andreas.liebenberg » Thu Jul 22, 2021 12:56 pm

Hi,

I managed to scan for BT devices using the esp_bt_gap_start_discovery function. I do get the callback with available devices and their RSSI. Unfortunately it does not show my Android phone even though Bluetooth is switched on. It only shows the phone if I go into the Bluetooth menu and start a Scan from the phone. During this scan on the phone it is visible to the ESP32. As soon as the scan is done, the ESP32 cannot see my phone anymore.
Is this normal?
Is there some way of discovering devices without having to start a scan from the device?

Thanks

Who is online

Users browsing this forum: stdenits and 340 guests