CDC Badge OS
Firmware for the CDC Badge v1.0 hardware security key
Loading...
Searching...
No Matches
host_api_event.cpp
Go to the documentation of this file.
1
10
11#include "cdc_core/EventBus.h"
12#include "cdc_hal/IKeypad.h"
17
18extern "C" void* plg_get_active_plugin(void);
19extern "C" void plg_log_warn(const char* msg);
20
21namespace {
22
23// The public EVENT_* bits (host_api.h) MUST equal 1u << the matching core
24// EventType ordinal, because on_bus_event matches subscriptions with
25// `1u << evt.type`. cdc::core::EventType is the single source of truth; these
26// asserts fail the build if the enum is ever reordered out from under the
27// public constants (instead of silently breaking plugin subscriptions).
45
46struct PluginSubscription {
47 void* plugin = nullptr;
48 uint32_t action_id = 0;
49 uint32_t mask = 0;
50 uint8_t bus_id = 0;
51 bool used = false;
52};
53
54constexpr size_t MAX_PLUGIN_SUBSCRIPTIONS = 16;
56
57// on_bus_event is registered with the core EventBus exactly once; the per-plugin
58// fan-out happens in on_bus_event, so plugin subscriptions never consume more
59// than one slot of the small core handler table.
60bool s_core_subscribed = false;
61uint8_t s_core_bus_id = 0;
62
63PluginSubscription* slotForId(uint32_t id) {
64 return s_subs.lookup(static_cast<int>(id));
65}
66
67// Keep the keypad in deferred short-press mode whenever any plugin is
68// subscribed to KEY_LONG_PRESS, so a held key yields only the long-press and
69// not the tap. Recomputed from the table on every subscribe/unsubscribe.
70void update_long_press_defer() {
71 constexpr uint32_t kLongPressBit =
72 1u << static_cast<uint8_t>(cdc::core::EventType::KEY_LONG_PRESS);
73 bool wanted = false;
74 for (auto& s : s_subs.slots) {
75 if (s.used && (s.mask & kLongPressBit)) {
76 wanted = true;
77 break;
78 }
79 }
80 if (auto* kp = cdc::hal::getKeypadInstance()) {
81 kp->setDeferShortPress(cdc::hal::IKeypad::DEFER_SRC_EVENT, wanted);
82 }
83}
84
85void on_bus_event(const cdc::core::Event& evt) {
86 const uint32_t bit = 1u << static_cast<uint8_t>(evt.type);
87 for (auto& s : s_subs.slots) {
88 if (!s.used || (s.mask & bit) == 0) continue;
89 auto* plugin = static_cast<cdc::plugin_manager::Plugin*>(s.plugin);
91 plugin,
92 s.action_id,
93 static_cast<uint32_t>(evt.type),
94 evt.data.value);
95 }
96}
97
98} // namespace
99
100extern "C" {
101
102int host_event_subscribe(uint32_t event_mask, uint32_t action_id)
103{
104 auto* plugin = plg_get_active_plugin();
105 if (!plugin) return HOST_ERR_NO_CAPABILITY;
106
107 int slot_id = 0;
108 PluginSubscription* slot = s_subs.allocate(slot_id);
109 if (!slot) {
110 plg_log_warn("EventBus: plugin subscription table full");
111 return HOST_ERR_NO_MEMORY;
112 }
113
114 slot->plugin = plugin;
115 slot->action_id = action_id;
116 slot->mask = event_mask;
117 slot->used = true;
118 if (!s_core_subscribed) {
119 s_core_bus_id = cdc::core::EventBus::instance().subscribe(on_bus_event, 0xFFFFFFFFu);
120 s_core_subscribed = true;
121 }
122 slot->bus_id = s_core_bus_id;
123
124 update_long_press_defer();
125 return slot_id;
126}
127
128int host_event_unsubscribe(uint32_t subscription_id)
129{
130 auto* slot = slotForId(subscription_id);
131 if (!slot) return HOST_ERR_NOT_FOUND;
132 // The shared core subscription stays registered for the process lifetime;
133 // only the per-plugin fan-out slot is released here.
134 *slot = PluginSubscription{};
135 update_long_press_defer();
136 return HOST_OK;
137}
138
139int host_event_publish(uint32_t module_event_subtype, uint32_t value)
140{
141 // The v1 Event carries a single byte (data.value), defined by the core as the
142 // module-event sub-type. The separate `value` argument has no transport slot
143 // in this model and is not forwarded to subscribers.
144 (void)value;
145 cdc::core::Event evt{};
147 evt.timestamp = 0;
148 evt.data.value = static_cast<uint8_t>(module_event_subtype & 0xff);
150 return HOST_OK;
151}
152
153} // extern "C"
Discovers, loads, runs and unloads WASM plugins on the badge.
Owned WAMR module instance + per-plugin state.
Fixed-capacity, 1-based slot table for host-API resources.
static EventBus & instance()
Returns singleton event-bus instance.
Definition EventBus.cpp:19
bool publish(const Event &event, bool fromISR=false)
Publishes an event to the queue.
Definition EventBus.cpp:88
static constexpr uint32_t eventMask(EventType type)
Definition EventBus.h:139
uint8_t subscribe(EventHandler handler, uint32_t mask=0)
Subscribes an event handler with optional type mask.
Definition EventBus.cpp:52
static constexpr uint32_t DEFER_SRC_EVENT
plugin KEY_LONG_PRESS subscription
Definition IKeypad.h:91
static PluginManager & instance() noexcept
void dispatchActionTo(Plugin *plugin, uint32_t action_id, uint32_t idx, uint32_t user_data)
#define EVENT_SYSTEM_UNLOCK
Definition host_api.h:1673
#define EVENT_SYSTEM_LOCK
Definition host_api.h:1674
#define EVENT_TIMER_TICK
Definition host_api.h:1679
#define EVENT_POWER_CHARGING
Definition host_api.h:1670
#define EVENT_KEY_PRESSED
Definition host_api.h:1665
#define EVENT_POWER_BATT_CRIT
Definition host_api.h:1672
int host_event_publish(uint32_t module_event_subtype, uint32_t value)
Publish an EVENT_MODULE_EVENT carrying subtype and value.
#define EVENT_SYSTEM_SLEEP
Definition host_api.h:1675
int host_event_unsubscribe(uint32_t subscription_id)
Cancel a subscription returned by host_event_subscribe.
#define EVENT_BLE_CONNECTED
Definition host_api.h:1677
#define EVENT_POWER_USB_CONN
Definition host_api.h:1668
#define EVENT_POWER_USB_DISCONN
Definition host_api.h:1669
#define EVENT_MODULE_EVENT
Definition host_api.h:1680
#define EVENT_KEY_LONG_PRESS
Definition host_api.h:1667
int host_event_subscribe(uint32_t event_mask, uint32_t action_id)
Subscribe to one or more events.
#define EVENT_BLE_DISCONNECTED
Definition host_api.h:1678
#define EVENT_DISPLAY_REFRESH
Definition host_api.h:1684
#define EVENT_POWER_BATT_LOW
Definition host_api.h:1671
#define EVENT_SYSTEM_WAKE
Definition host_api.h:1676
#define EVENT_KEY_RELEASED
Definition host_api.h:1666
CDC Badge OS plugin host API - canonical C ABI contract.
#define HOST_ERR_NO_CAPABILITY
Definition host_api.h:40
#define HOST_OK
Definition host_api.h:37
#define HOST_ERR_NO_MEMORY
Definition host_api.h:43
#define HOST_ERR_NOT_FOUND
Definition host_api.h:41
void plg_log_warn(const char *msg)
void * plg_get_active_plugin(void)
IKeypad * getKeypadInstance()
Returns the singleton keypad service instance.
uint8_t value
Definition EventBus.h:70
uint32_t timestamp
Definition EventBus.h:67
union cdc::core::Event::@234350273243204124075032151001065005273232113040 data
EventType type
Definition EventBus.h:66
T * lookup(int id)
1-based lookup. Returns nullptr if id is out of range or slot unused.
Definition SlotTable.h:26
std::array< T, N > slots
Definition SlotTable.h:21
T * allocate(int &out_id)
Definition SlotTable.h:37