From 7963abb27a253460c9353c87b7c8ebef86c4ba8a Mon Sep 17 00:00:00 2001 From: Joe Date: Wed, 12 Apr 2023 04:33:15 -0400 Subject: [PATCH] Fix BedJet setup priority [fixes esphome/issues#3807] (#4677) There is a race condition where a BedJet unit previously had its BLE "notify" flag enabled, and it continues to broadcast these notify packets even after the ESP32 (and BLEClient) goes away, such as during a crash or unplugging power. BLEClient::setup_priority=AFTER_BLUETOOTH, while BedJetHub::setup_priority=AFTER_WIFI. When the ESP32 starts back up again, BLEClient::setup() happens first and will start receiving the BLE notify packets almost immediately. Since we register the BLEClient child from codegen, BedJetHub is registered as a child already by this point, so BLEClient dispatches the notify status packet (and other gatt events) to the BedJetHub handler, even though BedJetHub::setup() has not been called yet. We initialize BedJetHub::codec_ in setup(), so if BLEClient starts dispatching gatt events before setup() is called, then codec_ will not be initialized yet. This causes BedJetHub's gatt notify handler to call `this->codec_->decode_notify()` on an uninitialized null pointer. Since invoking a method does not have to dereference the pointer, that method invocation is allowed; but later trying to access memory on that instance results in a StoreProhibited panic. Changing the BedJetHub's setup_priority to BLUETOOTH causes it to be setup before BLEClient, so that by the time BLEClient starts to receive BLE packets, BedJetHub is ready to receive them. --- esphome/components/bedjet/bedjet_hub.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esphome/components/bedjet/bedjet_hub.h b/esphome/components/bedjet/bedjet_hub.h index e4af2bca51..5809827cfa 100644 --- a/esphome/components/bedjet/bedjet_hub.h +++ b/esphome/components/bedjet/bedjet_hub.h @@ -116,7 +116,7 @@ class BedJetHub : public esphome::ble_client::BLEClientNode, public PollingCompo void update() override; void dump_config() override; void setup() override { this->codec_ = make_unique(); } - float get_setup_priority() const override { return setup_priority::AFTER_WIFI; } + float get_setup_priority() const override { return setup_priority::BLUETOOTH; } /** @return The BedJet's configured name, or the MAC address if not discovered yet. */ std::string get_name() {