11static const char*
TAG =
"BLE_UART";
17 0x9e, 0xca, 0xdc, 0x24, 0x0e, 0xe5, 0xa9, 0xe0,
18 0x93, 0xf3, 0xa3, 0xb5, 0x01, 0x00, 0x40, 0x6e
22 0x9e, 0xca, 0xdc, 0x24, 0x0e, 0xe5, 0xa9, 0xe0,
23 0x93, 0xf3, 0xa3, 0xb5, 0x02, 0x00, 0x40, 0x6e
27 0x9e, 0xca, 0xdc, 0x24, 0x0e, 0xe5, 0xa9, 0xe0,
28 0x93, 0xf3, 0xa3, 0xb5, 0x03, 0x00, 0x40, 0x6e
36 static BleUartService* inst =
new BleUartService();
50 if (!ble || !ble->isEnabled()) {
65 chars[0].
onWrite = [](uint16_t , uint16_t ,
66 const uint8_t* data, uint16_t len) ->
int {
86 if (!ble->registerGattService(svcDef)) {
87 LOG_E(
TAG,
"Failed to register NUS GATT service");
95 connToken_ = ble->addConnectionCallback([](uint16_t ) {
98 disconnToken_ = ble->addDisconnectionCallback([](uint16_t ,
int ) {
103 rxHead_.store(0, std::memory_order_relaxed);
104 rxTail_.store(0, std::memory_order_relaxed);
107 LOG_I(
TAG,
"NUS service registered (txHandle=%d)", txCharHandle_);
122 ble->removeConnectionCallback(connToken_);
123 ble->removeDisconnectionCallback(disconnToken_);
128 initialized_ =
false;
129 LOG_I(
TAG,
"NUS service deinitialized");
139 if (!initialized_ || !
isConnected() || !data || len == 0) {
147 txInProgress_ =
true;
151 txInProgress_ =
false;
155 uint16_t connHandle = ble->getConnectionHandle();
156 uint16_t mtu = ble->getMtu();
160 txInProgress_ =
false;
166 size_t remaining = len - sent;
167 uint16_t chunkLen =
static_cast<uint16_t
>(
168 (remaining > mtu) ? mtu : remaining);
170 if (!ble->sendNotification(connHandle, txCharHandle_, data + sent, chunkLen)) {
176 txInProgress_ =
false;
187 return send(
reinterpret_cast<const uint8_t*
>(str), strlen(str));
195 return initialized_ &&
isConnected() && !txCongested_;
203 if (!initialized_)
return 0;
205 size_t head = rxHead_.load(std::memory_order_acquire);
206 size_t tail = rxTail_.load(std::memory_order_acquire);
211 return RX_BUFFER_SIZE - tail + head;
224 size_t tail = rxTail_.load(std::memory_order_relaxed);
225 uint8_t c = rxBuffer_[tail];
226 rxTail_.store((tail + 1) % RX_BUFFER_SIZE, std::memory_order_release);
237 if (!buf || maxLen == 0)
return 0;
240 while (count < maxLen &&
available() > 0) {
243 buf[count++] =
static_cast<uint8_t
>(c);
254 return ble && ble->isConnected();
263 if (!data || len == 0)
return;
265 size_t head = rxHead_.load(std::memory_order_relaxed);
266 for (
size_t i = 0; i < len; i++) {
267 size_t nextHead = (head + 1) % RX_BUFFER_SIZE;
268 size_t tail = rxTail_.load(std::memory_order_acquire);
269 if (nextHead == tail) {
271 rxTail_.store((tail + 1) % RX_BUFFER_SIZE, std::memory_order_release);
273 rxBuffer_[head] = data[i];
276 rxHead_.store(head, std::memory_order_release);
286 if (onConnect_) onConnect_();
289 rxHead_.store(0, std::memory_order_relaxed);
290 rxTail_.store(0, std::memory_order_relaxed);
291 if (onDisconnect_) onDisconnect_();
CDC Log: logging over TinyUSB CDC and UART.
#define LOG_I(tag, fmt,...)
#define LOG_E(tag, fmt,...)
static constexpr ListenerToken INVALID_LISTENER
void onConnectionChange(bool connected)
Handles BLE connection state changes.
void deinit()
Deinitializes BLE UART service runtime state.
int getchar()
Reads one byte from RX ring buffer.
size_t available() const
Returns number of buffered RX bytes.
size_t read(uint8_t *buf, size_t maxLen)
Reads up to maxLen bytes from RX ring buffer.
bool isConnected() const
Returns whether BLE link is currently connected.
void onRxData(const uint8_t *data, size_t len)
Appends received BLE UART data into RX ring buffer.
bool txReady() const
Returns whether TX path is currently ready.
size_t send(const uint8_t *data, size_t len)
Sends binary payload to connected BLE peer via notifications.
bool init()
Initializes Nordic UART Service over BLE GATT.
static BleUartService & instance()
Returns singleton BLE UART service instance.
constexpr uint8_t WRITE_NO_RSP
IBluetoothController * getBluetoothControllerInstance()
Returns singleton Bluetooth stub when NimBLE is unavailable.
static const uint8_t NUS_TX_UUID[16]
TX characteristic UUID (badge notifies phone).
static const uint8_t NUS_RX_UUID[16]
RX characteristic UUID (phone writes to badge).
static const uint8_t NUS_SVC_UUID[16]
NUS UUIDs in little-endian byte order for BleUuid::from128.
static BleUuid from128(const uint8_t v[16])
GattWriteCallback onWrite
uint8_t numCharacteristics
GattCharacteristic * characteristics
static BleUuid from128(const uint8_t v[16])