Fix BLE logging on nrf52 (#4244)

* allow ble logrecords to be fetched either by NOTIFY or INDICATE ble types

This allows 'lossless' log reading.  If client has requested INDICATE
(rather than NOTIFY) each log record emitted via log() will have to fetched
by the client device before the meshtastic node can continue.

* Fix serious problem with nrf52 BLE logging.
When doing notifies of LogRecords it is important to use the
binary write routines - writing using the 'string' write won't work.
Because protobufs can contain \0 nuls inside of them which if being
parsed as a string will cause only a portion of the protobuf to be sent.
I noticed this because some log messages were not getting through.

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
This commit is contained in:
geeksville 2024-07-07 04:50:47 -07:00 committed by GitHub
parent 7b838d388d
commit 27dfe10689
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 17 additions and 9 deletions

View File

@ -206,7 +206,7 @@ void RedirectablePrint::log_to_ble(const char *logLevel, const char *format, va_
#ifdef ARCH_ESP32
nimbleBluetooth->sendLog(buffer, size);
#elif defined(ARCH_NRF52)
nrf52Bluetooth->sendLog(reinterpret_cast<const char *>(buffer));
nrf52Bluetooth->sendLog(buffer, size);
#endif
delete[] message;
delete[] buffer;

View File

@ -74,11 +74,16 @@ void onCccd(uint16_t conn_hdl, BLECharacteristic *chr, uint16_t cccd_value)
LOG_INFO("CCCD Updated: %u\n", cccd_value);
// Check the characteristic this CCCD update is associated with in case
// this handler is used for multiple CCCD records.
// According to the GATT spec: cccd value = 0x0001 means notifications are enabled
// and cccd value = 0x0002 means indications are enabled
if (chr->uuid == fromNum.uuid || chr->uuid == logRadio.uuid) {
if (chr->notifyEnabled(conn_hdl)) {
LOG_INFO("fromNum 'Notify' enabled\n");
auto result = cccd_value == 2 ? chr->indicateEnabled(conn_hdl) : chr->notifyEnabled(conn_hdl);
if (result) {
LOG_INFO("Notify/Indicate enabled\n");
} else {
LOG_INFO("fromNum 'Notify' disabled\n");
LOG_INFO("Notify/Indicate disabled\n");
}
}
}
@ -176,7 +181,7 @@ void setupMeshService(void)
toRadio.setWriteCallback(onToRadioWrite, false);
toRadio.begin();
logRadio.setProperties(CHR_PROPS_NOTIFY | CHR_PROPS_READ);
logRadio.setProperties(CHR_PROPS_INDICATE | CHR_PROPS_NOTIFY | CHR_PROPS_READ);
logRadio.setPermission(secMode, SECMODE_NO_ACCESS);
logRadio.setMaxLen(512);
logRadio.setCccdWriteCallback(onCccd);
@ -334,9 +339,12 @@ void NRF52Bluetooth::onPairingCompleted(uint16_t conn_handle, uint8_t auth_statu
screen->endAlert();
}
void NRF52Bluetooth::sendLog(const char *logMessage)
void NRF52Bluetooth::sendLog(const uint8_t *logMessage, size_t length)
{
if (!isConnected() || strlen(logMessage) > 512)
if (!isConnected() || length > 512)
return;
logRadio.notify(logMessage);
if (logRadio.indicateEnabled())
logRadio.indicate(logMessage, (uint16_t)length);
else
logRadio.notify(logMessage, (uint16_t)length);
}

View File

@ -13,7 +13,7 @@ class NRF52Bluetooth : BluetoothApi
void clearBonds();
bool isConnected();
int getRssi();
void sendLog(const char *logMessage);
void sendLog(const uint8_t *logMessage, size_t length);
private:
static void onConnectionSecured(uint16_t conn_handle);