Skip to content

Commit 118b371

Browse files
author
Krim
committed
Upgrade docs, reduce RAM usage, and fix minor bugs (plugin power_source mapping, serial diagnostic label)
1 parent 5c180b5 commit 118b371

36 files changed

Lines changed: 369 additions & 517 deletions

README.md

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,16 +27,16 @@ Modular firmware for the CDC Badge v1.0/v1.1 hardware security key featuring TRO
2727
| **TOTP Authenticator** | Working | Time-based OTP (100 accounts, Google Authenticator compatible) |
2828
| **Password Vault** | Working | Secure password storage (369 entries) |
2929
| **GPG/CCID** | Working (UI WIP) | OpenPGP smartcard via USB CCID, sign / encrypt / decrypt / SSH end-to-end with GnuPG |
30-
| **BLE vCard** | WIP | Badge-to-badge contact exchange via BLE |
31-
| **BLE HID** | WIP | Bluetooth keyboard for auto-type |
30+
| **BLE vCard** | Working | Badge-to-badge contact exchange via BLE |
31+
| **BLE HID** | Working | Bluetooth keyboard for auto-type |
3232
| **WiFi + NTP** | Working | Time synchronization over WiFi, serial control (scan, connect, status, ..) |
33-
| **BLE Serial** | WIP | Bluetooth serial console (Nordic UART Service) |
33+
| **BLE Serial** | Working | Bluetooth serial console (Nordic UART Service) |
3434
| **SAO Detection** | Working | Shitty Add-On port detection and info |
3535
| **E-Paper Display** | Working | 2.9" low-power display with backlight |
3636
| **12-Button Keypad** | Working | Phone-style T9 input |
3737
| **Multi-Language** | Working | English and German UI |
3838
| **Secure Serial** | Working | PIN authentication for serial commands |
39-
| **WASM Plugin Runtime** | WIP | Sandboxed third-party plugins via WebAssembly (WAMR Fast Interpreter). Host API exposes 80+ symbols under module `"cdc"`, including a Canvas view for plugin-drawn UIs. |
39+
| **WASM Plugin Runtime** | Working | Sandboxed third-party plugins via WebAssembly (WAMR). The host API under module `"cdc"` covers NVS, vFAT, i18n, HTTP/WiFi, GPIO/ADC/I2C, Pixel-Strip, BLE, SecureElement, Crypto, and UI views including a Canvas for plugin-drawn UIs. |
4040
| **vFAT File Browser** | Working | On-device file explorer (Tools  Expert) and a `VFAT` serial shell for the plugins FAT partition. |
4141

4242
### Planned
@@ -56,9 +56,9 @@ partition and can be installed / updated without re-flashing.
5656
| Web installer | [krim404.github.io/cdc-badge-plugins](https://krim404.github.io/cdc-badge-plugins/) |
5757
| SDK + examples + source | [github.com/krim404/cdc-badge-plugins](https://github.com/krim404/cdc-badge-plugins) |
5858

59-
The plugin host API surface (80+ functions: NVS, sandboxed vFAT file access,
60-
i18n, HTTP, WiFi, GPIO, ADC, I2C, Pixel-Strip, BLE, SecureElement, Crypto, UI
61-
views, Canvas, RGB Color Picker, …) is defined canonically in
59+
The plugin host API surface (NVS, sandboxed vFAT file access, i18n, HTTP, WiFi,
60+
GPIO, ADC, I2C, Pixel-Strip, BLE, SecureElement, Crypto, UI views, Canvas, RGB
61+
Color Picker, …) is defined canonically in
6262
[`components/plugin_manager/include/plugin_manager/host_api.h`](components/plugin_manager/include/plugin_manager/host_api.h)
6363
and mirrored byte-identical into the SDK repo.
6464

@@ -129,7 +129,8 @@ reset.
129129
- Tamper-resistant key storage
130130
- Keys cannot be extracted or cloned
131131

132-
See [Module Development Guide](docs/MODULE_DEVELOPMENT.md) for the storage map.
132+
See [Module Development Guide](docs/MODULE_DEVELOPMENT.md) for the storage map
133+
(canonical source: `main/tropic_slot_map.h`).
133134

134135
## Hardware
135136

@@ -163,7 +164,7 @@ pip install -r tools/requirements.txt
163164
python tools/flash_firmware.py --release latest
164165

165166
# Flash a specific version
166-
python tools/flash_firmware.py --release v0.4.1
167+
python tools/flash_firmware.py --release latest
167168

168169
# Flash from a local directory
169170
python tools/flash_firmware.py --dir ./artifacts/

components/cdc_core/src/ModuleRegistry.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ namespace cdc::core {
2020
* \return Registry singleton reference.
2121
*/
2222
ModuleRegistry& ModuleRegistry::instance() {
23-
static ModuleRegistry instance;
24-
return instance;
23+
static ModuleRegistry* instance = new ModuleRegistry();
24+
return *instance;
2525
}
2626

2727
/**

components/cdc_hal/src/BluetoothController.cpp

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "cdc_hal/hw_config.h"
1010
#include "cdc_log.h"
1111
#include "sdkconfig.h"
12+
#include "esp_attr.h"
1213

1314
static const char* TAG = "BT-Ctrl";
1415

@@ -96,7 +97,7 @@ struct InternalService {
9697
uint8_t numChars = 0;
9798
};
9899

99-
static InternalService s_services[MAX_REGISTERED_SERVICES];
100+
EXT_RAM_BSS_ATTR static InternalService s_services[MAX_REGISTERED_SERVICES];
100101

101102
/**
102103
* \brief Converts a generic BLE UUID into NimBLE's `ble_uuid_any_t` format.
@@ -152,7 +153,7 @@ static ble_gatt_chr_flags mapProperties(uint8_t props, uint8_t perms) {
152153
* cannot race with itself. Hoisting it out of `gattServiceAccessCb` reclaims
153154
* roughly 1 KB of host-task stack per call.
154155
*/
155-
static uint8_t s_gattAccessBuf[512];
156+
EXT_RAM_BSS_ATTR static uint8_t s_gattAccessBuf[512];
156157

157158
static int gattServiceAccessCb(uint16_t connHandle, uint16_t attrHandle,
158159
struct ble_gatt_access_ctxt* ctxt, void* arg) {
@@ -2126,17 +2127,13 @@ void BluetoothController::setWriteCompleteCallback(WriteCompleteCallback cb) {
21262127
if (cb) addListener(writeCompleteCallbacks_, cb);
21272128
}
21282129

2129-
/**
2130-
* \brief Singleton Bluetooth controller instance.
2131-
*/
2132-
static BluetoothController g_bluetoothController;
2133-
21342130
/**
21352131
* \brief Returns the singleton Bluetooth controller instance.
21362132
* \return Pointer to the global `IBluetoothController` implementation.
21372133
*/
21382134
IBluetoothController* getBluetoothControllerInstance() {
2139-
return &g_bluetoothController;
2135+
static BluetoothController* g_bluetoothController = new BluetoothController();
2136+
return g_bluetoothController;
21402137
}
21412138

21422139
} // namespace cdc::hal

components/cdc_hal/src/TCA9535Keypad.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@
99
#include "cdc_core/SystemLock.h"
1010
#include "cdc_log.h"
1111
#include "esp_attr.h"
12+
#include "esp_heap_caps.h"
1213
#include "driver/gpio.h"
1314
#include "freertos/FreeRTOS.h"
15+
#include "freertos/idf_additions.h"
1416
#include "freertos/task.h"
1517
#include "freertos/semphr.h"
1618

@@ -241,8 +243,8 @@ bool TCA9535Keypad::init() {
241243
}
242244

243245
// Create task
244-
BaseType_t ret = xTaskCreate(taskFunc, "keypad", TASK_STACK_SIZE,
245-
this, TASK_PRIORITY, &taskHandle_);
246+
BaseType_t ret = xTaskCreateWithCaps(taskFunc, "keypad", TASK_STACK_SIZE,
247+
this, TASK_PRIORITY, &taskHandle_, MALLOC_CAP_SPIRAM);
246248
if (ret != pdPASS) {
247249
LOG_E(TAG, "Failed to create task");
248250
vSemaphoreDelete(semaphore_);

components/cdc_os_ui/src/WifiMenuUi.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "freertos/FreeRTOS.h"
1616
#include "freertos/task.h"
1717
#include "esp_timer.h"
18+
#include "esp_attr.h"
1819

1920
namespace cdc::ui {
2021

@@ -73,7 +74,7 @@ static ListItem s_wifiAuthItems[WIFI_AUTH_COUNT];
7374
static ListItem s_wifiIpItems[WIFI_IP_COUNT];
7475
static ListItem s_wifiScanItems[WIFI_MAX_NETWORKS + 1];
7576
static char s_wifiManualLabel[48];
76-
static WifiItem s_wifiScanResults[WIFI_MAX_NETWORKS];
77+
EXT_RAM_BSS_ATTR static WifiItem s_wifiScanResults[WIFI_MAX_NETWORKS];
7778
static uint8_t s_wifiScanCount = 0;
7879
static const char* s_wifiAuthLabels[WIFI_AUTH_COUNT] = {
7980
"WPA2", "WPA/WPA2", "WPA3", "WPA", "Open", "WEP"

components/mod_ble_serial/src/BleUartService.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ static const uint8_t NUS_TX_UUID[16] = {
3333
* \return Service singleton reference.
3434
*/
3535
BleUartService& BleUartService::instance() {
36-
static BleUartService inst;
37-
return inst;
36+
static BleUartService* inst = new BleUartService();
37+
return *inst;
3838
}
3939

4040
/**

components/mod_fido2/src/Fido2Ui.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "cdc_views/ListView.h"
2222
#include "cdc_views/PinEntryView.h"
2323
#include "cdc_views/ToastView.h"
24+
#include <esp_attr.h>
2425
#include <freertos/FreeRTOS.h>
2526
#include <freertos/semphr.h>
2627
#include <algorithm>
@@ -56,7 +57,7 @@ static ui::InfoView* s_promptView = nullptr;
5657
static ui::PinEntryView* s_pinEntry = nullptr;
5758

5859
static ui::ListItem s_listItems[FIDO2_MAX_CREDENTIALS];
59-
static char s_labels[FIDO2_MAX_CREDENTIALS][100];
60+
EXT_RAM_BSS_ATTR static char s_labels[FIDO2_MAX_CREDENTIALS][100];
6061
static uint8_t s_sortMap[FIDO2_MAX_CREDENTIALS];
6162
static uint8_t s_listCount = 0;
6263

components/mod_gpg/src/GpgModule.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,7 @@ struct WizardState {
384384
uint8_t curve;
385385
};
386386

387-
static WizardState s_wizard = {};
387+
EXT_RAM_BSS_ATTR static WizardState s_wizard = {};
388388

389389
enum GpgMenuAction : uintptr_t {
390390
GPG_MENU_STATUS = 1,

components/mod_nvsedit/src/NvsEditModule.cpp

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "cdc_views/InfoView.h"
1414
#include "cdc_views/ToastView.h"
1515
#include "cdc_log.h"
16+
#include "esp_attr.h"
1617
#include "nvs_flash.h"
1718
#include "nvs.h"
1819
#include <cstring>
@@ -28,6 +29,9 @@ namespace cdc::mod_nvsedit {
2829
/** \brief Returns the NVS editor entry view callback target. */
2930
static IView* getNvsEditorView();
3031

32+
/** \brief Rebuilds key list labels into s_keyLabels and refreshes the key list view. */
33+
static void rebuildKeyListView();
34+
3135
/** \brief Upper bounds for list sizes and value preview buffers. */
3236

3337
static constexpr uint8_t MAX_NAMESPACES = 32;
@@ -336,16 +340,7 @@ static void onDeleteKey() {
336340
if (deleteKey(s_selectedNamespace, s_selectedKey)) {
337341
showToastInfo("Deleted");
338342
loadKeys(s_selectedNamespace);
339-
// Update list
340-
for (uint8_t i = 0; i < s_keyCount; i++) {
341-
static char keyLabels[MAX_KEYS][24];
342-
snprintf(keyLabels[i], sizeof(keyLabels[i]), "%s [%s]",
343-
s_keys[i], nvsTypeToString(s_keyTypes[i]));
344-
s_keyItems[i] = {keyLabels[i], 0, false, nullptr};
345-
}
346-
if (s_keyListView) {
347-
s_keyListView->init(s_selectedNamespace, s_keyItems, s_keyCount);
348-
}
343+
rebuildKeyListView();
349344
// Go back if no more keys
350345
if (s_keyCount == 0) {
351346
ViewStack::instance().pop();
@@ -420,7 +415,7 @@ static void showNamespaceListView() {
420415
}
421416

422417
/** \brief Persistent key label storage used by list items. */
423-
static char s_keyLabels[MAX_KEYS][24];
418+
EXT_RAM_BSS_ATTR static char s_keyLabels[MAX_KEYS][24];
424419

425420
/**
426421
* \brief Handles key selection and opens detailed value view.

components/mod_password/src/PasswordModule.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "serial_cmd/SubCommand.h"
1919
#include "serial_cmd/Console.h"
2020
#include "cdc_log.h"
21+
#include "esp_attr.h"
2122
#include <cctype>
2223
#include <cstring>
2324
#include <strings.h>
@@ -436,7 +437,7 @@ struct WizardState {
436437
uint16_t editSlot;
437438
};
438439

439-
static WizardState s_wizard = {};
440+
EXT_RAM_BSS_ATTR static WizardState s_wizard = {};
440441

441442
static constexpr uint16_t NOTES_INPUT_MAX =
442443
(PasswordStore::NOTES_LEN < ui::T9InputView::MAX_TEXT_LEN)
@@ -551,7 +552,7 @@ static void showDetails(uint16_t slot) {
551552
strncpy(s_passwordToType, entry.password, sizeof(s_passwordToType) - 1);
552553
s_passwordToType[sizeof(s_passwordToType) - 1] = '\0';
553554

554-
static char detailText[ui::InfoView::MAX_TEXT_LEN];
555+
static EXT_RAM_BSS_ATTR char detailText[ui::InfoView::MAX_TEXT_LEN];
555556
char totpBuf[16] = {};
556557
const char* emptyText = ui::tr("core.empty");
557558
char emptyWrapped[16] = {};

0 commit comments

Comments
 (0)