From b6a3deb341b72cea18897a7759f46973e9a90491 Mon Sep 17 00:00:00 2001 From: geeksville Date: Wed, 22 Jul 2020 12:08:54 -0700 Subject: [PATCH] nimble WIP - writes kinda work now --- docs/software/TODO.md | 1 + src/esp32/BluetoothSoftwareUpdate.cpp | 12 +++-- src/esp32/main-esp32.cpp | 2 +- src/main.cpp | 2 +- src/{esp32 => nimble}/BluetoothUtil.cpp | 71 ++++++++++++++++++++----- src/{esp32 => nimble}/BluetoothUtil.h | 0 src/nimble/NimbleDefs.c | 29 ++++++---- src/sleep.cpp | 18 +++---- 8 files changed, 96 insertions(+), 39 deletions(-) rename src/{esp32 => nimble}/BluetoothUtil.cpp (92%) rename src/{esp32 => nimble}/BluetoothUtil.h (100%) diff --git a/docs/software/TODO.md b/docs/software/TODO.md index 7cac0626e..2d53048b7 100644 --- a/docs/software/TODO.md +++ b/docs/software/TODO.md @@ -15,6 +15,7 @@ Nimble tasks: - check BLE handle stability - apply nimble RPA patches - start RPA long test +- use a random pairing key rather than 123456 - implement nimble software update api * update protocol description per cyclomies email thread diff --git a/src/esp32/BluetoothSoftwareUpdate.cpp b/src/esp32/BluetoothSoftwareUpdate.cpp index a1143e964..7477ded05 100644 --- a/src/esp32/BluetoothSoftwareUpdate.cpp +++ b/src/esp32/BluetoothSoftwareUpdate.cpp @@ -1,17 +1,19 @@ +#include + +#ifdef CONFIG_BLUEDROID_ENABLED + +#include "../concurrency/LockGuard.h" +#include "../timing.h" #include "BluetoothSoftwareUpdate.h" #include "BluetoothUtil.h" #include "RadioLibInterface.h" #include "configuration.h" -#include "../concurrency/LockGuard.h" -#include "../timing.h" -#include + #include #include #include #include -#ifdef CONFIG_BLUEDROID_ENABLED - #include "CallbackCharacteristic.h" CRC32 crc; diff --git a/src/esp32/main-esp32.cpp b/src/esp32/main-esp32.cpp index 1a96eed41..5936e8c8e 100644 --- a/src/esp32/main-esp32.cpp +++ b/src/esp32/main-esp32.cpp @@ -1,9 +1,9 @@ -#include "BluetoothUtil.h" #include "MeshBluetoothService.h" #include "PowerFSM.h" #include "configuration.h" #include "esp_task_wdt.h" #include "main.h" +#include "nimble/BluetoothUtil.h" #include "sleep.h" #include "target_specific.h" #include "utils.h" diff --git a/src/main.cpp b/src/main.cpp index 92c8f424d..dfbe7288d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -43,8 +43,8 @@ // #include #ifndef NO_ESP32 -#include "BluetoothUtil.h" #include "WiFi.h" +#include "nimble/BluetoothUtil.h" #endif #include "RF95Interface.h" diff --git a/src/esp32/BluetoothUtil.cpp b/src/nimble/BluetoothUtil.cpp similarity index 92% rename from src/esp32/BluetoothUtil.cpp rename to src/nimble/BluetoothUtil.cpp index 1921b8f7e..f856e27bc 100644 --- a/src/esp32/BluetoothUtil.cpp +++ b/src/nimble/BluetoothUtil.cpp @@ -345,37 +345,75 @@ void reinitBluetooth() #else +#include "PhoneAPI.h" #include "host/util/util.h" +#include "main.h" #include "nimble/NimbleDefs.h" #include "services/gap/ble_svc_gap.h" #include "services/gatt/ble_svc_gatt.h" static uint8_t own_addr_type; +// 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(FromRadio_size, ToRadio_size)]; + +class BluetoothPhoneAPI : public PhoneAPI +{ + /** + * Subclasses can use this as a hook to provide custom notifications for their transport (i.e. bluetooth notifies) + */ + virtual void onNowHasData(uint32_t fromRadioNum) + { + PhoneAPI::onNowHasData(fromRadioNum); + + DEBUG_MSG("BLE notify fromNum\n"); + // fromNum.notify32(fromRadioNum); + } +}; + +static BluetoothPhoneAPI *bluetoothPhoneAPI; + int toradio_callback(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg) { - return BLE_ATT_ERR_UNLIKELY; // unimplemented + auto om = ctxt->om; + uint16_t len = 0; + + auto rc = ble_hs_mbuf_to_flat(om, trBytes, sizeof(trBytes), &len); + if (rc != 0) { + return BLE_ATT_ERR_UNLIKELY; + } + + DEBUG_MSG("toRadioWriteCb data %p, len %u\n", trBytes, len); + + bluetoothPhoneAPI->handleToRadio(trBytes, len); + return 0; } int fromradio_callback(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg) { - return BLE_ATT_ERR_UNLIKELY; // unimplemented + DEBUG_MSG("BLE fromRadio called\n"); + size_t numBytes = bluetoothPhoneAPI->getFromRadio(trBytes); + + // 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 + auto rc = os_mbuf_append(ctxt->om, trBytes, numBytes); + assert(rc == 0); + + return 0; // success } int fromnum_callback(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg) { - return BLE_ATT_ERR_UNLIKELY; // unimplemented -} + static uint32_t fromNum = 0; -// A C++ version of BLE_UUID128_INIT -#define BLE_UUID128_INIT_CPP(uuid128...) \ - { \ - u : { \ - type: \ - BLE_UUID_TYPE_128 \ - } \ - , value: { uuid128 } \ - } + DEBUG_MSG("BLE fromNum called\n"); + auto rc = os_mbuf_append(ctxt->om, &fromNum, + sizeof(fromNum)); // FIXME - once we report real numbers we will need to consider endianness + assert(rc == 0); + + return 0; // success +} // Force arduino to keep ble data around extern "C" bool btInUse() @@ -679,6 +717,11 @@ void reinitBluetooth() DEBUG_MSG("Starting bluetooth\n"); esp_log_level_set("BTDM_INIT", ESP_LOG_VERBOSE); + if (!bluetoothPhoneAPI) { + bluetoothPhoneAPI = new BluetoothPhoneAPI(); + bluetoothPhoneAPI->init(); + } + // FIXME - if waking from light sleep, only esp_nimble_hci_init // FIXME - why didn't this version work? auto res = esp_nimble_hci_and_controller_init(); @@ -723,7 +766,7 @@ void reinitBluetooth() assert(res == 0); /* Set the default device name. */ - res = ble_svc_gap_device_name_set("nimble-bleprph"); + res = ble_svc_gap_device_name_set(getDeviceName()); assert(res == 0); /* XXX Need to have template for store */ diff --git a/src/esp32/BluetoothUtil.h b/src/nimble/BluetoothUtil.h similarity index 100% rename from src/esp32/BluetoothUtil.h rename to src/nimble/BluetoothUtil.h diff --git a/src/nimble/NimbleDefs.c b/src/nimble/NimbleDefs.c index 1ce7d8e58..1e1f09a85 100644 --- a/src/nimble/NimbleDefs.c +++ b/src/nimble/NimbleDefs.c @@ -27,15 +27,26 @@ const struct ble_gatt_svc_def gatt_svr_svcs[] = { /*** Service: Security test. */ .type = BLE_GATT_SVC_TYPE_PRIMARY, .uuid = &mesh_service_uuid.u, - .characteristics = (struct ble_gatt_chr_def[]){{ - /*** Characteristic: Random number generator. */ - .uuid = &toradio_uuid.u, - .access_cb = toradio_callback, - .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_READ_ENC, - }, - { - 0, /* No more characteristics in this service. */ - }}, + .characteristics = + (struct ble_gatt_chr_def[]){{ + // FIXME - remove non ENC access + .uuid = &toradio_uuid.u, + .access_cb = toradio_callback, + .flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_WRITE_ENC, + }, + { + .uuid = &fromradio_uuid.u, + .access_cb = fromradio_callback, + .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_READ_ENC, + }, + { + .uuid = &fromnum_uuid.u, + .access_cb = fromnum_callback, + .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_READ_ENC | BLE_GATT_CHR_F_NOTIFY, + }, + { + 0, /* No more characteristics in this service. */ + }}, }, { diff --git a/src/sleep.cpp b/src/sleep.cpp index 59106494c..f7d61eb77 100644 --- a/src/sleep.cpp +++ b/src/sleep.cpp @@ -5,9 +5,9 @@ #include "NodeDB.h" #include "configuration.h" #include "error.h" -#include "timing.h" #include "main.h" #include "target_specific.h" +#include "timing.h" #ifndef NO_ESP32 #include "esp32/pm.h" @@ -16,7 +16,7 @@ #include #include -#include "BluetoothUtil.h" +#include "nimble/BluetoothUtil.h" esp_sleep_source_t wakeCause; // the reason we booted this time #endif @@ -294,18 +294,18 @@ esp_sleep_wakeup_cause_t doLightSleep(uint64_t sleepMsec) // FIXME, use a more r /** * enable modem sleep mode as needed and available. Should lower our CPU current draw to an average of about 20mA. - * + * * per https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/system/power_management.html - * + * * supposedly according to https://github.com/espressif/arduino-esp32/issues/475 this is already done in arduino */ void enableModemSleep() { - static esp_pm_config_esp32_t config; // filled with zeros because bss + static esp_pm_config_esp32_t config; // filled with zeros because bss - config.max_freq_mhz = CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ; - config.min_freq_mhz = 20; // 10Mhz is minimum recommended - config.light_sleep_enable = false; - DEBUG_MSG("Sleep request result %x\n", esp_pm_configure(&config)); + config.max_freq_mhz = CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ; + config.min_freq_mhz = 20; // 10Mhz is minimum recommended + config.light_sleep_enable = false; + DEBUG_MSG("Sleep request result %x\n", esp_pm_configure(&config)); } #endif