10#include "freertos/FreeRTOS.h"
11#include "freertos/semphr.h"
17static const char*
TAG =
"2FA_CR_BLE";
25 0x01, 0x1A, 0x8B, 0x6A, 0x9D, 0x4C, 0x6E, 0x9A,
26 0x7A, 0x4D, 0x5D, 0x8B, 0x30, 0x1F, 0x2F, 0x8E
33 0x01, 0x1A, 0x8B, 0x6A, 0x9D, 0x4C, 0x6E, 0x9A,
34 0x7A, 0x4D, 0x5D, 0x8B, 0x31, 0x1F, 0x2F, 0x8E
41 0x01, 0x1A, 0x8B, 0x6A, 0x9D, 0x4C, 0x6E, 0x9A,
42 0x7A, 0x4D, 0x5D, 0x8B, 0x32, 0x1F, 0x2F, 0x8E
62static SemaphoreHandle_t
s_mutex =
nullptr;
104static void notifyResponse(uint16_t connHandle,
const uint8_t* data,
size_t len) {
107 ble->sendNotification(connHandle,
s_response_handle, data,
static_cast<uint16_t
>(len));
119 LOG_I(
TAG,
"CR response notified (%u bytes)",
static_cast<unsigned>(
s_confirm.responseLen));
139 LOG_W(
TAG,
"CR request declined by user");
154static int onChallengeWrite(uint16_t connHandle, uint16_t,
const uint8_t* data, uint16_t len) {
159 while (nameLen < len && data[nameLen] !=
'\0') nameLen++;
160 if (nameLen == 0 || nameLen >
MAX_NAME_LEN || nameLen >= len) {
164 const uint8_t* challenge = data + nameLen + 1;
165 size_t challengeLen = len - nameLen - 1;
170 LOG_W(
TAG,
"CR request already in progress");
188 if (!ble)
return false;
200 s_gattChars[1].onRead = [](uint16_t, uint16_t, uint8_t* buf, uint16_t* len) ->
int {
202 if (buf && len) *len = 0;
211 LOG_E(
TAG,
"Failed to register CR GATT service");
214 LOG_I(
TAG,
"CR GATT service registered");
242 s_mutex = xSemaphoreCreateMutex();
244 LOG_E(
TAG,
"Failed to create mutex");
251 LOG_E(
TAG,
"Bluetooth controller not available");
255 if (!ble->isEnabled()) {
256 if (!ble->enable()) {
257 LOG_E(
TAG,
"Bluetooth enable failed");
262 for (
int i = 0; i < 50 && !ble->isEnabled(); i++) {
263 vTaskDelay(pdMS_TO_TICKS(100));
273 LOG_I(
TAG,
"BLE CR service initialized");
304 size_t challengeLen = 0;
320 bool touchRequired =
true;
322 response, &touchRequired);
332 memcpy(
s_confirm.response, response,
static_cast<size_t>(rc));
333 s_confirm.responseLen =
static_cast<size_t>(rc);
Internationalization with English fallbacks in code and overlay translations loaded at runtime from a...
char name[cdc::hal::ISecureElement::RMEM_NAME_LEN]
Shared RAII wrappers for firmware resources.
CDC Log: logging over TinyUSB CDC and UART.
#define LOG_W(tag, fmt,...)
#define LOG_I(tag, fmt,...)
#define LOG_E(tag, fmt,...)
static constexpr ListenerToken INVALID_LISTENER
static constexpr size_t MAX_RESPONSE_LEN
Largest possible raw HMAC response (SHA256). Callers size out to this.
RAII wrapper for a FreeRTOS semaphore / mutex.
int challengeResponse(const char *entryName, const uint8_t *challenge, size_t clen, uint8_t *out, bool *touchRequiredOut=nullptr)
Computes the raw HMAC challenge-response for a CR entry by name.
static OathStore & instance()
Returns singleton OATH store instance.
IBluetoothController * getBluetoothControllerInstance()
Returns singleton Bluetooth stub when NimBLE is unavailable.
static const uint8_t CR_RESPONSE_UUID[16]
Response characteristic UUID (...1F32...), read + notify.
static GattCharacteristic s_gattChars[2]
static void onTouchConfirm(void *userData)
Touch-confirm accepted: notify the prepared response.
static void deliverConfirmedResponse()
Computes and notifies the response stashed in s_confirm.
static constexpr size_t MAX_CHALLENGE_LEN
static const uint8_t CR_CHALLENGE_UUID[16]
Challenge characteristic UUID (...1F31...), write.
void ble_chalresp_deinit()
Tears down the BLE CR subsystem and removes GATT callbacks.
static SemaphoreHandle_t s_mutex
static PendingChallenge s_pending
static constexpr size_t MAX_NAME_LEN
Max challenge payload (entry name + NUL + challenge bytes) accepted per write.
bool ble_chalresp_init()
BLE GATT challenge-response transport.
static IBluetoothController * getBle()
Returns shared Bluetooth controller instance.
static constexpr size_t MAX_FRAME_LEN
static void onDisconnect(uint16_t connHandle, int reason)
Clears pending request state if the requesting peer disconnects.
static IBluetoothController::ListenerToken s_tokDisconn
static uint8_t s_challengeBuf[MAX_CHALLENGE_LEN]
static bool s_initialized
static uint16_t s_response_handle
static const uint8_t CR_SVC_UUID[16]
CR service UUID: 8E2F1F30-8B5D-4D7A-9A6E-4C9D6A8B1A01 (little-endian).
static uint16_t s_challenge_handle
static void notifyResponse(uint16_t connHandle, const uint8_t *data, size_t len)
Sends a response notification to the requesting connection.
static bool registerGattService()
Registers the CR GATT service and characteristics.
static int onChallengeWrite(uint16_t connHandle, uint16_t, const uint8_t *data, uint16_t len)
GATT challenge write callback (BLE host task).
static PendingConfirm s_confirm
static void onTouchCancel(void *userData)
Touch-confirm declined: discard the prepared response.
static GattServiceDef s_gattSvcDef
static constexpr uint16_t INVALID_HANDLE
void ble_chalresp_tick(uint32_t nowMs)
Main-task tick: processes a pending challenge (confirm + notify).
const char * tr(const char *key)
Look up a translation by string key.
void showConfirm(const char *message, ConfirmView::ConfirmCallback onConfirm, ConfirmView::CancelCallback onCancel=nullptr, ConfirmView::Icon icon=ConfirmView::Icon::QUESTION, void *userData=nullptr)
Shows a shared modal confirmation dialog instance.
static BleUuid from128(const uint8_t v[16])
Pending challenge handed from the BLE host task to the main task.
char name[MAX_NAME_LEN+1]
Response awaiting an on-device touch confirmation.
uint8_t response[core::IChallengeResponder::MAX_RESPONSE_LEN]