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();
}
Max