From 6c1762613282b0b5bc951b42a4ba3c616f84fac2 Mon Sep 17 00:00:00 2001 From: Joshua Pirihi Date: Tue, 15 Feb 2022 06:52:00 +1300 Subject: [PATCH 1/4] Use NimBLE API for ESP32 bluetooth --- src/esp32/BluetoothSoftwareUpdate.cpp | 4 + src/esp32/BluetoothSoftwareUpdate.h | 6 +- src/esp32/ESP32Bluetooth.cpp | 205 ++++++++++++++++++++++++++ src/esp32/ESP32Bluetooth.h | 33 +++++ src/esp32/NimbleSoftwareUpdate.c | 3 + src/esp32/main-esp32.cpp | 26 +++- src/main.cpp | 10 +- src/nimble/BluetoothUtil.cpp | 24 ++- src/nimble/BluetoothUtil.h | 6 +- src/nimble/NimbleBluetoothAPI.cpp | 4 + src/nimble/NimbleBluetoothAPI.h | 4 + src/nimble/NimbleDefs.c | 4 + src/nimble/NimbleDefs.h | 6 +- 13 files changed, 328 insertions(+), 7 deletions(-) create mode 100644 src/esp32/ESP32Bluetooth.cpp create mode 100644 src/esp32/ESP32Bluetooth.h diff --git a/src/esp32/BluetoothSoftwareUpdate.cpp b/src/esp32/BluetoothSoftwareUpdate.cpp index d097e95f8..02a94abce 100644 --- a/src/esp32/BluetoothSoftwareUpdate.cpp +++ b/src/esp32/BluetoothSoftwareUpdate.cpp @@ -1,3 +1,5 @@ +#ifndef USE_NEW_ESP32_BLUETOOTH + #include #include "../concurrency/LockGuard.h" @@ -154,3 +156,5 @@ void reinitUpdateService() res = ble_gatts_add_svcs(gatt_update_svcs); assert(res == 0); } + +#endif //#ifndef USE_NEW_ESP32_BLUETOOTH \ No newline at end of file diff --git a/src/esp32/BluetoothSoftwareUpdate.h b/src/esp32/BluetoothSoftwareUpdate.h index 478d478d5..468cc6060 100644 --- a/src/esp32/BluetoothSoftwareUpdate.h +++ b/src/esp32/BluetoothSoftwareUpdate.h @@ -1,3 +1,5 @@ +#ifndef USE_NEW_ESP32_BLUETOOTH + #pragma once #include "nimble/NimbleDefs.h" @@ -22,4 +24,6 @@ extern int16_t updateResultHandle; #ifdef __cplusplus }; -#endif \ No newline at end of file +#endif + +#endif //#ifndef USE_NEW_ESP32_BLUETOOTH \ No newline at end of file diff --git a/src/esp32/ESP32Bluetooth.cpp b/src/esp32/ESP32Bluetooth.cpp new file mode 100644 index 000000000..c74a64ff7 --- /dev/null +++ b/src/esp32/ESP32Bluetooth.cpp @@ -0,0 +1,205 @@ +#ifdef USE_NEW_ESP32_BLUETOOTH + +#include "configuration.h" +#include "ESP32Bluetooth.h" +#include "BluetoothCommon.h" +#include "main.h" +#include "mesh/PhoneAPI.h" +#include "mesh/mesh-pb-constants.h" +#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 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 + +// This scratch buffer is used for various bluetooth reads/writes - but it is safe because only one bt operation can be in +// proccess at once +// static uint8_t trBytes[_max(_max(_max(_max(ToRadio_size, RadioConfig_size), User_size), MyNodeInfo_size), FromRadio_size)]; +static uint8_t fromRadioBytes[FromRadio_size]; +static uint8_t toRadioBytes[ToRadio_size]; + +static bool bleConnected; + +NimBLECharacteristic *FromNumCharacteristic; +NimBLEServer *bleServer; + +/** + * Subclasses can use this as a hook to provide custom notifications for their transport (i.e. bluetooth notifies) + */ +void BluetoothPhoneAPI::onNowHasData(uint32_t fromRadioNum) +{ + PhoneAPI::onNowHasData(fromRadioNum); + + DEBUG_MSG("BLE notify fromNum\n"); + //fromNum.notify32(fromRadioNum); + + uint8_t val[4]; + put_le32(val, fromRadioNum); + + std::string fromNumByteString(&val[0], &val[0] + sizeof(val)); + + FromNumCharacteristic->setValue(fromNumByteString); + FromNumCharacteristic->notify(); +} + +/// Check the current underlying physical link to see if the client is currently connected +bool BluetoothPhoneAPI::checkIsConnected() { + if (bleServer && bleServer->getConnectedCount() > 0) { + return true; + } + return false; +} + +PhoneAPI *bluetoothPhoneAPI; + +class ESP32BluetoothToRadioCallback : public NimBLECharacteristicCallbacks { + virtual void onWrite(NimBLECharacteristic *pCharacteristic) { + DEBUG_MSG("To Radio onwrite"); + auto valueString = pCharacteristic->getValue(); + + bluetoothPhoneAPI->handleToRadio(reinterpret_cast(&valueString[0]), pCharacteristic->getDataLength()); + } +}; + +class ESP32BluetoothFromRadioCallback : public NimBLECharacteristicCallbacks { + virtual void onRead(NimBLECharacteristic *pCharacteristic) { + DEBUG_MSG("From Radio onread"); + size_t numBytes = bluetoothPhoneAPI->getFromRadio(fromRadioBytes); + + std::string fromRadioByteString(fromRadioBytes, fromRadioBytes + numBytes); + + pCharacteristic->setValue(fromRadioByteString); + } +}; + + + +static ESP32BluetoothToRadioCallback *toRadioCallbacks; +static ESP32BluetoothFromRadioCallback *fromRadioCallbacks; + +void ESP32Bluetooth::shutdown() +{ + // Shutdown bluetooth for minimum power draw + DEBUG_MSG("Disable NRF52 bluetooth\n"); + //Bluefruit.Advertising.stop(); +} + +void ESP32Bluetooth::setup() +{ + // Initialise the Bluefruit module + DEBUG_MSG("Initialise the ESP32 bluetooth module\n"); + //Bluefruit.autoConnLed(false); + //Bluefruit.begin(); + + // Set the advertised device name (keep it short!) + //Bluefruit.setName(getDeviceName()); + + // Set the connect/disconnect callback handlers + //Bluefruit.Periph.setConnectCallback(connect_callback); + //Bluefruit.Periph.setDisconnectCallback(disconnect_callback); + + // Configure and Start the Device Information Service + DEBUG_MSG("Configuring the Device Information Service\n"); + // FIXME, we should set a mfg string based on our HW_VENDOR enum + // bledis.setManufacturer(HW_VENDOR); + //bledis.setModel(optstr(HW_VERSION)); + //bledis.setFirmwareRev(optstr(APP_VERSION)); + //bledis.begin(); + + // Start the BLE Battery Service and set it to 100% + //DEBUG_MSG("Configuring the Battery Service\n"); + //blebas.begin(); + //blebas.write(0); // Unknown battery level for now + + //bledfu.begin(); // Install the DFU helper + + // Setup the Heart Rate Monitor service using + // BLEService and BLECharacteristic classes + DEBUG_MSG("Configuring the Mesh bluetooth service\n"); + //setupMeshService(); + + // Supposedly debugging works with soft device if you disable advertising + //if (isSoftDeviceAllowed) { + // Setup the advertising packet(s) + // DEBUG_MSG("Setting up the advertising payload(s)\n"); + // startAdv(); + + // DEBUG_MSG("Advertising\n"); + //} + + //NimBLEDevice::deleteAllBonds(); + + NimBLEDevice::init("Meshtastic_1234"); + NimBLEDevice::setPower(ESP_PWR_LVL_P9); + + NimBLEDevice::setSecurityAuth(true, true, true); + NimBLEDevice::setSecurityPasskey(123456); + NimBLEDevice::setSecurityIOCap(BLE_HS_IO_DISPLAY_ONLY); + bleServer = NimBLEDevice::createServer(); + NimBLEService *bleService = bleServer->createService(MESH_SERVICE_UUID); + //NimBLECharacteristic *pNonSecureCharacteristic = bleService->createCharacteristic("1234", NIMBLE_PROPERTY::READ ); + //NimBLECharacteristic *pSecureCharacteristic = bleService->createCharacteristic("1235", NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::READ_ENC | NIMBLE_PROPERTY::READ_AUTHEN); + + //define the characteristics that the app is looking for + NimBLECharacteristic *ToRadioCharacteristic = bleService->createCharacteristic(TORADIO_UUID, NIMBLE_PROPERTY::WRITE | NIMBLE_PROPERTY::WRITE_AUTHEN | NIMBLE_PROPERTY::WRITE_ENC); + NimBLECharacteristic *FromRadioCharacteristic = bleService->createCharacteristic(FROMRADIO_UUID, NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::READ_AUTHEN | NIMBLE_PROPERTY::READ_ENC); + FromNumCharacteristic = bleService->createCharacteristic(FROMNUM_UUID, NIMBLE_PROPERTY::NOTIFY | NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::READ_AUTHEN | NIMBLE_PROPERTY::READ_ENC); + + bluetoothPhoneAPI = new BluetoothPhoneAPI(); + + toRadioCallbacks = new ESP32BluetoothToRadioCallback(); + ToRadioCharacteristic->setCallbacks(toRadioCallbacks); + + fromRadioCallbacks = new ESP32BluetoothFromRadioCallback(); + FromRadioCharacteristic->setCallbacks(fromRadioCallbacks); + + //uint8_t val[4]; + //uint32_t zero = 0; + //put_le32(val, zero); + //std::string fromNumByteString(&val[0], &val[0] + sizeof(val)); + //FromNumCharacteristic->setValue(fromNumByteString); + + bleService->start(); + //pNonSecureCharacteristic->setValue("Hello Non Secure BLE"); + //pSecureCharacteristic->setValue("Hello Secure BLE"); + + //FromRadioCharacteristic->setValue("FromRadioString"); + //ToRadioCharacteristic->setCallbacks() + + NimBLEAdvertising *pAdvertising = NimBLEDevice::getAdvertising(); + pAdvertising->addServiceUUID(MESH_SERVICE_UUID); + pAdvertising->start(); + +} + + +/// Given a level between 0-100, update the BLE attribute +void updateBatteryLevel(uint8_t level) +{ + //blebas.write(level); +} + +void ESP32Bluetooth::clearBonds() +{ + DEBUG_MSG("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 clearNVS() { + +} + +void disablePin() { + +} + +#endif \ No newline at end of file diff --git a/src/esp32/ESP32Bluetooth.h b/src/esp32/ESP32Bluetooth.h new file mode 100644 index 000000000..b839a7926 --- /dev/null +++ b/src/esp32/ESP32Bluetooth.h @@ -0,0 +1,33 @@ +#ifdef USE_NEW_ESP32_BLUETOOTH + +#pragma once + +extern uint16_t fromNumValHandle; + +class BluetoothPhoneAPI : public PhoneAPI +{ +protected: + /** + * 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; + + /// Check the current underlying physical link to see if the client is currently connected + virtual bool checkIsConnected() override; +}; + +extern PhoneAPI *bluetoothPhoneAPI; + +class ESP32Bluetooth +{ + public: + void setup(); + void shutdown(); + void clearBonds(); +}; + +void setBluetoothEnable(bool on); +void clearNVS(); +void disablePin(); + +#endif \ No newline at end of file diff --git a/src/esp32/NimbleSoftwareUpdate.c b/src/esp32/NimbleSoftwareUpdate.c index 956fdf53f..6f7ebf6cc 100644 --- a/src/esp32/NimbleSoftwareUpdate.c +++ b/src/esp32/NimbleSoftwareUpdate.c @@ -1,3 +1,4 @@ +#ifndef USE_NEW_ESP32_BLUETOOTH #include "BluetoothSoftwareUpdate.h" // NRF52 wants these constants as byte arrays @@ -68,3 +69,5 @@ const struct ble_gatt_svc_def gatt_update_svcs[] = { 0, /* No more services. */ }, }; + +#endif //#ifndef USE_NEW_ESP32_BLUETOOTH \ No newline at end of file diff --git a/src/esp32/main-esp32.cpp b/src/esp32/main-esp32.cpp index b0afab656..2e012297b 100644 --- a/src/esp32/main-esp32.cpp +++ b/src/esp32/main-esp32.cpp @@ -3,7 +3,13 @@ #include "configuration.h" #include "esp_task_wdt.h" #include "main.h" + +#ifdef USE_NEW_ESP32_BLUETOOTH +#include "ESP32Bluetooth.h" +#else #include "nimble/BluetoothUtil.h" +#endif + #include "sleep.h" #include "target_specific.h" #include "utils.h" @@ -12,6 +18,10 @@ #include #include +#ifdef USE_NEW_ESP32_BLUETOOTH +ESP32Bluetooth *esp32Bluetooth; +#endif + void getMacAddr(uint8_t *dmac) { assert(esp_efuse_mac_get_default(dmac) == ESP_OK); @@ -28,6 +38,19 @@ static void printBLEinfo() { } } */ +#ifdef USE_NEW_ESP32_BLUETOOTH +void setBluetoothEnable(bool on) { + + if (!esp32Bluetooth) { + esp32Bluetooth = new ESP32Bluetooth(); + } + if (on) { + esp32Bluetooth->setup(); + } else { + esp32Bluetooth->shutdown(); + } +} +#endif void esp32Setup() { @@ -92,11 +115,12 @@ uint32_t axpDebugRead() Periodic axpDebugOutput(axpDebugRead); #endif + /// loop code specific to ESP32 targets void esp32Loop() { esp_task_wdt_reset(); // service our app level watchdog - loopBLE(); + //loopBLE(); // for debug printing // radio.radioIf.canSleep(); diff --git a/src/main.cpp b/src/main.cpp index 544040ac0..0b7420c31 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -28,8 +28,14 @@ #include "mesh/http/WiFiAPClient.h" #ifndef NO_ESP32 -#include "mesh/http/WebServer.h" -#include "nimble/BluetoothUtil.h" + #include "mesh/http/WebServer.h" + + #ifdef USE_NEW_ESP32_BLUETOOTH + #include "esp32/ESP32Bluetooth.h" + #else + #include "nimble/BluetoothUtil.h" + #endif + #endif #if defined(HAS_WIFI) || defined(PORTDUINO) diff --git a/src/nimble/BluetoothUtil.cpp b/src/nimble/BluetoothUtil.cpp index 016eafe06..fc4501ccb 100644 --- a/src/nimble/BluetoothUtil.cpp +++ b/src/nimble/BluetoothUtil.cpp @@ -1,3 +1,5 @@ +#ifndef USE_NEW_ESP32_BLUETOOTH + #include "BluetoothUtil.h" #include "BluetoothSoftwareUpdate.h" #include "NimbleBluetoothAPI.h" @@ -23,6 +25,8 @@ static uint32_t doublepressed; static bool bluetoothActive; +//put the wider device into a bluetooth pairing mode, and show the pin on screen. +//called in this file only static void startCb(uint32_t pin) { pinShowing = true; @@ -30,6 +34,8 @@ static void startCb(uint32_t pin) screen->startBluetoothPinScreen(pin); }; +//pairing has ended +//called in this file only static void stopCb() { if (pinShowing) { @@ -52,6 +58,8 @@ void updateBatteryLevel(uint8_t level) // FIXME } +//shutdown the bluetooth and tear down all the data structures. to prevent memory leaks +//called here only void deinitBLE() { if (bluetoothActive) { @@ -85,6 +93,7 @@ void loopBLE() extern "C" void ble_store_config_init(void); /// Print a macaddr - bytes are sometimes stored in reverse order +//called here only static void print_addr(const uint8_t v[], bool isReversed = true) { const int macaddrlen = 6; @@ -96,6 +105,7 @@ static void print_addr(const uint8_t v[], bool isReversed = true) /** * Logs information about a connection to the console. + * called here only */ static void print_conn_desc(struct ble_gap_conn_desc *desc) { @@ -260,6 +270,8 @@ static int gap_event(struct ble_gap_event *event, void *arg) * Enables advertising with the following parameters: * o General discoverable mode. * o Undirected connectable mode. + * + * Called here only */ static void advertise(void) { @@ -324,12 +336,16 @@ static void advertise(void) } } +//callback +//doesn't do anything static void on_reset(int reason) { // 19 == BLE_HS_ETIMEOUT_HCI DEBUG_MSG("Resetting state; reason=%d\n", reason); } +//callback +// static void on_sync(void) { int rc; @@ -356,6 +372,7 @@ static void on_sync(void) advertise(); } +//do the bluetooth tasks static void ble_host_task(void *param) { DEBUG_MSG("BLE task running\n"); @@ -366,6 +383,7 @@ static void ble_host_task(void *param) nimble_port_freertos_deinit(); // delete the task } +//saves the stream handles when characteristics are successfully registered void gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg) { char buf[BLE_UUID_STR_LEN]; @@ -405,6 +423,8 @@ void gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg) * * If a read, the provided value will be returned over bluetooth. If a write, the value from the received packet * will be written into the variable. + * + * used a few places */ int chr_readwrite32le(uint32_t *v, struct ble_gatt_access_ctxt *ctxt) { @@ -637,4 +657,6 @@ void updateBatteryLevel(uint8_t level) BLEServer *serve = initBLE(, , getDeviceName(), HW_VENDOR, optstr(APP_VERSION), optstr(HW_VERSION)); // FIXME, use a real name based on the macaddr -#endif \ No newline at end of file +#endif + +#endif //#ifndef USE_NEW_ESP32_BLUETOOTH \ No newline at end of file diff --git a/src/nimble/BluetoothUtil.h b/src/nimble/BluetoothUtil.h index 8d02c0afc..bd2c08e27 100644 --- a/src/nimble/BluetoothUtil.h +++ b/src/nimble/BluetoothUtil.h @@ -1,3 +1,5 @@ +#ifndef USE_NEW_ESP32_BLUETOOTH + #pragma once #include @@ -28,4 +30,6 @@ int chr_readwrite32le(uint32_t *v, struct ble_gatt_access_ctxt *ctxt); /** * A helper for readwrite access to an array of bytes (with no endian conversion) */ -int chr_readwrite8(uint8_t *v, size_t vlen, struct ble_gatt_access_ctxt *ctxt); \ No newline at end of file +int chr_readwrite8(uint8_t *v, size_t vlen, struct ble_gatt_access_ctxt *ctxt); + +#endif //#ifndef USE_NEW_ESP32_BLUETOOTH \ No newline at end of file diff --git a/src/nimble/NimbleBluetoothAPI.cpp b/src/nimble/NimbleBluetoothAPI.cpp index 6b44e44d0..a2bd718d7 100644 --- a/src/nimble/NimbleBluetoothAPI.cpp +++ b/src/nimble/NimbleBluetoothAPI.cpp @@ -1,3 +1,5 @@ +#ifndef USE_NEW_ESP32_BLUETOOTH + #include "NimbleBluetoothAPI.h" #include "PhoneAPI.h" #include "configuration.h" @@ -69,3 +71,5 @@ int fromnum_callback(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt { return chr_readwrite32le(&fromNum, ctxt); } + +#endif //#ifndef USE_NEW_ESP32_BLUETOOTH \ No newline at end of file diff --git a/src/nimble/NimbleBluetoothAPI.h b/src/nimble/NimbleBluetoothAPI.h index 4df2498b8..0945ae422 100644 --- a/src/nimble/NimbleBluetoothAPI.h +++ b/src/nimble/NimbleBluetoothAPI.h @@ -1,3 +1,5 @@ +#ifndef USE_NEW_ESP32_BLUETOOTH + #pragma once #include "PhoneAPI.h" @@ -17,3 +19,5 @@ protected: }; extern PhoneAPI *bluetoothPhoneAPI; + +#endif //#ifndef USE_NEW_ESP32_BLUETOOTH \ No newline at end of file diff --git a/src/nimble/NimbleDefs.c b/src/nimble/NimbleDefs.c index 179cbebf6..8be1401ae 100644 --- a/src/nimble/NimbleDefs.c +++ b/src/nimble/NimbleDefs.c @@ -1,3 +1,5 @@ +#ifndef USE_NEW_ESP32_BLUETOOTH + #include "NimbleDefs.h" // NRF52 wants these constants as byte arrays @@ -44,3 +46,5 @@ const struct ble_gatt_svc_def gatt_svr_svcs[] = { 0, /* No more services. */ }, }; + +#endif //#ifndef USE_NEW_ESP32_BLUETOOTH \ No newline at end of file diff --git a/src/nimble/NimbleDefs.h b/src/nimble/NimbleDefs.h index 7a2b0b46a..e7c2c4c0f 100644 --- a/src/nimble/NimbleDefs.h +++ b/src/nimble/NimbleDefs.h @@ -1,3 +1,5 @@ +#ifndef USE_NEW_ESP32_BLUETOOTH + #pragma once // Keep nimble #defs from messing up the build @@ -28,4 +30,6 @@ extern const ble_uuid128_t mesh_service_uuid, fromnum_uuid; #ifdef __cplusplus }; -#endif \ No newline at end of file +#endif + +#endif //#ifndef USE_NEW_ESP32_BLUETOOTH \ No newline at end of file From a37f49bcbfcff3745d42021a495628eb2a036931 Mon Sep 17 00:00:00 2001 From: Joshua Pirihi Date: Wed, 16 Feb 2022 19:57:35 +1300 Subject: [PATCH 2/4] Add define to platformio.ini to switch between old and new bluetooth --- platformio.ini | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/platformio.ini b/platformio.ini index f7974b2e6..e3258f9cf 100644 --- a/platformio.ini +++ b/platformio.ini @@ -130,10 +130,11 @@ debug_init_break = tbreak setup # Remove -DMYNEWT_VAL_BLE_HS_LOG_LVL=LOG_LEVEL_CRITICAL for low level BLE logging. # See library directory for BLE logging possible values: .pio/libdeps/tbeam/NimBLE-Arduino/src/log_common/log_common.h # This overrides the BLE logging default of LOG_LEVEL_INFO (1) from: .pio/libdeps/tbeam/NimBLE-Arduino/src/esp_nimble_cfg.h +# -DUSE_NEW_ESP32_BLUETOOTH will enable the new NimBLE C++ api build_flags = ${arduino_base.build_flags} -Wall -Wextra -Isrc/esp32 -Isrc/esp32-mfix-esp32-psram-cache-issue -lnimble -std=c++11 -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG -DMYNEWT_VAL_BLE_HS_LOG_LVL=LOG_LEVEL_CRITICAL - -DAXP_DEBUG_PORT=Serial + -DAXP_DEBUG_PORT=Serial -DUSE_NEW_ESP32_BLUETOOTH lib_deps = ${arduino_base.lib_deps} ${environmental.lib_deps} From 3ab2ca57e9d1f6a001068bdfd907dadf8d469968 Mon Sep 17 00:00:00 2001 From: Joshua Pirihi Date: Sun, 6 Mar 2022 05:43:26 +1300 Subject: [PATCH 3/4] NimBLE implementation --- src/esp32/ESP32Bluetooth.cpp | 67 +++++++++++++++++++++++++++++++++--- 1 file changed, 62 insertions(+), 5 deletions(-) diff --git a/src/esp32/ESP32Bluetooth.cpp b/src/esp32/ESP32Bluetooth.cpp index c74a64ff7..b7e8d47aa 100644 --- a/src/esp32/ESP32Bluetooth.cpp +++ b/src/esp32/ESP32Bluetooth.cpp @@ -3,6 +3,8 @@ #include "configuration.h" #include "ESP32Bluetooth.h" #include "BluetoothCommon.h" +#include "PowerFSM.h" +#include "sleep.h" #include "main.h" #include "mesh/PhoneAPI.h" #include "mesh/mesh-pb-constants.h" @@ -28,6 +30,9 @@ static bool bleConnected; NimBLECharacteristic *FromNumCharacteristic; NimBLEServer *bleServer; +static bool passkeyShowing; +static uint32_t doublepressed; + /** * Subclasses can use this as a hook to provide custom notifications for their transport (i.e. bluetooth notifies) */ @@ -59,7 +64,7 @@ PhoneAPI *bluetoothPhoneAPI; class ESP32BluetoothToRadioCallback : public NimBLECharacteristicCallbacks { virtual void onWrite(NimBLECharacteristic *pCharacteristic) { - DEBUG_MSG("To Radio onwrite"); + DEBUG_MSG("To Radio onwrite\n"); auto valueString = pCharacteristic->getValue(); bluetoothPhoneAPI->handleToRadio(reinterpret_cast(&valueString[0]), pCharacteristic->getDataLength()); @@ -68,7 +73,7 @@ class ESP32BluetoothToRadioCallback : public NimBLECharacteristicCallbacks { class ESP32BluetoothFromRadioCallback : public NimBLECharacteristicCallbacks { virtual void onRead(NimBLECharacteristic *pCharacteristic) { - DEBUG_MSG("From Radio onread"); + DEBUG_MSG("From Radio onread\n"); size_t numBytes = bluetoothPhoneAPI->getFromRadio(fromRadioBytes); std::string fromRadioByteString(fromRadioBytes, fromRadioBytes + numBytes); @@ -77,6 +82,37 @@ class ESP32BluetoothFromRadioCallback : public NimBLECharacteristicCallbacks { } }; +class ESP32BluetoothServerCallback : public NimBLEServerCallbacks { + virtual uint32_t onPassKeyRequest() { + + uint32_t passkey = 0; + + if (doublepressed > 0 && (doublepressed + (30 * 1000)) > millis()) { + DEBUG_MSG("User has overridden passkey\n"); + passkey = defaultBLEPin; + } else { + DEBUG_MSG("Using random passkey\n"); + passkey = random( + 100000, 999999); // This is the passkey to be entered on peer - we pick a number >100,000 to ensure 6 digits + } + DEBUG_MSG("*** Enter passkey %d on the peer side ***\n", passkey); + + powerFSM.trigger(EVENT_BLUETOOTH_PAIR); + screen->startBluetoothPinScreen(passkey); + passkeyShowing = true; + + return passkey; + } + + virtual void onAuthenticationComplete(ble_gap_conn_desc *desc) { + DEBUG_MSG("BLE authentication complete\n"); + + if (passkeyShowing) { + passkeyShowing = false; + screen->stopBluetoothPinScreen(); + } + } +}; static ESP32BluetoothToRadioCallback *toRadioCallbacks; @@ -85,7 +121,7 @@ static ESP32BluetoothFromRadioCallback *fromRadioCallbacks; void ESP32Bluetooth::shutdown() { // Shutdown bluetooth for minimum power draw - DEBUG_MSG("Disable NRF52 bluetooth\n"); + DEBUG_MSG("Disable bluetooth\n"); //Bluefruit.Advertising.stop(); } @@ -138,9 +174,12 @@ void ESP32Bluetooth::setup() NimBLEDevice::setPower(ESP_PWR_LVL_P9); NimBLEDevice::setSecurityAuth(true, true, true); - NimBLEDevice::setSecurityPasskey(123456); NimBLEDevice::setSecurityIOCap(BLE_HS_IO_DISPLAY_ONLY); bleServer = NimBLEDevice::createServer(); + + ESP32BluetoothServerCallback *serverCallbacks = new ESP32BluetoothServerCallback(); + bleServer->setCallbacks(serverCallbacks); + NimBLEService *bleService = bleServer->createService(MESH_SERVICE_UUID); //NimBLECharacteristic *pNonSecureCharacteristic = bleService->createCharacteristic("1234", NIMBLE_PROPERTY::READ ); //NimBLECharacteristic *pSecureCharacteristic = bleService->createCharacteristic("1235", NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::READ_ENC | NIMBLE_PROPERTY::READ_AUTHEN); @@ -192,14 +231,32 @@ void ESP32Bluetooth::clearBonds() //Bluefruit.Periph.clearBonds(); //Bluefruit.Central.clearBonds(); + } void clearNVS() { - + NimBLEDevice::deleteAllBonds(); + ESP.restart(); } void disablePin() { + DEBUG_MSG("User Override, disabling bluetooth pin requirement\n"); + // keep track of when it was pressed, so we know it was within X seconds + // Flash the LED + setLed(true); + delay(100); + setLed(false); + delay(100); + setLed(true); + delay(100); + setLed(false); + delay(100); + setLed(true); + delay(100); + setLed(false); + + doublepressed = millis(); } #endif \ No newline at end of file From d59de171c55912ec9ae11fbd36e37f811192b08e Mon Sep 17 00:00:00 2001 From: Joshua Pirihi Date: Sun, 6 Mar 2022 05:57:38 +1300 Subject: [PATCH 4/4] NimBLE implementation --- platformio.ini | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platformio.ini b/platformio.ini index f19c6a526..0a58a3826 100644 --- a/platformio.ini +++ b/platformio.ini @@ -134,12 +134,12 @@ debug_init_break = tbreak setup build_flags = ${arduino_base.build_flags} -Wall -Wextra -Isrc/esp32 -Isrc/esp32-mfix-esp32-psram-cache-issue -lnimble -std=c++11 -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG -DMYNEWT_VAL_BLE_HS_LOG_LVL=LOG_LEVEL_CRITICAL - -DAXP_DEBUG_PORT=Serial + -DAXP_DEBUG_PORT=Serial #-DUSE_NEW_ESP32_BLUETOOTH lib_deps = ${arduino_base.lib_deps} ${environmental.lib_deps} https://github.com/meshtastic/esp32_https_server.git - h2zero/NimBLE-Arduino@1.3.6 + h2zero/NimBLE-Arduino@1.3.7 tobozo/ESP32-targz@^1.1.4 arduino-libraries/NTPClient#531eff39d9fbc831f3d03f706a161739203fbe2a lorol/LittleFS_esp32@^1.0.6