Compare commits

..

7 Commits

Author SHA1 Message Date
Roberto Viola
63c45c1689 Update gradle-wrapper.properties 2023-11-30 10:35:14 +01:00
Roberto Viola
91e1623689 Update build.gradle 2023-11-30 10:03:39 +01:00
Roberto Viola
278c5d58a2 trying java version 2023-11-30 09:37:55 +01:00
Roberto Viola
8de55c85af Update build.gradle 2023-11-30 09:13:14 +01:00
Roberto Viola
bc19418432 Update build.gradle 2023-11-30 08:50:33 +01:00
Roberto Viola
e9f711ae49 Update build.gradle 2023-11-30 08:15:22 +01:00
Roberto Viola
560df01ca1 Update build.gradle 2023-11-30 07:46:37 +01:00
809 changed files with 7253 additions and 133816 deletions

View File

@@ -70,20 +70,15 @@ jobs:
- uses: actions/setup-python@v4
with:
python-version: 3.7
python-version: 3.10.11
- name: download python and paddleocr
run: |
python -VV
python -m pip install --upgrade pip
python -m pip install --upgrade setuptools
python -m pip install "protobuf<=3.20.2,>=3.1.0"
python -m pip install paddlepaddle==2.5.1
python -m pip install paddleocr
python -m pip install imutils
python -m pip install "Pillow<10.0.0"
python -m pip install opencv-python
python -m pip install numpy
python -m pip install pywin32
python -m pip install paddlepaddle-gpu==2.4.2.post117 -f https://www.paddlepaddle.org.cn/whl/windows/mkl/avx/stable.html
python -m pip install https://files.pythonhosted.org/packages/03/ac/13fbe0ebf110d57a89f055a292d4fe430fee3fb22c56f8c077e63e0c5a4e/paddlepaddle-2.4.2-cp310-cp310-win_amd64.whl
python -m pip install paddleocr>=2.0.1
if: matrix.config.python
- uses: msys2/setup-msys2@v2
@@ -122,20 +117,16 @@ jobs:
make install
cd ../..
- name: Secrets
if: github.ref == 'refs/heads/master'
run: |
cd src
echo "#define STRAVA_SECRET_KEY ${{ secrets.strava_secret_key }}" > secret.h
echo "#define SMTP_USERNAME ${{ secrets.smtp_username }}" >> secret.h
echo "#define SMTP_PASSWORD ${{ secrets.smtp_password }}" >> secret.h
echo "#define SMTP_SERVER ${{ secrets.smtp_server }}" >> secret.h
echo "${{ secrets.cesiumkey }}" >> inner_templates/googlemaps/cesium-key.js
cd ..
- name: Build
run: |
qmake
cd src
echo "#define STRAVA_SECRET_KEY ${{ secrets.strava_secret_key }}" > secret.h
echo "#define SMTP_USERNAME ${{ secrets.smtp_username }}" >> secret.h
echo "#define SMTP_PASSWORD ${{ secrets.smtp_password }}" >> secret.h
echo "#define SMTP_SERVER ${{ secrets.smtp_server }}" >> secret.h
echo "${{ secrets.cesiumkey }}" >> inner_templates/googlemaps/cesium-key.js
cd ..
make -j8
cd src/debug
mkdir output
@@ -153,7 +144,7 @@ jobs:
cp ../../../windows_openssl/*.* .
mkdir adb
mkdir python
Copy-Item -Path C:\hostedtoolcache\windows\Python\3.7.9\x64 -Destination python -Recurse
Copy-Item -Path C:\hostedtoolcache\windows\Python\3.10.11\x64 -Destination python -Recurse
cp ../../adb/* adb/
cd ..
cd appx
@@ -163,6 +154,13 @@ jobs:
- name: Build without python
run: |
qmake
cd src
echo "#define STRAVA_SECRET_KEY ${{ secrets.strava_secret_key }}" > secret.h
echo "#define SMTP_USERNAME ${{ secrets.smtp_username }}" >> secret.h
echo "#define SMTP_PASSWORD ${{ secrets.smtp_password }}" >> secret.h
echo "#define SMTP_SERVER ${{ secrets.smtp_server }}" >> secret.h
echo "${{ secrets.cesiumkey }}" >> inner_templates/googlemaps/cesium-key.js
cd ..
make -j8
cd src/debug
mkdir output
@@ -195,21 +193,21 @@ jobs:
if: ${{ ! matrix.config.python }}
- name: Archive windows binary
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v2
with:
name: windows-binary
path: windows-binary.zip
if: matrix.config.python
- name: Archive windows binary
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v2
with:
name: windows-binary-no-python
path: windows-binary-no-python.zip
if: ${{ ! matrix.config.python }}
# - name: Exit if not on master branch
# if: github.ref == 'refs/heads/master'
# if: github.ref == 'refs/heads/main'
# run: exit 1
# - uses: actions/checkout@v3
@@ -337,7 +335,7 @@ jobs:
# This workflow contains a single job called "build"
linux-x86-build:
# The type of runner that the job will run on
runs-on: ubuntu-20.04
runs-on: ubuntu-latest
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
@@ -433,7 +431,7 @@ jobs:
run: qmake; make -j8
- name: Archive linux-desktop binary
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v2
with:
name: linux-desktop-binary
path: src/qdomyos-zwift
@@ -442,7 +440,7 @@ jobs:
run: cd tst; GTEST_OUTPUT=xml:test-results/ GTEST_COLOR=1 ./qdomyos-zwift-tests; cd ..
- name: Upload test results
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v2
if: failure()
with:
name: test_results_xml
@@ -507,7 +505,7 @@ jobs:
# This workflow contains a single job called "build"
android-build:
# The type of runner that the job will run on
runs-on: ubuntu-20.04
runs-on: ubuntu-latest
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
@@ -582,10 +580,10 @@ jobs:
cache-key-prefix: 'install-qt-action-android'
- name: Install Java
uses: actions/setup-java@v3
uses: actions/setup-java@v4
with:
distribution: 'temurin' # See 'Supported distributions' for available options
java-version: '11.0.23+9'
java-version: '17'
- name: patching qt for bluetooth
run: cp qt-patches/android/5.15.0/jar/*.* ${{ github.workspace }}/output/android/Qt/5.15.0/android/jar/
@@ -593,6 +591,14 @@ jobs:
- name: download 3rd party files for qthttpserver
run: cp qHttpServerBin/5.15.2/headers/* src/qthttpserver/src/3rdparty/http-parser/
- name: Build qthttpserver
run: |
cd src/qthttpserver
qmake
make -j8
make install
cd ../..
- name: Set Android NDK 21 && build
run: |
# Install NDK 21 after GitHub update
@@ -614,14 +620,6 @@ jobs:
ln -sfn $ANDROID_SDK_ROOT/ndk/21.4.7075529 $ANDROID_NDK
rm -rf /usr/local/lib/android/sdk/ndk/25.1.8937393
# QTHTTPSERVER must use the same NDK
cd src/qthttpserver
qmake
make -j8
make install
cd ../..
qmake -spec android-clang 'ANDROID_ABIS=armeabi-v7a arm64-v8a x86 x86_64' 'ANDROID_NDK_ROOT=/usr/local/lib/android/sdk/ndk/21.4.7075529' && make -j4 && make INSTALL_ROOT=${{ github.workspace }}/output/android/ install
sed -i '1s|{|{\n "android-extra-libs": "${{ github.workspace }}/android_openssl/no-asm/latest/arm/libcrypto_1_1.so,${{ github.workspace }}/android_openssl/no-asm/latest/arm/libssl_1_1.so,${{ github.workspace }}/android_openssl/no-asm/latest/arm64/libcrypto_1_1.so,${{ github.workspace }}/android_openssl/no-asm/latest/arm64/libssl_1_1.so,${{ github.workspace }}/android_openssl/no-asm/latest/x86/libcrypto_1_1.so,${{ github.workspace }}/android_openssl/no-asm/latest/x86/libssl_1_1.so,${{ github.workspace }}/android_openssl/no-asm/latest/x86_64/libcrypto_1_1.so,${{ github.workspace }}/android_openssl/no-asm/latest/x86_64/libssl_1_1.so",|' src/android-qdomyos-zwift-deployment-settings.json
cat src/android-qdomyos-zwift-deployment-settings.json
@@ -630,13 +628,13 @@ jobs:
run: cd src; androiddeployqt --input android-qdomyos-zwift-deployment-settings.json --output ${{ github.workspace }}/output/android/ --android-platform android-31 --gradle --aab
- name: Archive apk binary
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v2
with:
name: fdroid-android-trial
path: ${{ github.workspace }}/output/android/build/outputs/apk/debug/
# - name: Exit if not on master branch
# if: github.ref == 'refs/heads/master'
# if: github.ref == 'refs/heads/main'
# run: exit 1
# - name: upload windows artifact
@@ -651,7 +649,7 @@ jobs:
ios-build:
# The type of runner that the job will run on
runs-on: macos-12
runs-on: macos-latest
permissions:
contents: write
@@ -765,20 +763,15 @@ jobs:
- uses: actions/setup-python@v4
with:
python-version: 3.7
python-version: 3.10.11
- name: download python and paddleocr
run: |
python -VV
python -m pip install --upgrade pip
python -m pip install --upgrade setuptools
python -m pip install "protobuf<=3.20.2,>=3.1.0"
python -m pip install paddlepaddle==2.5.1
python -m pip install paddleocr
python -m pip install imutils
python -m pip install "Pillow<10.0.0"
python -m pip install opencv-python
python -m pip install numpy
python -m pip install pywin32
python -m pip install paddlepaddle-gpu==2.4.2.post117 -f https://www.paddlepaddle.org.cn/whl/windows/mkl/avx/stable.html
python -m pip install https://files.pythonhosted.org/packages/03/ac/13fbe0ebf110d57a89f055a292d4fe430fee3fb22c56f8c077e63e0c5a4e/paddlepaddle-2.4.2-cp310-cp310-win_amd64.whl
python -m pip install paddleocr>=2.0.1
if: matrix.config.python
- name: Install Qt
@@ -813,36 +806,16 @@ jobs:
nmake install
cd ../..
- name: Secrets
if: github.ref == 'refs/heads/master'
run: |
cd src
echo "#define STRAVA_SECRET_KEY ${{ secrets.strava_secret_key }}" > secret.h
echo "#define SMTP_USERNAME ${{ secrets.smtp_username }}" >> secret.h
echo "#define SMTP_PASSWORD ${{ secrets.smtp_password }}" >> secret.h
echo "#define SMTP_SERVER ${{ secrets.smtp_server }}" >> secret.h
echo "${{ secrets.cesiumkey }}" >> inner_templates/googlemaps/cesium-key.js
cd ..
- name: Clone vcpkg
run: git clone https://github.com/microsoft/vcpkg.git
working-directory: ${{ runner.workspace }}
- name: Bootstrap vcpkg
run: .\vcpkg\bootstrap-vcpkg.bat
working-directory: ${{ runner.workspace }}
- name: Install dependencies
run: |
.\vcpkg\vcpkg install protobuf protobuf-c abseil
working-directory: ${{ runner.workspace }}
- name: Build
run: |
Copy-Item -Path ${{ runner.workspace }}\vcpkg\installed\x64-windows\lib\*.* -Destination . -Verbose
Copy-Item -Path ${{ runner.workspace }}\vcpkg\installed\x64-windows\lib\*.* -Destination src/ -Verbose
Copy-Item -Path ${{ runner.workspace }}\vcpkg\installed\x64-windows\include\* -Destination src/ -Recurse -Verbose
qmake
qmake
cd src
echo "#define STRAVA_SECRET_KEY ${{ secrets.strava_secret_key }}" > secret.h
echo "#define SMTP_USERNAME ${{ secrets.smtp_username }}" >> secret.h
echo "#define SMTP_PASSWORD ${{ secrets.smtp_password }}" >> secret.h
echo "#define SMTP_SERVER ${{ secrets.smtp_server }}" >> secret.h
echo "${{ secrets.cesiumkey }}" >> inner_templates/googlemaps/cesium-key.js
cd ..
nmake
cd src/debug
mkdir output
@@ -855,10 +828,9 @@ jobs:
cp ../../windows/*.py .
cp ../../windows/*.bat .
cp ../../../windows_openssl/*.* .
Copy-Item -Path ${{ runner.workspace }}\vcpkg\installed\x64-windows\bin\*.* -Destination . -Verbose
mkdir adb
mkdir python
Copy-Item -Path C:\hostedtoolcache\windows\Python\3.7.9\x64 -Destination python -Recurse
Copy-Item -Path C:\hostedtoolcache\windows\Python\3.10.11\x64 -Destination python -Recurse
cp ../../adb/* adb/
cd ..
cd appx
@@ -866,11 +838,15 @@ jobs:
if: matrix.config.python
- name: Build without python
run: |
Copy-Item -Path ${{ runner.workspace }}\vcpkg\installed\x64-windows\lib\*.* -Destination . -Verbose
Copy-Item -Path ${{ runner.workspace }}\vcpkg\installed\x64-windows\lib\*.* -Destination src/ -Verbose
Copy-Item -Path ${{ runner.workspace }}\vcpkg\installed\x64-windows\include\* -Destination src/ -Recurse -Verbose
qmake
run: |
qmake
cd src
echo "#define STRAVA_SECRET_KEY ${{ secrets.strava_secret_key }}" > secret.h
echo "#define SMTP_USERNAME ${{ secrets.smtp_username }}" >> secret.h
echo "#define SMTP_PASSWORD ${{ secrets.smtp_password }}" >> secret.h
echo "#define SMTP_SERVER ${{ secrets.smtp_server }}" >> secret.h
echo "${{ secrets.cesiumkey }}" >> inner_templates/googlemaps/cesium-key.js
cd ..
nmake
cd src/debug
mkdir output
@@ -880,11 +856,10 @@ jobs:
windeployqt --qmldir ../../ qdomyos-zwift.exe
cp "C:/mingw64/bin/libwinpthread-1.dll" .
cp "C:/mingw64/bin/libgcc_s_seh-1.dll" .
cp "C:/mingw64/bin/libstdc++-6.dll" .
cp "C:/mingw64/bin/libstdc++-6.dll" .
cp ../../../icons/iOS/iTunesArtwork@2x.png .
cp ../../AppxManifest.xml .
cp ../../../windows_openssl/*.* .
Copy-Item -Path ${{ runner.workspace }}\vcpkg\installed\x64-windows\bin\*.* -Destination . -Verbose
mkdir adb
cp ../../adb/* adb/
cd ..
@@ -904,162 +879,27 @@ jobs:
if: ${{ ! matrix.config.python }}
- name: Archive windows binary
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v2
with:
name: windows-msvc2019-binary
path: windows-msvc2019-binary.zip
if: matrix.config.python
- name: Archive windows binary
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v2
with:
name: windows-msvc2019-binary-no-python
path: windows-msvc2019-binary-no-python.zip
if: ${{ ! matrix.config.python }}
window-msvc2019-aiserver-build:
runs-on: windows-latest
steps:
- uses: actions/checkout@v2
- name: Checkout submodule repo
uses: actions/checkout@v2
with:
repository: bluetiger9/SmtpClient-for-Qt
path: "src/smtpclient/"
ref: 3fa4a0fe5797070339422cf18b5e9ed8dcb91f9c
- uses: actions/checkout@v2
- name: Checkout submodule repo
uses: actions/checkout@v2
with:
repository: cagnulein/qmdnsengine
path: "src/qmdnsengine/"
ref: "zwift"
- uses: actions/checkout@v2
- name: Checkout submodule repo
uses: actions/checkout@v2
with:
repository: google/googletest
path: "tst/googletest/"
ref: "release-1.12.1"
- uses: actions/checkout@v2
- name: Checkout qHttpServer
uses: actions/checkout@v2
with:
repository: qt-labs/qthttpserver
path: "src/qthttpserver"
- name: Install CMake
uses: lukka/get-cmake@latest
- name: Install Qt
uses: jurplel/install-qt-action@v3
with:
version: '5.15.2'
host: 'windows'
modules: 'qtnetworkauth qtcharts'
target: "desktop"
arch: win64_msvc2019_64
dir: "${{github.workspace}}/qt/"
install-deps: "true"
cache: 'true'
cache-key-prefix: 'install-qt-action-windows'
- name: Install MSVC compiler
uses: ilammy/msvc-dev-cmd@v1
with:
# 14.1 is for vs2017, 14.2 is vs2019, following the upstream vcpkg build from Qv2ray-deps repo
toolset: 14.2
arch: x64
- name: download 3rd party files for qthttpserver
run: |
cp qHttpServerBin/5.15.2/headers/* src/qthttpserver/src/3rdparty/http-parser/
- name: Build qthttpserver
run: |
cd src\qthttpserver
qmake
nmake
nmake install
cd ../..
- name: Secrets
if: github.ref == 'refs/heads/master'
run: |
cd src
echo "#define STRAVA_SECRET_KEY ${{ secrets.strava_secret_key }}" > secret.h
echo "#define SMTP_USERNAME ${{ secrets.smtp_username }}" >> secret.h
echo "#define SMTP_PASSWORD ${{ secrets.smtp_password }}" >> secret.h
echo "#define SMTP_SERVER ${{ secrets.smtp_server }}" >> secret.h
echo "${{ secrets.cesiumkey }}" >> inner_templates/googlemaps/cesium-key.js
cd ..
- name: Clone vcpkg
run: git clone https://github.com/microsoft/vcpkg.git
working-directory: ${{ runner.workspace }}
- name: Bootstrap vcpkg
run: .\vcpkg\bootstrap-vcpkg.bat
working-directory: ${{ runner.workspace }}
- name: Install dependencies
run: |
.\vcpkg\vcpkg install protobuf protobuf-c abseil
working-directory: ${{ runner.workspace }}
- name: Build
run: |
Copy-Item -Path ${{ runner.workspace }}\vcpkg\installed\x64-windows\lib\*.* -Destination . -Verbose
Copy-Item -Path ${{ runner.workspace }}\vcpkg\installed\x64-windows\lib\*.* -Destination src/ -Verbose
Copy-Item -Path ${{ runner.workspace }}\vcpkg\installed\x64-windows\include\* -Destination src/ -Recurse -Verbose
cd src
echo "#define AISERVER" >> aiserver.h
cd ..
qmake
nmake
cd src/debug
mkdir output
mkdir appx
cp qdomyos-zwift.exe output/
cd output
windeployqt --qmldir ../../ qdomyos-zwift.exe
cp ../../../icons/iOS/iTunesArtwork@2x.png .
cp ../../AppxManifest.xml .
cp ../../windows/zwift-incline-ai-server.py zwift-incline.py
cp ../../windows/zwift-incline-climb-portal-ai-server.py zwift-incline-climb-portal.py
cp ../../windows/zwift-workout-ai-server.py zwift-workout.py
cp ../../windows/*.bat .
cp ../../../windows_openssl/*.* .
Copy-Item -Path ${{ runner.workspace }}\vcpkg\installed\x64-windows\bin\*.* -Destination . -Verbose
mkdir adb
cp ../../adb/* adb/
cd ..
cd appx
#../../MSIX-Toolkit/WindowsSDK/10/10.0.20348.0/x64/makeappx.exe pack /d ../output/ /p qz
- name: patching qt for bluetooth
run: cp qt-patches/windows/5.15.2/binary/msvc2019/*.* ${{ github.workspace }}/src/debug/output/
- name: Zip artifact for deployment
run: Compress-Archive src/debug/output windows-msvc2019-ai-server-binary.zip
- name: Archive windows binary
uses: actions/upload-artifact@v4
with:
name: windows-msvc2019-ai-server-binary
path: windows-msvc2019-ai-server-binary.zip
upload_to_release:
permissions: write-all
runs-on: ubuntu-20.04
runs-on: ubuntu-latest
if: github.event_name == 'schedule'
needs: [linux-x86-build, window-msvc2019-build, ios-build, window-build, android-build] # Specify the job dependencies
steps:
- name: Download artifacts
uses: actions/download-artifact@v4
uses: actions/download-artifact@v3
- name: Update nightly release
uses: andelf/nightly-release@main
env:
@@ -1081,7 +921,6 @@ jobs:
files: |
windows-msvc2019-binary-no-python/*
windows-msvc2019-binary/*
windows-msvc2019-ai-server-binary/*
windows-binary-no-python/*
windows-binary/*
fdroid-android-trial/*

4
.gitmodules vendored
View File

@@ -16,7 +16,3 @@
[submodule "src/qthttpserver"]
path = src/qthttpserver
url = https://github.com/qt-labs/qthttpserver
[submodule "zwiftplay"]
path = zwiftplay
url = https://github.com/cagnulein/zwiftplay.git
branch = lib

View File

@@ -1,53 +0,0 @@
#include <NimBLEDevice.h>
#define INDOOR_BIKE_DATA_UUID "00002AD2-0000-1000-8000-00805f9b34fb"
#define CUSTOM_SERVICE_UUID "ce060000-43e5-11e4-916c-0800200c9a66"
NimBLEServer* pServer = nullptr;
NimBLECharacteristic* pIndoorBikeDataChar = nullptr;
class ServerCallbacks: public NimBLEServerCallbacks {
void onConnect(NimBLEServer* pServer) {
Serial.println("Client connected");
};
void onDisconnect(NimBLEServer* pServer) {
Serial.println("Client disconnected");
}
};
void setup() {
Serial.begin(115200);
Serial.println("Starting NimBLE Server");
NimBLEDevice::init("PM5 431431183 Row");
pServer = NimBLEDevice::createServer();
pServer->setCallbacks(new ServerCallbacks());
NimBLEService* pFtmService = pServer->createService("1826");
//NimBLEService* pCustomService = pServer->createService(CUSTOM_SERVICE_UUID);
pIndoorBikeDataChar = pFtmService->createCharacteristic(
INDOOR_BIKE_DATA_UUID,
NIMBLE_PROPERTY::READ |
NIMBLE_PROPERTY::NOTIFY
);
pFtmService->start();
//pCustomService->start();
NimBLEAdvertising* pAdvertising = NimBLEDevice::getAdvertising();
pAdvertising->addServiceUUID(pFtmService->getUUID());
//pAdvertising->addServiceUUID(CUSTOM_SERVICE_UUID);
const std::string data = { 0x01, 0x10, 0x00 }; // Imposta i valori desiderati
pAdvertising->setServiceData(pFtmService->getUUID(), data);
pAdvertising->start();
Serial.println("Advertising started");
}
void loop() {
// Metti qui il tuo codice principale, da eseguire ripetutamente
// Ad esempio, potresti aggiornare il valore della caratteristica Indoor Bike Data
}

View File

@@ -69,7 +69,6 @@ Zwift bridge for Treadmills and Bike!
|Echelon app Compatibility|X|||||
|Wahoo Dircon Compatibility|X|X|X|X|in order to send data to Zwift or RGT with Wifi only!|
|One device only support for Zwift and Wahoo RGT|X|X|X|X|using Wahoo Dircon https://www.youtube.com/watch?v=gYYUXNWFAok|
|BitGym Compatibility|X|X|X|X||
# Training Program
|Feature|Bike|Treadmill|Elliptical|Rower|Notes|

View File

@@ -2,4 +2,3 @@
// Use this file to import your target's public headers that you would like to expose to Swift.
//
#import "swiftDebug.h"

View File

@@ -53,17 +53,12 @@ qdomyoszwift.xcodeproj/project.pbxproj: ../src/qdomyos-zwift.pro ../../Qt/5.15.2
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_accessibility_support_private.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_bluetooth.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_bluetooth_private.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_bodymovin_private.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_bootstrap_private.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_charts.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_charts_private.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_clipboard_support_private.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_concurrent.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_concurrent_private.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_core.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_core_private.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_datavisualization.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_datavisualization_private.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_devicediscovery_support_private.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_edid_support_private.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_eventdispatcher_support_private.pri \
@@ -76,9 +71,6 @@ qdomyoszwift.xcodeproj/project.pbxproj: ../src/qdomyos-zwift.pro ../../Qt/5.15.2
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_gui_private.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_help.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_help_private.pri \
../../Qt/5.15.2/ios/mkspecs/modules-inst/qt_lib_httpserver.pri \
../../Qt/5.15.2/ios/mkspecs/modules-inst/qt_lib_httpserver_private.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_httpserver.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_location.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_location_private.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_macextras.pri \
@@ -103,8 +95,6 @@ qdomyoszwift.xcodeproj/project.pbxproj: ../src/qdomyos-zwift.pro ../../Qt/5.15.2
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_positioning_private.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_positioningquick.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_positioningquick_private.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_purchasing.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_purchasing_private.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_qml.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_qml_private.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_qmldebug_private.pri \
@@ -117,16 +107,6 @@ qdomyoszwift.xcodeproj/project.pbxproj: ../src/qdomyos-zwift.pro ../../Qt/5.15.2
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_qmlworkerscript_private.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_qtmultimediaquicktools_private.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_quick.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_quick3d.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_quick3d_private.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_quick3dassetimport.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_quick3dassetimport_private.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_quick3drender.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_quick3drender_private.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_quick3druntimerender.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_quick3druntimerender_private.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_quick3dutils.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_quick3dutils_private.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_quick_private.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_quickcontrols2.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_quickcontrols2_private.pri \
@@ -140,21 +120,12 @@ qdomyoszwift.xcodeproj/project.pbxproj: ../src/qdomyos-zwift.pro ../../Qt/5.15.2
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_remoteobjects_private.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_repparser.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_repparser_private.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_script.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_script_private.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_scripttools.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_scripttools_private.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_scxml.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_scxml_private.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_sensors.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_sensors_private.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_serialbus.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_serialbus_private.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_sql.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_sql_private.pri \
../../Qt/5.15.2/ios/mkspecs/modules-inst/qt_lib_sslserver.pri \
../../Qt/5.15.2/ios/mkspecs/modules-inst/qt_lib_sslserver_private.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_sslserver.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_svg.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_svg_private.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_testlib.pri \
@@ -165,8 +136,6 @@ qdomyoszwift.xcodeproj/project.pbxproj: ../src/qdomyos-zwift.pro ../../Qt/5.15.2
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_uiplugin.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_uitools.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_uitools_private.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_virtualkeyboard.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_virtualkeyboard_private.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_webchannel.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_webchannel_private.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_websockets.pri \
@@ -225,26 +194,15 @@ qdomyoszwift.xcodeproj/project.pbxproj: ../src/qdomyos-zwift.pro ../../Qt/5.15.2
../../Qt/5.15.2/ios/mkspecs/modules/qt_plugin_qtiff.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_plugin_qtmedia_audioengine.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_plugin_qtmultimedia_m3u.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_plugin_qtpassthrucanbus.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_plugin_qtpeakcanbus.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_plugin_qtposition_cl.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_plugin_qtposition_positionpoll.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_plugin_qtsensorgestures_plugin.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_plugin_qtsensorgestures_shakeplugin.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_plugin_qtsensors_generic.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_plugin_qtsensors_ios.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_plugin_qttinycanbus.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_plugin_qtuiotouchplugin.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_plugin_qtvirtualcanbus.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_plugin_qtvirtualkeyboard_hangul.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_plugin_qtvirtualkeyboard_openwnn.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_plugin_qtvirtualkeyboard_pinyin.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_plugin_qtvirtualkeyboard_tcime.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_plugin_qtvirtualkeyboard_thai.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_plugin_qtvirtualkeyboardplugin.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_plugin_qtwebview_darwin.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_plugin_qwbmp.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_plugin_qwebgl.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_plugin_qwebp.pri \
../../Qt/5.15.2/ios/mkspecs/modules/qt_plugin_scene2d.pri \
../../Qt/5.15.2/ios/mkspecs/features/qt_functions.prf \
@@ -261,9 +219,6 @@ qdomyoszwift.xcodeproj/project.pbxproj: ../src/qdomyos-zwift.pro ../../Qt/5.15.2
../../Qt/5.15.2/ios/mkspecs/features/default_pre.prf \
../../Qt/5.15.2/ios/mkspecs/features/mac/default_pre.prf \
../../Qt/5.15.2/ios/mkspecs/features/uikit/default_pre.prf \
../defaults.pri \
../src/purchasing/purchasing.pri \
../src/qdomyos-zwift.pri \
../../Qt/5.15.2/ios/mkspecs/features/resolve_config.prf \
../../Qt/5.15.2/ios/mkspecs/features/uikit/resolve_config.prf \
../../Qt/5.15.2/ios/mkspecs/features/default_post.prf \
@@ -271,9 +226,6 @@ qdomyoszwift.xcodeproj/project.pbxproj: ../src/qdomyos-zwift.pro ../../Qt/5.15.2
../../Qt/5.15.2/ios/mkspecs/features/uikit/default_post.prf \
../../Qt/5.15.2/ios/mkspecs/macx-ios-clang/features/default_post.prf \
../../Qt/5.15.2/ios/mkspecs/features/mac/objective_c.prf \
../../Qt/5.15.2/ios/mkspecs/features/qmltypes.prf \
../../Qt/5.15.2/ios/mkspecs/features/metatypes.prf \
../../Qt/5.15.2/ios/mkspecs/features/ltcg.prf \
../../Qt/5.15.2/ios/mkspecs/features/qml_debug.prf \
../../Qt/5.15.2/ios/mkspecs/features/mac/mac.prf \
../../Qt/5.15.2/ios/mkspecs/features/uikit/bitcode.prf \
@@ -312,18 +264,6 @@ qdomyoszwift.xcodeproj/project.pbxproj: ../src/qdomyos-zwift.pro ../../Qt/5.15.2
../../Qt/5.15.2/ios/lib/libqtharfbuzz_debug.prl \
../../Qt/5.15.2/ios/lib/libQt5Core_debug.prl \
../../Qt/5.15.2/ios/lib/libqtpcre2_debug.prl \
../../Qt/5.15.2/ios/plugins/mediaservice/libqavfmediaplayer_debug.prl \
../../Qt/5.15.2/ios/plugins/geoservices/libqtgeoservices_esri_debug.prl \
../../Qt/5.15.2/ios/plugins/geoservices/libqtgeoservices_itemsoverlay_debug.prl \
../../Qt/5.15.2/ios/plugins/geoservices/libqtgeoservices_mapbox_debug.prl \
../../Qt/5.15.2/ios/plugins/geoservices/libqtgeoservices_mapboxgl_debug.prl \
../../Qt/5.15.2/ios/plugins/geoservices/libqtgeoservices_nokia_debug.prl \
../../Qt/5.15.2/ios/plugins/geoservices/libqtgeoservices_osm_debug.prl \
../../Qt/5.15.2/ios/plugins/webview/libqtwebview_darwin_debug.prl \
../../Qt/5.15.2/ios/plugins/mediaservice/libqavfcamera_debug.prl \
../../Qt/5.15.2/ios/plugins/mediaservice/libqtmedia_audioengine_debug.prl \
../../Qt/5.15.2/ios/plugins/audio/libqtaudio_coreaudio_debug.prl \
../../Qt/5.15.2/ios/plugins/playlistformats/libqtmultimedia_m3u_debug.prl \
../../Qt/5.15.2/ios/plugins/imageformats/libqgif_debug.prl \
../../Qt/5.15.2/ios/plugins/imageformats/libqicns_debug.prl \
../../Qt/5.15.2/ios/plugins/imageformats/libqico_debug.prl \
@@ -348,51 +288,32 @@ qdomyoszwift.xcodeproj/project.pbxproj: ../src/qdomyos-zwift.pro ../../Qt/5.15.2
../../Qt/5.15.2/ios/plugins/qmltooling/libqmldbg_server_debug.prl \
../../Qt/5.15.2/ios/plugins/qmltooling/libqmldbg_tcp_debug.prl \
../../Qt/5.15.2/ios/plugins/bearer/libqgenericbearer_debug.prl \
../../Qt/5.15.2/ios/plugins/texttospeech/libqtexttospeech_speechios_debug.prl \
../../Qt/5.15.2/ios/plugins/sqldrivers/libqsqlite_debug.prl \
../../Qt/5.15.2/ios/lib/libQt5HttpServer_debug.prl \
../../Qt/5.15.2/ios/lib/libQt5SslServer_debug.prl \
../../Qt/5.15.2/ios/lib/libQt5Charts_debug.prl \
../../Qt/5.15.2/ios/lib/libQt5Widgets_debug.prl \
../../Qt/5.15.2/ios/lib/libQt5Location_debug.prl \
../../Qt/5.15.2/ios/lib/libQt5PositioningQuick_debug.prl \
../../Qt/5.15.2/ios/lib/libQt5QuickControls2_debug.prl \
../../Qt/5.15.2/ios/lib/libQt5Quick_debug.prl \
../../Qt/5.15.2/ios/lib/libQt5Multimedia_debug.prl \
../../Qt/5.15.2/ios/lib/libQt5WebView_debug.prl \
../../Qt/5.15.2/ios/lib/libQt5Bluetooth_debug.prl \
../../Qt/5.15.2/ios/lib/libQt5Xml_debug.prl \
../../Qt/5.15.2/ios/lib/libQt5Positioning_debug.prl \
../../Qt/5.15.2/ios/lib/libQt5QmlModels_debug.prl \
../../Qt/5.15.2/ios/lib/libQt5Qml_debug.prl \
../../Qt/5.15.2/ios/lib/libQt5NetworkAuth_debug.prl \
../../Qt/5.15.2/ios/lib/libQt5WebSockets_debug.prl \
../../Qt/5.15.2/ios/lib/libQt5Network_debug.prl \
../../Qt/5.15.2/ios/lib/libQt5TextToSpeech_debug.prl \
../../Qt/5.15.2/ios/lib/libQt5Concurrent_debug.prl \
../../Qt/5.15.2/ios/qml/QtQuick.2/libqtquick2plugin_debug.prl \
../../Qt/5.15.2/ios/qml/QtQuick/Layouts/libqquicklayoutsplugin_debug.prl \
../../Qt/5.15.2/ios/qml/QtQuick/Controls.2/libqtquickcontrols2plugin_debug.prl \
../../Qt/5.15.2/ios/qml/Qt/labs/settings/libqmlsettingsplugin_debug.prl \
../../Qt/5.15.2/ios/qml/QtQuick/Controls.2/Material/libqtquickcontrols2materialstyleplugin_debug.prl \
../../Qt/5.15.2/ios/qml/QtGraphicalEffects/libqtgraphicaleffectsplugin_debug.prl \
../../Qt/5.15.2/ios/qml/QtQuick/Window.2/libwindowplugin_debug.prl \
../../Qt/5.15.2/ios/qml/QtQml/libqmlplugin_debug.prl \
../../Qt/5.15.2/ios/qml/QtQuick/Templates.2/libqtquicktemplates2plugin_debug.prl \
../../Qt/5.15.2/ios/qml/QtGraphicalEffects/private/libqtgraphicaleffectsprivate_debug.prl \
../../Qt/5.15.2/ios/qml/QtQml/Models.2/libmodelsplugin_debug.prl \
../../Qt/5.15.2/ios/qml/QtQml/WorkerScript.2/libworkerscriptplugin_debug.prl \
../../Qt/5.15.2/ios/qml/QtQuick/Window.2/libwindowplugin_debug.prl \
../../Qt/5.15.2/ios/qml/QtQuick/Controls.2/Material/libqtquickcontrols2materialstyleplugin_debug.prl \
../../Qt/5.15.2/ios/qml/QtWebView/libdeclarative_webview_debug.prl \
../../Qt/5.15.2/ios/qml/QtCharts/libqtchartsqml2_debug.prl \
../../Qt/5.15.2/ios/qml/Qt/labs/folderlistmodel/libqmlfolderlistmodelplugin_debug.prl \
../../Qt/5.15.2/ios/qml/QtQuick/Dialogs/libdialogplugin_debug.prl \
../../Qt/5.15.2/ios/qml/QtPositioning/libdeclarative_positioning_debug.prl \
../../Qt/5.15.2/ios/qml/QtLocation/libdeclarative_location_debug.prl \
../../Qt/5.15.2/ios/qml/Qt/labs/folderlistmodel/libqmlfolderlistmodelplugin_debug.prl \
../../Qt/5.15.2/ios/qml/Qt/labs/settings/libqmlsettingsplugin_debug.prl \
../../Qt/5.15.2/ios/qml/QtQuick/Dialogs/Private/libdialogsprivateplugin_debug.prl \
../../Qt/5.15.2/ios/qml/QtQuick/Controls/libqtquickcontrolsplugin_debug.prl \
../../Qt/5.15.2/ios/qml/QtQuick/PrivateWidgets/libwidgetsplugin_debug.prl \
../../Qt/5.15.2/ios/qml/QtGraphicalEffects/libqtgraphicaleffectsplugin_debug.prl \
../../Qt/5.15.2/ios/qml/Qt/labs/platform/libqtlabsplatformplugin_debug.prl \
../../Qt/5.15.2/ios/qml/QtMultimedia/libdeclarative_multimedia_debug.prl \
../../Qt/5.15.2/ios/qml/QtGraphicalEffects/private/libqtgraphicaleffectsprivate_debug.prl \
../../Qt/5.15.2/ios/qml/QtQuick/Layouts/libqquicklayoutsplugin_debug.prl \
../../Qt/5.15.2/ios/qml/QtQuick/Controls.2/Fusion/libqtquickcontrols2fusionstyleplugin_debug.prl \
../../Qt/5.15.2/ios/qml/QtQuick/Controls.2/Universal/libqtquickcontrols2universalstyleplugin_debug.prl \
../../Qt/5.15.2/ios/qml/QtQuick/Controls.2/Imagine/libqtquickcontrols2imaginestyleplugin_debug.prl
@@ -440,17 +361,12 @@ qdomyoszwift.xcodeproj/project.pbxproj: ../src/qdomyos-zwift.pro ../../Qt/5.15.2
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_accessibility_support_private.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_bluetooth.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_bluetooth_private.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_bodymovin_private.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_bootstrap_private.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_charts.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_charts_private.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_clipboard_support_private.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_concurrent.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_concurrent_private.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_core.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_core_private.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_datavisualization.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_datavisualization_private.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_devicediscovery_support_private.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_edid_support_private.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_eventdispatcher_support_private.pri:
@@ -463,9 +379,6 @@ qdomyoszwift.xcodeproj/project.pbxproj: ../src/qdomyos-zwift.pro ../../Qt/5.15.2
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_gui_private.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_help.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_help_private.pri:
../../Qt/5.15.2/ios/mkspecs/modules-inst/qt_lib_httpserver.pri:
../../Qt/5.15.2/ios/mkspecs/modules-inst/qt_lib_httpserver_private.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_httpserver.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_location.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_location_private.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_macextras.pri:
@@ -490,8 +403,6 @@ qdomyoszwift.xcodeproj/project.pbxproj: ../src/qdomyos-zwift.pro ../../Qt/5.15.2
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_positioning_private.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_positioningquick.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_positioningquick_private.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_purchasing.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_purchasing_private.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_qml.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_qml_private.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_qmldebug_private.pri:
@@ -504,16 +415,6 @@ qdomyoszwift.xcodeproj/project.pbxproj: ../src/qdomyos-zwift.pro ../../Qt/5.15.2
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_qmlworkerscript_private.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_qtmultimediaquicktools_private.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_quick.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_quick3d.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_quick3d_private.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_quick3dassetimport.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_quick3dassetimport_private.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_quick3drender.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_quick3drender_private.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_quick3druntimerender.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_quick3druntimerender_private.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_quick3dutils.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_quick3dutils_private.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_quick_private.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_quickcontrols2.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_quickcontrols2_private.pri:
@@ -527,21 +428,12 @@ qdomyoszwift.xcodeproj/project.pbxproj: ../src/qdomyos-zwift.pro ../../Qt/5.15.2
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_remoteobjects_private.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_repparser.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_repparser_private.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_script.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_script_private.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_scripttools.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_scripttools_private.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_scxml.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_scxml_private.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_sensors.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_sensors_private.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_serialbus.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_serialbus_private.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_sql.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_sql_private.pri:
../../Qt/5.15.2/ios/mkspecs/modules-inst/qt_lib_sslserver.pri:
../../Qt/5.15.2/ios/mkspecs/modules-inst/qt_lib_sslserver_private.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_sslserver.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_svg.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_svg_private.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_testlib.pri:
@@ -552,8 +444,6 @@ qdomyoszwift.xcodeproj/project.pbxproj: ../src/qdomyos-zwift.pro ../../Qt/5.15.2
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_uiplugin.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_uitools.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_uitools_private.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_virtualkeyboard.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_virtualkeyboard_private.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_webchannel.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_webchannel_private.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_lib_websockets.pri:
@@ -612,26 +502,15 @@ qdomyoszwift.xcodeproj/project.pbxproj: ../src/qdomyos-zwift.pro ../../Qt/5.15.2
../../Qt/5.15.2/ios/mkspecs/modules/qt_plugin_qtiff.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_plugin_qtmedia_audioengine.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_plugin_qtmultimedia_m3u.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_plugin_qtpassthrucanbus.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_plugin_qtpeakcanbus.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_plugin_qtposition_cl.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_plugin_qtposition_positionpoll.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_plugin_qtsensorgestures_plugin.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_plugin_qtsensorgestures_shakeplugin.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_plugin_qtsensors_generic.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_plugin_qtsensors_ios.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_plugin_qttinycanbus.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_plugin_qtuiotouchplugin.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_plugin_qtvirtualcanbus.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_plugin_qtvirtualkeyboard_hangul.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_plugin_qtvirtualkeyboard_openwnn.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_plugin_qtvirtualkeyboard_pinyin.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_plugin_qtvirtualkeyboard_tcime.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_plugin_qtvirtualkeyboard_thai.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_plugin_qtvirtualkeyboardplugin.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_plugin_qtwebview_darwin.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_plugin_qwbmp.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_plugin_qwebgl.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_plugin_qwebp.pri:
../../Qt/5.15.2/ios/mkspecs/modules/qt_plugin_scene2d.pri:
../../Qt/5.15.2/ios/mkspecs/features/qt_functions.prf:
@@ -648,9 +527,6 @@ qdomyoszwift.xcodeproj/project.pbxproj: ../src/qdomyos-zwift.pro ../../Qt/5.15.2
../../Qt/5.15.2/ios/mkspecs/features/default_pre.prf:
../../Qt/5.15.2/ios/mkspecs/features/mac/default_pre.prf:
../../Qt/5.15.2/ios/mkspecs/features/uikit/default_pre.prf:
../defaults.pri:
../src/purchasing/purchasing.pri:
../src/qdomyos-zwift.pri:
../../Qt/5.15.2/ios/mkspecs/features/resolve_config.prf:
../../Qt/5.15.2/ios/mkspecs/features/uikit/resolve_config.prf:
../../Qt/5.15.2/ios/mkspecs/features/default_post.prf:
@@ -658,9 +534,6 @@ qdomyoszwift.xcodeproj/project.pbxproj: ../src/qdomyos-zwift.pro ../../Qt/5.15.2
../../Qt/5.15.2/ios/mkspecs/features/uikit/default_post.prf:
../../Qt/5.15.2/ios/mkspecs/macx-ios-clang/features/default_post.prf:
../../Qt/5.15.2/ios/mkspecs/features/mac/objective_c.prf:
../../Qt/5.15.2/ios/mkspecs/features/qmltypes.prf:
../../Qt/5.15.2/ios/mkspecs/features/metatypes.prf:
../../Qt/5.15.2/ios/mkspecs/features/ltcg.prf:
../../Qt/5.15.2/ios/mkspecs/features/qml_debug.prf:
../../Qt/5.15.2/ios/mkspecs/features/mac/mac.prf:
../../Qt/5.15.2/ios/mkspecs/features/uikit/bitcode.prf:
@@ -699,18 +572,6 @@ qdomyoszwift.xcodeproj/project.pbxproj: ../src/qdomyos-zwift.pro ../../Qt/5.15.2
../../Qt/5.15.2/ios/lib/libqtharfbuzz_debug.prl:
../../Qt/5.15.2/ios/lib/libQt5Core_debug.prl:
../../Qt/5.15.2/ios/lib/libqtpcre2_debug.prl:
../../Qt/5.15.2/ios/plugins/mediaservice/libqavfmediaplayer_debug.prl:
../../Qt/5.15.2/ios/plugins/geoservices/libqtgeoservices_esri_debug.prl:
../../Qt/5.15.2/ios/plugins/geoservices/libqtgeoservices_itemsoverlay_debug.prl:
../../Qt/5.15.2/ios/plugins/geoservices/libqtgeoservices_mapbox_debug.prl:
../../Qt/5.15.2/ios/plugins/geoservices/libqtgeoservices_mapboxgl_debug.prl:
../../Qt/5.15.2/ios/plugins/geoservices/libqtgeoservices_nokia_debug.prl:
../../Qt/5.15.2/ios/plugins/geoservices/libqtgeoservices_osm_debug.prl:
../../Qt/5.15.2/ios/plugins/webview/libqtwebview_darwin_debug.prl:
../../Qt/5.15.2/ios/plugins/mediaservice/libqavfcamera_debug.prl:
../../Qt/5.15.2/ios/plugins/mediaservice/libqtmedia_audioengine_debug.prl:
../../Qt/5.15.2/ios/plugins/audio/libqtaudio_coreaudio_debug.prl:
../../Qt/5.15.2/ios/plugins/playlistformats/libqtmultimedia_m3u_debug.prl:
../../Qt/5.15.2/ios/plugins/imageformats/libqgif_debug.prl:
../../Qt/5.15.2/ios/plugins/imageformats/libqicns_debug.prl:
../../Qt/5.15.2/ios/plugins/imageformats/libqico_debug.prl:
@@ -735,51 +596,32 @@ qdomyoszwift.xcodeproj/project.pbxproj: ../src/qdomyos-zwift.pro ../../Qt/5.15.2
../../Qt/5.15.2/ios/plugins/qmltooling/libqmldbg_server_debug.prl:
../../Qt/5.15.2/ios/plugins/qmltooling/libqmldbg_tcp_debug.prl:
../../Qt/5.15.2/ios/plugins/bearer/libqgenericbearer_debug.prl:
../../Qt/5.15.2/ios/plugins/texttospeech/libqtexttospeech_speechios_debug.prl:
../../Qt/5.15.2/ios/plugins/sqldrivers/libqsqlite_debug.prl:
../../Qt/5.15.2/ios/lib/libQt5HttpServer_debug.prl:
../../Qt/5.15.2/ios/lib/libQt5SslServer_debug.prl:
../../Qt/5.15.2/ios/lib/libQt5Charts_debug.prl:
../../Qt/5.15.2/ios/lib/libQt5Widgets_debug.prl:
../../Qt/5.15.2/ios/lib/libQt5Location_debug.prl:
../../Qt/5.15.2/ios/lib/libQt5PositioningQuick_debug.prl:
../../Qt/5.15.2/ios/lib/libQt5QuickControls2_debug.prl:
../../Qt/5.15.2/ios/lib/libQt5Quick_debug.prl:
../../Qt/5.15.2/ios/lib/libQt5Multimedia_debug.prl:
../../Qt/5.15.2/ios/lib/libQt5WebView_debug.prl:
../../Qt/5.15.2/ios/lib/libQt5Bluetooth_debug.prl:
../../Qt/5.15.2/ios/lib/libQt5Xml_debug.prl:
../../Qt/5.15.2/ios/lib/libQt5Positioning_debug.prl:
../../Qt/5.15.2/ios/lib/libQt5QmlModels_debug.prl:
../../Qt/5.15.2/ios/lib/libQt5Qml_debug.prl:
../../Qt/5.15.2/ios/lib/libQt5NetworkAuth_debug.prl:
../../Qt/5.15.2/ios/lib/libQt5WebSockets_debug.prl:
../../Qt/5.15.2/ios/lib/libQt5Network_debug.prl:
../../Qt/5.15.2/ios/lib/libQt5TextToSpeech_debug.prl:
../../Qt/5.15.2/ios/lib/libQt5Concurrent_debug.prl:
../../Qt/5.15.2/ios/qml/QtQuick.2/libqtquick2plugin_debug.prl:
../../Qt/5.15.2/ios/qml/QtQuick/Layouts/libqquicklayoutsplugin_debug.prl:
../../Qt/5.15.2/ios/qml/QtQuick/Controls.2/libqtquickcontrols2plugin_debug.prl:
../../Qt/5.15.2/ios/qml/Qt/labs/settings/libqmlsettingsplugin_debug.prl:
../../Qt/5.15.2/ios/qml/QtQuick/Controls.2/Material/libqtquickcontrols2materialstyleplugin_debug.prl:
../../Qt/5.15.2/ios/qml/QtGraphicalEffects/libqtgraphicaleffectsplugin_debug.prl:
../../Qt/5.15.2/ios/qml/QtQuick/Window.2/libwindowplugin_debug.prl:
../../Qt/5.15.2/ios/qml/QtQml/libqmlplugin_debug.prl:
../../Qt/5.15.2/ios/qml/QtQuick/Templates.2/libqtquicktemplates2plugin_debug.prl:
../../Qt/5.15.2/ios/qml/QtGraphicalEffects/private/libqtgraphicaleffectsprivate_debug.prl:
../../Qt/5.15.2/ios/qml/QtQml/Models.2/libmodelsplugin_debug.prl:
../../Qt/5.15.2/ios/qml/QtQml/WorkerScript.2/libworkerscriptplugin_debug.prl:
../../Qt/5.15.2/ios/qml/QtQuick/Window.2/libwindowplugin_debug.prl:
../../Qt/5.15.2/ios/qml/QtQuick/Controls.2/Material/libqtquickcontrols2materialstyleplugin_debug.prl:
../../Qt/5.15.2/ios/qml/QtWebView/libdeclarative_webview_debug.prl:
../../Qt/5.15.2/ios/qml/QtCharts/libqtchartsqml2_debug.prl:
../../Qt/5.15.2/ios/qml/Qt/labs/folderlistmodel/libqmlfolderlistmodelplugin_debug.prl:
../../Qt/5.15.2/ios/qml/QtQuick/Dialogs/libdialogplugin_debug.prl:
../../Qt/5.15.2/ios/qml/QtPositioning/libdeclarative_positioning_debug.prl:
../../Qt/5.15.2/ios/qml/QtLocation/libdeclarative_location_debug.prl:
../../Qt/5.15.2/ios/qml/Qt/labs/folderlistmodel/libqmlfolderlistmodelplugin_debug.prl:
../../Qt/5.15.2/ios/qml/Qt/labs/settings/libqmlsettingsplugin_debug.prl:
../../Qt/5.15.2/ios/qml/QtQuick/Dialogs/Private/libdialogsprivateplugin_debug.prl:
../../Qt/5.15.2/ios/qml/QtQuick/Controls/libqtquickcontrolsplugin_debug.prl:
../../Qt/5.15.2/ios/qml/QtQuick/PrivateWidgets/libwidgetsplugin_debug.prl:
../../Qt/5.15.2/ios/qml/QtGraphicalEffects/libqtgraphicaleffectsplugin_debug.prl:
../../Qt/5.15.2/ios/qml/Qt/labs/platform/libqtlabsplatformplugin_debug.prl:
../../Qt/5.15.2/ios/qml/QtMultimedia/libdeclarative_multimedia_debug.prl:
../../Qt/5.15.2/ios/qml/QtGraphicalEffects/private/libqtgraphicaleffectsprivate_debug.prl:
../../Qt/5.15.2/ios/qml/QtQuick/Layouts/libqquicklayoutsplugin_debug.prl:
../../Qt/5.15.2/ios/qml/QtQuick/Controls.2/Fusion/libqtquickcontrols2fusionstyleplugin_debug.prl:
../../Qt/5.15.2/ios/qml/QtQuick/Controls.2/Universal/libqtquickcontrols2universalstyleplugin_debug.prl:
../../Qt/5.15.2/ios/qml/QtQuick/Controls.2/Imagine/libqtquickcontrols2imaginestyleplugin_debug.prl:

View File

@@ -1,17 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSPrivacyAccessedAPITypes</key>
<array>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryUserDefaults</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>CA92.1</string>
</array>
</dict>
</array>
</dict>
</plist>

View File

@@ -162,12 +162,6 @@ extension WorkoutTracking: WorkoutTrackingProtocol {
HKSampleType.quantityType(forIdentifier: .cyclingPower)!,
HKSampleType.quantityType(forIdentifier: .cyclingSpeed)!,
HKSampleType.quantityType(forIdentifier: .cyclingCadence)!,
HKSampleType.quantityType(forIdentifier: .runningPower)!,
HKSampleType.quantityType(forIdentifier: .runningSpeed)!,
HKSampleType.quantityType(forIdentifier: .runningStrideLength)!,
HKSampleType.quantityType(forIdentifier: .runningVerticalOscillation)!,
HKSampleType.quantityType(forIdentifier: .walkingSpeed)!,
HKSampleType.quantityType(forIdentifier: .walkingStepLength)!,
HKSampleType.workoutType()
])
} else {
@@ -341,131 +335,64 @@ extension WorkoutTracking: HKLiveWorkoutBuilderDelegate {
}
}
if(sport == 0) {
if #available(watchOSApplicationExtension 10.0, *) {
let wattPerInterval = HKQuantity(unit: HKUnit.watt(),
doubleValue: WorkoutTracking.power)
if(WorkoutTracking.lastDateMetric.distance(to: Date()) < 1) {
return
}
guard let powerType = HKQuantityType.quantityType(
forIdentifier: .cyclingPower) else {
return
}
let wattPerIntervalSample = HKQuantitySample(type: powerType,
quantity: wattPerInterval,
start: WorkoutTracking.lastDateMetric,
end: Date())
workoutBuilder.add([wattPerIntervalSample]) {(success, error) in
if let error = error {
print(error)
}
}
let cadencePerInterval = HKQuantity(unit: HKUnit.count().unitDivided(by: HKUnit.second()),
doubleValue: WorkoutTracking.cadence / 60.0)
guard let cadenceType = HKQuantityType.quantityType(
forIdentifier: .cyclingCadence) else {
return
}
let cadencePerIntervalSample = HKQuantitySample(type: cadenceType,
quantity: cadencePerInterval,
start: WorkoutTracking.lastDateMetric,
end: Date())
workoutBuilder.add([cadencePerIntervalSample]) {(success, error) in
if let error = error {
print(error)
}
}
let speedPerInterval = HKQuantity(unit: HKUnit.meter().unitDivided(by: HKUnit.second()),
doubleValue: WorkoutTracking.speed * 0.277778)
guard let speedType = HKQuantityType.quantityType(
forIdentifier: .cyclingSpeed) else {
return
}
let speedPerIntervalSample = HKQuantitySample(type: speedType,
quantity: speedPerInterval,
start: WorkoutTracking.lastDateMetric,
end: Date())
workoutBuilder.add([speedPerIntervalSample]) {(success, error) in
if let error = error {
print(error)
}
}
} else {
// Fallback on earlier versions
}
} else if(sport == 1) {
if #available(watchOSApplicationExtension 10.0, *) {
let wattPerInterval = HKQuantity(unit: HKUnit.watt(),
doubleValue: WorkoutTracking.power)
if(WorkoutTracking.lastDateMetric.distance(to: Date()) < 1) {
return
}
guard let powerType = HKQuantityType.quantityType(
forIdentifier: .runningPower) else {
return
}
let wattPerIntervalSample = HKQuantitySample(type: powerType,
quantity: wattPerInterval,
start: WorkoutTracking.lastDateMetric,
end: Date())
workoutBuilder.add([wattPerIntervalSample]) {(success, error) in
if let error = error {
print(error)
}
}
if #available(watchOSApplicationExtension 10.0, *) {
let wattPerInterval = HKQuantity(unit: HKUnit.watt(),
doubleValue: WorkoutTracking.power)
let speedPerInterval = HKQuantity(unit: HKUnit.meter().unitDivided(by: HKUnit.second()),
doubleValue: WorkoutTracking.speed * 0.277778)
guard let speedType = HKQuantityType.quantityType(
forIdentifier: .runningSpeed) else {
if(WorkoutTracking.lastDateMetric.distance(to: Date()) < 1) {
return
}
let speedPerIntervalSample = HKQuantitySample(type: speedType,
quantity: speedPerInterval,
start: WorkoutTracking.lastDateMetric,
end: Date())
workoutBuilder.add([speedPerIntervalSample]) {(success, error) in
if let error = error {
print(error)
}
}
} else {
// Fallback on earlier versions
}
} else if(sport == 2) {
if #available(watchOSApplicationExtension 10.0, *) {
let speedPerInterval = HKQuantity(unit: HKUnit.meter().unitDivided(by: HKUnit.second()),
doubleValue: WorkoutTracking.speed * 0.277778)
guard let speedType = HKQuantityType.quantityType(
forIdentifier: .walkingSpeed) else {
return
}
let speedPerIntervalSample = HKQuantitySample(type: speedType,
quantity: speedPerInterval,
start: WorkoutTracking.lastDateMetric,
end: Date())
workoutBuilder.add([speedPerIntervalSample]) {(success, error) in
if let error = error {
print(error)
}
}
} else {
// Fallback on earlier versions
guard let powerType = HKQuantityType.quantityType(
forIdentifier: .cyclingPower) else {
return
}
let wattPerIntervalSample = HKQuantitySample(type: powerType,
quantity: wattPerInterval,
start: WorkoutTracking.lastDateMetric,
end: Date())
workoutBuilder.add([wattPerIntervalSample]) {(success, error) in
if let error = error {
print(error)
}
}
let cadencePerInterval = HKQuantity(unit: HKUnit.count().unitDivided(by: HKUnit.second()),
doubleValue: WorkoutTracking.cadence / 60.0)
guard let cadenceType = HKQuantityType.quantityType(
forIdentifier: .cyclingCadence) else {
return
}
let cadencePerIntervalSample = HKQuantitySample(type: cadenceType,
quantity: cadencePerInterval,
start: WorkoutTracking.lastDateMetric,
end: Date())
workoutBuilder.add([cadencePerIntervalSample]) {(success, error) in
if let error = error {
print(error)
}
}
let speedPerInterval = HKQuantity(unit: HKUnit.meter().unitDivided(by: HKUnit.second()),
doubleValue: WorkoutTracking.speed * 0.277778)
guard let speedType = HKQuantityType.quantityType(
forIdentifier: .cyclingSpeed) else {
return
}
let speedPerIntervalSample = HKQuantitySample(type: speedType,
quantity: speedPerInterval,
start: WorkoutTracking.lastDateMetric,
end: Date())
workoutBuilder.add([speedPerIntervalSample]) {(success, error) in
if let error = error {
print(error)
}
}
} else {
// Fallback on earlier versions
}
WorkoutTracking.lastDateMetric = Date()

View File

@@ -1,505 +0,0 @@
# QDomyos-Zwift Guide to Writing Unit Tests
## About
The testing project tst/qdomyos-zwift-tests.pro contains test code that uses the Google Test library.
## Adding a new device
New devices are added to the main QZ application by creating or modifying a subclass of the bluetoothdevice class.
At minimum, each device has a corresponding BluetoothDeviceTestData subclass in the test project, which is coded to provide information to the test framework to generate tests for device detection and potentially other things.
In the test project
* create a new folder for the device under tst/Devices. This is for anything you define for testing this device.
* add a new class with header file and optionally .cpp file to the project in that folder. Name the class DeviceNameTestData, substituting an appropriate name in place of "DeviceName".
* edit the header file to inherit the class from the BluetoothDeviceTestData abstract subclass appropriate to the device type, i.e. BikeTestData, RowerTestData, EllipticalTestData, TreadmillTestData.
* have this new subclass' constructor pass a unique test name to its superclass.
The tests are not organised around real devices that are handled, but the bluetoothdevice subclass that handles them - the "driver" of sorts.
You need to provide the following:
- patterns for valid names (e.g. equals a value, starts with a value, case sensitivity, specific length)
- invalid names to ensure the device is not identified when the name is invalid
- configuration settings that are required for the device to be detected
- invalid configurations to test that the device is not detected, e.g. when it's disabled in the settings, but the name is correct
- exclusion devices: if a device with the same name but of a higher priority type is detected, this device should not be detected
- valid and invalid QBluetoothDeviceInfo configurations, e.g. to check the device is only detected when the manufacturer data is set correctly, or certain services are available or not.
## Tools in the Test Framework
### TestSettings
The detection of many devices depends on settings that are accessed programmatically using the QSettings class and the constants in the QZSettings namespace. The TestSettings class stores a QSettings object with what is intended to be a unique application and organisation name, to keep the configuration it represents seperate from others in the system. It also makes the stored QSettings object the default by setting the QCoreApplication's organisation and application names to those of the QSettings object. The original values are restored by calling the deactivate() function or on object destruction.
i.e. a test will
* apply a configuration from a TestSettings object
* perform device detection
* use the TestSettings object to restore the previous settings either directly or by letting its destructor be called.
### DeviceDiscoveryInfo
This class contains a set of fields that store strongly typed QSettings values.
It also provides methods to read and write the values it knows about from and to a QSettings object.
It is used in conjunction with a TestSettings object to write a configuration during a test.
## Writing a device detection test
Because of the way the TestData classes currently work, it may be necessary to define multiple test data classes to cover the various cases.
For example, if any of a list of names is enough to identify a device, or another group of names but with a certain service in the bluetooth device info, that will require multiple classes.
### Recognition by Name
Consider the detection code for the Domyos Bike:
```
} else if (b.name().startsWith(QStringLiteral("Domyos-Bike")) &&
!b.name().startsWith(QStringLiteral("DomyosBridge")) && !domyosBike && filter) {
```
Reading this, to identify this device:
- bluetooth name should start with "Domyos-Bike" using a case sensitive comparison
- bluetooth name should NOT start with "DomyosBridge", also using a case sensitive comparison
- there should not have been a device using the corresponding device class detected already (i.e. domyos)
- filter has not been activated (this isn't tested)
In this case, we are not testing the last two, but can test the first two.
```
#pragma once
#include "Devices/Bike/biketestdata.h"
#include "devices/domyosbike/domyosbike.h"
class DomyosBikeTestData : public BikeTestData {
public:
DomyosBikeTestData() : BikeTestData("Domyos Bike") {
this->addDeviceName("Domyos-Bike", comparison::StartsWith);
this->addInvalidDeviceName("DomyosBridge", comparison::StartsWith);
}
// not used yet
deviceType get_expectedDeviceType() const override { return deviceType::DomyosBike; }
bool get_isExpectedDevice(bluetoothdevice * detectedDevice) const override {
return dynamic_cast<domyosbike*>(detectedDevice)!=nullptr;
}
};
```
The constructor adds a valid device name, and an invalid one. Various overloads of these methods and other members of the comparison enumeration provide other capabilities for specifying test data. If you add a valid device name that says the name should start with a value, additional names will be added automatically to the valid list with additional characters to test that it is in fact a "starts with" relationship. Also, valid and invalid names will be generated base on whether the comparison is case sensitive or not.
The get_expectedDeviceType() function is not actually used and is part of an unfinished refactoring of the device detection code, whereby the bluetoothdevice object doesn't actually get created intially. You could add a new value to the deviceType enum and return that, but it's not used yet. There's always deviceType::None.
The get_isExpectedDevice(bluetoothdevice *) function must be overridden to indicate if the specified object is of the type expected for this test data.
### Configuration Settings
Consider the CompuTrainerTestData. This device is not detected by name, but only by whether or not it is enabled in the settings.
To specify this in the test data, we override one of the configureSettings methods, the one for the simple case where there is a single valid and a single invalid configuration.
Settings from QSettings that contribute to tests should be put into the DeviceDiscoveryInfo class.
For example, for the Computrainer Bike, the "computrainer_serial_port" value from the QSettings determines if the bike should be detected or not.
```
class DeviceDiscoveryInfo {
public :
...
QString computrainer_serial_port = nullptr;
...
}
```
The getValues and setValues methods should be updated to include the addition(s):
```
void DeviceDiscoveryInfo::setValues(QSettings &settings, bool clear) const {
if(clear) settings.clear();
...
settings.setValue(QZSettings::computrainer_serialport, this->computrainer_serial_port);
...
}
void DeviceDiscoveryInfo::getValues(QSettings &settings){
...
this->computrainer_serial_port = settings.value(QZSettings::computrainer_serialport, QZSettings::default_computrainer_serialport).toString();
...
}
```
In the following example, the DeviceDiscoveryInfo class has been updated to contain the device's configuration setting (computrainer_serial_port).
- if an enabling configuration is requested (enable==true) a string that is known to be accepted is supplied
- if a disabling configuration is requested (enable==false) an empty string is supplied.
This example uses the simpler of 2 configureSettings methods returns true/false to indicate if the configuration should be used for the test.
```
#pragma once
#include "Devices/Bike/biketestdata.h"
#include "devices/computrainerbike/computrainerbike.h"
class CompuTrainerTestData : public BikeTestData {
protected:
bool configureSettings(DeviceDiscoveryInfo& info, bool enable) const override {
info.computrainer_serial_port = enable ? "X":QString();
return true;
}
public:
CompuTrainerTestData() : BikeTestData("CompuTrainer Bike") {
// any name
this->addDeviceName("", comparison::StartsWithIgnoreCase);
}
deviceType get_expectedDeviceType() const override { return deviceType::CompuTrainerBike; }
bool get_isExpectedDevice(bluetoothdevice * detectedDevice) const override {
return dynamic_cast<computrainerbike*>(detectedDevice)!=nullptr;
}
};
```
Similarly, the Pafers Bike has a simple configuration setting:
```
#include "Devices/Bike/biketestdata.h"
#include "devices/pafersbike/pafersbike.h"
class PafersBikeTestData : public BikeTestData {
protected:
bool configureSettings(DeviceDiscoveryInfo& info, bool enable) const override {
// the treadmill is given priority
info.pafers_treadmill = !enable;
return true;
}
public:
PafersBikeTestData() : BikeTestData("Pafers Bike") {
this->addDeviceName("PAFERS_", comparison::StartsWithIgnoreCase);
}
deviceType get_expectedDeviceType() const override { return deviceType::PafersBike; }
bool get_isExpectedDevice(bluetoothdevice * detectedDevice) const override {
return dynamic_cast<pafersbike*>(detectedDevice)!=nullptr;
}
};
```
A more complicated example is the Pafers Treadmill. It involves a name match, but also some configuration settings obtained earlier...
```
bool pafers_treadmill = settings.value(QZSettings::pafers_treadmill, QZSettings::default_pafers_treadmill).toBool();
...
bool pafers_treadmill_bh_iboxster_plus =
settings
.value(QZSettings::pafers_treadmill_bh_iboxster_plus, QZSettings::default_pafers_treadmill_bh_iboxster_plus)
.toBool();
...
} else if (b.name().toUpper().startsWith(QStringLiteral("PAFERS_")) && !pafersTreadmill &&
(pafers_treadmill || pafers_treadmill_bh_iboxster_plus) && filter) {
```
Here the device could be activated due to a name match and various combinations of settings.
For this, the configureSettings function that takes a vector of DeviceDiscoveryInfo objects which is populated with configurations that lead to the specified result (enable = detected, !enable=not detected). Instead of returning a boolean to indicate if a configuration has been supplied, it populates a vector of DeviceDiscoveryInfo objects.
```
#pragma once
#include "Devices/Treadmill/treadmilltestdata.h"
#include "devices/paferstreadmill/paferstreadmill.h"
class PafersTreadmillTestData : public TreadmillTestData {
protected:
void configureSettings(const DeviceDiscoveryInfo& info, bool enable, std::vector<DeviceDiscoveryInfo>& configurations) const override {
DeviceDiscoveryInfo config(info);
if (enable) {
for(int x = 1; x<=3; x++) {
config.pafers_treadmill = x & 1;
config.pafers_treadmill_bh_iboxster_plus = x & 2;
configurations.push_back(config);
}
} else {
config.pafers_treadmill = false;
config.pafers_treadmill_bh_iboxster_plus = false;
configurations.push_back(config);
}
}
public:
PafersTreadmillTestData() : TreadmillTestData("Pafers Treadmill") {
this->addDeviceName("PAFERS_", comparison::StartsWithIgnoreCase);
}
deviceType get_expectedDeviceType() const override { return deviceType::PafersTreadmill; }
bool get_isExpectedDevice(bluetoothdevice * detectedDevice) const override {
return dynamic_cast<paferstreadmill*>(detectedDevice)!=nullptr;
}
};
```
### Considering Extra QBluetoothDeviceInfo Content
Detection of some devices requires some specific bluetooth device information.
Supplying enabling and disabling QBluetoothDeviceInfo objects is done using a similar pattern to the multiple configurations scenario.
For example, the M3iBike requires specific manufacturer information.
```
void M3IBikeTestData::configureBluetoothDeviceInfos(const QBluetoothDeviceInfo& info, bool enable, std::vector<QBluetoothDeviceInfo>& bluetoothDeviceInfos) const {
// The M3I bike detector looks into the manufacturer data.
QBluetoothDeviceInfo result = info;
if(!enable) {
result.setManufacturerData(1, QByteArray("Invalid manufacturer data."));
bluetoothDeviceInfos.push_back(result);
return;
}
int key=0;
result.setManufacturerData(key++, hex2bytes("02010639009F00000000000000000014008001"));
bluetoothDeviceInfos.push_back(result);
}
```
The test framework populates the incoming QBluetoothDeviceInfo object with a name and a UUID. This is expected to have nothing else defined.
Another example is one of the test data classes for detecting a device that uses the statesbike class:
Detection code from bluetooth.cpp:
```
((b.name().toUpper().startsWith("KICKR CORE")) && !deviceHasService(b, QBluetoothUuid((quint16)0x1826)) && deviceHasService(b, QBluetoothUuid((quint16)0x1818)))
```
This condition is actually extracted from a more complicated example where the current test data classes can't cover all the detection criteria in one implementation. This is why this class inherits from StagesBikeTestData rather than BikeTestData directly.
```
class StagesBike3TestData : public StagesBikeTestData {
protected:
void configureBluetoothDeviceInfos(const QBluetoothDeviceInfo& info, bool enable, std::vector<QBluetoothDeviceInfo>& bluetoothDeviceInfos) const override {
// The condition, if the name is acceptable, is:
// !deviceHasService(b, QBluetoothUuid((quint16)0x1826)) && deviceHasService(b, QBluetoothUuid((quint16)0x1818)))
if(enable) {
QBluetoothDeviceInfo result = info;
result.setServiceUuids(QVector<QBluetoothUuid>({QBluetoothUuid((quint16)0x1818)}));
bluetoothDeviceInfos.push_back(result);
} else {
QBluetoothDeviceInfo hasInvalid = info;
hasInvalid.setServiceUuids(QVector<QBluetoothUuid>({QBluetoothUuid((quint16)0x1826)}));
QBluetoothDeviceInfo hasBoth = hasInvalid;
hasBoth.setServiceUuids(QVector<QBluetoothUuid>({QBluetoothUuid((quint16)0x1818),QBluetoothUuid((quint16)0x1826)}));
bluetoothDeviceInfos.push_back(info); // has neither
bluetoothDeviceInfos.push_back(hasInvalid);
bluetoothDeviceInfos.push_back(hasBoth);
}
}
public:
StagesBike3TestData() : StagesBikeTestData("Stages Bike (KICKR CORE)") {
this->addDeviceName("KICKR CORE", comparison::StartsWithIgnoreCase);
}
};
```
In this case, it populates the vector with the single enabling configuration if that's what's been requested, otherwise 3 disabling ones.
### Exclusions
Sometimes there might be ambiguity when multiple devices are available, and the detection code may specify that if the other conditions match, but certain specific kinds of devices (the exclusion devices) have already been detected, the newly matched device should be ignored.
The TestData class can be made to cover this by overriding the configureExclusions() method to add instances of the TestData classes for the exclusion devices to the object's internal list of exclusions.
Detection code:
```
} else if (b.name().startsWith(QStringLiteral("ECH")) && !echelonRower && !echelonStride &&
!echelonConnectSport && filter) {
```
The configureExclusions code is overridden to specify the exclusion test data objects. Note that the test for a previously detected device of the same type is not included.
```
#pragma once
#include "Devices/Bike/biketestdata.h"
#include "Devices/EchelonRower/echelonrowertestdata.h"
#include "Devices/EchelonStrideTreadmill/echelonstridetreadmilltestdata.h"
#include "devices/echelonconnectsport/echelonconnectsport.h"
class EchelonConnectSportBikeTestData : public BikeTestData {
public:
EchelonConnectSportBikeTestData() : BikeTestData("Echelon Connect Sport Bike") {
this->addDeviceName("ECH", comparison::StartsWith);
}
void configureExclusions() override {
this->exclude(new EchelonRowerTestData());
this->exclude(new EchelonStrideTreadmillTestData());
}
deviceType get_expectedDeviceType() const override { return deviceType::EchelonConnectSport; }
bool get_isExpectedDevice(bluetoothdevice * detectedDevice) const override {
return dynamic_cast<echelonconnectsport*>(detectedDevice)!=nullptr;
}
};
```
### When a single TestData Class Can't Cover all the Conditions
Detection code:
```
QString powerSensorName =
settings.value(QZSettings::power_sensor_name, QZSettings::default_power_sensor_name).toString();
...
} else if ((b.name().toUpper().startsWith(QStringLiteral("STAGES ")) ||
(b.name().toUpper().startsWith("TACX SATORI")) ||
((b.name().toUpper().startsWith("KICKR CORE")) && !deviceHasService(b, QBluetoothUuid((quint16)0x1826)) && deviceHasService(b, QBluetoothUuid((quint16)0x1818))) ||
(b.name().toUpper()==QStringLiteral("QD")) ||
(b.name().toUpper().startsWith(QStringLiteral("ASSIOMA")) &&
powerSensorName.startsWith(QStringLiteral("Disabled")))) &&
!stagesBike && !ftmsBike && filter) {
```
This presents 3 scenarios for the current test framework.
1. Match names only (starts with:"STAGES ", starts with: "TACX SATORI", equals: "QD")
2. Match the name "KICKR CORE", presence and absence of specific service ids
3. Match the name "ASSIOMA" and the power sensor name setting starts with "Disabled"
The framework is not currently capable of specifying all these scenarios in a single class.
The generated test data is approximately the combinations of these lists: names * settings * bluetoothdeviceInfo * exclusions.
If a combination should not exist, a separate class should be used.
In the example of the StagesBikeTestData classes, the exclusions, which apply to all situations, are implemented in the superclass StagesBikeTestData,
```
#pragma once
#include "Devices/Bike/biketestdata.h"
#include "devices/stagesbike/stagesbike.h"
#include "Devices/FTMSBike/ftmsbiketestdata.h"
class StagesBikeTestData : public BikeTestData {
protected:
StagesBikeTestData(std::string testName): BikeTestData(testName) {
}
void configureExclusions() override {
this->exclude(new FTMSBike1TestData());
this->exclude(new FTMSBike2TestData());
}
public:
deviceType get_expectedDeviceType() const override { return deviceType::StagesBike; }
bool get_isExpectedDevice(bluetoothdevice * detectedDevice) const override {
return dynamic_cast<stagesbike*>(detectedDevice)!=nullptr;
}
};
```
The name-match only in one subclass:
```
class StagesBike1TestData : public StagesBikeTestData {
public:
StagesBike1TestData() : StagesBikeTestData("Stages Bike") {
this->addDeviceName("STAGES ", comparison::StartsWithIgnoreCase);
this->addDeviceName("TACX SATORI", comparison::StartsWithIgnoreCase);
}
};
```
The name and setting match in another subclass:
```
class StagesBike2TestData : public StagesBikeTestData {
protected:
bool configureSettings(DeviceDiscoveryInfo& info, bool enable) const override {
info.powerSensorName = enable ? "Disabled":"Roberto";
return true;
}
public:
StagesBike2TestData() : StagesBikeTestData("Stages Bike (Assioma / Power Sensor disabled") {
this->addDeviceName("ASSIOMA", comparison::StartsWithIgnoreCase);
}
};
```
The name and bluetooth device info configurations in another:
```
class StagesBike3TestData : public StagesBikeTestData {
protected:
void configureBluetoothDeviceInfos(const QBluetoothDeviceInfo& info, bool enable, std::vector<QBluetoothDeviceInfo>& bluetoothDeviceInfos) const override {
// The condition, if the name is acceptable, is:
// !deviceHasService(b, QBluetoothUuid((quint16)0x1826)) && deviceHasService(b, QBluetoothUuid((quint16)0x1818)))
if(enable) {
QBluetoothDeviceInfo result = info;
result.setServiceUuids(QVector<QBluetoothUuid>({QBluetoothUuid((quint16)0x1818)}));
bluetoothDeviceInfos.push_back(result);
} else {
QBluetoothDeviceInfo hasInvalid = info;
hasInvalid.setServiceUuids(QVector<QBluetoothUuid>({QBluetoothUuid((quint16)0x1826)}));
QBluetoothDeviceInfo hasBoth = hasInvalid;
hasBoth.setServiceUuids(QVector<QBluetoothUuid>({QBluetoothUuid((quint16)0x1818),QBluetoothUuid((quint16)0x1826)}));
bluetoothDeviceInfos.push_back(info); // has neither
bluetoothDeviceInfos.push_back(hasInvalid);
bluetoothDeviceInfos.push_back(hasBoth);
}
}
public:
StagesBike3TestData() : StagesBikeTestData("Stages Bike (KICKR CORE)") {
this->addDeviceName("KICKR CORE", comparison::StartsWithIgnoreCase);
}
};
```
## Telling Google Test Where to Look
To register your test data class(es) with Google Test:
- open tst/Devices/devices.h
- add a #include for your new header file(s)
- add your new classes to the BluetoothDeviceTestDataTypes list.
This will add tests for your new device class to test runs of the tests in the BluetoothDeviceTestSuite class, which are about detecting, and not detecting devices in circumstances generated from the TestData classes.

View File

@@ -1,143 +0,0 @@
import sys
import logging
import asyncio
import threading
import random
import struct
import binascii
from typing import Any, Union
from bless import (
BlessServer,
BlessGATTCharacteristic,
GATTCharacteristicProperties,
GATTAttributePermissions,
)
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(name=__name__)
trigger: Union[asyncio.Event, threading.Event]
if sys.platform in ["darwin", "win32"]:
trigger = threading.Event()
else:
trigger = asyncio.Event()
def read_request(characteristic: BlessGATTCharacteristic, **kwargs) -> bytearray:
logger.debug(f"Reading {characteristic.value}")
return characteristic.value
def write_request(characteristic: BlessGATTCharacteristic, value: Any, **kwargs):
characteristic.value = value
logger.debug(f"Char value set to {characteristic.value}")
if characteristic.value == b"\x0f":
logger.debug("NICE")
trigger.set()
def generate_indoor_bike_data():
# Flags (16 bits)
flags = (1 << 2) | (1 << 6) # Instantaneous Cadence and Instantaneous Power present
speed = random.randint(0, 20000) # 0-20000
# Instantaneous Cadence (uint16, 0.5 rpm resolution)
cadence = random.randint(0, 400) # 0-200 rpm
# Instantaneous Power (sint16, watts)
power = random.randint(10, 50)
# Pack data into bytes
data = struct.pack("<HHHh", flags, speed, cadence, power)
return data
def generate_zwift_ride_data():
data_str = "2308ffbfffff0f1a04080010001a04080110001a04080210001a0408031000"
data = binascii.unhexlify(data_str)
return data
async def update_indoor_bike_data(server, service_uuid, char_uuid):
while True:
c = server.get_characteristic(char_uuid)
c.value = bytes(generate_indoor_bike_data())
server.update_value(service_uuid, char_uuid)
await asyncio.sleep(1)
async def update_zwift_ride_data(server, service_uuid, char_uuid):
while True:
c = server.get_characteristic(char_uuid)
c.value = bytes(generate_zwift_ride_data())
server.update_value(service_uuid, char_uuid)
await asyncio.sleep(1)
async def run(loop):
trigger.clear()
# Instantiate the server
server = BlessServer(name="FTMS Indoor Bike", loop=loop)
server.read_request_func = read_request
server.write_request_func = write_request
# Add Fitness Machine Service
ftms_uuid = "00001826-0000-1000-8000-00805f9b34fb"
await server.add_new_service(ftms_uuid)
# Add Indoor Bike Data Characteristic
indoor_bike_data_uuid = "00002ad2-0000-1000-8000-00805f9b34fb"
char_flags = (
GATTCharacteristicProperties.read
| GATTCharacteristicProperties.notify
)
permissions = GATTAttributePermissions.readable
await server.add_new_characteristic(
ftms_uuid, indoor_bike_data_uuid, char_flags, generate_indoor_bike_data(), permissions
)
zwift_ride_uuid = "00000001-19ca-4651-86e5-fa29dcdd09d1"
await server.add_new_service(zwift_ride_uuid)
syncRxChar = "00000003-19CA-4651-86E5-FA29DCDD09D1"
syncRx_flags = (
GATTCharacteristicProperties.write
)
syncRx_permissions = GATTAttributePermissions.writeable
syncTxChar = "00000004-19CA-4651-86E5-FA29DCDD09D1"
syncTx_flags = (
GATTCharacteristicProperties.read
| GATTCharacteristicProperties.indicate
)
syncTx_permissions = GATTAttributePermissions.readable
asyncChar = "00000002-19CA-4651-86E5-FA29DCDD09D1"
async_flags = (
GATTCharacteristicProperties.read
| GATTCharacteristicProperties.notify
)
async_permissions = GATTAttributePermissions.readable
await server.add_new_characteristic(
zwift_ride_uuid, syncRxChar, syncRx_flags, generate_indoor_bike_data(), syncRx_permissions
)
await server.add_new_characteristic(
zwift_ride_uuid, syncTxChar, syncTx_flags, generate_indoor_bike_data(), syncTx_permissions
)
await server.add_new_characteristic(
zwift_ride_uuid, asyncChar, async_flags, generate_zwift_ride_data(), async_permissions
)
logger.debug(server.get_characteristic(indoor_bike_data_uuid))
await server.start()
logger.debug("Advertising")
logger.info(f"FTMS Indoor Bike is now advertising")
# Start updating the indoor bike data
update_task = asyncio.create_task(update_indoor_bike_data(server, ftms_uuid, indoor_bike_data_uuid))
update_task_zwift_ride = asyncio.create_task(update_zwift_ride_data(server, zwift_ride_uuid, asyncChar))
await asyncio.sleep(99999999)
await server.stop()
loop = asyncio.get_event_loop()
loop.run_until_complete(run(loop))

View File

@@ -1,28 +0,0 @@
import json
def generate_code(hex_string, start_index):
hex_pairs = [hex_string[i:i+2] for i in range(0, len(hex_string), 2)]
output = ""
array_name = f"initData{start_index}"
array_elements = ', '.join([f"0x{hex_pair}" for hex_pair in hex_pairs])
output += f"uint8_t {array_name}[] = {{{array_elements}}};\n"
output += f'writeCharacteristic({array_name}, sizeof({array_name}), QStringLiteral("init"), false, false);\n'
output += "QThread::msleep(sleepms);\n\n"
return output
json_file_path = "C:\\Work\\qdomyos-zwift\\helpers\\tmp.json"
with open(json_file_path, 'r') as file:
# Carica i dati JSON
json_data = json.load(file)
line = 0
for item in json_data:
try:
if(item['_source']['layers']['btatt']['btatt.value_raw'][0] != ''):
line = line + 1
print(generate_code(item['_source']['layers']['btatt']['btatt.value_raw'][0], line))
except:
pass

View File

@@ -329,7 +329,6 @@ public slots:
descData.uuid = QBluetoothUuid(descriptorUuid);
charData.descriptorList.insert(descHandle, descData);
if (descData.uuid == QBluetoothUuid(QBluetoothUuid::ClientCharacteristicConfiguration)) {
mIndicateChars << charData.uuid;
ComPtr<IAsyncOperation<ClientCharConfigDescriptorResult *>> readOp;
hr = characteristic->ReadClientCharacteristicConfigurationDescriptorAsync(&readOp);
WARN_AND_CONTINUE_IF_FAILED(hr, "Could not read descriptor value")
@@ -357,7 +356,7 @@ public slots:
descData.value = QByteArray(2, Qt::Uninitialized);
qToLittleEndian(result, descData.value.data());
mIndicateChars << charData.uuid;
} else {
ComPtr<IAsyncOperation<GattReadResult *>> readOp;
hr = descriptor->ReadValueWithCacheModeAsync(BluetoothCacheMode_Uncached,
@@ -613,7 +612,6 @@ HRESULT QLowEnergyControllerPrivateWinRTNew::onValueChange(IGattCharacteristic *
{
HRESULT hr;
quint16 handle;
qCDebug(QT_BT_WINRT) << __FUNCTION__ << characteristic;
hr = characteristic->get_AttributeHandle(&handle);
RETURN_IF_FAILED("Could not obtain characteristic's handle", return S_OK)
ComPtr<IBuffer> buffer;

View File

@@ -1,61 +0,0 @@
#ifndef CRC16IBM_H
#define CRC16IBM_H
#include <QByteArray>
#include <QDebug>
class CRC16IBM {
public:
// Function to calculate CRC-16 (XMODEM) checksum
static quint16 calculateCRC(const QByteArray &data) {
quint16 crc = 0xFFFF; // Initial value
for (char byte : data) {
quint8 index = (crc >> 8) ^ static_cast<quint8>(byte);
crc = (crc << 8) ^ crc16Table[index];
}
return crc;
}
private:
// Precomputed CRC-16-IBM table
static constexpr quint16 crc16Table[256] = {
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
};
};
#endif // CRC16IBM_H

View File

@@ -5,29 +5,26 @@
<key>AvailableLibraries</key>
<array>
<dict>
<key>BinaryPath</key>
<string>ConnectIQ.framework/ConnectIQ</string>
<key>LibraryIdentifier</key>
<string>ios-arm64</string>
<string>ios-armv7_arm64</string>
<key>LibraryPath</key>
<string>ConnectIQ.framework</string>
<key>SupportedArchitectures</key>
<array>
<string>armv7</string>
<string>arm64</string>
</array>
<key>SupportedPlatform</key>
<string>ios</string>
</dict>
<dict>
<key>BinaryPath</key>
<string>ConnectIQ.framework/ConnectIQ</string>
<key>LibraryIdentifier</key>
<string>ios-arm64_x86_64-simulator</string>
<string>ios-i386_x86_64-simulator</string>
<key>LibraryPath</key>
<string>ConnectIQ.framework</string>
<key>SupportedArchitectures</key>
<array>
<string>arm64</string>
<string>i386</string>
<string>x86_64</string>
</array>
<key>SupportedPlatform</key>

View File

@@ -6,9 +6,9 @@
//
#import <Foundation/Foundation.h>
#import <ConnectIQ/IQConstants.h>
#import <ConnectIQ/IQDevice.h>
#import <ConnectIQ/IQApp.h>
#import "IQConstants.h"
#import "IQDevice.h"
#import "IQApp.h"
// --------------------------------------------------------------------------------
#pragma mark - PUBLIC TYPES

View File

@@ -6,8 +6,8 @@
//
#import <Foundation/Foundation.h>
#import <ConnectIQ/IQDevice.h>
#import <ConnectIQ/IQAppStatus.h>
#import "IQDevice.h"
#import "IQAppStatus.h"
/// @brief Represents an instance of a ConnectIQ app that is installed on a
/// Garmin device.

View File

@@ -13,9 +13,6 @@ extern int const IQSDKVersion;
/// @brief The bundle identifier for the Garmin Connect Mobile app.
extern NSString * const IQGCMBundle;
/// @brief The bundle identifier for the Garmin Connect Mobile Beta app.
extern NSString * const IQGCMInternalBetaBundle;
/// @brief The result of a SendMessage operation
typedef NS_ENUM(NSInteger, IQSendMessageResult){
///! @brief The message was sent successfully.

View File

@@ -6,9 +6,9 @@
//
#import <Foundation/Foundation.h>
#import <ConnectIQ/IQConstants.h>
#import <ConnectIQ/IQDevice.h>
#import <ConnectIQ/IQApp.h>
#import "IQConstants.h"
#import "IQDevice.h"
#import "IQApp.h"
// --------------------------------------------------------------------------------
#pragma mark - PUBLIC TYPES

View File

@@ -6,8 +6,8 @@
//
#import <Foundation/Foundation.h>
#import <ConnectIQ/IQDevice.h>
#import <ConnectIQ/IQAppStatus.h>
#import "IQDevice.h"
#import "IQAppStatus.h"
/// @brief Represents an instance of a ConnectIQ app that is installed on a
/// Garmin device.

View File

@@ -13,9 +13,6 @@ extern int const IQSDKVersion;
/// @brief The bundle identifier for the Garmin Connect Mobile app.
extern NSString * const IQGCMBundle;
/// @brief The bundle identifier for the Garmin Connect Mobile Beta app.
extern NSString * const IQGCMInternalBetaBundle;
/// @brief The result of a SendMessage operation
typedef NS_ENUM(NSInteger, IQSendMessageResult){
///! @brief The message was sent successfully.

View File

@@ -6,11 +6,11 @@
<dict>
<key>Headers/ConnectIQ.h</key>
<data>
yih4e2KjbC/GqavxdCZ3xQ4mHmA=
F1hICh90Ex4ADEjYLcSi0YPhrPA=
</data>
<key>Headers/IQApp.h</key>
<data>
NDlj8k5C84UPFmD+qEMz2WcZloY=
R7+SmeArgBACIBWHRnEAugyFHKE=
</data>
<key>Headers/IQAppStatus.h</key>
<data>
@@ -18,7 +18,7 @@
</data>
<key>Headers/IQConstants.h</key>
<data>
z5FAXaGG7RDVUTai1Vvqs33zc98=
eI7keKSkaajUZACnuMhgtV1RuBA=
</data>
<key>Headers/IQDevice.h</key>
<data>
@@ -26,11 +26,11 @@
</data>
<key>Info.plist</key>
<data>
YUOCJU/YBLc4CRWV1z8JHDjCx8M=
sMY09qXRBL/m1OGNWejLjfNg04w=
</data>
<key>Modules/module.modulemap</key>
<data>
eEyhq/G44PBlD3KiydN8B1vbfCU=
SSRVAtIAdFmowQqE4HzOpWYLubg=
</data>
<key>ar.lproj/IQLocalizable.strings</key>
<dict>
@@ -298,20 +298,32 @@
<dict>
<key>Headers/ConnectIQ.h</key>
<dict>
<key>hash</key>
<data>
F1hICh90Ex4ADEjYLcSi0YPhrPA=
</data>
<key>hash2</key>
<data>
kAenemss8n98vVLi54JqBUtGwaL1/i+HSejFBZgawHA=
ABtgvHbvmly4QpZO/KmmrwYkL0N+AqV3gXdPVrseysY=
</data>
</dict>
<key>Headers/IQApp.h</key>
<dict>
<key>hash</key>
<data>
R7+SmeArgBACIBWHRnEAugyFHKE=
</data>
<key>hash2</key>
<data>
bSRRooQ0FKFr3BgrFolAnkU402889YFHrH+6EEca3cg=
X4vXt0sO9gxQNzQalIaLqMpSGNRC9ue2USDcfjBYkec=
</data>
</dict>
<key>Headers/IQAppStatus.h</key>
<dict>
<key>hash</key>
<data>
WnybOSMMVqCKGns0rEz9C3EfQOg=
</data>
<key>hash2</key>
<data>
tg9qNXtTmFUvNoJtq7O/aEXBNngcGENVRhvxLJ8C/xo=
@@ -319,13 +331,21 @@
</dict>
<key>Headers/IQConstants.h</key>
<dict>
<key>hash</key>
<data>
eI7keKSkaajUZACnuMhgtV1RuBA=
</data>
<key>hash2</key>
<data>
qVLQDlPhVsyAAQ/LCGOCdEOUaabcgwTHijMQiuWbAXM=
bqDpm8yikc2FIqaSUHcLqPY6TPXLlXSUo+Dl9NUYwmA=
</data>
</dict>
<key>Headers/IQDevice.h</key>
<dict>
<key>hash</key>
<data>
bl545C/cu0mw2KlRmzojKmHPom0=
</data>
<key>hash2</key>
<data>
4N4+64IHeb9iBwyziNxo0SMuCM75ez9Em4UfmtgtTHA=
@@ -333,13 +353,21 @@
</dict>
<key>Modules/module.modulemap</key>
<dict>
<key>hash</key>
<data>
SSRVAtIAdFmowQqE4HzOpWYLubg=
</data>
<key>hash2</key>
<data>
6a9Ehz1N4Sm/6qBlTfQpHUqRlpzQr2JMF26AfW4xUtY=
lQGjVO5Q0wfztjETCwDkwAkQ7nZInCgWdStnHL3o6Co=
</data>
</dict>
<key>ar.lproj/IQLocalizable.strings</key>
<dict>
<key>hash</key>
<data>
1CDTE/Qaf1Z/HuhSt9CUnwitv4M=
</data>
<key>hash2</key>
<data>
CWyQue2TCS0heGoGbN4ffetM2QZSk7lqgc2Wer2fgTg=
@@ -349,6 +377,10 @@
</dict>
<key>cs.lproj/IQLocalizable.strings</key>
<dict>
<key>hash</key>
<data>
/jkyQ77G2Xd9wy6QptBphGNbtCY=
</data>
<key>hash2</key>
<data>
1mSn+EYeYcTV1dArgHz7PkmZrV6mHWfnuG5aDa6Y87E=
@@ -358,6 +390,10 @@
</dict>
<key>da.lproj/IQLocalizable.strings</key>
<dict>
<key>hash</key>
<data>
FYi0wjOu/Hw//Qe96yqxSb9yClc=
</data>
<key>hash2</key>
<data>
yLkvGzd+smkOjicvW/+Oe6wGGyirHS+/YfjuSzyVoMM=
@@ -367,6 +403,10 @@
</dict>
<key>de.lproj/IQLocalizable.strings</key>
<dict>
<key>hash</key>
<data>
MitzVbGhXhTLjPvw9vuWcQQa50Q=
</data>
<key>hash2</key>
<data>
DFHv7MWBJmyAkOj993NmSFKbS2t8/vtSev603sBUtjI=
@@ -376,6 +416,10 @@
</dict>
<key>el.lproj/IQLocalizable.strings</key>
<dict>
<key>hash</key>
<data>
n82gLcjjjHszaroTFeJUvSrrc0o=
</data>
<key>hash2</key>
<data>
i4FAK4mi+SgS6oZv8zM74kRZToakn49E8GD7FcJBLoQ=
@@ -385,6 +429,10 @@
</dict>
<key>en.lproj/IQLocalizable.strings</key>
<dict>
<key>hash</key>
<data>
hcxxLyrTI+aElXlPc5dwr7jdqwc=
</data>
<key>hash2</key>
<data>
vmBi9DFJzFcG0OwaWKSDjgklNi407U8u2pz3EnEENN4=
@@ -394,6 +442,10 @@
</dict>
<key>es.lproj/IQLocalizable.strings</key>
<dict>
<key>hash</key>
<data>
ff8DVQtNhO8pF7HFnXjh8foHXbo=
</data>
<key>hash2</key>
<data>
z6RjynaWjrRKHmv4sLirc4eXwKOtQdylzj5+TiHpaTc=
@@ -403,6 +455,10 @@
</dict>
<key>fi.lproj/IQLocalizable.strings</key>
<dict>
<key>hash</key>
<data>
R9cr8yqJmu91Xz31tGyprGR3t/s=
</data>
<key>hash2</key>
<data>
6BI0iPRVWaP63/XFdjLBz6z7DsvvuOoaEAS+mYzrx8E=
@@ -412,6 +468,10 @@
</dict>
<key>fr.lproj/IQLocalizable.strings</key>
<dict>
<key>hash</key>
<data>
PwFmqFeRTcjdHmkXYrPzNVYoe5o=
</data>
<key>hash2</key>
<data>
geXjZzXre2CRiALecPFBGz4JSJA7MbkDnB4qrEMKNwk=
@@ -421,6 +481,10 @@
</dict>
<key>he.lproj/IQLocalizable.strings</key>
<dict>
<key>hash</key>
<data>
/jPUgFtYbbyELG5DZ3Sjoi/If9w=
</data>
<key>hash2</key>
<data>
47mcrSx16SFjWPIiN7guCAG0va8NiJ6I5s45tSVEHlY=
@@ -430,6 +494,10 @@
</dict>
<key>hr.lproj/IQLocalizable.strings</key>
<dict>
<key>hash</key>
<data>
H2GtdTeORRPCnogvpWY69Dg9uME=
</data>
<key>hash2</key>
<data>
4bQvygPax6VBpoFlyS5by1N6otnDMliHu+bWsDaWSQc=
@@ -439,6 +507,10 @@
</dict>
<key>hu.lproj/IQLocalizable.strings</key>
<dict>
<key>hash</key>
<data>
QIimMhNyYmqp4ZW01hfj554WAMg=
</data>
<key>hash2</key>
<data>
0m2fIyz26vh3RlUqqSXvoNTLovxIixrUyJoL/IDSoVk=
@@ -448,6 +520,10 @@
</dict>
<key>id.lproj/IQLocalizable.strings</key>
<dict>
<key>hash</key>
<data>
2/54a0gkcVuk1I3m4ulDAXOLL5o=
</data>
<key>hash2</key>
<data>
hQf9SrG7d8aVWsXIbCIxkKEJjbnW1FLvS+MbOI1VtHQ=
@@ -457,6 +533,10 @@
</dict>
<key>it.lproj/IQLocalizable.strings</key>
<dict>
<key>hash</key>
<data>
hNIKYIcP/87e6g7AUP+zKRtJ52M=
</data>
<key>hash2</key>
<data>
XAbEWX6cicDxGzxGgSx3DhF4rjUHX4LV+dO0X3rUEqc=
@@ -466,6 +546,10 @@
</dict>
<key>ja.lproj/IQLocalizable.strings</key>
<dict>
<key>hash</key>
<data>
0iU2PbJ/3xgXMZ20ffsqaWpxKWc=
</data>
<key>hash2</key>
<data>
YOqOvZq0WEN4DCoSwc0lcTSRc4C812DqzjIsaid1SHg=
@@ -475,6 +559,10 @@
</dict>
<key>ko.lproj/IQLocalizable.strings</key>
<dict>
<key>hash</key>
<data>
ERH8oHR9H9jMHjP0EAgaTtVhnX4=
</data>
<key>hash2</key>
<data>
WJyaRCWn1KqmcDeajRnC41MdNrlpbI+1JbPkXhbKrKY=
@@ -484,6 +572,10 @@
</dict>
<key>ms.lproj/IQLocalizable.strings</key>
<dict>
<key>hash</key>
<data>
DkbQA2+v/qSgQWma/fg3647Bkqs=
</data>
<key>hash2</key>
<data>
gztYxa4Hn58HkKmcUIZI1jCz44IETZeMsqrpZSKxJvc=
@@ -493,6 +585,10 @@
</dict>
<key>nb.lproj/IQLocalizable.strings</key>
<dict>
<key>hash</key>
<data>
T3zFOvuvrJt5Vnmfqt2Mf/du8as=
</data>
<key>hash2</key>
<data>
Oy6UOwSN+/xPIrthAEvzV8PEn27kfsHpMMLU5w1rww0=
@@ -502,6 +598,10 @@
</dict>
<key>nl.lproj/IQLocalizable.strings</key>
<dict>
<key>hash</key>
<data>
t9PD5JEbfoSLaQ7f8M2cLghOReI=
</data>
<key>hash2</key>
<data>
XbijhSaZgmsW59Vo9ZEbhDuUQH18fHizWKzsLosiM0o=
@@ -511,6 +611,10 @@
</dict>
<key>pl.lproj/IQLocalizable.strings</key>
<dict>
<key>hash</key>
<data>
wfTnhBccAm6JfwH/JkZKNRKTUAU=
</data>
<key>hash2</key>
<data>
MQYgqA+Hl03JJ261Q19K5Lt64kSTBP+pfpD+jOVE3AU=
@@ -520,6 +624,10 @@
</dict>
<key>pt-PT.lproj/IQLocalizable.strings</key>
<dict>
<key>hash</key>
<data>
7yXkcZEpJ4UiRHAzhK+vw/Q857Y=
</data>
<key>hash2</key>
<data>
seINq3QazVameLGOW+pIAtGWLa6NDl5XWRtqnObxywo=
@@ -529,6 +637,10 @@
</dict>
<key>pt.lproj/IQLocalizable.strings</key>
<dict>
<key>hash</key>
<data>
tZPncsQs8weCDJa03AKLpijXSUw=
</data>
<key>hash2</key>
<data>
GnzdqEuQwORzVCih99bwr79UHIyzXm+zuN5b9m1NrKY=
@@ -538,6 +650,10 @@
</dict>
<key>ru.lproj/IQLocalizable.strings</key>
<dict>
<key>hash</key>
<data>
Ct+byJ3rWeigvg0q6rB/kQaR+yE=
</data>
<key>hash2</key>
<data>
yCN9s/JXYqsMNZ1icaH4hUwyMQ1NtxOmV6sIAtRd9pc=
@@ -547,6 +663,10 @@
</dict>
<key>sk.lproj/IQLocalizable.strings</key>
<dict>
<key>hash</key>
<data>
1yTM1nAsAYpSH7NrYU6/nFlqk5E=
</data>
<key>hash2</key>
<data>
OFHDtkGLLSfTuSx8GOTycKDCKOKmX0Wh2QG1CHhRz3I=
@@ -556,6 +676,10 @@
</dict>
<key>sv.lproj/IQLocalizable.strings</key>
<dict>
<key>hash</key>
<data>
i84z6vuHLrFpO0qZ2V0zYjixIws=
</data>
<key>hash2</key>
<data>
a3Gk+3USOT5uundOXrNCgnbcD0rDo2lkCO7b7+zg2Is=
@@ -565,6 +689,10 @@
</dict>
<key>th.lproj/IQLocalizable.strings</key>
<dict>
<key>hash</key>
<data>
oW5npy+pDJM1wUOgTkw9FY1Ave4=
</data>
<key>hash2</key>
<data>
qxGqAqRMwm0/dMd0W7DUsvbWb9x65GT+3d1zOQEql1w=
@@ -574,6 +702,10 @@
</dict>
<key>tr.lproj/IQLocalizable.strings</key>
<dict>
<key>hash</key>
<data>
76rD7PLrQMiT5YTlI8IjEFgsiU4=
</data>
<key>hash2</key>
<data>
Y6TnKQmqO/TAx+0KYqRRG6UOz7I/gM1YmbUwgSfZSQU=
@@ -583,6 +715,10 @@
</dict>
<key>zh-Hans.lproj/IQLocalizable.strings</key>
<dict>
<key>hash</key>
<data>
DNlMxUKypOvKArzi7ioJUiFfFXg=
</data>
<key>hash2</key>
<data>
BI3m4MTMHuPI4sQKPGeQnxIlBJJrXwgVuR7Ho1Q5o6Y=
@@ -592,6 +728,10 @@
</dict>
<key>zh-Hant.lproj/IQLocalizable.strings</key>
<dict>
<key>hash</key>
<data>
U6I+uL07KIv2b77w0c0glaJlhMg=
</data>
<key>hash2</key>
<data>
14dQnjX3pEz2Um4J/fOdQDRe/LSuXxqkg1hEkO8E5ys=

Some files were not shown because too many files have changed in this diff Show More