summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjacqueline <me@jacqueline.id.au>2023-08-15 17:32:57 +1000
committerjacqueline <me@jacqueline.id.au>2023-08-15 17:32:57 +1000
commit544b0013b104a6584660724ccd502adcccd7ca6c (patch)
tree46b140ca9d51cdc14f0004ce64c7b89d021d5fce
parentd6b83fcf4a1a3039c06e0b1d1a1f7e2af2351efb (diff)
downloadtangara-fw-544b0013b104a6584660724ccd502adcccd7ca6c.tar.gz
persist preferred bluetooth device in nvs
-rw-r--r--src/audio/audio_fsm.cpp2
-rw-r--r--src/drivers/bluetooth.cpp21
-rw-r--r--src/drivers/include/bluetooth.hpp20
-rw-r--r--src/drivers/include/bluetooth_types.hpp20
-rw-r--r--src/drivers/include/nvs.hpp7
-rw-r--r--src/drivers/nvs.cpp22
-rw-r--r--src/system_fsm/booting.cpp3
7 files changed, 77 insertions, 18 deletions
diff --git a/src/audio/audio_fsm.cpp b/src/audio/audio_fsm.cpp
index 8791b9c4..9558d778 100644
--- a/src/audio/audio_fsm.cpp
+++ b/src/audio/audio_fsm.cpp
@@ -59,7 +59,7 @@ auto AudioState::Init(drivers::IGpios* gpio_expander,
sFileSource.reset(new FatfsAudioInput(tag_parser));
sI2SOutput.reset(new I2SAudioOutput(sIGpios, sDac));
- // sBtOutput.reset(new BluetoothAudioOutput(bluetooth));
+ sBtOutput.reset(new BluetoothAudioOutput(bluetooth));
AudioTask::Start(sFileSource.get(), sI2SOutput.get());
// AudioTask::Start(sFileSource.get(), sBtOutput.get());
diff --git a/src/drivers/bluetooth.cpp b/src/drivers/bluetooth.cpp
index 79999b2c..f6992f05 100644
--- a/src/drivers/bluetooth.cpp
+++ b/src/drivers/bluetooth.cpp
@@ -20,6 +20,7 @@
#include "esp_wifi.h"
#include "esp_wifi_types.h"
#include "freertos/portmacro.h"
+#include "nvs.hpp"
#include "tinyfsm/include/tinyfsm.hpp"
namespace drivers {
@@ -55,8 +56,8 @@ auto a2dp_data_cb(uint8_t* buf, int32_t buf_size) -> int32_t {
return xStreamBufferReceive(stream, buf, buf_size, 0);
}
-Bluetooth::Bluetooth() {
- tinyfsm::FsmList<bluetooth::BluetoothState>::start();
+Bluetooth::Bluetooth(NvsStorage* storage) {
+ bluetooth::BluetoothState::Init(storage);
}
auto Bluetooth::Enable() -> bool {
@@ -101,12 +102,15 @@ auto DeviceName() -> std::string {
uint8_t mac[8]{0};
esp_efuse_mac_get_default(mac);
std::ostringstream name;
- name << "TANGARA " << std::hex << mac[0] << mac[1];
+ name << "TANGARA " << std::hex << static_cast<int>(mac[0])
+ << static_cast<int>(mac[1]);
return name.str();
}
namespace bluetooth {
+NvsStorage* BluetoothState::sStorage_;
+
std::mutex BluetoothState::sDevicesMutex_;
std::map<mac_addr_t, Device> BluetoothState::sDevices_;
std::optional<mac_addr_t> BluetoothState::sPreferredDevice_;
@@ -114,6 +118,12 @@ mac_addr_t BluetoothState::sCurrentDevice_;
std::atomic<StreamBufferHandle_t> BluetoothState::sSource_;
+auto BluetoothState::Init(NvsStorage* storage) -> void {
+ sStorage_ = storage;
+ sPreferredDevice_ = storage->PreferredBluetoothDevice();
+ tinyfsm::FsmList<bluetooth::BluetoothState>::start();
+}
+
auto BluetoothState::devices() -> std::vector<Device> {
std::lock_guard lock{sDevicesMutex_};
std::vector<Device> out;
@@ -417,6 +427,11 @@ void Connecting::react(const events::internal::A2dp& ev) {
void Connected::entry() {
ESP_LOGI(kTag, "entering connected state");
+
+ auto stored_pref = sStorage_->PreferredBluetoothDevice();
+ if (stored_pref != sPreferredDevice_) {
+ sStorage_->PreferredBluetoothDevice(sPreferredDevice_);
+ }
// TODO: if we already have a source, immediately start playing
}
diff --git a/src/drivers/include/bluetooth.hpp b/src/drivers/include/bluetooth.hpp
index bdc45910..fc72d393 100644
--- a/src/drivers/include/bluetooth.hpp
+++ b/src/drivers/include/bluetooth.hpp
@@ -11,32 +11,22 @@
#include <freertos/FreeRTOS.h>
#include <freertos/stream_buffer.h>
+#include "bluetooth_types.hpp"
#include "esp_a2dp_api.h"
#include "esp_avrc_api.h"
#include "esp_gap_bt_api.h"
+#include "nvs.hpp"
#include "tinyfsm.hpp"
#include "tinyfsm/include/tinyfsm.hpp"
namespace drivers {
-namespace bluetooth {
-
-typedef std::array<uint8_t, 6> mac_addr_t;
-
-struct Device {
- mac_addr_t address;
- std::string name;
- uint32_t class_of_device;
- int8_t signal_strength;
-};
-} // namespace bluetooth
-
/*
* A handle used to interact with the bluetooth state machine.
*/
class Bluetooth {
public:
- Bluetooth();
+ Bluetooth(NvsStorage* storage);
auto Enable() -> bool;
auto Disable() -> void;
@@ -74,6 +64,8 @@ struct Avrc : public tinyfsm::Event {
class BluetoothState : public tinyfsm::Fsm<BluetoothState> {
public:
+ static auto Init(NvsStorage* storage) -> void;
+
static auto devices() -> std::vector<Device>;
static auto preferred_device() -> std::optional<mac_addr_t>;
static auto preferred_device(const mac_addr_t&) -> void;
@@ -96,6 +88,8 @@ class BluetoothState : public tinyfsm::Fsm<BluetoothState> {
virtual void react(const events::internal::Avrc& ev){};
protected:
+ static NvsStorage* sStorage_;
+
static std::mutex sDevicesMutex_;
static std::map<mac_addr_t, Device> sDevices_;
static std::optional<mac_addr_t> sPreferredDevice_;
diff --git a/src/drivers/include/bluetooth_types.hpp b/src/drivers/include/bluetooth_types.hpp
new file mode 100644
index 00000000..03100651
--- /dev/null
+++ b/src/drivers/include/bluetooth_types.hpp
@@ -0,0 +1,20 @@
+
+#pragma once
+
+#include <array>
+#include <string>
+
+namespace drivers {
+namespace bluetooth {
+
+typedef std::array<uint8_t, 6> mac_addr_t;
+
+struct Device {
+ mac_addr_t address;
+ std::string name;
+ uint32_t class_of_device;
+ int8_t signal_strength;
+};
+
+} // namespace bluetooth
+} // namespace drivers
diff --git a/src/drivers/include/nvs.hpp b/src/drivers/include/nvs.hpp
index be783583..32c2ae73 100644
--- a/src/drivers/include/nvs.hpp
+++ b/src/drivers/include/nvs.hpp
@@ -6,9 +6,13 @@
#pragma once
+#include <optional>
+
#include "esp_err.h"
#include "nvs.h"
+#include "bluetooth_types.hpp"
+
namespace drivers {
class NvsStorage {
@@ -17,6 +21,9 @@ class NvsStorage {
auto SchemaVersion() -> uint8_t;
+ auto PreferredBluetoothDevice() -> std::optional<bluetooth::mac_addr_t>;
+ auto PreferredBluetoothDevice(std::optional<bluetooth::mac_addr_t>) -> void;
+
explicit NvsStorage(nvs_handle_t);
~NvsStorage();
diff --git a/src/drivers/nvs.cpp b/src/drivers/nvs.cpp
index a2de9518..8c7e54a8 100644
--- a/src/drivers/nvs.cpp
+++ b/src/drivers/nvs.cpp
@@ -10,6 +10,7 @@
#include <cstdint>
#include <memory>
+#include "bluetooth.hpp"
#include "esp_log.h"
#include "nvs.h"
#include "nvs_flash.h"
@@ -20,6 +21,7 @@ static constexpr char kTag[] = "nvm";
static constexpr uint8_t kSchemaVersion = 1;
static constexpr char kKeyVersion[] = "ver";
+static constexpr char kKeyBluetooth[] = "bt";
auto NvsStorage::Open() -> NvsStorage* {
esp_err_t err = nvs_flash_init();
@@ -70,4 +72,24 @@ auto NvsStorage::SchemaVersion() -> uint8_t {
return ret;
}
+auto NvsStorage::PreferredBluetoothDevice()
+ -> std::optional<bluetooth::mac_addr_t> {
+ bluetooth::mac_addr_t out{0};
+ size_t size = out.size();
+ if (nvs_get_blob(handle_, kKeyBluetooth, out.data(), &size) != ESP_OK) {
+ return {};
+ }
+ return out;
+}
+auto NvsStorage::PreferredBluetoothDevice(
+ std::optional<bluetooth::mac_addr_t> addr) -> void {
+ if (!addr) {
+ nvs_erase_key(handle_, kKeyBluetooth);
+ } else {
+ nvs_set_blob(handle_, kKeyBluetooth, addr.value().data(),
+ addr.value().size());
+ }
+ nvs_commit(handle_);
+}
+
} // namespace drivers
diff --git a/src/system_fsm/booting.cpp b/src/system_fsm/booting.cpp
index 7bd5f890..1fc01976 100644
--- a/src/system_fsm/booting.cpp
+++ b/src/system_fsm/booting.cpp
@@ -62,7 +62,8 @@ auto Booting::entry() -> void {
}
ESP_LOGI(kTag, "starting bluetooth");
- sBluetooth.reset(new drivers::Bluetooth());
+ sBluetooth.reset(new drivers::Bluetooth(sNvs.get()));
+ // sBluetooth->Enable();
// At this point we've done all of the essential boot tasks. Start remaining
// state machines and inform them that the system is ready.