|
|
@ -25,13 +25,40 @@ namespace states { |
|
|
|
|
|
|
|
|
|
|
|
static database::IFileGatherer* sFileGatherer; |
|
|
|
static database::IFileGatherer* sFileGatherer; |
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
|
|
* Ensure the storage and database are both available. If either of these fails |
|
|
|
|
|
|
|
* to open, then we assume it's an issue with the underlying SD card. |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
void Running::entry() { |
|
|
|
void Running::entry() { |
|
|
|
|
|
|
|
if (mountStorage()) { |
|
|
|
|
|
|
|
events::Ui().Dispatch(StorageMounted{}); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void Running::exit() { |
|
|
|
|
|
|
|
unmountStorage(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void Running::react(const KeyLockChanged& ev) { |
|
|
|
|
|
|
|
if (IdleCondition()) { |
|
|
|
|
|
|
|
transit<Idle>(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void Running::react(const audio::PlaybackFinished& ev) { |
|
|
|
|
|
|
|
if (IdleCondition()) { |
|
|
|
|
|
|
|
transit<Idle>(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void Running::react(const SdDetectChanged& ev) { |
|
|
|
|
|
|
|
if (ev.has_sd_card) { |
|
|
|
|
|
|
|
if (!sStorage && mountStorage()) { |
|
|
|
|
|
|
|
events::Ui().Dispatch(StorageMounted{}); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
unmountStorage(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
auto Running::mountStorage() -> bool { |
|
|
|
ESP_LOGI(kTag, "mounting sd card"); |
|
|
|
ESP_LOGI(kTag, "mounting sd card"); |
|
|
|
vTaskDelay(pdMS_TO_TICKS(250)); |
|
|
|
|
|
|
|
auto storage_res = drivers::SdStorage::Create(sServices->gpios()); |
|
|
|
auto storage_res = drivers::SdStorage::Create(sServices->gpios()); |
|
|
|
if (storage_res.has_error()) { |
|
|
|
if (storage_res.has_error()) { |
|
|
|
ESP_LOGW(kTag, "failed to mount!"); |
|
|
|
ESP_LOGW(kTag, "failed to mount!"); |
|
|
@ -44,12 +71,9 @@ void Running::entry() { |
|
|
|
sServices->sd(drivers::SdState::kNotPresent); |
|
|
|
sServices->sd(drivers::SdState::kNotPresent); |
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
return false; |
|
|
|
events::System().Dispatch(StorageError{}); |
|
|
|
|
|
|
|
events::Audio().Dispatch(StorageError{}); |
|
|
|
|
|
|
|
events::Ui().Dispatch(StorageError{}); |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
sStorage.reset(storage_res.value()); |
|
|
|
sStorage.reset(storage_res.value()); |
|
|
|
sServices->sd(drivers::SdState::kMounted); |
|
|
|
sServices->sd(drivers::SdState::kMounted); |
|
|
|
|
|
|
|
|
|
|
@ -59,43 +83,21 @@ void Running::entry() { |
|
|
|
database::Database::Open(*sFileGatherer, sServices->tag_parser(), |
|
|
|
database::Database::Open(*sFileGatherer, sServices->tag_parser(), |
|
|
|
sServices->collator(), sServices->bg_worker()); |
|
|
|
sServices->collator(), sServices->bg_worker()); |
|
|
|
if (database_res.has_error()) { |
|
|
|
if (database_res.has_error()) { |
|
|
|
ESP_LOGW(kTag, "failed to open!"); |
|
|
|
unmountStorage(); |
|
|
|
events::System().Dispatch(StorageError{}); |
|
|
|
return false; |
|
|
|
events::Audio().Dispatch(StorageError{}); |
|
|
|
|
|
|
|
events::Ui().Dispatch(StorageError{}); |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
sServices->database( |
|
|
|
sServices->database( |
|
|
|
std::unique_ptr<database::Database>{database_res.value()}); |
|
|
|
std::unique_ptr<database::Database>{database_res.value()}); |
|
|
|
|
|
|
|
|
|
|
|
ESP_LOGI(kTag, "storage loaded okay"); |
|
|
|
ESP_LOGI(kTag, "storage loaded okay"); |
|
|
|
StorageMounted ev{}; |
|
|
|
return true; |
|
|
|
events::System().Dispatch(ev); |
|
|
|
|
|
|
|
events::Audio().Dispatch(ev); |
|
|
|
|
|
|
|
events::Ui().Dispatch(ev); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void Running::exit() { |
|
|
|
auto Running::unmountStorage() -> void { |
|
|
|
sServices->database({}); |
|
|
|
sServices->database({}); |
|
|
|
sStorage.reset(); |
|
|
|
sStorage.reset(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void Running::react(const KeyLockChanged& ev) { |
|
|
|
|
|
|
|
if (IdleCondition()) { |
|
|
|
|
|
|
|
transit<Idle>(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void Running::react(const audio::PlaybackFinished& ev) { |
|
|
|
|
|
|
|
if (IdleCondition()) { |
|
|
|
|
|
|
|
transit<Idle>(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void Running::react(const StorageError& ev) { |
|
|
|
|
|
|
|
ESP_LOGW(kTag, "error loading storage"); |
|
|
|
|
|
|
|
// TODO.
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} // namespace states
|
|
|
|
} // namespace states
|
|
|
|
} // namespace system_fsm
|
|
|
|
} // namespace system_fsm
|
|
|
|