persist preferred bluetooth device in nvs
This commit is contained in:
@@ -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());
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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_;
|
||||
|
||||
@@ -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
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user