From 999625852c8dcb3f865ba5ac659616d0e505ef5c Mon Sep 17 00:00:00 2001 From: Leonid Meleshin Date: Wed, 23 Nov 2022 22:33:36 +0400 Subject: [PATCH] feat(BLE): option to use NimBLE library --- .github/codeql/codeql-config.yml | 5 ++ .github/workflows/build-bhaptics.yml | 5 ++ .github/workflows/codeql-analysis.yml | 12 +-- include/config/bluetooth.h | 24 +++--- lib/bh/connection_bhble.cpp | 110 ++++++++++++++------------ lib/bh/connection_bhble.hpp | 8 +- platformio.ini | 2 + 7 files changed, 93 insertions(+), 73 deletions(-) create mode 100644 .github/codeql/codeql-config.yml diff --git a/.github/codeql/codeql-config.yml b/.github/codeql/codeql-config.yml new file mode 100644 index 00000000..d234b37a --- /dev/null +++ b/.github/codeql/codeql-config.yml @@ -0,0 +1,5 @@ +paths: + - firmware + - include +paths-ignore: + - .pio/libdeps diff --git a/.github/workflows/build-bhaptics.yml b/.github/workflows/build-bhaptics.yml index f31fcc3c..9fa1058c 100644 --- a/.github/workflows/build-bhaptics.yml +++ b/.github/workflows/build-bhaptics.yml @@ -98,6 +98,9 @@ jobs: serial_plotter_flag: - SERIAL_PLOTTER=false - SERIAL_PLOTTER=true + nimble_flag: + - BLUETOOTH_USE_NIMBLE=true + - BLUETOOTH_USE_NIMBLE=false steps: - uses: actions/checkout@v3 @@ -128,12 +131,14 @@ jobs: run: | sed -i '/__OH_FIRMWARE__/p; s/__OH_FIRMWARE__/${{ matrix.battery_flag }}/' platformio.ini sed -i '/__OH_FIRMWARE__/p; s/__OH_FIRMWARE__/${{ matrix.serial_plotter_flag }}/' platformio.ini + sed -i '/__OH_FIRMWARE__/p; s/__OH_FIRMWARE__/${{ matrix.nimble_flag }}/' platformio.ini - name: Update build flags (macOS) if: runner.os == 'macOS' run: | sed -i '' '/__OH_FIRMWARE__/p; s/__OH_FIRMWARE__/${{ matrix.battery_flag }}/' platformio.ini sed -i '' '/__OH_FIRMWARE__/p; s/__OH_FIRMWARE__/${{ matrix.serial_plotter_flag }}/' platformio.ini + sed -i '' '/__OH_FIRMWARE__/p; s/__OH_FIRMWARE__/${{ matrix.nimble_flag }}/' platformio.ini - name: Install PlatformIO run: | diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index c13a50f0..ecc5cffd 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -1,14 +1,3 @@ -# For most projects, this workflow file will not need changing; you simply need -# to commit it to your repository. -# -# You may wish to alter this file to override the set of languages analyzed, -# or to provide custom queries or build logic. -# -# ******** NOTE ******** -# We have attempted to detect the languages in your repository. Please check -# the `language` matrix defined below to confirm you have the correct set of -# supported CodeQL languages. -# name: "CodeQL" on: @@ -58,6 +47,7 @@ jobs: uses: github/codeql-action/init@v2 with: languages: ${{ matrix.language }} + config-file: ./.github/codeql/codeql-config.yml # If you wish to specify custom queries, you can do so here or in a config file. # By default, queries listed here will override any specified in a config file. # Prefix the list here with "+" to use these queries and those in the config file. diff --git a/include/config/bluetooth.h b/include/config/bluetooth.h index a9bca958..85c8c8f7 100644 --- a/include/config/bluetooth.h +++ b/include/config/bluetooth.h @@ -1,10 +1,14 @@ -#pragma once - -#ifndef BLUETOOTH_NAME -#define BLUETOOTH_NAME "OpenHaptics" -#endif - -#ifndef BLUETOOTH_ADDRESS -#define BLUETOOTH_ADDRESS \ - { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB } -#endif +#pragma once + +#ifndef BLUETOOTH_NAME +#define BLUETOOTH_NAME "OpenHaptics" +#endif + +#ifndef BLUETOOTH_ADDRESS +#define BLUETOOTH_ADDRESS \ + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB } +#endif + +#ifndef BLUETOOTH_USE_NIMBLE +#define BLUETOOTH_USE_NIMBLE false +#endif diff --git a/lib/bh/connection_bhble.cpp b/lib/bh/connection_bhble.cpp index 02d20d2a..43a866f4 100644 --- a/lib/bh/connection_bhble.cpp +++ b/lib/bh/connection_bhble.cpp @@ -1,12 +1,31 @@ -#include +#include "connection_bhble.hpp" #include #include #include -#include #include +#if defined(BLUETOOTH_USE_NIMBLE) && BLUETOOTH_USE_NIMBLE == true + // BLE2902 not needed: https://github.com/h2zero/NimBLE-Arduino/blob/release/1.4/docs/Migration_guide.md#descriptors + + #define PROPERTY_READ NIMBLE_PROPERTY::READ + #define PROPERTY_WRITE NIMBLE_PROPERTY::WRITE + #define PROPERTY_WRITE_NR NIMBLE_PROPERTY::WRITE_NR + #define PROPERTY_BROADCAST NIMBLE_PROPERTY::BROADCAST + #define PROPERTY_NOTIFY NIMBLE_PROPERTY::NOTIFY + #define PROPERTY_INDICATE NIMBLE_PROPERTY::INDICATE +#else + #include + + #define PROPERTY_READ BLECharacteristic::PROPERTY_READ + #define PROPERTY_WRITE BLECharacteristic::PROPERTY_WRITE + #define PROPERTY_WRITE_NR BLECharacteristic::PROPERTY_WRITE_NR + #define PROPERTY_BROADCAST BLECharacteristic::PROPERTY_BROADCAST + #define PROPERTY_NOTIFY BLECharacteristic::PROPERTY_NOTIFY + #define PROPERTY_INDICATE BLECharacteristic::PROPERTY_INDICATE +#endif + class BHServerCallbacks final : public BLEServerCallbacks { public: BHServerCallbacks() {} @@ -41,9 +60,12 @@ class SerialOutputCharCallbacks : public BLECharacteristicCallbacks { pCharacteristic->getValue().length()); }; - void onStatus(BLECharacteristic* pCharacteristic, - Status s, - uint32_t code) override { + #if defined(BLUETOOTH_USE_NIMBLE) && BLUETOOTH_USE_NIMBLE == true + void onStatus(BLECharacteristic* pCharacteristic, Status s, int code) override + #else + void onStatus(BLECharacteristic* pCharacteristic, Status s, uint32_t code) override + #endif + { Serial.printf(">>\tonStatus (UUID: %s) \n", pCharacteristic->getUUID().toString().c_str()); Serial.printf("\tstatus: %d, code: %u \n", s, code); @@ -58,11 +80,10 @@ class MotorCharCallbacks : public BLECharacteristicCallbacks { bh_motor_handler_t motorTransformer; public: - MotorCharCallbacks(bh_motor_handler_t motorTransformer) - : motorTransformer(motorTransformer) {} + MotorCharCallbacks(bh_motor_handler_t motorTransformer) : motorTransformer(motorTransformer) {} void onWrite(BLECharacteristic* pCharacteristic) override { - auto value = pCharacteristic->getValue(); + std::string value = pCharacteristic->getValue(); this->motorTransformer(value); }; @@ -100,34 +121,37 @@ void BH::ConnectionBHBLE::begin() { // Each characteristic needs 2 handles and descriptor 1 handle. this->motorService = - this->bleServer->createService(BH_BLE_SERVICE_MOTOR_UUID, 25); + this->bleServer->createService(BH_BLE_SERVICE_MOTOR_UUID); { - MotorCharCallbacks* motorCallbacks = - new MotorCharCallbacks(this->motorHandler); + MotorCharCallbacks* motorCallbacks = new MotorCharCallbacks(this->motorHandler); auto* motorChar = this->motorService->createCharacteristic( BH_BLE_SERVICE_MOTOR_CHAR_MOTOR_UUID, - BLECharacteristic::PROPERTY_WRITE_NR); + PROPERTY_WRITE_NR + ); motorChar->setCallbacks(motorCallbacks); auto* motorCharStable = this->motorService->createCharacteristic( BH_BLE_SERVICE_MOTOR_CHAR_MOTOR_STABLE_UUID, - BLECharacteristic::PROPERTY_WRITE); + PROPERTY_WRITE + ); motorCharStable->setCallbacks(motorCallbacks); } { auto* configChar = this->motorService->createCharacteristic( BH_BLE_SERVICE_MOTOR_CHAR_CONFIG_UUID, - BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_WRITE); + PROPERTY_READ | PROPERTY_WRITE + ); configChar->setCallbacks(new ConfigCharCallbacks()); } { auto* serialNumberChar = this->motorService->createCharacteristic( BH_BLE_SERVICE_MOTOR_CHAR_SERIAL_KEY_UUID, - BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_WRITE); + PROPERTY_READ | PROPERTY_WRITE + ); serialNumberChar->setValue(this->config.serialNumber, BH_SERIAL_NUMBER_LENGTH); serialNumberChar->setCallbacks(new SerialOutputCharCallbacks()); } @@ -135,28 +159,29 @@ void BH::ConnectionBHBLE::begin() { { this->batteryChar = this->motorService->createCharacteristic( BH_BLE_SERVICE_MOTOR_CHAR_BATTERY_UUID, - BLECharacteristic::PROPERTY_READ | - BLECharacteristic:: - PROPERTY_WRITE_NR // for whatever reason, it have to be - // writable, otherwise Desktop app crashes + PROPERTY_READ | PROPERTY_WRITE_NR // for whatever reason, it have to bewritable, otherwise Desktop app crashes ); + +#if !defined(BLUETOOTH_USE_NIMBLE) || BLUETOOTH_USE_NIMBLE != true batteryChar->addDescriptor(new BLE2902()); +#endif // original bHaptics Player require non-null value for battery level, otherwise it crashes #if defined(BATTERY_ENABLED) && BATTERY_ENABLED == true - uint16_t defaultLevel = 0; + uint16_t defaultLevel = 0; #else - uint16_t defaultLevel = 100; + uint16_t defaultLevel = 100; #endif - this->batteryChar->setValue(defaultLevel); - // this->batteryChar->notify(); + this->batteryChar->setValue(defaultLevel); + // this->batteryChar->notify(); } { auto* versionChar = this->motorService->createCharacteristic( BH_BLE_SERVICE_MOTOR_CHAR_VERSION_UUID, - BLECharacteristic::PROPERTY_READ); + PROPERTY_READ + ); versionChar->setCallbacks(new SerialOutputCharCallbacks()); uint16_t firmwareVersion = BH_FIRMWARE_VERSION; versionChar->setValue(firmwareVersion); @@ -165,54 +190,39 @@ void BH::ConnectionBHBLE::begin() { { auto* monitorChar = this->motorService->createCharacteristic( BH_BLE_SERVICE_MOTOR_CHAR_TACTSUIT_MONITOR_UUID, - BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_WRITE | - BLECharacteristic::PROPERTY_NOTIFY | - BLECharacteristic::PROPERTY_BROADCAST | - BLECharacteristic::PROPERTY_INDICATE | - BLECharacteristic::PROPERTY_WRITE_NR); + PROPERTY_READ | PROPERTY_WRITE | PROPERTY_NOTIFY | PROPERTY_BROADCAST | PROPERTY_INDICATE | PROPERTY_WRITE_NR + ); monitorChar->setCallbacks(new SerialOutputCharCallbacks()); + +#if !defined(BLUETOOTH_USE_NIMBLE) || BLUETOOTH_USE_NIMBLE != true monitorChar->addDescriptor(new BLE2902()); +#endif + uint16_t audioCableState = NO_AUDIO_CABLE; monitorChar->setValue(audioCableState); } // auto* athGlobalChar = this->motorService->createCharacteristic( // BH_BLE_SERVICE_MOTOR_CHAR_ATH_GLOBAL_CONF_UUID, - // BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_WRITE | - // BLECharacteristic::PROPERTY_NOTIFY | - // BLECharacteristic::PROPERTY_BROADCAST| - // BLECharacteristic::PROPERTY_INDICATE| - // BLECharacteristic::PROPERTY_WRITE_NR + // PROPERTY_READ | PROPERTY_WRITE | PROPERTY_NOTIFY | PROPERTY_BROADCAST | PROPERTY_INDICATE | PROPERTY_WRITE_NR // ); // athGlobalChar->setCallbacks(new SerialOutputCharCallbacks()); // auto* athThemeChar = this->motorService->createCharacteristic( // BH_BLE_SERVICE_MOTOR_CHAR_ATH_THEME_UUID, - // BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_WRITE | - // BLECharacteristic::PROPERTY_NOTIFY | - // BLECharacteristic::PROPERTY_BROADCAST| - // BLECharacteristic::PROPERTY_INDICATE| - // BLECharacteristic::PROPERTY_WRITE_NR + // PROPERTY_READ | PROPERTY_WRITE | PROPERTY_NOTIFY | PROPERTY_BROADCAST | PROPERTY_INDICATE | PROPERTY_WRITE_NR // ); // athThemeChar->setCallbacks(new SerialOutputCharCallbacks()); // auto* motorMappingChar = this->motorService->createCharacteristic( // BH_BLE_SERVICE_MOTOR_CHAR_MOTTOR_MAPPING_UUID, - // BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_WRITE | - // BLECharacteristic::PROPERTY_NOTIFY | - // BLECharacteristic::PROPERTY_BROADCAST| - // BLECharacteristic::PROPERTY_INDICATE| - // BLECharacteristic::PROPERTY_WRITE_NR + // PROPERTY_READ | PROPERTY_WRITE | PROPERTY_NOTIFY | PROPERTY_BROADCAST | PROPERTY_INDICATE | PROPERTY_WRITE_NR // ); // motorMappingChar->setCallbacks(new SerialOutputCharCallbacks()); // auto* signatureMappingChar = this->motorService->createCharacteristic( // BH_BLE_SERVICE_MOTOR_CHAR_SIGNATURE_PATTERN_UUID, - // BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_WRITE | - // BLECharacteristic::PROPERTY_NOTIFY | - // BLECharacteristic::PROPERTY_BROADCAST| - // BLECharacteristic::PROPERTY_INDICATE| - // BLECharacteristic::PROPERTY_WRITE_NR + // PROPERTY_READ | PROPERTY_WRITE | PROPERTY_NOTIFY | PROPERTY_BROADCAST | PROPERTY_INDICATE | PROPERTY_WRITE_NR // ); // signatureMappingChar->setCallbacks(new SerialOutputCharCallbacks()); @@ -223,7 +233,7 @@ void BH::ConnectionBHBLE::begin() { auto* dfuControlChar = dfuService->createCharacteristic( BH_BLE_SERVICE_MOTOR_CHAR_SIGNATURE_PATTERN_UUID, - BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_WRITE); + PROPERTY_READ | PROPERTY_WRITE); dfuService->start(); } diff --git a/lib/bh/connection_bhble.hpp b/lib/bh/connection_bhble.hpp index b7070e15..fe5ffc1a 100644 --- a/lib/bh/connection_bhble.hpp +++ b/lib/bh/connection_bhble.hpp @@ -6,12 +6,16 @@ #include #include -#include #include +#if defined(BLUETOOTH_USE_NIMBLE) && BLUETOOTH_USE_NIMBLE == true + #include +#else + #include +#endif + #if defined(BATTERY_ENABLED) && BATTERY_ENABLED == true #include "abstract_battery.hpp" -#include #endif // typedef void (*bh_motor_handler_t)(std::string&); diff --git a/platformio.ini b/platformio.ini index 4115d612..9877431f 100644 --- a/platformio.ini +++ b/platformio.ini @@ -24,6 +24,7 @@ build_flags = ; -D DEBUG_ESP_PORT=Serial ; -D SERIAL_PLOTTER=true -D BATTERY_ENABLED=true + -D BLUETOOTH_USE_NIMBLE=true build_unflags = -std=gnu++11 build_src_filter = @@ -36,6 +37,7 @@ lib_deps = adafruit/Adafruit PWM Servo Driver Library@^2.4.0 adafruit/Adafruit INA219@^1.2.1 sparkfun/SparkFun MAX1704x Fuel Gauge Arduino Library@^1.0.4 + h2zero/NimBLE-Arduino@^1.4.0 [env] framework = arduino