From b6b3fb210111f023c61e66b42f55e26efd767303 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Tue, 18 Jun 2024 08:36:24 -0500 Subject: [PATCH 01/15] WIP log characteristic --- src/BluetoothCommon.cpp | 3 ++- src/BluetoothCommon.h | 3 ++- src/RedirectablePrint.cpp | 11 ++++++++ src/main.cpp | 1 + src/main.h | 1 + src/mesh/PhoneAPI.h | 5 ++++ src/platform/nrf52/NRF52Bluetooth.cpp | 37 ++++++++++++++------------- src/platform/nrf52/NRF52Bluetooth.h | 9 ++++++- 8 files changed, 49 insertions(+), 21 deletions(-) diff --git a/src/BluetoothCommon.cpp b/src/BluetoothCommon.cpp index 53faae997c..dfefca6e2b 100644 --- a/src/BluetoothCommon.cpp +++ b/src/BluetoothCommon.cpp @@ -10,4 +10,5 @@ const uint8_t TORADIO_UUID_16[16u] = {0xe7, 0x01, 0x44, 0x12, 0x66, 0x78, 0xdd, const uint8_t FROMRADIO_UUID_16[16u] = {0x02, 0x00, 0x12, 0xac, 0x42, 0x02, 0x78, 0xb8, 0xed, 0x11, 0x93, 0x49, 0x9e, 0xe6, 0x55, 0x2c}; const uint8_t FROMNUM_UUID_16[16u] = {0x53, 0x44, 0xe3, 0x47, 0x75, 0xaa, 0x70, 0xa6, - 0x66, 0x4f, 0x00, 0xa8, 0x8c, 0xa1, 0x9d, 0xed}; \ No newline at end of file + 0x66, 0x4f, 0x00, 0xa8, 0x8c, 0xa1, 0x9d, 0xed}; +const uint8_t LOG_UUID_16[16u] = {0xe2, 0xf2, 0x1e, 0xbe, 0xc5, 0x15, 0xcf, 0xaa, 0x6b, 0x43, 0xfa, 0x78, 0x38, 0xd2, 0x6f, 0x6c}; \ No newline at end of file diff --git a/src/BluetoothCommon.h b/src/BluetoothCommon.h index 586ffaa3c1..ec0d5f7c70 100644 --- a/src/BluetoothCommon.h +++ b/src/BluetoothCommon.h @@ -11,10 +11,11 @@ #define TORADIO_UUID "f75c76d2-129e-4dad-a1dd-7866124401e7" #define FROMRADIO_UUID "2c55e69e-4993-11ed-b878-0242ac120002" #define FROMNUM_UUID "ed9da18c-a800-4f66-a670-aa7547e34453" +#define LOG_UUID "6c6fd238-78fa-436b-aacf-15c5be1ef2e2" // NRF52 wants these constants as byte arrays // Generated here https://yupana-engineering.com/online-uuid-to-c-array-converter - but in REVERSE BYTE ORDER -extern const uint8_t MESH_SERVICE_UUID_16[], TORADIO_UUID_16[16u], FROMRADIO_UUID_16[], FROMNUM_UUID_16[]; +extern const uint8_t MESH_SERVICE_UUID_16[], TORADIO_UUID_16[16u], FROMRADIO_UUID_16[], FROMNUM_UUID_16[], LOG_UUID_16[]; /// Given a level between 0-100, update the BLE attribute void updateBatteryLevel(uint8_t level); diff --git a/src/RedirectablePrint.cpp b/src/RedirectablePrint.cpp index e09e5fe30a..cdf6edb557 100644 --- a/src/RedirectablePrint.cpp +++ b/src/RedirectablePrint.cpp @@ -3,6 +3,7 @@ #include "RTC.h" #include "concurrency/OSThread.h" #include "configuration.h" +#include "main.h" #include #include #include @@ -166,6 +167,16 @@ size_t RedirectablePrint::log(const char *logLevel, const char *format, ...) } #endif +#ifdef ARCH_ESP32 + // if(nimbleBluetooth->isConnected()) { + + // } +#elif defined(ARCH_NRF52) + if (nrf52Bluetooth->isConnected()) { + bluetoothPhoneAPI->sendLog(format); + } +#endif + va_end(arg); isContinuationMessage = !hasNewline; diff --git a/src/main.cpp b/src/main.cpp index 6797c83759..2fc12fa258 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -48,6 +48,7 @@ NimbleBluetooth *nimbleBluetooth; #ifdef ARCH_NRF52 #include "NRF52Bluetooth.h" NRF52Bluetooth *nrf52Bluetooth; +BluetoothPhoneAPI *bluetoothPhoneAPI; #endif #if HAS_WIFI diff --git a/src/main.h b/src/main.h index 2ef7edb3a9..267e210c6e 100644 --- a/src/main.h +++ b/src/main.h @@ -20,6 +20,7 @@ extern NimbleBluetooth *nimbleBluetooth; #ifdef ARCH_NRF52 #include "NRF52Bluetooth.h" extern NRF52Bluetooth *nrf52Bluetooth; +extern BluetoothPhoneAPI *bluetoothPhoneAPI; #endif #if ARCH_PORTDUINO diff --git a/src/mesh/PhoneAPI.h b/src/mesh/PhoneAPI.h index 49bf0e292b..9562bcbfb7 100644 --- a/src/mesh/PhoneAPI.h +++ b/src/mesh/PhoneAPI.h @@ -91,6 +91,11 @@ class PhoneAPI */ size_t getFromRadio(uint8_t *buf); + /** + * Log a message to the phone + */ + virtual void sendLog(const char *msg); + /** * Return true if we have data available to send to the phone */ diff --git a/src/platform/nrf52/NRF52Bluetooth.cpp b/src/platform/nrf52/NRF52Bluetooth.cpp index 4c25f38ea3..030e5b1d9e 100644 --- a/src/platform/nrf52/NRF52Bluetooth.cpp +++ b/src/platform/nrf52/NRF52Bluetooth.cpp @@ -12,6 +12,7 @@ static BLEService meshBleService = BLEService(BLEUuid(MESH_SERVICE_UUID_16)); static BLECharacteristic fromNum = BLECharacteristic(BLEUuid(FROMNUM_UUID_16)); static BLECharacteristic fromRadio = BLECharacteristic(BLEUuid(FROMRADIO_UUID_16)); static BLECharacteristic toRadio = BLECharacteristic(BLEUuid(TORADIO_UUID_16)); +static BLECharacteristic logC = BLECharacteristic(BLEUuid(LOG_UUID_16)); static BLEDis bledis; // DIS (Device Information Service) helper class instance static BLEBas blebas; // BAS (Battery Service) helper class instance @@ -25,28 +26,28 @@ static uint8_t toRadioBytes[meshtastic_ToRadio_size]; static uint16_t connectionHandle; -class BluetoothPhoneAPI : public PhoneAPI +/** + * Subclasses can use this as a hook to provide custom notifications for their transport (i.e. bluetooth notifies) + */ +void BluetoothPhoneAPI::onNowHasData(uint32_t fromRadioNum) { - /** - * Subclasses can use this as a hook to provide custom notifications for their transport (i.e. bluetooth notifies) - */ - virtual void onNowHasData(uint32_t fromRadioNum) override - { - PhoneAPI::onNowHasData(fromRadioNum); + PhoneAPI::onNowHasData(fromRadioNum); - LOG_INFO("BLE notify fromNum\n"); - fromNum.notify32(fromRadioNum); - } + LOG_INFO("BLE notify fromNum\n"); + fromNum.notify32(fromRadioNum); +} - /// Check the current underlying physical link to see if the client is currently connected - virtual bool checkIsConnected() override - { - BLEConnection *connection = Bluefruit.Connection(connectionHandle); - return connection->connected(); - } -}; +/// Check the current underlying physical link to see if the client is currently connected +bool BluetoothPhoneAPI::checkIsConnected() +{ + BLEConnection *connection = Bluefruit.Connection(connectionHandle); + return connection->connected(); +} -static BluetoothPhoneAPI *bluetoothPhoneAPI; +void BluetoothPhoneAPI::sendLog(const char *logMessage) +{ + logC.notify(logMessage); +} void onConnect(uint16_t conn_handle) { diff --git a/src/platform/nrf52/NRF52Bluetooth.h b/src/platform/nrf52/NRF52Bluetooth.h index 450af47f91..4c3ff3a6d0 100644 --- a/src/platform/nrf52/NRF52Bluetooth.h +++ b/src/platform/nrf52/NRF52Bluetooth.h @@ -3,6 +3,14 @@ #include "BluetoothCommon.h" #include +class BluetoothPhoneAPI : public PhoneAPI +{ + public: + virtual void onNowHasData(uint32_t fromRadioNum); + virtual bool checkIsConnected(); + virtual void sendLog(const char *logMessage); +}; + class NRF52Bluetooth : BluetoothApi { public: @@ -16,7 +24,6 @@ class NRF52Bluetooth : BluetoothApi private: static void onConnectionSecured(uint16_t conn_handle); - void convertToUint8(uint8_t target[4], uint32_t source); static bool onPairingPasskey(uint16_t conn_handle, uint8_t const passkey[6], bool match_request); static void onPairingCompleted(uint16_t conn_handle, uint8_t auth_status); }; \ No newline at end of file From 3426383449f1864201a64a0b9e4803f31f865210 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Tue, 18 Jun 2024 19:09:17 -0500 Subject: [PATCH 02/15] Bluetooth logging plumbing --- src/BluetoothCommon.cpp | 3 +- src/BluetoothCommon.h | 3 +- src/RedirectablePrint.cpp | 2 +- src/main.cpp | 256 ++++++++------------------ src/main.h | 1 - src/mesh/PhoneAPI.h | 5 - src/nimble/NimbleBluetooth.h | 1 + src/platform/nrf52/NRF52Bluetooth.cpp | 104 ++++------- src/platform/nrf52/NRF52Bluetooth.h | 13 +- 9 files changed, 127 insertions(+), 261 deletions(-) diff --git a/src/BluetoothCommon.cpp b/src/BluetoothCommon.cpp index dfefca6e2b..7ef1c39b45 100644 --- a/src/BluetoothCommon.cpp +++ b/src/BluetoothCommon.cpp @@ -11,4 +11,5 @@ const uint8_t FROMRADIO_UUID_16[16u] = {0x02, 0x00, 0x12, 0xac, 0x42, 0x02, 0x78 0xed, 0x11, 0x93, 0x49, 0x9e, 0xe6, 0x55, 0x2c}; const uint8_t FROMNUM_UUID_16[16u] = {0x53, 0x44, 0xe3, 0x47, 0x75, 0xaa, 0x70, 0xa6, 0x66, 0x4f, 0x00, 0xa8, 0x8c, 0xa1, 0x9d, 0xed}; -const uint8_t LOG_UUID_16[16u] = {0xe2, 0xf2, 0x1e, 0xbe, 0xc5, 0x15, 0xcf, 0xaa, 0x6b, 0x43, 0xfa, 0x78, 0x38, 0xd2, 0x6f, 0x6c}; \ No newline at end of file +const uint8_t LOGRADIO_UUID_16[16u] = {0xe2, 0xf2, 0x1e, 0xbe, 0xc5, 0x15, 0xcf, 0xaa, + 0x6b, 0x43, 0xfa, 0x78, 0x38, 0xd2, 0x6f, 0x6c}; \ No newline at end of file diff --git a/src/BluetoothCommon.h b/src/BluetoothCommon.h index ec0d5f7c70..1ba2b9f48e 100644 --- a/src/BluetoothCommon.h +++ b/src/BluetoothCommon.h @@ -15,7 +15,7 @@ // NRF52 wants these constants as byte arrays // Generated here https://yupana-engineering.com/online-uuid-to-c-array-converter - but in REVERSE BYTE ORDER -extern const uint8_t MESH_SERVICE_UUID_16[], TORADIO_UUID_16[16u], FROMRADIO_UUID_16[], FROMNUM_UUID_16[], LOG_UUID_16[]; +extern const uint8_t MESH_SERVICE_UUID_16[], TORADIO_UUID_16[16u], FROMRADIO_UUID_16[], FROMNUM_UUID_16[], LOGRADIO_UUID_16[]; /// Given a level between 0-100, update the BLE attribute void updateBatteryLevel(uint8_t level); @@ -28,4 +28,5 @@ class BluetoothApi virtual void clearBonds(); virtual bool isConnected(); virtual int getRssi() = 0; + virtual void sendLog(const char *logMessage); }; \ No newline at end of file diff --git a/src/RedirectablePrint.cpp b/src/RedirectablePrint.cpp index cdf6edb557..0fe43c657b 100644 --- a/src/RedirectablePrint.cpp +++ b/src/RedirectablePrint.cpp @@ -173,7 +173,7 @@ size_t RedirectablePrint::log(const char *logLevel, const char *format, ...) // } #elif defined(ARCH_NRF52) if (nrf52Bluetooth->isConnected()) { - bluetoothPhoneAPI->sendLog(format); + nrf52Bluetooth->sendLog(format); } #endif diff --git a/src/main.cpp b/src/main.cpp index 451733acb7..83b4b59bfd 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -48,8 +48,6 @@ NimbleBluetooth *nimbleBluetooth = nullptr; #ifdef ARCH_NRF52 #include "NRF52Bluetooth.h" NRF52Bluetooth *nrf52Bluetooth = nullptr; - -BluetoothPhoneAPI *bluetoothPhoneAPI; #endif #if HAS_WIFI @@ -174,12 +172,9 @@ const char *getDeviceName() static char name[20]; snprintf(name, sizeof(name), "%02x%02x", dmac[4], dmac[5]); // if the shortname exists and is NOT the new default of ab3c, use it for BLE name. - if ((owner.short_name != NULL) && (strcmp(owner.short_name, name) != 0)) - { + if ((owner.short_name != NULL) && (strcmp(owner.short_name, name) != 0)) { snprintf(name, sizeof(name), "%s_%02x%02x", owner.short_name, dmac[4], dmac[5]); - } - else - { + } else { snprintf(name, sizeof(name), "Meshtastic_%02x%02x", dmac[4], dmac[5]); } return name; @@ -348,13 +343,10 @@ void setup() #elif defined(I2C_SDA) && !defined(ARCH_RP2040) Wire.begin(I2C_SDA, I2C_SCL); #elif defined(ARCH_PORTDUINO) - if (settingsStrings[i2cdev] != "") - { + if (settingsStrings[i2cdev] != "") { LOG_INFO("Using %s as I2C device.\n", settingsStrings[i2cdev].c_str()); Wire.begin(settingsStrings[i2cdev].c_str()); - } - else - { + } else { LOG_INFO("No I2C device configured, skipping.\n"); } #elif HAS_WIRE @@ -418,8 +410,7 @@ void setup() Wire.begin(I2C_SDA, I2C_SCL); i2cScanner->scanPort(ScanI2C::I2CPort::WIRE); #elif defined(ARCH_PORTDUINO) - if (settingsStrings[i2cdev] != "") - { + if (settingsStrings[i2cdev] != "") { LOG_INFO("Scanning for i2c devices...\n"); i2cScanner->scanPort(ScanI2C::I2CPort::WIRE); } @@ -428,19 +419,15 @@ void setup() #endif auto i2cCount = i2cScanner->countDevices(); - if (i2cCount == 0) - { + if (i2cCount == 0) { LOG_INFO("No I2C devices found\n"); - } - else - { + } else { LOG_INFO("%i I2C devices found\n", i2cCount); } #ifdef ARCH_ESP32 // Don't init display if we don't have one or we are waking headless due to a timer event - if (wakeCause == ESP_SLEEP_WAKEUP_TIMER) - { + if (wakeCause == ESP_SLEEP_WAKEUP_TIMER) { LOG_DEBUG("suppress screen wake because this is a headless timer wakeup"); i2cScanner->setSuppressScreen(); } @@ -449,10 +436,8 @@ void setup() auto screenInfo = i2cScanner->firstScreen(); screen_found = screenInfo.type != ScanI2C::DeviceType::NONE ? screenInfo.address : ScanI2C::ADDRESS_NONE; - if (screen_found.port != ScanI2C::I2CPort::NO_I2C) - { - switch (screenInfo.type) - { + if (screen_found.port != ScanI2C::I2CPort::NO_I2C) { + switch (screenInfo.type) { case ScanI2C::DeviceType::SCREEN_SH1106: screen_model = meshtastic_Config_DisplayConfig_OledType::meshtastic_Config_DisplayConfig_OledType_OLED_SH1106; break; @@ -473,11 +458,9 @@ void setup() auto kb_info = i2cScanner->firstKeyboard(); - if (kb_info.type != ScanI2C::DeviceType::NONE) - { + if (kb_info.type != ScanI2C::DeviceType::NONE) { cardkb_found = kb_info.address; - switch (kb_info.type) - { + switch (kb_info.type) { case ScanI2C::DeviceType::RAK14004: kb_model = 0x02; break; @@ -520,15 +503,14 @@ void setup() #define STRING(S) #S -#define SCANNER_TO_SENSORS_MAP(SCANNER_T, PB_T) \ - { \ - auto found = i2cScanner->find(SCANNER_T); \ - if (found.type != ScanI2C::DeviceType::NONE) \ - { \ - nodeTelemetrySensorsMap[PB_T].first = found.address.address; \ - nodeTelemetrySensorsMap[PB_T].second = i2cScanner->fetchI2CBus(found.address); \ - LOG_DEBUG("found i2c sensor %s\n", STRING(PB_T)); \ - } \ +#define SCANNER_TO_SENSORS_MAP(SCANNER_T, PB_T) \ + { \ + auto found = i2cScanner->find(SCANNER_T); \ + if (found.type != ScanI2C::DeviceType::NONE) { \ + nodeTelemetrySensorsMap[PB_T].first = found.address.address; \ + nodeTelemetrySensorsMap[PB_T].second = i2cScanner->fetchI2CBus(found.address); \ + LOG_DEBUG("found i2c sensor %s\n", STRING(PB_T)); \ + } \ } SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::BME_680, meshtastic_TelemetrySensorType_BME680) @@ -589,14 +571,12 @@ void setup() nodeDB = new NodeDB; // If we're taking on the repeater role, use flood router and turn off 3V3_S rail because peripherals are not needed - if (config.device.role == meshtastic_Config_DeviceConfig_Role_REPEATER) - { + if (config.device.role == meshtastic_Config_DeviceConfig_Role_REPEATER) { router = new FloodingRouter(); #ifdef PIN_3V3_EN digitalWrite(PIN_3V3_EN, LOW); #endif - } - else + } else router = new ReliableRouter(); #if HAS_BUTTON || defined(ARCH_PORTDUINO) @@ -620,8 +600,7 @@ void setup() #endif #if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR - if (acc_info.type != ScanI2C::DeviceType::NONE) - { + if (acc_info.type != ScanI2C::DeviceType::NONE) { config.display.wake_on_tap_or_motion = true; moduleConfig.external_notification.enabled = true; accelerometerThread = new AccelerometerThread(acc_info.type); @@ -631,8 +610,7 @@ void setup() #if defined(HAS_NEOPIXEL) || defined(UNPHONE) || defined(RGBLED_RED) ambientLightingThread = new AmbientLightingThread(ScanI2C::DeviceType::NONE); #elif !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) - if (rgb_found.type != ScanI2C::DeviceType::NONE) - { + if (rgb_found.type != ScanI2C::DeviceType::NONE) { ambientLightingThread = new AmbientLightingThread(rgb_found.type); } #endif @@ -673,12 +651,9 @@ void setup() screen = new graphics::Screen(screen_found, screen_model, screen_geometry); // setup TZ prior to time actions. - if (*config.device.tzdef) - { + if (*config.device.tzdef) { setenv("TZ", config.device.tzdef, 1); - } - else - { + } else { setenv("TZ", "GMT0", 1); } tzset(); @@ -688,18 +663,13 @@ void setup() #if !MESHTASTIC_EXCLUDE_GPS // If we're taking on the repeater role, ignore GPS - if (HAS_GPS) - { + if (HAS_GPS) { if (config.device.role != meshtastic_Config_DeviceConfig_Role_REPEATER && - config.position.gps_mode != meshtastic_Config_PositionConfig_GpsMode_NOT_PRESENT) - { + config.position.gps_mode != meshtastic_Config_PositionConfig_GpsMode_NOT_PRESENT) { gps = GPS::createGps(); - if (gps) - { + if (gps) { gpsStatus->observe(&gps->newStatus); - } - else - { + } else { LOG_DEBUG("Running without GPS.\n"); } } @@ -735,8 +705,7 @@ void setup() #if defined(ST7735_CS) || defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7789_CS) || defined(HX8357_CS) screen->setup(); #elif defined(ARCH_PORTDUINO) - if (screen_found.port != ScanI2C::I2CPort::NO_I2C || settingsMap[displayPanel]) - { + if (screen_found.port != ScanI2C::I2CPort::NO_I2C || settingsMap[displayPanel]) { screen->setup(); } #else @@ -758,87 +727,64 @@ void setup() #endif #ifdef ARCH_PORTDUINO - if (settingsMap[use_sx1262]) - { - if (!rIf) - { + if (settingsMap[use_sx1262]) { + if (!rIf) { LOG_DEBUG("Attempting to activate sx1262 radio on SPI port %s\n", settingsStrings[spidev].c_str()); LockingArduinoHal *RadioLibHAL = new LockingArduinoHal(SPI, spiSettings, (settingsMap[ch341Quirk] ? settingsMap[busy] : RADIOLIB_NC)); rIf = new SX1262Interface((LockingArduinoHal *)RadioLibHAL, settingsMap[cs], settingsMap[irq], settingsMap[reset], settingsMap[busy]); - if (!rIf->init()) - { + if (!rIf->init()) { LOG_ERROR("Failed to find SX1262 radio\n"); delete rIf; exit(EXIT_FAILURE); - } - else - { + } else { LOG_INFO("SX1262 Radio init succeeded, using SX1262 radio\n"); } } - } - else if (settingsMap[use_rf95]) - { - if (!rIf) - { + } else if (settingsMap[use_rf95]) { + if (!rIf) { LOG_DEBUG("Attempting to activate rf95 radio on SPI port %s\n", settingsStrings[spidev].c_str()); LockingArduinoHal *RadioLibHAL = new LockingArduinoHal(SPI, spiSettings, (settingsMap[ch341Quirk] ? settingsMap[busy] : RADIOLIB_NC)); rIf = new RF95Interface((LockingArduinoHal *)RadioLibHAL, settingsMap[cs], settingsMap[irq], settingsMap[reset], settingsMap[busy]); - if (!rIf->init()) - { + if (!rIf->init()) { LOG_ERROR("Failed to find RF95 radio\n"); delete rIf; rIf = NULL; exit(EXIT_FAILURE); - } - else - { + } else { LOG_INFO("RF95 Radio init succeeded, using RF95 radio\n"); } } - } - else if (settingsMap[use_sx1280]) - { - if (!rIf) - { + } else if (settingsMap[use_sx1280]) { + if (!rIf) { LOG_DEBUG("Attempting to activate sx1280 radio on SPI port %s\n", settingsStrings[spidev].c_str()); LockingArduinoHal *RadioLibHAL = new LockingArduinoHal(SPI, spiSettings); rIf = new SX1280Interface((LockingArduinoHal *)RadioLibHAL, settingsMap[cs], settingsMap[irq], settingsMap[reset], settingsMap[busy]); - if (!rIf->init()) - { + if (!rIf->init()) { LOG_ERROR("Failed to find SX1280 radio\n"); delete rIf; rIf = NULL; exit(EXIT_FAILURE); - } - else - { + } else { LOG_INFO("SX1280 Radio init succeeded, using SX1280 radio\n"); } } - } - else if (settingsMap[use_sx1268]) - { - if (!rIf) - { + } else if (settingsMap[use_sx1268]) { + if (!rIf) { LOG_DEBUG("Attempting to activate sx1268 radio on SPI port %s\n", settingsStrings[spidev].c_str()); LockingArduinoHal *RadioLibHAL = new LockingArduinoHal(SPI, spiSettings); rIf = new SX1268Interface((LockingArduinoHal *)RadioLibHAL, settingsMap[cs], settingsMap[irq], settingsMap[reset], settingsMap[busy]); - if (!rIf->init()) - { + if (!rIf->init()) { LOG_ERROR("Failed to find SX1268 radio\n"); delete rIf; rIf = NULL; exit(EXIT_FAILURE); - } - else - { + } else { LOG_INFO("SX1268 Radio init succeeded, using SX1268 radio\n"); } } @@ -852,17 +798,13 @@ void setup() // radio init MUST BE AFTER service.init, so we have our radio config settings (from nodedb init) #if defined(USE_STM32WLx) - if (!rIf) - { + if (!rIf) { rIf = new STM32WLE5JCInterface(RadioLibHAL, SX126X_CS, SX126X_DIO1, SX126X_RESET, SX126X_BUSY); - if (!rIf->init()) - { + if (!rIf->init()) { LOG_WARN("Failed to find STM32WL radio\n"); delete rIf; rIf = NULL; - } - else - { + } else { LOG_INFO("STM32WL Radio init succeeded, using STM32WL radio\n"); radioType = STM32WLx_RADIO; } @@ -870,17 +812,13 @@ void setup() #endif #if !HAS_RADIO && defined(ARCH_PORTDUINO) - if (!rIf) - { + if (!rIf) { rIf = new SimRadio; - if (!rIf->init()) - { + if (!rIf->init()) { LOG_WARN("Failed to find simulated radio\n"); delete rIf; rIf = NULL; - } - else - { + } else { LOG_INFO("Using SIMULATED radio!\n"); radioType = SIM_RADIO; } @@ -888,17 +826,13 @@ void setup() #endif #if defined(RF95_IRQ) - if (!rIf) - { + if (!rIf) { rIf = new RF95Interface(RadioLibHAL, LORA_CS, RF95_IRQ, RF95_RESET, RF95_DIO1); - if (!rIf->init()) - { + if (!rIf->init()) { LOG_WARN("Failed to find RF95 radio\n"); delete rIf; rIf = NULL; - } - else - { + } else { LOG_INFO("RF95 Radio init succeeded, using RF95 radio\n"); radioType = RF95_RADIO; } @@ -906,17 +840,13 @@ void setup() #endif #if defined(USE_SX1262) && !defined(ARCH_PORTDUINO) - if (!rIf) - { + if (!rIf) { rIf = new SX1262Interface(RadioLibHAL, SX126X_CS, SX126X_DIO1, SX126X_RESET, SX126X_BUSY); - if (!rIf->init()) - { + if (!rIf->init()) { LOG_WARN("Failed to find SX1262 radio\n"); delete rIf; rIf = NULL; - } - else - { + } else { LOG_INFO("SX1262 Radio init succeeded, using SX1262 radio\n"); radioType = SX1262_RADIO; } @@ -924,17 +854,13 @@ void setup() #endif #if defined(USE_SX1268) - if (!rIf) - { + if (!rIf) { rIf = new SX1268Interface(RadioLibHAL, SX126X_CS, SX126X_DIO1, SX126X_RESET, SX126X_BUSY); - if (!rIf->init()) - { + if (!rIf->init()) { LOG_WARN("Failed to find SX1268 radio\n"); delete rIf; rIf = NULL; - } - else - { + } else { LOG_INFO("SX1268 Radio init succeeded, using SX1268 radio\n"); radioType = SX1268_RADIO; } @@ -942,17 +868,13 @@ void setup() #endif #if defined(USE_LLCC68) - if (!rIf) - { + if (!rIf) { rIf = new LLCC68Interface(RadioLibHAL, SX126X_CS, SX126X_DIO1, SX126X_RESET, SX126X_BUSY); - if (!rIf->init()) - { + if (!rIf->init()) { LOG_WARN("Failed to find LLCC68 radio\n"); delete rIf; rIf = NULL; - } - else - { + } else { LOG_INFO("LLCC68 Radio init succeeded, using LLCC68 radio\n"); radioType = LLCC68_RADIO; } @@ -960,51 +882,39 @@ void setup() #endif #if defined(USE_LR1110) - if (!rIf) - { + if (!rIf) { rIf = new LR1110Interface(RadioLibHAL, LR1110_SPI_NSS_PIN, LR1110_IRQ_PIN, LR1110_NRESER_PIN, LR1110_BUSY_PIN); - if (!rIf->init()) - { + if (!rIf->init()) { LOG_WARN("Failed to find LR1110 radio\n"); delete rIf; rIf = NULL; - } - else - { + } else { LOG_INFO("LR1110 Radio init succeeded, using LR1110 radio\n"); } } #endif #if defined(USE_LR1120) - if (!rIf) - { + if (!rIf) { rIf = new LR1120Interface(RadioLibHAL, LR1120_SPI_NSS_PIN, LR1120_IRQ_PIN, LR1120_NRESER_PIN, LR1120_BUSY_PIN); - if (!rIf->init()) - { + if (!rIf->init()) { LOG_WARN("Failed to find LR1120 radio\n"); delete rIf; rIf = NULL; - } - else - { + } else { LOG_INFO("LR1120 Radio init succeeded, using LR1120 radio\n"); } } #endif #if defined(USE_SX1280) - if (!rIf) - { + if (!rIf) { rIf = new SX1280Interface(RadioLibHAL, SX128X_CS, SX128X_DIO1, SX128X_RESET, SX128X_BUSY); - if (!rIf->init()) - { + if (!rIf->init()) { LOG_WARN("Failed to find SX1280 radio\n"); delete rIf; rIf = NULL; - } - else - { + } else { LOG_INFO("SX1280 Radio init succeeded, using SX1280 radio\n"); radioType = SX1280_RADIO; } @@ -1013,13 +923,11 @@ void setup() // check if the radio chip matches the selected region - if ((config.lora.region == meshtastic_Config_LoRaConfig_RegionCode_LORA_24) && (!rIf->wideLora())) - { + if ((config.lora.region == meshtastic_Config_LoRaConfig_RegionCode_LORA_24) && (!rIf->wideLora())) { LOG_WARN("Radio chip does not support 2.4GHz LoRa. Reverting to unset.\n"); config.lora.region = meshtastic_Config_LoRaConfig_RegionCode_UNSET; nodeDB->saveToDisk(SEGMENT_CONFIG); - if (!rIf->reconfigure()) - { + if (!rIf->reconfigure()) { LOG_WARN("Reconfigure failed, rebooting\n"); screen->startRebootScreen(); rebootAtMsec = millis() + 5000; @@ -1050,8 +958,7 @@ void setup() #ifdef ARCH_PORTDUINO #if __has_include() - if (settingsMap[webserverport] != -1) - { + if (settingsMap[webserverport] != -1) { piwebServerThread = new PiWebServerThread(); } #endif @@ -1063,8 +970,7 @@ void setup() if (!rIf) RECORD_CRITICALERROR(meshtastic_CriticalErrorCode_NO_RADIO); - else - { + else { router->addInterface(rIf); // Log bit rate to debug output @@ -1123,8 +1029,7 @@ void loop() #ifdef DEBUG_STACK static uint32_t lastPrint = 0; - if (millis() - lastPrint > 10 * 1000L) - { + if (millis() - lastPrint > 10 * 1000L) { lastPrint = millis(); meshtastic::printThreadInfo("main"); } @@ -1142,8 +1047,7 @@ void loop() mainController.nextThread->tillRun(millis())); */ // We want to sleep as long as possible here - because it saves power - if (!runASAP && loopCanSleep()) - { + if (!runASAP && loopCanSleep()) { // if(delayMsec > 100) LOG_DEBUG("sleeping %ld\n", delayMsec); mainDelay.delay(delayMsec); } diff --git a/src/main.h b/src/main.h index 267e210c6e..2ef7edb3a9 100644 --- a/src/main.h +++ b/src/main.h @@ -20,7 +20,6 @@ extern NimbleBluetooth *nimbleBluetooth; #ifdef ARCH_NRF52 #include "NRF52Bluetooth.h" extern NRF52Bluetooth *nrf52Bluetooth; -extern BluetoothPhoneAPI *bluetoothPhoneAPI; #endif #if ARCH_PORTDUINO diff --git a/src/mesh/PhoneAPI.h b/src/mesh/PhoneAPI.h index 9562bcbfb7..49bf0e292b 100644 --- a/src/mesh/PhoneAPI.h +++ b/src/mesh/PhoneAPI.h @@ -91,11 +91,6 @@ class PhoneAPI */ size_t getFromRadio(uint8_t *buf); - /** - * Log a message to the phone - */ - virtual void sendLog(const char *msg); - /** * Return true if we have data available to send to the phone */ diff --git a/src/nimble/NimbleBluetooth.h b/src/nimble/NimbleBluetooth.h index d1e347830a..39794779b2 100644 --- a/src/nimble/NimbleBluetooth.h +++ b/src/nimble/NimbleBluetooth.h @@ -11,6 +11,7 @@ class NimbleBluetooth : BluetoothApi bool isActive(); bool isConnected(); int getRssi(); + void sendLog(const char *logMessage); private: void setupService(); diff --git a/src/platform/nrf52/NRF52Bluetooth.cpp b/src/platform/nrf52/NRF52Bluetooth.cpp index 030e5b1d9e..e5a8f9ee18 100644 --- a/src/platform/nrf52/NRF52Bluetooth.cpp +++ b/src/platform/nrf52/NRF52Bluetooth.cpp @@ -7,17 +7,16 @@ #include "mesh/mesh-pb-constants.h" #include #include - static BLEService meshBleService = BLEService(BLEUuid(MESH_SERVICE_UUID_16)); static BLECharacteristic fromNum = BLECharacteristic(BLEUuid(FROMNUM_UUID_16)); static BLECharacteristic fromRadio = BLECharacteristic(BLEUuid(FROMRADIO_UUID_16)); static BLECharacteristic toRadio = BLECharacteristic(BLEUuid(TORADIO_UUID_16)); -static BLECharacteristic logC = BLECharacteristic(BLEUuid(LOG_UUID_16)); +static BLECharacteristic logRadio = BLECharacteristic(BLEUuid(LOGRADIO_UUID_16)); static BLEDis bledis; // DIS (Device Information Service) helper class instance static BLEBas blebas; // BAS (Battery Service) helper class instance -static BLEDfu bledfu; // DFU software update helper service +static BLEDfu bledfu; // DFU software update helper service // This scratch buffer is used for various bluetooth reads/writes - but it is safe because only one bt operation can be in // process at once // static uint8_t trBytes[_max(_max(_max(_max(ToRadio_size, RadioConfig_size), User_size), MyNodeInfo_size), FromRadio_size)]; @@ -26,41 +25,39 @@ static uint8_t toRadioBytes[meshtastic_ToRadio_size]; static uint16_t connectionHandle; -/** - * Subclasses can use this as a hook to provide custom notifications for their transport (i.e. bluetooth notifies) - */ -void BluetoothPhoneAPI::onNowHasData(uint32_t fromRadioNum) +class BluetoothPhoneAPI : public PhoneAPI { - PhoneAPI::onNowHasData(fromRadioNum); + /** + * Subclasses can use this as a hook to provide custom notifications for their transport (i.e. bluetooth notifies) + */ + virtual void onNowHasData(uint32_t fromRadioNum) override + { + PhoneAPI::onNowHasData(fromRadioNum); - LOG_INFO("BLE notify fromNum\n"); - fromNum.notify32(fromRadioNum); -} + LOG_INFO("BLE notify fromNum\n"); + fromNum.notify32(fromRadioNum); + } -/// Check the current underlying physical link to see if the client is currently connected -bool BluetoothPhoneAPI::checkIsConnected() -{ - BLEConnection *connection = Bluefruit.Connection(connectionHandle); - return connection->connected(); -} + /// Check the current underlying physical link to see if the client is currently connected + virtual bool checkIsConnected() override + { + BLEConnection *connection = Bluefruit.Connection(connectionHandle); + return connection->connected(); + } +}; -void BluetoothPhoneAPI::sendLog(const char *logMessage) -{ - logC.notify(logMessage); -} +static BluetoothPhoneAPI *bluetoothPhoneAPI; void onConnect(uint16_t conn_handle) { + // Get the reference to current connection BLEConnection *connection = Bluefruit.Connection(conn_handle); connectionHandle = conn_handle; - char central_name[32] = {0}; connection->getPeerName(central_name, sizeof(central_name)); - LOG_INFO("BLE Connected to %s\n", central_name); } - /** * Callback invoked when a connection is dropped * @param conn_handle connection where this event happens @@ -71,12 +68,10 @@ void onDisconnect(uint16_t conn_handle, uint8_t reason) // FIXME - we currently assume only one active connection LOG_INFO("BLE Disconnected, reason = 0x%x\n", reason); } - void onCccd(uint16_t conn_hdl, BLECharacteristic *chr, uint16_t cccd_value) { // Display the raw request packet 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. if (chr->uuid == fromNum.uuid) { @@ -87,21 +82,17 @@ void onCccd(uint16_t conn_hdl, BLECharacteristic *chr, uint16_t cccd_value) } } } - void startAdv(void) { // Advertising packet Bluefruit.Advertising.addFlags(BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE); - // IncludeService UUID // Bluefruit.ScanResponse.addService(meshBleService); Bluefruit.ScanResponse.addTxPower(); Bluefruit.ScanResponse.addName(); - // Include Name // Bluefruit.Advertising.addName(); Bluefruit.Advertising.addService(meshBleService); - /* Start Advertising * - Enable auto advertising if disconnected * - Interval: fast mode = 20 ms, slow mode = 152.5 ms @@ -116,7 +107,6 @@ void startAdv(void) Bluefruit.Advertising.setFastTimeout(30); // number of seconds in fast mode Bluefruit.Advertising.start(0); // 0 = Don't stop advertising after n seconds. FIXME, we should stop advertising after X } - // Just ack that the caller is allowed to read static void authorizeRead(uint16_t conn_hdl) { @@ -124,7 +114,6 @@ static void authorizeRead(uint16_t conn_hdl) reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS; sd_ble_gatts_rw_authorize_reply(conn_hdl, &reply); } - /** * client is starting read, pull the bytes from our API class */ @@ -133,7 +122,6 @@ void onFromRadioAuthorize(uint16_t conn_hdl, BLECharacteristic *chr, ble_gatts_e if (request->offset == 0) { // If the read is long, we will get multiple authorize invocations - we only populate data on the first size_t numBytes = bluetoothPhoneAPI->getFromRadio(fromRadioBytes); - // Someone is going to read our value as soon as this callback returns. So fill it with the next message in the queue // or make empty if the queue is empty fromRadio.write(fromRadioBytes, numBytes); @@ -142,37 +130,29 @@ void onFromRadioAuthorize(uint16_t conn_hdl, BLECharacteristic *chr, ble_gatts_e } authorizeRead(conn_hdl); } - void onToRadioWrite(uint16_t conn_hdl, BLECharacteristic *chr, uint8_t *data, uint16_t len) { LOG_INFO("toRadioWriteCb data %p, len %u\n", data, len); - bluetoothPhoneAPI->handleToRadio(data, len); } - /** * client is starting read, pull the bytes from our API class */ void onFromNumAuthorize(uint16_t conn_hdl, BLECharacteristic *chr, ble_gatts_evt_read_t *request) { LOG_INFO("fromNumAuthorizeCb\n"); - authorizeRead(conn_hdl); } - void setupMeshService(void) { bluetoothPhoneAPI = new BluetoothPhoneAPI(); - meshBleService.begin(); - // Note: You must call .begin() on the BLEService before calling .begin() on // any characteristic(s) within that service definition.. Calling .begin() on // a BLECharacteristic will cause it to be added to the last BLEService that // was 'begin()'ed! auto secMode = config.bluetooth.mode == meshtastic_Config_BluetoothConfig_PairingMode_NO_PIN ? SECMODE_OPEN : SECMODE_ENC_NO_MITM; - fromNum.setProperties(CHR_PROPS_NOTIFY | CHR_PROPS_READ); fromNum.setPermission(secMode, SECMODE_NO_ACCESS); // FIXME, secure this!!! fromNum.setFixedLen( @@ -183,7 +163,6 @@ void setupMeshService(void) // fromNum.setReadAuthorizeCallback(fromNumAuthorizeCb); fromNum.write32(0); // Provide default fromNum of 0 fromNum.begin(); - fromRadio.setProperties(CHR_PROPS_READ); fromRadio.setPermission(secMode, SECMODE_NO_ACCESS); fromRadio.setMaxLen(sizeof(fromRadioBytes)); @@ -193,7 +172,6 @@ void setupMeshService(void) fromRadio.setBuffer(fromRadioBytes, sizeof(fromRadioBytes)); // we preallocate our fromradio buffer so we won't waste space // for two copies fromRadio.begin(); - toRadio.setProperties(CHR_PROPS_WRITE); toRadio.setPermission(secMode, secMode); // FIXME secure this! toRadio.setFixedLen(0); @@ -202,10 +180,14 @@ void setupMeshService(void) // We don't call this callback via the adafruit queue, because we can safely run in the BLE context toRadio.setWriteCallback(onToRadioWrite, false); toRadio.begin(); -} + logRadio.setProperties(CHR_PROPS_NOTIFY); + logRadio.setPermission(secMode, SECMODE_NO_ACCESS); + logRadio.setFixedLen(0); + logRadio.setMaxLen(512); + logRadio.begin(); +} static uint32_t configuredPasskey; - void NRF52Bluetooth::shutdown() { // Shutdown bluetooth for minimum power draw @@ -215,29 +197,23 @@ void NRF52Bluetooth::shutdown() } Bluefruit.Advertising.stop(); } - void NRF52Bluetooth::startDisabled() { // Setup Bluetooth nrf52Bluetooth->setup(); - // Shutdown bluetooth for minimum power draw Bluefruit.Advertising.stop(); Bluefruit.setTxPower(-40); // Minimum power - LOG_INFO("Disabling NRF52 Bluetooth. (Workaround: tx power min, advertising stopped)\n"); } - bool NRF52Bluetooth::isConnected() { return Bluefruit.connected(connectionHandle); } - int NRF52Bluetooth::getRssi() { return 0; // FIXME figure out where to source this } - void NRF52Bluetooth::setup() { // Initialise the Bluefruit module @@ -245,12 +221,10 @@ void NRF52Bluetooth::setup() Bluefruit.autoConnLed(false); Bluefruit.configPrphBandwidth(BANDWIDTH_MAX); Bluefruit.begin(); - // Clear existing data. Bluefruit.Advertising.stop(); Bluefruit.Advertising.clearData(); Bluefruit.ScanResponse.clearData(); - if (config.bluetooth.mode != meshtastic_Config_BluetoothConfig_PairingMode_NO_PIN) { configuredPasskey = config.bluetooth.mode == meshtastic_Config_BluetoothConfig_PairingMode_FIXED_PIN ? config.bluetooth.fixed_pin @@ -269,37 +243,29 @@ void NRF52Bluetooth::setup() } // Set the advertised device name (keep it short!) Bluefruit.setName(getDeviceName()); - // Set the connect/disconnect callback handlers Bluefruit.Periph.setConnectCallback(onConnect); Bluefruit.Periph.setDisconnectCallback(onDisconnect); - bledfu.setPermission(SECMODE_ENC_WITH_MITM, SECMODE_ENC_WITH_MITM); bledfu.begin(); // Install the DFU helper - // Configure and Start the Device Information Service LOG_INFO("Configuring the Device Information Service\n"); bledis.setModel(optstr(HW_VERSION)); bledis.setFirmwareRev(optstr(APP_VERSION)); bledis.begin(); - // Start the BLE Battery Service and set it to 100% LOG_INFO("Configuring the Battery Service\n"); blebas.begin(); blebas.write(0); // Unknown battery level for now - // Setup the Heart Rate Monitor service using // BLEService and BLECharacteristic classes LOG_INFO("Configuring the Mesh bluetooth service\n"); setupMeshService(); - // Setup the advertising packet(s) LOG_INFO("Setting up the advertising payload(s)\n"); startAdv(); - LOG_INFO("Advertising\n"); } - void NRF52Bluetooth::resumeAdvertising() { Bluefruit.Advertising.restartOnDisconnect(true); @@ -307,34 +273,28 @@ void NRF52Bluetooth::resumeAdvertising() Bluefruit.Advertising.setFastTimeout(30); // number of seconds in fast mode Bluefruit.Advertising.start(0); } - /// Given a level between 0-100, update the BLE attribute void updateBatteryLevel(uint8_t level) { blebas.write(level); } - void NRF52Bluetooth::clearBonds() { LOG_INFO("Clearing bluetooth bonds!\n"); bond_print_list(BLE_GAP_ROLE_PERIPH); bond_print_list(BLE_GAP_ROLE_CENTRAL); - Bluefruit.Periph.clearBonds(); Bluefruit.Central.clearBonds(); } - void NRF52Bluetooth::onConnectionSecured(uint16_t conn_handle) { LOG_INFO("BLE connection secured\n"); } - bool NRF52Bluetooth::onPairingPasskey(uint16_t conn_handle, uint8_t const passkey[6], bool match_request) { LOG_INFO("BLE pairing process started with passkey %.3s %.3s\n", passkey, passkey + 3); powerFSM.trigger(EVENT_BLUETOOTH_PAIR); screen->startBluetoothPinScreen(configuredPasskey); - if (match_request) { uint32_t start_time = millis(); while (millis() < start_time + 30000) { @@ -345,13 +305,19 @@ bool NRF52Bluetooth::onPairingPasskey(uint16_t conn_handle, uint8_t const passke LOG_INFO("BLE passkey pairing: match_request=%i\n", match_request); return true; } - void NRF52Bluetooth::onPairingCompleted(uint16_t conn_handle, uint8_t auth_status) { if (auth_status == BLE_GAP_SEC_STATUS_SUCCESS) LOG_INFO("BLE pairing success\n"); else LOG_INFO("BLE pairing failed\n"); - screen->stopBluetoothPinScreen(); +} + +void NRF52Bluetooth::sendLog(const char *logMessage) +{ + if (!isConnected()) + return; + + logRadio.notify(logMessage); } \ No newline at end of file diff --git a/src/platform/nrf52/NRF52Bluetooth.h b/src/platform/nrf52/NRF52Bluetooth.h index 4c3ff3a6d0..807b0e4882 100644 --- a/src/platform/nrf52/NRF52Bluetooth.h +++ b/src/platform/nrf52/NRF52Bluetooth.h @@ -3,13 +3,11 @@ #include "BluetoothCommon.h" #include -class BluetoothPhoneAPI : public PhoneAPI -{ - public: - virtual void onNowHasData(uint32_t fromRadioNum); - virtual bool checkIsConnected(); - virtual void sendLog(const char *logMessage); -}; +// class BluetoothWrapper +// { +// public: +// virtual void sendLog(const char *logMessage); +// }; class NRF52Bluetooth : BluetoothApi { @@ -21,6 +19,7 @@ class NRF52Bluetooth : BluetoothApi void clearBonds(); bool isConnected(); int getRssi(); + void sendLog(const char *logMessage); private: static void onConnectionSecured(uint16_t conn_handle); From 721538ec81c34600e8fc6139737e10dc74993613 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Tue, 18 Jun 2024 19:56:07 -0500 Subject: [PATCH 03/15] Characteristic --- src/BluetoothCommon.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/BluetoothCommon.h b/src/BluetoothCommon.h index 1ba2b9f48e..5497e1d6db 100644 --- a/src/BluetoothCommon.h +++ b/src/BluetoothCommon.h @@ -11,7 +11,7 @@ #define TORADIO_UUID "f75c76d2-129e-4dad-a1dd-7866124401e7" #define FROMRADIO_UUID "2c55e69e-4993-11ed-b878-0242ac120002" #define FROMNUM_UUID "ed9da18c-a800-4f66-a670-aa7547e34453" -#define LOG_UUID "6c6fd238-78fa-436b-aacf-15c5be1ef2e2" +#define LOGRADIO_UUID "6c6fd238-78fa-436b-aacf-15c5be1ef2e2" // NRF52 wants these constants as byte arrays // Generated here https://yupana-engineering.com/online-uuid-to-c-array-converter - but in REVERSE BYTE ORDER From 87ba9ed892e10455193b561b93855ada780ba8a9 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Tue, 18 Jun 2024 20:22:52 -0500 Subject: [PATCH 04/15] Callback --- src/platform/nrf52/NRF52Bluetooth.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/platform/nrf52/NRF52Bluetooth.cpp b/src/platform/nrf52/NRF52Bluetooth.cpp index e5a8f9ee18..577db20c16 100644 --- a/src/platform/nrf52/NRF52Bluetooth.cpp +++ b/src/platform/nrf52/NRF52Bluetooth.cpp @@ -163,6 +163,7 @@ void setupMeshService(void) // fromNum.setReadAuthorizeCallback(fromNumAuthorizeCb); fromNum.write32(0); // Provide default fromNum of 0 fromNum.begin(); + fromRadio.setProperties(CHR_PROPS_READ); fromRadio.setPermission(secMode, SECMODE_NO_ACCESS); fromRadio.setMaxLen(sizeof(fromRadioBytes)); @@ -172,6 +173,7 @@ void setupMeshService(void) fromRadio.setBuffer(fromRadioBytes, sizeof(fromRadioBytes)); // we preallocate our fromradio buffer so we won't waste space // for two copies fromRadio.begin(); + toRadio.setProperties(CHR_PROPS_WRITE); toRadio.setPermission(secMode, secMode); // FIXME secure this! toRadio.setFixedLen(0); @@ -185,6 +187,7 @@ void setupMeshService(void) logRadio.setPermission(secMode, SECMODE_NO_ACCESS); logRadio.setFixedLen(0); logRadio.setMaxLen(512); + logRadio.setCccdWriteCallback(onCccd); logRadio.begin(); } static uint32_t configuredPasskey; @@ -316,8 +319,5 @@ void NRF52Bluetooth::onPairingCompleted(uint16_t conn_handle, uint8_t auth_statu void NRF52Bluetooth::sendLog(const char *logMessage) { - if (!isConnected()) - return; - logRadio.notify(logMessage); } \ No newline at end of file From 771ccebf20627086715ded170bea1e3531361c03 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Tue, 18 Jun 2024 20:33:05 -0500 Subject: [PATCH 05/15] Check for nullptr --- src/RedirectablePrint.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/RedirectablePrint.cpp b/src/RedirectablePrint.cpp index 0fe43c657b..5ebb053ac3 100644 --- a/src/RedirectablePrint.cpp +++ b/src/RedirectablePrint.cpp @@ -168,11 +168,11 @@ size_t RedirectablePrint::log(const char *logLevel, const char *format, ...) #endif #ifdef ARCH_ESP32 - // if(nimbleBluetooth->isConnected()) { + // if(nimbleBluetooth != nullptr && nimbleBluetooth->isConnected()) { // } #elif defined(ARCH_NRF52) - if (nrf52Bluetooth->isConnected()) { + if (nrf52Bluetooth != nullptr && nrf52Bluetooth->isConnected()) { nrf52Bluetooth->sendLog(format); } #endif From 78394c4014e78868933b6d8967a0815c60010c22 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Wed, 19 Jun 2024 07:30:54 -0500 Subject: [PATCH 06/15] Esp32 bluetooth impl --- src/RedirectablePrint.cpp | 12 +++++++++--- src/nimble/NimbleBluetooth.cpp | 14 ++++++++++++++ src/platform/nrf52/NRF52Bluetooth.cpp | 3 +++ 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/src/RedirectablePrint.cpp b/src/RedirectablePrint.cpp index 5ebb053ac3..4c242e0926 100644 --- a/src/RedirectablePrint.cpp +++ b/src/RedirectablePrint.cpp @@ -168,11 +168,17 @@ size_t RedirectablePrint::log(const char *logLevel, const char *format, ...) #endif #ifdef ARCH_ESP32 - // if(nimbleBluetooth != nullptr && nimbleBluetooth->isConnected()) { - - // } + if (nimbleBluetooth != nullptr && nimbleBluetooth->isConnected()) { + // meshtastic_LogRecord logRecord = meshtastic_LogRecord_init_zero; + // logRecord.level = meshtastic_LogRecord_Level_DEBUG; + // logRecord.message = format; + nimbleBluetooth->sendLog(format); + } #elif defined(ARCH_NRF52) if (nrf52Bluetooth != nullptr && nrf52Bluetooth->isConnected()) { + // meshtastic_LogRecord logRecord = meshtastic_LogRecord_init_zero; + // logRecord.level = meshtastic_LogRecord_Level_DEBUG; + // logRecord.message = format; nrf52Bluetooth->sendLog(format); } #endif diff --git a/src/nimble/NimbleBluetooth.cpp b/src/nimble/NimbleBluetooth.cpp index 68aa9b4653..7be3f47587 100644 --- a/src/nimble/NimbleBluetooth.cpp +++ b/src/nimble/NimbleBluetooth.cpp @@ -12,6 +12,7 @@ NimBLECharacteristic *fromNumCharacteristic; NimBLECharacteristic *BatteryCharacteristic; +NimBLECharacteristic *logRadioCharacteristic; NimBLEServer *bleServer; static bool passkeyShowing; @@ -180,6 +181,7 @@ void NimbleBluetooth::setupService() ToRadioCharacteristic = bleService->createCharacteristic(TORADIO_UUID, NIMBLE_PROPERTY::WRITE); FromRadioCharacteristic = bleService->createCharacteristic(FROMRADIO_UUID, NIMBLE_PROPERTY::READ); fromNumCharacteristic = bleService->createCharacteristic(FROMNUM_UUID, NIMBLE_PROPERTY::NOTIFY | NIMBLE_PROPERTY::READ); + logRadioCharacteristic = bleService->createCharacteristic(LOGRADIO_UUID, NIMBLE_PROPERTY::NOTIFY | NIMBLE_PROPERTY::READ); } else { ToRadioCharacteristic = bleService->createCharacteristic( TORADIO_UUID, NIMBLE_PROPERTY::WRITE | NIMBLE_PROPERTY::WRITE_AUTHEN | NIMBLE_PROPERTY::WRITE_ENC); @@ -188,6 +190,9 @@ void NimbleBluetooth::setupService() fromNumCharacteristic = bleService->createCharacteristic(FROMNUM_UUID, NIMBLE_PROPERTY::NOTIFY | NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::READ_AUTHEN | NIMBLE_PROPERTY::READ_ENC); + logRadioCharacteristic = + bleService->createCharacteristic(LOGRADIO_UUID, NIMBLE_PROPERTY::NOTIFY | NIMBLE_PROPERTY::READ | + NIMBLE_PROPERTY::READ_AUTHEN | NIMBLE_PROPERTY::READ_ENC); } bluetoothPhoneAPI = new BluetoothPhoneAPI(); @@ -236,6 +241,15 @@ void NimbleBluetooth::clearBonds() NimBLEDevice::deleteAllBonds(); } +void NimbleBluetooth::sendLog(const char *logMessage) +{ + if (!bleServer || !isConnected() || strlen(logMessage) > 512) { + return; + } + logRadioCharacteristic->setValue(logMessage); + logRadioCharacteristic->notify(); +} + void clearNVS() { NimBLEDevice::deleteAllBonds(); diff --git a/src/platform/nrf52/NRF52Bluetooth.cpp b/src/platform/nrf52/NRF52Bluetooth.cpp index 577db20c16..f35b93d0d5 100644 --- a/src/platform/nrf52/NRF52Bluetooth.cpp +++ b/src/platform/nrf52/NRF52Bluetooth.cpp @@ -319,5 +319,8 @@ void NRF52Bluetooth::onPairingCompleted(uint16_t conn_handle, uint8_t auth_statu void NRF52Bluetooth::sendLog(const char *logMessage) { + if (!isConnected() || strlen(logMessage) > 512) + return; + logRadio.notify(logMessage); } \ No newline at end of file From 5b1324a43a0adf65f0362ce669315238b46be6d1 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Wed, 19 Jun 2024 13:21:42 -0500 Subject: [PATCH 07/15] Formatting --- src/RedirectablePrint.cpp | 45 +++++++++++++++++---------- src/platform/nrf52/NRF52Bluetooth.cpp | 16 +++------- 2 files changed, 33 insertions(+), 28 deletions(-) diff --git a/src/RedirectablePrint.cpp b/src/RedirectablePrint.cpp index 4c242e0926..fd3f3423c4 100644 --- a/src/RedirectablePrint.cpp +++ b/src/RedirectablePrint.cpp @@ -167,25 +167,38 @@ size_t RedirectablePrint::log(const char *logLevel, const char *format, ...) } #endif -#ifdef ARCH_ESP32 - if (nimbleBluetooth != nullptr && nimbleBluetooth->isConnected()) { - // meshtastic_LogRecord logRecord = meshtastic_LogRecord_init_zero; - // logRecord.level = meshtastic_LogRecord_Level_DEBUG; - // logRecord.message = format; - nimbleBluetooth->sendLog(format); - } -#elif defined(ARCH_NRF52) - if (nrf52Bluetooth != nullptr && nrf52Bluetooth->isConnected()) { - // meshtastic_LogRecord logRecord = meshtastic_LogRecord_init_zero; - // logRecord.level = meshtastic_LogRecord_Level_DEBUG; - // logRecord.message = format; - nrf52Bluetooth->sendLog(format); - } -#endif - va_end(arg); isContinuationMessage = !hasNewline; + + if (!isContinuationMessage) { + bool isConnected = false; +#ifdef ARCH_ESP32 + isConnected = nimbleBluetooth != nullptr && nimbleBluetooth->isConnected(); +#elif defined(ARCH_NRF52) + isConnected = nrf52Bluetooth != nullptr && nrf52Bluetooth->isConnected(); +#endif + if (isConnected) { + char *message; + size_t initialLen; + size_t len; + bool result; + initialLen = strlen(format); + message = new char[initialLen + 1]; + len = vsnprintf(message, initialLen + 1, format, arg); + if (len > initialLen) { + delete[] message; + message = new char[len + 1]; + vsnprintf(message, len + 1, format, arg); + } +#ifdef ARCH_ESP32 + nimbleBluetooth->sendLog(format); +#elif defined(ARCH_NRF52) + nrf52Bluetooth->sendLog(message); +#endif + delete[] message; + } + } #ifdef HAS_FREE_RTOS xSemaphoreGive(inDebugPrint); #else diff --git a/src/platform/nrf52/NRF52Bluetooth.cpp b/src/platform/nrf52/NRF52Bluetooth.cpp index f35b93d0d5..a14829285b 100644 --- a/src/platform/nrf52/NRF52Bluetooth.cpp +++ b/src/platform/nrf52/NRF52Bluetooth.cpp @@ -74,7 +74,7 @@ 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. - if (chr->uuid == fromNum.uuid) { + if (chr->uuid == fromNum.uuid || chr->uuid == logRadio.uuid) { if (chr->notifyEnabled(conn_hdl)) { LOG_INFO("fromNum 'Notify' enabled\n"); } else { @@ -135,14 +135,7 @@ void onToRadioWrite(uint16_t conn_hdl, BLECharacteristic *chr, uint8_t *data, ui LOG_INFO("toRadioWriteCb data %p, len %u\n", data, len); bluetoothPhoneAPI->handleToRadio(data, len); } -/** - * client is starting read, pull the bytes from our API class - */ -void onFromNumAuthorize(uint16_t conn_hdl, BLECharacteristic *chr, ble_gatts_evt_read_t *request) -{ - LOG_INFO("fromNumAuthorizeCb\n"); - authorizeRead(conn_hdl); -} + void setupMeshService(void) { bluetoothPhoneAPI = new BluetoothPhoneAPI(); @@ -183,11 +176,11 @@ void setupMeshService(void) toRadio.setWriteCallback(onToRadioWrite, false); toRadio.begin(); - logRadio.setProperties(CHR_PROPS_NOTIFY); + logRadio.setProperties(CHR_PROPS_NOTIFY | CHR_PROPS_READ); logRadio.setPermission(secMode, SECMODE_NO_ACCESS); - logRadio.setFixedLen(0); logRadio.setMaxLen(512); logRadio.setCccdWriteCallback(onCccd); + logRadio.write32(0); logRadio.begin(); } static uint32_t configuredPasskey; @@ -321,6 +314,5 @@ void NRF52Bluetooth::sendLog(const char *logMessage) { if (!isConnected() || strlen(logMessage) > 512) return; - logRadio.notify(logMessage); } \ No newline at end of file From e72362a4b718cf706ef3938f896d76b98cc9dc45 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Wed, 19 Jun 2024 14:41:25 -0500 Subject: [PATCH 08/15] Add thread name and log level --- src/RedirectablePrint.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/RedirectablePrint.cpp b/src/RedirectablePrint.cpp index fd3f3423c4..0e517d41ea 100644 --- a/src/RedirectablePrint.cpp +++ b/src/RedirectablePrint.cpp @@ -191,10 +191,17 @@ size_t RedirectablePrint::log(const char *logLevel, const char *format, ...) message = new char[len + 1]; vsnprintf(message, len + 1, format, arg); } + auto thread = concurrency::OSThread::currentThread; #ifdef ARCH_ESP32 - nimbleBluetooth->sendLog(format); + if (thread) + nimbleBluetooth->sendLog(mt_sprintf("%s | [%s] %s", logLevel, thread->ThreadName.c_str(), message).c_str()); + else + nimbleBluetooth->sendLog(mt_sprintf("%s | %s", logLevel, message).c_str()); #elif defined(ARCH_NRF52) - nrf52Bluetooth->sendLog(message); + if (thread) + nrf52Bluetooth->sendLog(mt_sprintf("%s | [%s] %s", logLevel, thread->ThreadName.c_str(), message).c_str()); + else + nrf52Bluetooth->sendLog(mt_sprintf("%s | %s", logLevel, message).c_str()); #endif delete[] message; } From 949c171ef9548c9d86396d5cff5931427bc13a99 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Wed, 19 Jun 2024 14:53:06 -0500 Subject: [PATCH 09/15] Add settings guard --- src/RedirectablePrint.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/RedirectablePrint.cpp b/src/RedirectablePrint.cpp index 0e517d41ea..1ef1b43df6 100644 --- a/src/RedirectablePrint.cpp +++ b/src/RedirectablePrint.cpp @@ -171,14 +171,14 @@ size_t RedirectablePrint::log(const char *logLevel, const char *format, ...) isContinuationMessage = !hasNewline; - if (!isContinuationMessage) { - bool isConnected = false; + if (!isContinuationMessage && config.bluetooth.device_logging_enabled) { + bool isBleConnected = false; #ifdef ARCH_ESP32 isConnected = nimbleBluetooth != nullptr && nimbleBluetooth->isConnected(); #elif defined(ARCH_NRF52) - isConnected = nrf52Bluetooth != nullptr && nrf52Bluetooth->isConnected(); + isBleConnected = nrf52Bluetooth != nullptr && nrf52Bluetooth->isConnected(); #endif - if (isConnected) { + if (isBleConnected) { char *message; size_t initialLen; size_t len; From 22b27c2a549eb212378a93d5384503c2ef32522b Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Wed, 19 Jun 2024 14:55:50 -0500 Subject: [PATCH 10/15] Remove comments --- src/platform/nrf52/NRF52Bluetooth.h | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/platform/nrf52/NRF52Bluetooth.h b/src/platform/nrf52/NRF52Bluetooth.h index 807b0e4882..0d621dda25 100644 --- a/src/platform/nrf52/NRF52Bluetooth.h +++ b/src/platform/nrf52/NRF52Bluetooth.h @@ -3,12 +3,6 @@ #include "BluetoothCommon.h" #include -// class BluetoothWrapper -// { -// public: -// virtual void sendLog(const char *logMessage); -// }; - class NRF52Bluetooth : BluetoothApi { public: From e539f270335ffd9f0f34451ed5321895a4628fb6 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Wed, 19 Jun 2024 15:03:58 -0500 Subject: [PATCH 11/15] Field name --- src/RedirectablePrint.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/RedirectablePrint.cpp b/src/RedirectablePrint.cpp index 1ef1b43df6..dc82df5663 100644 --- a/src/RedirectablePrint.cpp +++ b/src/RedirectablePrint.cpp @@ -174,7 +174,7 @@ size_t RedirectablePrint::log(const char *logLevel, const char *format, ...) if (!isContinuationMessage && config.bluetooth.device_logging_enabled) { bool isBleConnected = false; #ifdef ARCH_ESP32 - isConnected = nimbleBluetooth != nullptr && nimbleBluetooth->isConnected(); + isBleConnected = nimbleBluetooth != nullptr && nimbleBluetooth->isConnected(); #elif defined(ARCH_NRF52) isBleConnected = nrf52Bluetooth != nullptr && nrf52Bluetooth->isConnected(); #endif From ff02adea1c8f374fbb19074384f0e9fe24e07037 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Wed, 19 Jun 2024 15:38:40 -0500 Subject: [PATCH 12/15] Fixes esp32 --- src/RedirectablePrint.cpp | 3 +-- src/nimble/NimbleBluetooth.cpp | 4 +--- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/RedirectablePrint.cpp b/src/RedirectablePrint.cpp index dc82df5663..d9a890c3f9 100644 --- a/src/RedirectablePrint.cpp +++ b/src/RedirectablePrint.cpp @@ -174,7 +174,7 @@ size_t RedirectablePrint::log(const char *logLevel, const char *format, ...) if (!isContinuationMessage && config.bluetooth.device_logging_enabled) { bool isBleConnected = false; #ifdef ARCH_ESP32 - isBleConnected = nimbleBluetooth != nullptr && nimbleBluetooth->isConnected(); + isBleConnected = nimbleBluetooth && nimbleBluetooth->isActive() && nimbleBluetooth->isConnected(); #elif defined(ARCH_NRF52) isBleConnected = nrf52Bluetooth != nullptr && nrf52Bluetooth->isConnected(); #endif @@ -182,7 +182,6 @@ size_t RedirectablePrint::log(const char *logLevel, const char *format, ...) char *message; size_t initialLen; size_t len; - bool result; initialLen = strlen(format); message = new char[initialLen + 1]; len = vsnprintf(message, initialLen + 1, format, arg); diff --git a/src/nimble/NimbleBluetooth.cpp b/src/nimble/NimbleBluetooth.cpp index 7be3f47587..6ed4a49aed 100644 --- a/src/nimble/NimbleBluetooth.cpp +++ b/src/nimble/NimbleBluetooth.cpp @@ -59,7 +59,6 @@ class NimbleBluetoothFromRadioCallback : public NimBLECharacteristicCallbacks { virtual void onRead(NimBLECharacteristic *pCharacteristic) { - LOG_INFO("From Radio onread\n"); uint8_t fromRadioBytes[meshtastic_FromRadio_size]; size_t numBytes = bluetoothPhoneAPI->getFromRadio(fromRadioBytes); @@ -246,8 +245,7 @@ void NimbleBluetooth::sendLog(const char *logMessage) if (!bleServer || !isConnected() || strlen(logMessage) > 512) { return; } - logRadioCharacteristic->setValue(logMessage); - logRadioCharacteristic->notify(); + logRadioCharacteristic->notify((uint8_t *)logMessage, strlen(logMessage)); } void clearNVS() From b09bbf0d302ef2c2a3a58ee637ebb2157570ae35 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Wed, 19 Jun 2024 16:49:56 -0500 Subject: [PATCH 13/15] Open it up --- src/RedirectablePrint.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/RedirectablePrint.cpp b/src/RedirectablePrint.cpp index d9a890c3f9..4aca536f65 100644 --- a/src/RedirectablePrint.cpp +++ b/src/RedirectablePrint.cpp @@ -171,7 +171,7 @@ size_t RedirectablePrint::log(const char *logLevel, const char *format, ...) isContinuationMessage = !hasNewline; - if (!isContinuationMessage && config.bluetooth.device_logging_enabled) { + if (config.bluetooth.device_logging_enabled) { bool isBleConnected = false; #ifdef ARCH_ESP32 isBleConnected = nimbleBluetooth && nimbleBluetooth->isActive() && nimbleBluetooth->isConnected(); @@ -197,6 +197,7 @@ size_t RedirectablePrint::log(const char *logLevel, const char *format, ...) else nimbleBluetooth->sendLog(mt_sprintf("%s | %s", logLevel, message).c_str()); #elif defined(ARCH_NRF52) + Serial.print(message); if (thread) nrf52Bluetooth->sendLog(mt_sprintf("%s | [%s] %s", logLevel, thread->ThreadName.c_str(), message).c_str()); else From ce77b2ab9fff036b92fb61efd6acc1b82055e2aa Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Wed, 19 Jun 2024 16:51:00 -0500 Subject: [PATCH 14/15] Whoops --- src/RedirectablePrint.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/RedirectablePrint.cpp b/src/RedirectablePrint.cpp index 4aca536f65..55b662a288 100644 --- a/src/RedirectablePrint.cpp +++ b/src/RedirectablePrint.cpp @@ -197,7 +197,6 @@ size_t RedirectablePrint::log(const char *logLevel, const char *format, ...) else nimbleBluetooth->sendLog(mt_sprintf("%s | %s", logLevel, message).c_str()); #elif defined(ARCH_NRF52) - Serial.print(message); if (thread) nrf52Bluetooth->sendLog(mt_sprintf("%s | [%s] %s", logLevel, thread->ThreadName.c_str(), message).c_str()); else From 4377031fc5936165993b9f4c41c8f3e3abf91547 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Wed, 19 Jun 2024 18:48:12 -0500 Subject: [PATCH 15/15] Move va_end past our logic --- src/RedirectablePrint.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/RedirectablePrint.cpp b/src/RedirectablePrint.cpp index 55b662a288..2110761ffc 100644 --- a/src/RedirectablePrint.cpp +++ b/src/RedirectablePrint.cpp @@ -167,8 +167,6 @@ size_t RedirectablePrint::log(const char *logLevel, const char *format, ...) } #endif - va_end(arg); - isContinuationMessage = !hasNewline; if (config.bluetooth.device_logging_enabled) { @@ -205,6 +203,7 @@ size_t RedirectablePrint::log(const char *logLevel, const char *format, ...) delete[] message; } } + va_end(arg); #ifdef HAS_FREE_RTOS xSemaphoreGive(inDebugPrint); #else