CDC Badge OS
Firmware for the CDC Badge v1.0 hardware security key
Loading...
Searching...
No Matches
EventBus.cpp
Go to the documentation of this file.
1#include "cdc_core/EventBus.h"
2#include "freertos/FreeRTOS.h"
3#include "freertos/queue.h"
4#include "cdc_log.h"
5#include "esp_timer.h"
6
7static const char* TAG = "EventBus";
8
9namespace cdc::core {
10
11static_assert(static_cast<size_t>(EventType::EVENT_COUNT) < 32,
12 "EventType count exceeds bitmask width; widen typeMask or change matching scheme");
13
14
19EventBus& EventBus::instance() {
20 static EventBus instance;
21 return instance;
22}
23
29bool EventBus::init(size_t queueSize) {
30 if (initialized_) {
31 LOG_W(TAG, "Already initialized");
32 return true;
33 }
34
35 queue_ = xQueueCreate(queueSize, sizeof(Event));
36 if (!queue_) {
37 LOG_E(TAG, "Failed to create event queue");
38 return false;
39 }
40
41 initialized_ = true;
42 LOG_I(TAG, "Initialized with queue size %u", queueSize);
43 return true;
44}
45
52uint8_t EventBus::subscribe(EventHandler handler, uint32_t mask) {
53 if (!handler) return 0;
54
55 for (uint8_t i = 0; i < MAX_HANDLERS; i++) {
56 if (!handlers_[i].active) {
57 handlers_[i].handler = handler;
58 handlers_[i].mask = mask;
59 handlers_[i].active = true;
60 LOG_D(TAG, "Handler %u subscribed (mask: 0x%08lx)", i + 1, mask);
61 return i + 1; // Return 1-based ID
62 }
63 }
64
65 LOG_E(TAG, "No free handler slots");
66 return 0;
67}
68
74void EventBus::unsubscribe(uint8_t id) {
75 if (id == 0 || id > MAX_HANDLERS) return;
76
77 handlers_[id - 1].active = false;
78 handlers_[id - 1].handler = nullptr;
79 LOG_D(TAG, "Handler %u unsubscribed", id);
80}
81
88bool EventBus::publish(const Event& event, bool fromISR) {
89 if (!initialized_ || !queue_) return false;
90
91 BaseType_t result;
92 if (fromISR) {
93 BaseType_t xHigherPriorityTaskWoken = pdFALSE;
94 result = xQueueSendFromISR(static_cast<QueueHandle_t>(queue_),
95 &event, &xHigherPriorityTaskWoken);
96 if (xHigherPriorityTaskWoken) {
97 portYIELD_FROM_ISR();
98 }
99 } else {
100 result = xQueueSend(static_cast<QueueHandle_t>(queue_),
101 &event, pdMS_TO_TICKS(10));
102 }
103
104 return result == pdTRUE;
105}
106
113bool EventBus::publish(EventType type, uint8_t value) {
114 Event event = {};
115 event.type = type;
116 event.timestamp = static_cast<uint32_t>(esp_timer_get_time() / 1000);
117 event.data.value = value;
118 return publish(event);
119}
120
126 if (!initialized_ || !queue_) return;
127
128 Event event;
129 while (xQueueReceive(static_cast<QueueHandle_t>(queue_),
130 &event, 0) == pdTRUE) {
131 // Dispatch to all matching handlers
132 uint32_t typeMask = 1u << static_cast<uint8_t>(event.type);
133
134 for (uint8_t i = 0; i < MAX_HANDLERS; i++) {
135 if (handlers_[i].active && handlers_[i].handler) {
136 // Check mask (0 = receive all)
137 if (handlers_[i].mask == 0 ||
138 (handlers_[i].mask & typeMask)) {
139 handlers_[i].handler(event);
140 }
141 }
142 }
143 }
144}
145
146} // namespace cdc::core
static const char * TAG
CDC Log: logging over TinyUSB CDC and UART.
#define LOG_W(tag, fmt,...)
Definition cdc_log.h:146
#define LOG_D(tag, fmt,...)
Definition cdc_log.h:148
#define LOG_I(tag, fmt,...)
Definition cdc_log.h:147
#define LOG_E(tag, fmt,...)
Definition cdc_log.h:145
void unsubscribe(uint8_t id)
Removes subscription by handler ID.
Definition EventBus.cpp:74
static EventBus & instance()
Returns singleton event-bus instance.
Definition EventBus.cpp:19
static constexpr size_t MAX_HANDLERS
Definition EventBus.h:77
bool publish(const Event &event, bool fromISR=false)
Publishes an event to the queue.
Definition EventBus.cpp:88
void process()
Drains queued events and dispatches matching handlers.
Definition EventBus.cpp:125
uint8_t subscribe(EventHandler handler, uint32_t mask=0)
Subscribes an event handler with optional type mask.
Definition EventBus.cpp:52
bool init(size_t queueSize=DEFAULT_QUEUE_SIZE)
Initializes event queue and internal state.
Definition EventBus.cpp:29
void(*)(const Event &) EventHandler
Definition EventBus.h:66
EventType type
Definition EventBus.h:54