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
23struct PluginSubscription {
24 void* plugin = nullptr;
25 uint32_t action_id = 0;
26 uint32_t mask = 0;
27 uint8_t bus_id = 0;
28 bool used = false;
29};
30
31constexpr size_t MAX_PLUGIN_SUBSCRIPTIONS = 16;
33
34// on_bus_event is registered with the core EventBus exactly once; the per-plugin
35// fan-out happens in on_bus_event, so plugin subscriptions never consume more
36// than one slot of the small core handler table.
37bool s_core_subscribed = false;
38uint8_t s_core_bus_id = 0;
39
40PluginSubscription* slotForId(uint32_t id) {
41 return s_subs.lookup(static_cast<int>(id));
42}
43
44// Keep the keypad in deferred short-press mode whenever any plugin is
45// subscribed to KEY_LONG_PRESS, so a held key yields only the long-press and
46// not the tap. Recomputed from the table on every subscribe/unsubscribe.
47void update_long_press_defer() {
48 constexpr uint32_t kLongPressBit =
49 1u << static_cast<uint8_t>(cdc::core::EventType::KEY_LONG_PRESS);
50 bool wanted = false;
51 for (auto& s : s_subs.slots) {
52 if (s.used && (s.mask & kLongPressBit)) {
53 wanted = true;
54 break;
55 }
56 }
57 if (auto* kp = cdc::hal::getKeypadInstance()) {
58 kp->setDeferShortPress(cdc::hal::IKeypad::DEFER_SRC_EVENT, wanted);
59 }
60}
61
62void on_bus_event(const cdc::core::Event& evt) {
63 const uint32_t bit = 1u << static_cast<uint8_t>(evt.type);
64 for (auto& s : s_subs.slots) {
65 if (!s.used || (s.mask & bit) == 0) continue;
66 auto* plugin = static_cast<cdc::plugin_manager::Plugin*>(s.plugin);
68 plugin,
69 s.action_id,
70 static_cast<uint32_t>(evt.type),
71 evt.data.value);
72 }
73}
74
75} // namespace
76
77extern "C" {
78
79int host_event_subscribe(uint32_t event_mask, uint32_t action_id)
80{
81 auto* plugin = plg_get_active_plugin();
82 if (!plugin) return HOST_ERR_NO_CAPABILITY;
83
84 int slot_id = 0;
85 PluginSubscription* slot = s_subs.allocate(slot_id);
86 if (!slot) {
87 plg_log_warn("EventBus: plugin subscription table full");
88 return HOST_ERR_NO_MEMORY;
89 }
90
91 slot->plugin = plugin;
92 slot->action_id = action_id;
93 slot->mask = event_mask;
94 slot->used = true;
95 if (!s_core_subscribed) {
96 s_core_bus_id = cdc::core::EventBus::instance().subscribe(on_bus_event, 0xFFFFFFFFu);
97 s_core_subscribed = true;
98 }
99 slot->bus_id = s_core_bus_id;
100
101 update_long_press_defer();
102 return slot_id;
103}
104
105int host_event_unsubscribe(uint32_t subscription_id)
106{
107 auto* slot = slotForId(subscription_id);
108 if (!slot) return HOST_ERR_NOT_FOUND;
109 // The shared core subscription stays registered for the process lifetime;
110 // only the per-plugin fan-out slot is released here.
111 *slot = PluginSubscription{};
112 update_long_press_defer();
113 return HOST_OK;
114}
115
116int host_event_publish(uint32_t module_event_subtype, uint32_t value)
117{
118 // The v1 Event carries a single byte (data.value), defined by the core as the
119 // module-event sub-type. The separate `value` argument has no transport slot
120 // in this model and is not forwarded to subscribers.
121 (void)value;
122 cdc::core::Event evt{};
124 evt.timestamp = 0;
125 evt.data.value = static_cast<uint8_t>(module_event_subtype & 0xff);
127 return HOST_OK;
128}
129
130} // 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
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)
int host_event_publish(uint32_t module_event_subtype, uint32_t value)
Publish an EVENT_MODULE_EVENT carrying subtype and value.
int host_event_unsubscribe(uint32_t subscription_id)
Cancel a subscription returned by host_event_subscribe.
int host_event_subscribe(uint32_t event_mask, uint32_t action_id)
Subscribe to one or more events.
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:58
uint32_t timestamp
Definition EventBus.h:55
union cdc::core::Event::@234350273243204124075032151001065005273232113040 data
EventType type
Definition EventBus.h:54
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