Skip to content

Zwift shifting#733

Merged
doudar merged 29 commits into
garmin-pairingfrom
Zwift_shifting
May 4, 2026
Merged

Zwift shifting#733
doudar merged 29 commits into
garmin-pairingfrom
Zwift_shifting

Conversation

@doudar
Copy link
Copy Markdown
Owner

@doudar doudar commented May 2, 2026

Testing for cherry pick

doudar and others added 21 commits February 28, 2026 22:50
Move FTMS control point write logic from DirConManager.cpp into
BLE_Fitness_Machine_Service::handleDirConWrite().

Move Zwift sync_rx write logic (including auto-subscription UUIDs)
from DirConManager.cpp into BLE_Zwift_Service::handleDirConWrite().

DirConManager now calls each service's handleDirConWrite() generically
without referencing any service-specific UUIDs or protocol details.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ncy; adjust spacing and update service UUID references
Copilot AI review requested due to automatic review settings May 2, 2026 13:40
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds Zwift “virtual shifting” support (plus OpenBikeControl) and refactors DirCon integration so BLE services explicitly register for discovery and write-routing.

Changes:

  • Introduces new BLE services: Zwift custom service + OpenBikeControl, and forwards physical shifter input to connected virtual shifting clients.
  • Refactors DirCon to use registerService() for service discovery + optional write callbacks; improves subscription tracking and notification broadcasting.
  • Improves logging safety (snprintf/vsnprintf sizing) and enhances Device Information Service fields.

Reviewed changes

Copilot reviewed 25 out of 28 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
src/SS2KLog.cpp Safer formatting + message-buffer sending adjustments in logger.
include/SS2KLog.h Exposes new hex/log helper templates.
src/Main.cpp / include/Main.h Forwards shifter deltas to Zwift/OBC; adds last-shifter-position accessors.
src/DirConManager.cpp / include/DirConManager.h Service registration API, subscription tracking changes, notification broadcast mutexing, OBC mDNS advertising.
src/DirConMessage.cpp Expands unknown-message logging to include full hex payload.
src/BLE_Server.cpp Initializes and updates new Zwift/OBC services; adjusts advertising/scan response composition.
src/BLE_Zwift_Service.cpp + include/BLE_Zwift_Service.h New Zwift service implementation (handshake, riding data, virtual shifting, DirCon write support).
src/BLE_OpenBikeControl_Service.cpp + include/BLE_OpenBikeControl_Service.h New OpenBikeControl service implementation + DirCon write support.
src/BLE_Fitness_Machine_Service.cpp Registers FTMS service with DirCon and routes DirCon writes via callback.
src/BLE_Heart_Service.cpp / src/BLE_Cycling_* Switches DirCon integration to registerService().
src/BLE_Device_Information_Service.cpp Uses efuse MAC to populate Serial Number/System ID; sets consistent DIS strings.
lib/SS2K/include/Constants.h Adds UUID constants for Zwift + OpenBikeControl.
scripts/pre_build_cleanup.py Adds pre-build cleanup script for stale cert bundle artifacts; forces single-thread build.
scripts/pycache/pre_build_cleanup.cpython-313.pyc Adds a Python bytecode artifact (should not be committed).
platformio.ini Hooks pre-build cleanup script.
include/cert.h Updates embedded CA certificate.
sdkconfig.release / sdkconfig.release.old ESP-IDF/Arduino/NimBLE config updates.
CHANGELOG.md Adds a placeholder entry for version 26.1.31.

Comment thread src/BLE_Zwift_Service.cpp
Comment on lines +235 to +239
uint8_t zData[48];
size_t pos = 0;
const uint16_t powerWatts = static_cast<uint16_t>(rtConfig->watts.getValue());
const uint16_t cadence = static_cast<uint16_t>(rtConfig->cad.getValue());
const uint16_t heartRate = static_cast<uint16_t>(rtConfig->hr.getValue());
Comment thread src/BLE_Zwift_Service.cpp Outdated
// Also update lastShifterPosition so FTMSModeShiftModifier doesn't
// see this Zwift-driven change as a user shift and echo it back.
ss2k->setLastShifterPosition(newShifterPos);
SS2K_LOG(getLogTag(), "Gear %d -> shifter position %d", closestIndex + 1, newShifterPos);
Comment thread src/BLE_Zwift_Service.cpp Outdated
snprintf(buf, sizeof(buf), "%02X", value[i]);
hexValue.append(buf);
}
SS2K_LOG(zwiftService.getLogTag(), "Sync RX write from %s (len=%d) %s", connInfo.getAddress().toString().c_str(), value.length(), hexValue.c_str());
Comment thread src/BLE_Zwift_Service.cpp

void ZwiftSyncRxCallbacks::onWrite(NimBLECharacteristic* pCharacteristic, NimBLEConnInfo& connInfo) {
NimBLEAttValue value = pCharacteristic->getValue();
// log the entire data recieved in 0x
Comment thread src/DirConMessage.cpp Outdated
Comment on lines +323 to +328
char hexBuf[len * 3 + 1];
for (size_t i = 0; i < len; i++) {
snprintf(hexBuf + i * 3, 4, "%02X ", data[i]);
}
hexBuf[len * 3] = '\0';
SS2K_LOG(DIRCON_LOG_TAG, "Error parsing DirCon message: Unknown identifier %d. Full message (%d bytes): %s", this->Identifier, len, hexBuf);
Comment thread src/SS2KLog.cpp Outdated
Comment on lines 54 to 57
@@ -56,18 +57,27 @@ void LogHandler::writev(esp_log_level_t level, const char *module, const char *f
}
Comment thread src/BLE_Zwift_Service.cpp
Comment on lines +108 to +120
BLE_Zwift_Service::BLE_Zwift_Service()
: pZwiftService(nullptr),
asyncCharacteristic(nullptr),
syncRxCharacteristic(nullptr),
syncTxCharacteristic(nullptr),
unknownCharacteristic5(nullptr),
unknownCharacteristic6(nullptr),
_lastActivityTime(0),
_lastKeepaliveTime(0),
_lastRidingDataTime(0),
_gearRatioX10000(0) {}

const char* BLE_Zwift_Service::getLogTag() const { return isDirCon ? kZwiftDirConLogTag : kZwiftBleLogTag; }
doudar and others added 2 commits May 3, 2026 21:01
… to handle service UUIDs

Co-authored-by: Copilot <copilot@github.com>
Co-authored-by: Copilot <copilot@github.com>
@doudar doudar merged commit 0ccfeda into garmin-pairing May 4, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants