Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding csc #619

Merged
merged 26 commits into from
Feb 15, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
389 changes: 225 additions & 164 deletions data/bluetoothscanner.html

Large diffs are not rendered by default.

580 changes: 323 additions & 257 deletions data/settings.html

Large diffs are not rendered by default.

104 changes: 74 additions & 30 deletions include/BLE_Common.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,39 @@
#pragma once

#include <NimBLEDevice.h>
#include <NimBLEScan.h>
#include <memory>
#include <Arduino.h>
#include <queue>
#include <deque>
#include <vector>
#include "Main.h"
#include "BLE_Definitions.h"
#include "BLE_Wattbike_Service.h"
#include "Constants.h"

//Client size allocated to the queue for receiving characteristic data
#define NOTIFY_DATA_QUEUE_SIZE 25
#define NOTIFY_DATA_QUEUE_LENGTH 10

// Vector of supported BLE services and their corresponding characteristic UUIDs
struct BLEServiceInfo {
BLEUUID serviceUUID;
BLEUUID characteristicUUID;
String name;
};

namespace BLEServices {
const std::vector<BLEServiceInfo> SUPPORTED_SERVICES = {{CYCLINGPOWERSERVICE_UUID, CYCLINGPOWERMEASUREMENT_UUID, "Cycling Power Service"},
{CSCSERVICE_UUID, CSCMEASUREMENT_UUID, "Cycling Speed And Cadence Service"},
{HEARTSERVICE_UUID, HEARTCHARACTERISTIC_UUID, "Heart Rate Service"},
{FITNESSMACHINESERVICE_UUID, FITNESSMACHINEINDOORBIKEDATA_UUID, "Fitness Machine Service"},
{HID_SERVICE_UUID, HID_REPORT_DATA_UUID, "HID Service"},
{ECHELON_SERVICE_UUID, ECHELON_DATA_UUID, "Echelon Service"},
{FLYWHEEL_UART_SERVICE_UUID, FLYWHEEL_UART_TX_UUID, "Flywheel UART Service"}};
}

using BLEServices::SUPPORTED_SERVICES;

#define BLE_CLIENT_LOG_TAG "BLE_Client"
#define BLE_COMMON_LOG_TAG "BLE_Common"
Expand All @@ -35,12 +61,21 @@ void setupBLE();
extern TaskHandle_t BLEClientTask;
// ***********************Common**********************************
void BLECommunications();

// Check if a BLE device supports any of our supported services
bool isDeviceSupported(const NimBLEAdvertisedDevice* advertisedDevice, const String& deviceName = "");

// Get service info for a supported device
const BLEServiceInfo* getDeviceServiceInfo(const NimBLEAdvertisedDevice* advertisedDevice, const String& deviceName = "");
// *****************************Server****************************
class MyServerCallbacks : public NimBLEServerCallbacks {
public:
void onConnect(BLEServer *, ble_gap_conn_desc *desc);
void onDisconnect(BLEServer *);
bool onConnParamsUpdateRequest(NimBLEClient *pClient, const ble_gap_upd_params *params);
void onConnect(NimBLEServer* pServer, NimBLEConnInfo& connInfo);
void onDisconnect(NimBLEServer* pServer);
void onMTUChange(uint16_t MTU, NimBLEConnInfo& connInfo);
uint32_t onPassKeyDisplay();
void onAuthenticationComplete(NimBLEConnInfo& connInfo);
bool onConnParamsUpdateRequest(uint16_t handle, const ble_gap_upd_params* params);
};

// TODO add the rest of the server to this class
Expand All @@ -55,8 +90,8 @@ class SpinBLEServer {
bool IndoorBikeData : 1;
bool CyclingSpeedCadence : 1;
} clientSubscribed;
int spinDownFlag = 0;
NimBLEServer *pServer = nullptr;
int spinDownFlag = 0;
NimBLEServer* pServer = nullptr;
void setClientSubscribed(NimBLEUUID pUUID, bool subscribe);
void notifyShift();
double calculateSpeed();
Expand All @@ -66,18 +101,20 @@ class SpinBLEServer {
SpinBLEServer() { memset(&clientSubscribed, 0, sizeof(clientSubscribed)); }
};

class MyCallbacks : public NimBLECharacteristicCallbacks {
class MyCharacteristicCallbacks : public NimBLECharacteristicCallbacks {
public:
void onWrite(BLECharacteristic *);
void onSubscribe(NimBLECharacteristic *pCharacteristic, ble_gap_conn_desc *desc, uint16_t subValue);
void onWrite(NimBLECharacteristic* pCharacteristic, NimBLEConnInfo& connInfo) override;
void onRead(NimBLECharacteristic* pCharacteristic, NimBLEConnInfo& connInfo) override;
void onSubscribe(NimBLECharacteristic* pCharacteristic, NimBLEConnInfo& connInfo, uint16_t subValue) override;
void onStatus(NimBLECharacteristic* pCharacteristic, int code) override;
};

extern SpinBLEServer spinBLEServer;
extern BLE_Wattbike_Service wattbikeService;

void startBLEServer();
void logCharacteristic(char *buffer, const size_t bufferCapacity, const byte *data, const size_t dataLength, const NimBLEUUID serviceUUID, const NimBLEUUID charUUID,
const char *format, ...);
void logCharacteristic(char* buffer, const size_t bufferCapacity, const byte* data, const size_t dataLength, const NimBLEUUID serviceUUID, const NimBLEUUID charUUID,
const char* format, ...);
void calculateInstPwrFromHR();
int connectedClientCount();

Expand All @@ -88,7 +125,7 @@ void BLEFirmwareSetup();

// Keeping the task outside the class so we don't need a mask.
// We're only going to run one anyway.
void bleClientTask(void *pvParameters);
void bleClientTask(void* pvParameters);

// UUID's the client has methods for
// BLEUUID serviceUUIDs[4] = {FITNESSMACHINESERVICE_UUID,
Expand All @@ -97,8 +134,12 @@ void bleClientTask(void *pvParameters);
// CYCLINGPOWERMEASUREMENT_UUID, HEARTCHARACTERISTIC_UUID,
// FLYWHEEL_UART_TX_UUID};



typedef struct NotifyData {
uint8_t data[25];
NimBLEUUID serviceUUID;
NimBLEUUID charUUID;
uint8_t data[NOTIFY_DATA_QUEUE_SIZE];
size_t length;
} NotifyData;

Expand All @@ -119,7 +160,7 @@ class SpinBLEAdvertisedDevice {
// }
// }

NimBLEAdvertisedDevice *advertisedDevice = nullptr;
const NimBLEAdvertisedDevice* advertisedDevice = nullptr;
NimBLEAddress peerAddress;

int connectedClientID = BLE_HS_CONN_HANDLE_NONE;
Expand All @@ -133,10 +174,10 @@ class SpinBLEAdvertisedDevice {
bool doConnect = false;
void setPostConnected(bool pc) { isPostConnected = pc; }
bool getPostConnected() { return isPostConnected; }
void set(BLEAdvertisedDevice *device, int id = BLE_HS_CONN_HANDLE_NONE, BLEUUID inServiceUUID = (uint16_t)0x0000, BLEUUID inCharUUID = (uint16_t)0x0000);
void set(const NimBLEAdvertisedDevice* device, int id = BLE_HS_CONN_HANDLE_NONE, BLEUUID inServiceUUID = (uint16_t)0x0000, BLEUUID inCharUUID = (uint16_t)0x0000);
void reset();
void print();
bool enqueueData(uint8_t data[25], size_t length);
bool enqueueData(uint8_t data[NOTIFY_DATA_QUEUE_SIZE], size_t length, NimBLEUUID serviceUUID, NimBLEUUID charUUID);
NotifyData dequeueData();
};

Expand All @@ -160,7 +201,7 @@ class SpinBLEClient {
double cscLastWheelEvtTime = 0.0;
int reconnectTries = MAX_RECONNECT_TRIES;

BLERemoteCharacteristic *pRemoteCharacteristic = nullptr;
BLERemoteCharacteristic* pRemoteCharacteristic = nullptr;

// BLEDevices myBLEDevices;
SpinBLEAdvertisedDevice myBLEDevices[NUM_BLE_DEVICES];
Expand All @@ -170,34 +211,37 @@ class SpinBLEClient {
bool connectToServer();
// Check for duplicate services of BLEClient and remove the previously
// connected one.
void removeDuplicates(NimBLEClient *pClient);
void resetDevices(NimBLEClient *pClient);
void removeDuplicates(NimBLEClient* pClient);
void resetDevices(NimBLEClient* pClient);
void postConnect();
void FTMSControlPointWrite(const uint8_t *pData, int length);
void connectBLE_HID(NimBLEClient *pClient);
void keepAliveBLE_HID(NimBLEClient *pClient);
void handleBattInfo(NimBLEClient *pClient, bool updateNow);
void FTMSControlPointWrite(const uint8_t* pData, int length);
void connectBLE_HID(NimBLEClient* pClient);
void keepAliveBLE_HID(NimBLEClient* pClient);
void handleBattInfo(NimBLEClient* pClient, bool updateNow);
// Instead of using this directly, set the .doScan flag to start a scan.
void scanProcess(int duration = DEFAULT_SCAN_DURATION);
void checkBLEReconnect();
// Disconnects all devices. They will then be reconnected if scanned and preferred again.
void reconnectAllDevices();

String adevName2UniqueName(NimBLEAdvertisedDevice *inDev);
String adevName2UniqueName(const NimBLEAdvertisedDevice* inDev);
};

class MyAdvertisedDeviceCallback : public NimBLEAdvertisedDeviceCallbacks {
class ScanCallbacks : public NimBLEScanCallbacks {
public:
void onResult(NimBLEAdvertisedDevice *);
void onResult(const NimBLEAdvertisedDevice* advertisedDevice) override;
void onScanEnd(const NimBLEScanResults& results, int reason) override;

private:
};

class MyClientCallback : public NimBLEClientCallbacks {
public:
void onConnect(BLEClient *);
void onDisconnect(BLEClient *);
uint32_t onPassKeyRequest();
bool onConfirmPIN(uint32_t);
void onAuthenticationComplete(ble_gap_conn_desc);
void onConnect(NimBLEClient* pClient) override;
void onDisconnect(NimBLEClient* pClient, int reason) override;
void onPassKeyEntry(NimBLEConnInfo& connInfo) override;
void onConfirmPasskey(NimBLEConnInfo& connInfo, uint32_t pass_key) override;
void onAuthenticationComplete(NimBLEConnInfo& connInfo) override;
};

extern SpinBLEClient spinBLEClient;
11 changes: 6 additions & 5 deletions include/BLE_Custom_Characteristic.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ const uint8_t BLE_simulateTargetWatts = 0x29; // are we sending target watts
const uint8_t BLE_hMin = 0x2A; // Minimum homing value
const uint8_t BLE_hMax = 0x2B; // Maximum homing value
const uint8_t BLE_homingSensitivity = 0x2C; // Homing sensitivity value
const uint8_t BLE_pTab4Pwr = 0x2D; // Use power values for power table

class BLE_ss2kCustomCharacteristic {
public:
Expand All @@ -74,12 +75,12 @@ class BLE_ss2kCustomCharacteristic {
static void parseNemit();

private:
BLEService *pSmartSpin2kService;
BLECharacteristic *smartSpin2kCharacteristic;
NimBLEService *pSmartSpin2kService;
NimBLECharacteristic *smartSpin2kCharacteristic;
uint8_t ss2kCustomCharacteristicValue[3] = {0x00, 0x00, 0x00};
};

class ss2kCustomCharacteristicCallbacks : public BLECharacteristicCallbacks {
void onWrite(BLECharacteristic *);
void onSubscribe(NimBLECharacteristic *pCharacteristic, ble_gap_conn_desc *desc, uint16_t subValue);
class ss2kCustomCharacteristicCallbacks : public NimBLECharacteristicCallbacks {
void onWrite(NimBLECharacteristic* pCharacteristic, NimBLEConnInfo& connInfo) override;
void onSubscribe(NimBLECharacteristic* pCharacteristic, NimBLEConnInfo& connInfo, uint16_t subValue) override;
};
2 changes: 1 addition & 1 deletion include/BLE_Cycling_Power_Service.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
class BLE_Cycling_Power_Service {
public:
BLE_Cycling_Power_Service();
void setupService(NimBLEServer *pServer, MyCallbacks *chrCallbacks);
void setupService(NimBLEServer *pServer, MyCharacteristicCallbacks *chrCallbacks);
void update();

private:
Expand Down
2 changes: 1 addition & 1 deletion include/BLE_Cycling_Speed_Cadence.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
class BLE_Cycling_Speed_Cadence {
public:
BLE_Cycling_Speed_Cadence();
void setupService(NimBLEServer *pServer, MyCallbacks *chrCallbacks);
void setupService(NimBLEServer *pServer, MyCharacteristicCallbacks *chrCallbacks);
void update();

private:
Expand Down
2 changes: 1 addition & 1 deletion include/BLE_Fitness_Machine_Service.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
class BLE_Fitness_Machine_Service {
public:
BLE_Fitness_Machine_Service();
void setupService(NimBLEServer *pServer, MyCallbacks *chrCallbacks);
void setupService(NimBLEServer *pServer, MyCharacteristicCallbacks *chrCallbacks);
void update();
bool spinDown(uint8_t response);

Expand Down
2 changes: 1 addition & 1 deletion include/BLE_Heart_Service.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
class BLE_Heart_Service {
public:
BLE_Heart_Service();
void setupService(NimBLEServer *pServer, MyCallbacks *chrCallbacks);
void setupService(NimBLEServer *pServer, MyCharacteristicCallbacks *chrCallbacks);
void update();

private:
Expand Down
39 changes: 39 additions & 0 deletions include/BLE_SB20_Service.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* Copyright (C) 2020 Anthony Doud & Joel Baranick
* All rights reserved
*
* SPDX-License-Identifier: GPL-2.0-only
*/

#pragma once

#include <NimBLEDevice.h>
#include "BLE_Common.h"

// See https://github.com/JanDeVisser/stages-monitor/tree/master/sb20display
#define SB20_SERVICE_UUID "a026ee0b-0a7d-4ab3-97fa-f1500f9feb8b"
#define SB20_CHARACTERISTIC_UUID "a026e037-0a7d-4ab3-97fa-f1500f9feb8b"

struct SB20Data {
uint8_t gear; // Calculated Gear (1-22)
uint16_t cadence; // Cadence in RPM
uint16_t power; // Power in Watts
uint16_t heartrate; // Heart Rate in BPM
uint8_t battery; // always 4
};

class BLE_SB20_Service {
public:
BLE_SB20_Service();

void begin();
void setData(SB20Data data);
void notify();

private:
BLEService *pService;
BLECharacteristic *pCharacteristic;
SB20Data currentData;
bool deviceConnected;

};
6 changes: 5 additions & 1 deletion include/ERG_Mode.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ class TestResults {

class PowerTable {
public:
bool saveFlag = false;
TableRow tableRow[POWERTABLE_CAD_SIZE];

// What used to be in the ERGTaskLoop(). This is the main control function for ERG Mode and the powertable operations.
Expand All @@ -106,8 +107,11 @@ class PowerTable {
// returns incline for wattTarget. Null if not found.
int32_t lookup(int watts, int cad);

// returns watts for given cadence and target position. Returns RETURN_ERROR if not found.
int32_t lookupWatts(int cad, int32_t targetPosition);

// automatically load or save the Power Table
bool _manageSaveState();
bool _manageSaveState(bool canSkipReliabilityChecks = false);

// save powertable from littlefs
bool _save();
Expand Down
4 changes: 4 additions & 0 deletions include/SmartSpin_parameters.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ class userParameters {
int stepperSpeed;
bool stepperDir;
bool shifterDir;
bool pTab4Pwr = false;
bool udpLogEnabled = false;
int32_t hMin = INT32_MIN;
int32_t hMax = INT32_MIN;
Expand Down Expand Up @@ -199,6 +200,9 @@ class userParameters {
void setUdpLogEnabled(bool enabled) { udpLogEnabled = enabled; }
bool getUdpLogEnabled() { return udpLogEnabled; }

void setPTab4Pwr(bool pTab) { pTab4Pwr = pTab; }
bool getPTab4Pwr() { return pTab4Pwr; }

void setFoundDevices(String fdv) { foundDevices = fdv; }
const char* getFoundDevices() { return foundDevices.c_str(); }

Expand Down
12 changes: 6 additions & 6 deletions include/settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -224,11 +224,11 @@ const char* const DEFAULT_PASSWORD = "password";

// Name of default Power Meter. any connects to anything, none connects to
// nothing.
#define CONNECTED_POWER_METER "any"
#define CONNECTED_POWER_METER "none"

// Name of default heart monitor. any connects to anything, none connects to
// nothing.
#define CONNECTED_HEART_MONITOR "any"
#define CONNECTED_HEART_MONITOR "none"

// Name of default remote. any connects to anything, none connects to
// nothing.
Expand Down Expand Up @@ -305,14 +305,14 @@ const char* const DEFAULT_PASSWORD = "password";
// Interval for polling ble battery updates
#define BATTERY_UPDATE_INTERVAL_MILLIS 300000

// Initial and web scan duration.
#define DEFAULT_SCAN_DURATION 5
// Initial and web scan duration in milliseconds
#define DEFAULT_SCAN_DURATION 5000

// Default homing sensitivity value
#define DEFAULT_HOMING_SENSITIVITY 50

// BLE automatic reconnect duration. Set this low to avoid interruption.
#define BLE_RECONNECT_SCAN_DURATION 5
// BLE automatic reconnect duration in milliseconds. Set this low to avoid interruption.
#define BLE_RECONNECT_SCAN_DURATION 5000

// Task Stack Sizes
#define MAIN_STACK 6500
Expand Down
4 changes: 2 additions & 2 deletions lib/SS2K/include/Constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,8 @@
#define ECHELON_DATA_UUID NimBLEUUID("0bf669f4-45f2-11e7-9598-0800200c9a66")

// Dummy UUID for Peloton Serial Data Interface
#define PELOTON_DATA_UUID NimBLEUUID("00000000-0000-0000-0000-0000000000321")
#define PELOTON_ADDRESS NimBLEAddress("00:00:00:00:00:00:00")
#define PELOTON_DATA_UUID NimBLEUUID("00000000-0000-0000-0000-000000000321")
#define PELOTON_ADDRESS NimBLEAddress("00:00:00:00:00:00", 0)
// peloton Serial
#define PELOTON_RQ_SIZE 4
#define PELOTON_HEADER 0xF1
Expand Down
Loading
Loading