CDC Badge OS
Firmware for the CDC Badge v1.0 hardware security key
Loading...
Searching...
No Matches
Prerequisites.cpp
Go to the documentation of this file.
3#include "cdc_hal/IRtc.h"
5#include "cdc_log.h"
6
7#include "esp_heap_caps.h"
8
9#include <cstdlib>
10
11namespace cdc::plugin_manager {
12
13static const char* TAG = "PLG_PRE";
14
15namespace {
16
17int as_int(const std::map<std::string, std::string>& params,
18 const std::string& key, int dflt)
19{
20 auto it = params.find(key);
21 if (it == params.end()) return dflt;
22 return std::atoi(it->second.c_str());
23}
24
25PrereqResult prereq_wifi_connected(const PrerequisiteSpec& spec)
26{
27 (void)spec;
30}
31
32PrereqResult prereq_time_synced(const PrerequisiteSpec&)
33{
34 auto* rtc = cdc::hal::getRtcInstance();
35 return (rtc && rtc->isTimeSet()) ? PrereqResult::Ok : PrereqResult::HardFailed;
36}
37
38PrereqResult prereq_battery_min(const PrerequisiteSpec& spec)
39{
40 int min_pct = as_int(spec.params, "min_pct", 0);
42 if (!p) return PrereqResult::HardFailed;
43 return (p->getBatteryPercent() >= min_pct) ? PrereqResult::Ok : PrereqResult::HardFailed;
44}
45
46PrereqResult prereq_usb_connected(const PrerequisiteSpec&)
47{
49 return (p && p->isUsbConnected()) ? PrereqResult::Ok : PrereqResult::HardFailed;
50}
51
52PrereqResult prereq_not_charging(const PrerequisiteSpec&)
53{
55 if (!p) return PrereqResult::HardFailed;
56 auto s = p->getChargeStatus();
57 bool charging = (s == cdc::hal::ChargeStatus::FAST_CHARGE) ||
60}
61
62PrereqResult prereq_min_free_psram(const PrerequisiteSpec& spec)
63{
64 int min_kb = as_int(spec.params, "kb", 0);
65 size_t free_b = heap_caps_get_free_size(MALLOC_CAP_SPIRAM);
66 return (free_b >= static_cast<size_t>(min_kb) * 1024)
68}
69
70PrereqResult prereq_min_free_dram(const PrerequisiteSpec& spec)
71{
72 int min_kb = as_int(spec.params, "kb", 0);
73 size_t free_b = heap_caps_get_free_size(MALLOC_CAP_INTERNAL);
74 return (free_b >= static_cast<size_t>(min_kb) * 1024)
76}
77
78PrereqResult prereq_unlocked(const PrerequisiteSpec&)
79{
80 // Plugin start happens from the post-unlock UI, so this is always true
81 // by the time we get here. Kept as an explicit prerequisite anyway so
82 // future paths (auto-start from boot etc.) can still gate on it.
83 return PrereqResult::Ok;
84}
85
86PrereqResult check_one(const PrerequisiteSpec& spec)
87{
88 if (spec.name == "wifi_connected") return prereq_wifi_connected(spec);
89 if (spec.name == "time_synced") return prereq_time_synced(spec);
90 if (spec.name == "battery_min") return prereq_battery_min(spec);
91 if (spec.name == "usb_connected") return prereq_usb_connected(spec);
92 if (spec.name == "not_charging") return prereq_not_charging(spec);
93 if (spec.name == "min_free_psram") return prereq_min_free_psram(spec);
94 if (spec.name == "min_free_dram") return prereq_min_free_dram(spec);
95 if (spec.name == "unlocked") return prereq_unlocked(spec);
96 LOG_W(TAG, "unknown prerequisite '%s' - treating as soft-pass", spec.name.c_str());
97 return PrereqResult::Ok;
98}
99
100void release_one(const std::string& prereq_name)
101{
102 if (prereq_name == "wifi_connected") {
104 }
105 // Other prerequisites are read-only - no cleanup.
106}
107
108} // namespace
109
111 std::string& out_failed_name,
112 std::string& out_on_fail)
113{
114 for (const auto& spec : plugin.manifest().prerequisites) {
115 PrereqResult r = check_one(spec);
116 if (r == PrereqResult::Ok) {
117 plugin.acquired_prereqs.push_back(spec.name);
118 continue;
119 }
120 out_failed_name = spec.name;
121 out_on_fail = spec.on_fail.empty() ? "abort" : spec.on_fail;
122 LOG_W(TAG, "prerequisite '%s' failed for %s (on_fail=%s)",
123 spec.name.c_str(), plugin.id().c_str(), out_on_fail.c_str());
124 if (out_on_fail == "abort") return PrereqResult::HardFailed;
126 }
127 return PrereqResult::Ok;
128}
129
131{
132 for (auto it = plugin.acquired_prereqs.rbegin();
133 it != plugin.acquired_prereqs.rend(); ++it) {
134 release_one(*it);
135 }
136 plugin.acquired_prereqs.clear();
137}
138
139} // namespace cdc::plugin_manager
Walks the prerequisites list of a plugin manifest before plugin_on_enter.
CDC Log: logging over TinyUSB CDC and UART.
#define LOG_W(tag, fmt,...)
Definition cdc_log.h:146
std::vector< std::string > acquired_prereqs
Definition Plugin.h:118
const std::string & id() const noexcept
Definition Plugin.h:89
const PluginManifest & manifest() const noexcept
Definition Plugin.h:88
static PrereqResult walk(Plugin &plugin, std::string &out_failed_name, std::string &out_on_fail)
Walk the plugin's prerequisite list in order. Marks acquired resources on the Plugin so release() can...
static void release(Plugin &plugin)
Release every resource the plugin acquired during walk(), in reverse order of acquisition.
void release()
Releases a previously acquired WiFi hold.
bool acquire()
Acquires a hold on the WiFi connection for a plugin/host caller.
static WifiHandlers & instance()
Returns singleton Wi-Fi handlers instance.
IPowerManager * getPowerManagerInstance()
Returns the singleton power manager instance.
IRtc * getRtcInstance()
Returns the singleton RTC service instance.
Definition Rtc.cpp:304
static const char * TAG
std::vector< PrerequisiteSpec > prerequisites
std::map< std::string, std::string > params