CDC Badge OS
Firmware for the CDC Badge v1.0 hardware security key
Loading...
Searching...
No Matches
BleSerialModule.cpp
Go to the documentation of this file.
1
5
10#include "cdc_ui/I18n.h"
11#include "cdc_ui/ViewStack.h"
12#include "cdc_views/ToastView.h"
13#include "cdc_log.h"
14#include "nvs.h"
15#include <cstring>
16
17static const char* TAG = "BLE_SERIAL";
18
19namespace cdc::mod_ble_serial {
20
21constexpr ui::I18nEntry kStrings[] = {
22 {"mod_ble_serial.title", "BLE Serial"},
23 {"mod_ble_serial.enabled", "Enabled"},
24 {"mod_ble_serial.disabled", "Disabled"},
25};
26
27void BleSerialModule::registerStrings() {
29}
30
32
39static void bleOutputHook(const char* data, size_t len) {
40 auto& uart = BleUartService::instance();
41 if (uart.isConnected() && uart.isInitialized()) {
42 uart.send(reinterpret_cast<const uint8_t*>(data), len);
43 }
44}
45
50static bool bleInputAvailableHook() {
51 auto& uart = BleUartService::instance();
52 return uart.isConnected() && uart.available() > 0;
53}
54
59static int bleInputGetcharHook() {
60 auto& uart = BleUartService::instance();
61 return uart.getchar();
62}
63
67void BleSerialModule::registerConsoleHooks() {
70 LOG_I(TAG, "Console hooks registered");
71}
72
76void BleSerialModule::unregisterConsoleHooks() {
78 console_register_input_hook(nullptr, nullptr);
79 LOG_I(TAG, "Console hooks unregistered");
80}
81
85void BleSerialModule::registerPairingCallback() {
86}
87
89
93void BleSerialModule::loadSettings() {
94 nvs_handle_t nvs;
95 if (nvs_open(NVS_NAMESPACE, NVS_READONLY, &nvs) == ESP_OK) {
96 uint8_t val = 0;
97 if (nvs_get_u8(nvs, "enabled", &val) == ESP_OK) {
98 enabled_ = (val != 0);
99 }
100 nvs_close(nvs);
101 }
102}
103
107void BleSerialModule::saveSettings() {
108 nvs_handle_t nvs;
109 if (nvs_open(NVS_NAMESPACE, NVS_READWRITE, &nvs) == ESP_OK) {
110 nvs_set_u8(nvs, "enabled", enabled_ ? 1 : 0);
111 nvs_commit(nvs);
112 nvs_close(nvs);
113 }
114}
115
117
122BleSerialModule& BleSerialModule::instance() {
123 static BleSerialModule inst;
124 return inst;
125}
126
132 LOG_I(TAG, "Initializing BLE Serial module");
133
134 registerStrings();
135 loadSettings();
136
138 return true;
139}
140
146 if (state_ != core::ServiceState::INITIALIZED &&
147 state_ != core::ServiceState::STOPPED) {
148 return false;
149 }
150
151 // If auto-enable is set and BLE is enabled, start the service
152 if (enabled_) {
154 if (ble && ble->isEnabled()) {
155 auto& uart = BleUartService::instance();
156 if (uart.init()) {
157 registerConsoleHooks();
158 registerPairingCallback();
159 LOG_I(TAG, "BLE Serial service started");
160 }
161 }
162 }
163
165 return true;
166}
167
172 if (enabled_) {
173 unregisterConsoleHooks();
175 }
177}
178
184 if (!ble) {
185 ui::showToastError("BLE n/a");
186 return;
187 }
188
189 if (!ble->isEnabled()) {
190 ui::showToastError("BLE disabled");
191 return;
192 }
193
194 enabled_ = !enabled_;
195 saveSettings();
196
197 if (enabled_) {
198 auto& uart = BleUartService::instance();
199 if (uart.init()) {
200 registerConsoleHooks();
201 registerPairingCallback();
202 ui::showToastSuccess(ui::tr("mod_ble_serial.enabled"));
203 } else {
204 enabled_ = false;
205 saveSettings();
206 ui::showToastError("Init failed");
207 }
208 } else {
209 unregisterConsoleHooks();
211 ui::showToastInfo(ui::tr("mod_ble_serial.disabled"));
212 }
213}
214
221uint8_t BleSerialModule::getMenuItems(core::ModuleMenuItem* items, uint8_t maxItems) {
222 if (!items || maxItems == 0) return 0;
223
224 // Build label with status
225 snprintf(labelBuf_, LABEL_BUF_SIZE, "%s: %s",
226 ui::tr("mod_ble_serial.title"),
227 enabled_ ? ui::tr("mod_ble_serial.enabled") : ui::tr("mod_ble_serial.disabled"));
228
229 items[0].label = labelBuf_;
230 items[0].priority = 50;
231 items[0].getView = nullptr;
232 items[0].isVisible = nullptr;
233 items[0].moduleName = getName();
235 items[0].onSelect = []() { BleSerialModule::instance().toggle(); };
236
237 return 1;
238}
239
244void BleSerialModule::onTick(uint32_t nowMs) {
245 (void)nowMs;
246 // Could check connection state changes here if needed
247}
248
249} // namespace cdc::mod_ble_serial
250
254extern "C" void mod_ble_serial_register() {
256 auto& moduleReg = cdc::core::ModuleRegistry::instance();
257 auto& module = cdc::mod_ble_serial::BleSerialModule::instance();
258
259 moduleReg.registerModule(&module);
260
261 if (!module.init()) {
262 moduleReg.reportModuleError(module.getName(), "Init failed");
263 }
264 });
265}
static const char * TAG
void mod_ble_serial_register()
Registers BLE serial module initializer.
Internationalization with English fallbacks in code and overlay translations loaded at runtime from a...
CDC Log: logging over TinyUSB CDC and UART.
void console_register_input_hook(console_input_available_hook_t avail_hook, console_input_getchar_hook_t getchar_hook)
Registers the console input hooks (only one set supported at a time).
Definition cdc_log.cpp:416
#define LOG_I(tag, fmt,...)
Definition cdc_log.h:147
void console_register_output_hook(console_output_hook_t hook)
Registers the console output hook (only one supported at a time).
Definition cdc_log.cpp:407
static ModuleRegistry & instance()
Returns the singleton module registry instance.
void registerInitializer(ModuleInitFunc initFunc)
Registers a deferred module initializer callback.
static BleSerialModule & instance()
BLE serial module lifecycle implementation.
uint8_t getMenuItems(core::ModuleMenuItem *items, uint8_t maxItems) override
Provides Bluetooth-menu item for BLE serial toggle.
bool start() override
Starts BLE serial module and optionally auto-enables service.
void onTick(uint32_t nowMs) override
Periodic module tick hook.
void stop() override
Stops BLE serial module and deinitializes UART service when enabled.
bool init() override
Initializes BLE serial module resources and settings.
void toggle()
Toggles BLE serial service state and updates persisted setting.
const char * getName() const override
void deinit()
Deinitializes BLE UART service runtime state.
static BleUartService & instance()
Returns singleton BLE UART service instance.
static I18n & instance()
Singleton accessor.
Definition I18n.cpp:287
void registerEnglishTable(const I18nEntry *entries, std::size_t count)
Append English entries to the lookup table.
Definition I18n.cpp:307
IBluetoothController * getBluetoothControllerInstance()
Returns singleton Bluetooth stub when NimBLE is unavailable.
static bool bleInputAvailableHook()
Console input-available hook using BLE UART RX queue.
constexpr ui::I18nEntry kStrings[]
static int bleInputGetcharHook()
Console getchar hook reading one byte from BLE UART.
static void bleOutputHook(const char *data, size_t len)
Console hook bridge between shell I/O and BLE UART transport.
const char * tr(const char *key)
Look up a translation by string key.
Definition I18n.h:208
void showToastSuccess(const char *message, uint16_t durationMs=1500)
Shows a success toast message.
void showToastInfo(const char *message, uint16_t durationMs=1500)
Shows an informational toast message.
void showToastError(const char *message, uint16_t durationMs=1500)
Shows an error toast message.
Menu item registered by a module.
Definition IModule.h:29
ui::IView *(* getView)()
Definition IModule.h:32
MenuLocation location
Definition IModule.h:35
const char * moduleName
Definition IModule.h:34
Single English translation entry.
Definition I18n.h:44