mirror of
https://github.com/esphome/esphome.git
synced 2024-11-30 10:44:13 +01:00
Pending BT Classic changes
(Working changes prior to rebase / merge upstream)
This commit is contained in:
parent
f1ea245928
commit
ee89c32188
9 changed files with 166 additions and 26 deletions
|
@ -15,8 +15,9 @@ void BTClassicPresenceDevice::update() {
|
|||
parent()->addScan(esp32_bt_classic::bt_scan_item(u64_addr, num_scans));
|
||||
}
|
||||
|
||||
void BTClassicPresenceDevice::on_scan_result(const esp32_bt_classic::rmt_name_result &result) {
|
||||
void BTClassicPresenceDevice::on_scan_result(const esp32_bt_classic::rmt_name_result &result, const optional<esp32_bt_classic::bt_scan_item>& scan_item) {
|
||||
const uint64_t result_addr = esp32_bt_classic::bd_addr_to_uint64(result.bda);
|
||||
// ToDo: Use provided scan_item scans_remaining!!
|
||||
if (result_addr == u64_addr) {
|
||||
if (ESP_BT_STATUS_SUCCESS == result.stat) {
|
||||
this->publish_state(true);
|
||||
|
|
|
@ -24,7 +24,7 @@ class BTClassicPresenceDevice : public PollingComponent,
|
|||
|
||||
void dump_config() override;
|
||||
void update() override;
|
||||
void on_scan_result(const esp32_bt_classic::rmt_name_result &result) override;
|
||||
void on_scan_result(const esp32_bt_classic::rmt_name_result &result, const optional<esp32_bt_classic::bt_scan_item>& scan_item) override;
|
||||
|
||||
protected:
|
||||
uint8_t scans_remaining{0};
|
||||
|
|
|
@ -8,9 +8,11 @@ from esphome.const import (
|
|||
CONF_MAC_ADDRESS,
|
||||
CONF_NUM_SCANS,
|
||||
CONF_TRIGGER_ID,
|
||||
ENTITY_CATEGORY_DIAGNOSTIC,
|
||||
)
|
||||
from esphome.core import CORE
|
||||
from esphome import automation
|
||||
from esphome.components import text_sensor
|
||||
from esphome.components.esp32 import (
|
||||
add_idf_sdkconfig_option,
|
||||
get_esp32_variant,
|
||||
|
@ -20,19 +22,25 @@ from esphome.components.esp32 import (
|
|||
from .const import (
|
||||
CONF_ON_SCAN_START,
|
||||
CONF_ON_SCAN_RESULT,
|
||||
CONF_LAST_ERROR,
|
||||
)
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
AUTO_LOAD = ["esp32_bt_common"]
|
||||
AUTO_LOAD = ["esp32_bt_common", "text_sensor"]
|
||||
DEPENDENCIES = ["esp32"]
|
||||
CODEOWNERS = ["@RoboMagus"]
|
||||
|
||||
NO_BLUETOOTH_VARIANTS = [esp32_const.VARIANT_ESP32S2]
|
||||
|
||||
MIN_IDF_VERSION = cv.Version(4, 4, 4)
|
||||
# Required for support where BT scans report MAC for scan-result
|
||||
#MIN_IDF_VERSION = cv.Version(4, 4, 4)
|
||||
MIN_ARDUINO_VERSION = cv.Version(2, 0, 5)
|
||||
|
||||
# IDF V5+ seems to fix 'scans not working after a while...'
|
||||
MIN_IDF_VERSION = cv.Version(5, 1, 0)
|
||||
#MIN_ARDUINO_VERSION = cv.Version(3, 0, 0)
|
||||
|
||||
esp32_bt_classic_ns = cg.esphome_ns.namespace("esp32_bt_classic")
|
||||
ESP32BtClassic = esp32_bt_classic_ns.class_("ESP32BtClassic", cg.Component)
|
||||
|
||||
|
@ -42,6 +50,9 @@ BtAddressConstRef = BtAddress.operator("ref").operator("const")
|
|||
BtStatus = esp32_bt_classic_ns.class_("BtStatus")
|
||||
BtStatusConstRef = BtStatus.operator("ref").operator("const")
|
||||
|
||||
ScanStatus = esp32_bt_classic_ns.class_("ScanStatus")
|
||||
ScanStatusConstRef = ScanStatus.operator("ref").operator("const")
|
||||
|
||||
GAPEventHandler = esp32_bt_classic_ns.class_("GAPEventHandler")
|
||||
|
||||
# Actions
|
||||
|
@ -51,7 +62,9 @@ BtClassicScanAction = esp32_bt_classic_ns.class_(
|
|||
# Triggers
|
||||
BtClassicScanResultTrigger = esp32_bt_classic_ns.class_(
|
||||
"BtClassicScanResultTrigger",
|
||||
automation.Trigger.template(BtAddress, BtStatusConstRef, cg.const_char_ptr),
|
||||
automation.Trigger.template(
|
||||
BtAddress, BtStatusConstRef, cg.const_char_ptr, ScanStatusConstRef
|
||||
),
|
||||
)
|
||||
BtClassicScanStartTrigger = esp32_bt_classic_ns.class_(
|
||||
"BtClassicScanStartTrigger", automation.Trigger.template()
|
||||
|
@ -76,6 +89,9 @@ CONFIG_SCHEMA = cv.All(
|
|||
cv.Optional(CONF_MAC_ADDRESS): cv.ensure_list(cv.mac_address),
|
||||
}
|
||||
),
|
||||
cv.Optional(CONF_LAST_ERROR): text_sensor.text_sensor_schema(
|
||||
entity_category=ENTITY_CATEGORY_DIAGNOSTIC
|
||||
),
|
||||
}
|
||||
).extend(cv.COMPONENT_SCHEMA),
|
||||
cv.require_framework_version(
|
||||
|
@ -153,13 +169,25 @@ async def to_code(config):
|
|||
trigger,
|
||||
[
|
||||
(BtAddressConstRef, "address"),
|
||||
(BtStatusConstRef, "status"),
|
||||
(BtStatusConstRef, "scan_result"),
|
||||
(cg.const_char_ptr, "name"),
|
||||
(ScanStatusConstRef, "status"),
|
||||
],
|
||||
conf,
|
||||
)
|
||||
|
||||
if CONF_LAST_ERROR in config:
|
||||
sens = await text_sensor.new_text_sensor(config[CONF_LAST_ERROR])
|
||||
cg.add(var.set_last_error_sensor(sens))
|
||||
|
||||
if CORE.using_esp_idf:
|
||||
add_idf_sdkconfig_option("CONFIG_BT_ENABLED", True)
|
||||
add_idf_sdkconfig_option("CONFIG_BTDM_CTRL_MODE_BTDM", True)
|
||||
add_idf_sdkconfig_option("CONFIG_BT_CLASSIC_ENABLED", True)
|
||||
add_idf_sdkconfig_option("CONFIG_BTU_TASK_STACK_SIZE", 8192)
|
||||
|
||||
add_idf_sdkconfig_option("CONFIG_BT_LOG_GAP_TRACE_LEVEL_DEBUG", True)
|
||||
add_idf_sdkconfig_option("CONFIG_BT_LOG_GAP_TRACE_LEVEL", 5)
|
||||
|
||||
add_idf_sdkconfig_option("CONFIG_BT_LOG_BTC_TRACE_LEVEL_DEBUG", True)
|
||||
add_idf_sdkconfig_option("CONFIG_BT_LOG_BTC_TRACE_LEVEL", 5)
|
||||
|
|
|
@ -74,7 +74,7 @@ class BtClassicScanStartTrigger : public Trigger<>, public BtClassicScanStartLis
|
|||
void on_scan_start() override { this->trigger(); }
|
||||
};
|
||||
|
||||
class BtClassicScanResultTrigger : public Trigger<const BtAddress &, const BtStatus &, const char *>,
|
||||
class BtClassicScanResultTrigger : public Trigger<const BtAddress &, const BtStatus &, const char *, const ScanStatus &>,
|
||||
public BtClassicScanResultListner {
|
||||
public:
|
||||
explicit BtClassicScanResultTrigger(ESP32BtClassic *parent, std::initializer_list<uint64_t> addresses = {})
|
||||
|
@ -82,7 +82,7 @@ class BtClassicScanResultTrigger : public Trigger<const BtAddress &, const BtSta
|
|||
parent->register_scan_result_listener(this);
|
||||
}
|
||||
|
||||
void on_scan_result(const rmt_name_result &result) override {
|
||||
void on_scan_result(const rmt_name_result &result, const optional<bt_scan_item>& scan_item) override {
|
||||
|
||||
uint64_t result_addr = bd_addr_to_uint64(result.bda);
|
||||
if (!addresses_.empty()) {
|
||||
|
@ -91,7 +91,14 @@ class BtClassicScanResultTrigger : public Trigger<const BtAddress &, const BtSta
|
|||
}
|
||||
}
|
||||
|
||||
this->trigger(result_addr, result.stat, (const char *) result.rmt_name);
|
||||
ScanStatus scan_status = SCAN_STATUS_SCANNING;
|
||||
if (result.stat == ESP_BT_STATUS_SUCCESS) {
|
||||
scan_status = SCAN_STATUS_FOUND;
|
||||
}
|
||||
else if(scan_item.has_value() && result.stat == ESP_BT_STATUS_FAIL && scan_item.value().scans_remaining == 0) {
|
||||
scan_status = SCAN_STATUS_NOT_FOUND;
|
||||
}
|
||||
this->trigger(result_addr, result.stat, (const char *) result.rmt_name, scan_status);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
|
|
@ -13,13 +13,16 @@
|
|||
#include <nvs_flash.h>
|
||||
|
||||
#include "esphome/components/esp32_bt_common/bt_defs.h"
|
||||
// For time getting:
|
||||
#include "esphome/components/homeassistant/time/homeassistant_time.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace esp32_bt_classic {
|
||||
|
||||
float ESP32BtClassic::get_setup_priority() const {
|
||||
// Setup just after BLE, (but before AFTER_BLUETOOTH) to ensure both can co-exist!
|
||||
return setup_priority::BLUETOOTH - 5.0f;
|
||||
// return setup_priority::BLUETOOTH - 5.0f;
|
||||
return setup_priority::AFTER_BLUETOOTH + 5.0f;
|
||||
}
|
||||
|
||||
void ESP32BtClassic::setup() {
|
||||
|
@ -29,6 +32,11 @@ void ESP32BtClassic::setup() {
|
|||
if (!bt_setup_()) {
|
||||
ESP_LOGE(TAG, "BT Classic could not be set up");
|
||||
this->mark_failed();
|
||||
#ifdef USE_TEXT_SENSOR
|
||||
if (last_error_sensor_) {
|
||||
last_error_sensor_->publish_state("boot");
|
||||
}
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -74,6 +82,7 @@ bool ESP32BtClassic::bt_setup_() {
|
|||
}
|
||||
#endif
|
||||
|
||||
ESP_LOGD(TAG, "Initializing BlueDroid");
|
||||
if (esp_bluedroid_get_status() == ESP_BLUEDROID_STATUS_UNINITIALIZED) {
|
||||
if ((err = esp_bluedroid_init()) != ESP_OK) {
|
||||
ESP_LOGE(TAG, "%s initialize bluedroid failed: %s\n", __func__, esp_err_to_name(err));
|
||||
|
@ -81,6 +90,7 @@ bool ESP32BtClassic::bt_setup_() {
|
|||
}
|
||||
}
|
||||
|
||||
ESP_LOGD(TAG, "Enabling BlueDroid");
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
if ((err = esp_bluedroid_enable()) != ESP_OK) {
|
||||
ESP_LOGE(TAG, "%s enable bluedroid failed: %s\n", __func__, esp_err_to_name(err));
|
||||
|
@ -91,12 +101,16 @@ bool ESP32BtClassic::bt_setup_() {
|
|||
bool success = gap_startup();
|
||||
|
||||
// BT takes some time to be fully set up, 200ms should be more than enough
|
||||
delay(200); // NOLINT
|
||||
for (int i = 10; i < 20; i++) {
|
||||
App.feed_wdt();
|
||||
delay(10); // NOLINT
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
bool ESP32BtClassic::gap_startup() {
|
||||
ESP_LOGD(TAG, "Startup GAP");
|
||||
// set discoverable and connectable mode, wait to be connected
|
||||
esp_bt_gap_set_scan_mode(ESP_BT_NON_CONNECTABLE, ESP_BT_NON_DISCOVERABLE);
|
||||
|
||||
|
@ -134,14 +148,19 @@ void ESP32BtClassic::startScan(const uint64_t u64_addr) {
|
|||
esp_bd_addr_t bd_addr;
|
||||
uint64_to_bd_addr(u64_addr, bd_addr);
|
||||
ESP_LOGD(TAG, "Start scanning for %02X:%02X:%02X:%02X:%02X:%02X", EXPAND_MAC_F(bd_addr));
|
||||
scanPending_ = true;
|
||||
last_scan_ms = millis();
|
||||
esp_err_t result = esp_bt_gap_read_remote_name(bd_addr);
|
||||
|
||||
for (auto *listener : scan_start_listners_) {
|
||||
listener->on_scan_start();
|
||||
if (result == ESP_OK) {
|
||||
scanPending_ = true;
|
||||
last_scan_ms = millis();
|
||||
for (auto *listener : scan_start_listners_) {
|
||||
listener->on_scan_start();
|
||||
}
|
||||
}
|
||||
else {
|
||||
ESP_LOGE(TAG, "Could not start scan! Error: %s\n BlueDroid status: %d\n Controller status: %d", esp_err_to_name(result), esp_bluedroid_get_status(), esp_bt_controller_get_status());
|
||||
}
|
||||
|
||||
esp_bt_gap_read_remote_name(bd_addr);
|
||||
}
|
||||
|
||||
void ESP32BtClassic::addScan(const bt_scan_item &scan) {
|
||||
|
@ -176,10 +195,10 @@ void ESP32BtClassic::real_gap_event_handler_(esp_bt_gap_cb_event_t event, esp_bt
|
|||
|
||||
switch (event) {
|
||||
case ESP_BT_GAP_READ_REMOTE_NAME_EVT: {
|
||||
handle_scan_result(param->read_rmt_name);
|
||||
const auto& scan_item = handle_scan_result(param->read_rmt_name);
|
||||
|
||||
for (auto *listener : scan_result_listners_) {
|
||||
listener->on_scan_result(param->read_rmt_name);
|
||||
listener->on_scan_result(param->read_rmt_name, scan_item);
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -191,23 +210,30 @@ void ESP32BtClassic::real_gap_event_handler_(esp_bt_gap_cb_event_t event, esp_bt
|
|||
}
|
||||
}
|
||||
|
||||
void ESP32BtClassic::handle_scan_result(const rmt_name_result &result) {
|
||||
optional<bt_scan_item> ESP32BtClassic::handle_scan_result(const rmt_name_result &result) {
|
||||
scanPending_ = false;
|
||||
uint32_t scanDuration = millis() - last_scan_ms;
|
||||
const uint64_t u64_addr = bd_addr_to_uint64(result.bda);
|
||||
|
||||
optional<bt_scan_item> active_scan_item{};
|
||||
auto it = active_scan_list_.begin();
|
||||
while (it != active_scan_list_.end()) {
|
||||
if (it->address == u64_addr) {
|
||||
// copy scan_item to return value before modifications!
|
||||
active_scan_item = *it;
|
||||
active_scan_item->scan_duration = scanDuration;
|
||||
|
||||
// If device was found, remove it from the scan list
|
||||
if (ESP_BT_STATUS_SUCCESS == result.stat) {
|
||||
ESP_LOGI(TAG, "Found device '%02X:%02X:%02X:%02X:%02X:%02X' (%s) with %d scans remaining",
|
||||
EXPAND_MAC_F(result.bda), result.rmt_name, it->scans_remaining);
|
||||
ESP_LOGI(TAG, "Found device '%02X:%02X:%02X:%02X:%02X:%02X' (%s) in %lu ms with %d scans remaining",
|
||||
EXPAND_MAC_F(result.bda), result.rmt_name, scanDuration, it->scans_remaining);
|
||||
active_scan_list_.erase(it);
|
||||
} else {
|
||||
it->next_scan_time = millis() + scan_delay_;
|
||||
|
||||
ESP_LOGD(TAG, "Device '%02X:%02X:%02X:%02X:%02X:%02X' scan result: %s (%d)", EXPAND_MAC_F(result.bda),
|
||||
esp_bt_status_to_str(result.stat), result.stat);
|
||||
ESP_LOGD(TAG, "Device '%02X:%02X:%02X:%02X:%02X:%02X' scan result: %s (%d) in %lu ms", EXPAND_MAC_F(result.bda),
|
||||
esp_bt_status_to_str(result.stat), result.stat, scanDuration);
|
||||
ESP_LOGD(TAG, "BlueDroid status: %d\n Controller status: %d", esp_bluedroid_get_status(), esp_bt_controller_get_status());
|
||||
|
||||
if (it->scans_remaining == 0) {
|
||||
ESP_LOGW(TAG, "Device '%02X:%02X:%02X:%02X:%02X:%02X' not found on final scan. Removing from scan list.",
|
||||
|
@ -227,9 +253,17 @@ void ESP32BtClassic::handle_scan_result(const rmt_name_result &result) {
|
|||
it++;
|
||||
}
|
||||
|
||||
#ifdef USE_TEXT_SENSOR
|
||||
if (last_error_sensor_ && result.stat == ESP_BT_STATUS_FAIL && scanDuration < 100) {
|
||||
auto current_time = esphome::homeassistant::global_homeassistant_time->now();
|
||||
last_error_sensor_->publish_state(current_time.strftime("%Y-%m-%d %H:%M:%S"));
|
||||
}
|
||||
#endif
|
||||
|
||||
if (active_scan_list_.empty()) {
|
||||
ESP_LOGD(TAG, "Scan complete. No more devices left to scan.");
|
||||
}
|
||||
return active_scan_item;
|
||||
}
|
||||
|
||||
void ESP32BtClassic::dump_config() {
|
||||
|
|
|
@ -9,6 +9,10 @@
|
|||
|
||||
#include "esphome/components/esp32_bt_common/queue.h"
|
||||
|
||||
#ifdef USE_TEXT_SENSOR
|
||||
#include "esphome/components/text_sensor/text_sensor.h"
|
||||
#endif
|
||||
|
||||
// IDF headers
|
||||
#include <esp_bt_defs.h>
|
||||
#include <esp_gap_bt_api.h>
|
||||
|
@ -29,10 +33,12 @@ struct BtGapEvent {
|
|||
};
|
||||
|
||||
struct bt_scan_item {
|
||||
bt_scan_item(uint64_t u64_addr, uint8_t num_scans) : address(u64_addr), scans_remaining(num_scans) {}
|
||||
bt_scan_item() : address{}, scans_remaining{}, next_scan_time{}, scan_duration{} {}
|
||||
bt_scan_item(uint64_t u64_addr, uint8_t num_scans) : address(u64_addr), scans_remaining(num_scans), next_scan_time{}, scan_duration{} {}
|
||||
uint64_t address;
|
||||
uint8_t scans_remaining;
|
||||
uint32_t next_scan_time;
|
||||
uint32_t scan_duration;
|
||||
};
|
||||
|
||||
struct BtAddress {
|
||||
|
@ -70,6 +76,24 @@ struct BtStatus {
|
|||
esp_bt_status_t status_;
|
||||
};
|
||||
|
||||
|
||||
struct ScanStatus {
|
||||
ScanStatus(scan_status_t status) : status_(status) {}
|
||||
|
||||
// Implicit conversion operators
|
||||
operator scan_status_t() const { return status_; }
|
||||
operator const char *() const { return c_str(); }
|
||||
operator std::string() const { return c_str(); }
|
||||
|
||||
// Explicit type accessors
|
||||
scan_status_t scan_status() const { return status_; }
|
||||
const char *c_str() const { return scan_status_to_str(status_); }
|
||||
std::string str() const { return c_str(); }
|
||||
|
||||
protected:
|
||||
scan_status_t status_;
|
||||
};
|
||||
|
||||
class BtClassicItf {
|
||||
public:
|
||||
virtual void addScan(const bt_scan_item &scan) = 0;
|
||||
|
@ -92,7 +116,7 @@ class BtClassicScanStartListner : public BtClassicChildBase {
|
|||
|
||||
class BtClassicScanResultListner : public BtClassicChildBase {
|
||||
public:
|
||||
virtual void on_scan_result(const rmt_name_result &result) = 0;
|
||||
virtual void on_scan_result(const rmt_name_result &result, const optional<bt_scan_item> &scan_item) = 0;
|
||||
};
|
||||
|
||||
// -----------------------------------------------
|
||||
|
@ -106,6 +130,10 @@ class ESP32BtClassic : public Component, public BtClassicItf {
|
|||
void dump_config() override;
|
||||
float get_setup_priority() const override;
|
||||
|
||||
#ifdef USE_TEXT_SENSOR
|
||||
void set_last_error_sensor(text_sensor::TextSensor *last_error) { last_error_sensor_ = last_error; }
|
||||
#endif
|
||||
|
||||
void register_scan_start_listener(BtClassicScanStartListner *listner) {
|
||||
listner->set_parent(this);
|
||||
scan_start_listners_.push_back(listner);
|
||||
|
@ -125,7 +153,7 @@ class ESP32BtClassic : public Component, public BtClassicItf {
|
|||
|
||||
void startScan(const uint64_t u64_addr);
|
||||
|
||||
void handle_scan_result(const rmt_name_result &result);
|
||||
optional<bt_scan_item> handle_scan_result(const rmt_name_result &result);
|
||||
|
||||
bool bt_setup_();
|
||||
bool gap_startup();
|
||||
|
@ -141,6 +169,9 @@ class ESP32BtClassic : public Component, public BtClassicItf {
|
|||
// Ble-Queue which thread safety precautions:
|
||||
esp32_bt_common::Queue<BtGapEvent> bt_events_;
|
||||
|
||||
#ifdef USE_TEXT_SENSOR
|
||||
text_sensor::TextSensor *last_error_sensor_{nullptr};
|
||||
#endif
|
||||
const uint32_t scan_delay_{100}; // (ms) minimal time between consecutive scans
|
||||
};
|
||||
|
||||
|
|
|
@ -2,3 +2,5 @@ CONF_ESP32_BTCLASSIC_ID = "esp32_btclassic_id"
|
|||
|
||||
CONF_ON_SCAN_START = "on_scan_start"
|
||||
CONF_ON_SCAN_RESULT = "on_scan_result"
|
||||
|
||||
CONF_LAST_ERROR = "last_error"
|
||||
|
|
|
@ -12,6 +12,17 @@
|
|||
namespace esphome {
|
||||
namespace esp32_bt_classic {
|
||||
|
||||
typedef struct {
|
||||
scan_status_t code;
|
||||
const char *msg;
|
||||
} scan_status_msg_t;
|
||||
|
||||
static const scan_status_msg_t scan_status_msg_table[] = {
|
||||
{SCAN_STATUS_SCANNING, "Scanning"},
|
||||
{SCAN_STATUS_FOUND, "Found"},
|
||||
{SCAN_STATUS_NOT_FOUND, "Not Found"},
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
esp_bt_status_t code;
|
||||
const char *msg;
|
||||
|
@ -51,6 +62,16 @@ const char *esp_bt_status_to_str(esp_bt_status_t code) {
|
|||
return "Unknown Status";
|
||||
}
|
||||
|
||||
const char *scan_status_to_str(scan_status_t status) {
|
||||
for (int i = 0; i < sizeof(scan_status_msg_table) / sizeof(scan_status_msg_table[0]); ++i) {
|
||||
if (scan_status_msg_table[i].code == status) {
|
||||
return scan_status_msg_table[i].msg;
|
||||
}
|
||||
}
|
||||
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
void uint64_to_bd_addr(uint64_t address, esp_bd_addr_t &bd_addr) {
|
||||
bd_addr[0] = (address >> 40) & 0xff;
|
||||
bd_addr[1] = (address >> 32) & 0xff;
|
||||
|
@ -79,6 +100,14 @@ std::string u64_addr_to_str(uint64_t address) {
|
|||
return mac;
|
||||
}
|
||||
|
||||
uint64_t str_to_u64_addr(const char* addr_str) {
|
||||
esp_bd_addr_t addr;
|
||||
if(str_to_bd_addr(addr_str, addr)) {
|
||||
return bd_addr_to_uint64(addr);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string bd_addr_to_str(const esp_bd_addr_t &addr) {
|
||||
char mac[24];
|
||||
snprintf(mac, sizeof(mac), "%02X:%02X:%02X:%02X:%02X:%02X", EXPAND_MAC_F(addr));
|
||||
|
|
|
@ -15,6 +15,13 @@ const char *const TAG = "esp32_bt_classic";
|
|||
// Helper for printing Bt MAC addresses for format "%02X:%02X:%02X:%02X:%02X:%02X"
|
||||
#define EXPAND_MAC_F(addr) addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]
|
||||
|
||||
typedef enum {
|
||||
SCAN_STATUS_SCANNING= 0,
|
||||
SCAN_STATUS_FOUND,
|
||||
SCAN_STATUS_NOT_FOUND,
|
||||
} scan_status_t;
|
||||
|
||||
const char *scan_status_to_str(scan_status_t status);
|
||||
const char *esp_bt_status_to_str(esp_bt_status_t code);
|
||||
|
||||
// bd_addr_t <--> uint64_t conversion functions:
|
||||
|
@ -26,6 +33,7 @@ std::string bd_addr_to_str(const esp_bd_addr_t &addr);
|
|||
bool str_to_bd_addr(const char *addr_str, esp_bd_addr_t &addr);
|
||||
|
||||
std::string u64_addr_to_str(uint64_t address);
|
||||
uint64_t str_to_u64_addr(const char* addr_str);
|
||||
|
||||
template<typename T> void moveItemToBack(std::vector<T> &v, size_t item_index) {
|
||||
T tmp(v[item_index]);
|
||||
|
|
Loading…
Reference in a new issue