CDC Badge OS
Firmware for the CDC Badge v1.0 hardware security key
Loading...
Searching...
No Matches
UsbManager.cpp
Go to the documentation of this file.
2#include "cdc_log.h"
3#include "usb_badge/usb_hid.h"
4#include <string.h>
5
6static const char* TAG = "UsbManager";
7
8namespace cdc::core {
9
15 static UsbManager s_instance;
16 return s_instance;
17}
18
25 return true;
26}
27
33 state_ = ServiceState::STARTED;
34 return true;
35}
36
41 state_ = ServiceState::STOPPED;
42}
43
48uint8_t UsbManager::activeHidCount() const {
49 uint8_t count = 0;
50 for (const auto& entry : entries_) {
51 if (entry.active) count++;
52 }
53 return count;
54}
55
61bool UsbManager::canActivate(UsbHidInterface type) const {
62 (void)type;
63 return activeHidCount() < MAX_ACTIVE_HID;
64}
65
73bool UsbManager::registerInterface(UsbHidInterface type, const char* moduleName,
74 const UsbInterfaceSpec& def) {
75 const uint8_t idx = static_cast<uint8_t>(type);
76 if (idx >= (sizeof(entries_) / sizeof(entries_[0]))) return false;
77
78 auto& entry = entries_[idx];
79 if (entry.active) {
80 if (entry.owner && moduleName && strcmp(entry.owner, moduleName) == 0) {
81 return true;
82 }
83 LOG_W(TAG, "Interface %d already owned by %s", idx, entry.owner ? entry.owner : "?");
84 return false;
85 }
86
87 if (!canActivate(type)) {
88 LOG_W(TAG, "HID interface limit reached (max %d)", MAX_ACTIVE_HID);
89 return false;
90 }
91
92 entry.active = true;
93 entry.owner = moduleName;
94 entry.def = def;
95 activeMask_ |= (1u << idx);
96 LOG_I(TAG, "Registered HID interface %d for %s", idx, moduleName ? moduleName : "?");
98 return true;
99}
100
106void UsbManager::unregisterInterface(UsbHidInterface type, const char* moduleName) {
107 const uint8_t idx = static_cast<uint8_t>(type);
108 if (idx >= (sizeof(entries_) / sizeof(entries_[0]))) return;
109
110 auto& entry = entries_[idx];
111 if (!entry.active) return;
112 if (entry.owner && moduleName && strcmp(entry.owner, moduleName) != 0) {
113 LOG_W(TAG, "Interface %d owned by %s, not %s", idx,
114 entry.owner ? entry.owner : "?", moduleName ? moduleName : "?");
115 return;
116 }
117
118 entry.active = false;
119 entry.owner = nullptr;
120 entry.def = {};
121 activeMask_ &= ~(1u << idx);
122 LOG_I(TAG, "Unregistered HID interface %d", idx);
124}
125
131 needsReplug_ = false;
132 UsbInterfaceSpec defs[3] = {};
133 size_t count = 0;
134
135 auto append_def = [&](UsbHidInterface type) {
136 const auto& entry = entries_[static_cast<uint8_t>(type)];
137 if (!entry.active) return;
138 defs[count++] = entry.def;
139 };
140
141 append_def(UsbHidInterface::Fido);
142 append_def(UsbHidInterface::Keyboard);
143 append_def(UsbHidInterface::Ccid);
144
145 bool replug_needed = false;
146 bool ok = usb_hid_apply_config(defs, count, &replug_needed);
147 if (!ok || replug_needed) {
148 needsReplug_ = true;
149 }
150 return ok;
151}
152
153} // 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_I(tag, fmt,...)
Definition cdc_log.h:147
bool init() override
Initializes USB manager service state.
bool registerInterface(UsbHidInterface type, const char *moduleName, const UsbInterfaceSpec &def)
Registers a HID interface request from a module.
bool start() override
Starts USB manager service state.
static UsbManager & instance()
Returns singleton USB manager instance.
void unregisterInterface(UsbHidInterface type, const char *moduleName)
Unregisters a previously registered HID interface.
void stop() override
Stops USB manager service state.
bool applyConfiguration()
Applies current interface set to USB HID stack.
bool usb_hid_apply_config(const UsbInterfaceDef *defs, size_t count, bool *needs_replug)
Applies the runtime interface configuration and optionally triggers re-enumeration.
Definition usb_hid.cpp:367