diff --git a/src/Gui/GcCrashDialog.cpp b/src/Gui/GcCrashDialog.cpp index eb19ba1c5..a7b1ce84d 100644 --- a/src/Gui/GcCrashDialog.cpp +++ b/src/Gui/GcCrashDialog.cpp @@ -63,10 +63,6 @@ #include "kqoauthmanager.h" #endif -#ifdef GC_HAVE_WFAPI -#include "WFApi.h" -#endif - #ifdef GC_HAVE_SAMPLERATE #include #endif @@ -266,12 +262,6 @@ QString GcCrashDialog::versionHTML() vlc = "yes"; #endif - #ifdef GC_HAVE_WFAPI - QString wfapi = WFApi::getInstance()->apiVersion(); - #else - QString wfapi = QString("none"); - #endif - #ifdef GC_HAVE_SAMPLERATE QString src = QString(src_get_version()).mid(14,6); #else @@ -332,7 +322,6 @@ QString GcCrashDialog::versionHTML() .arg(ical) .arg(usbxpress) .arg(libusb) - .arg(wfapi) .arg(vlc) #if defined GC_VIDEO_QUICKTIME .arg("quicktime") diff --git a/src/Gui/MainWindow.cpp b/src/Gui/MainWindow.cpp index 6d7cf97ca..25744bce0 100644 --- a/src/Gui/MainWindow.cpp +++ b/src/Gui/MainWindow.cpp @@ -108,10 +108,6 @@ // LTM CHART DRAG/DROP PARSE #include "LTMChartParser.h" -#ifdef GC_HAVE_WFAPI -#include "WFApi.h" -#endif - // CloudDB #ifdef GC_HAS_CLOUD_DB #include "CloudDBCommon.h" @@ -155,10 +151,6 @@ MainWindow::MainWindow(const QDir &home) setContentsMargins(0,0,0,0); setAcceptDrops(true); - #ifdef GC_HAVE_WFAPI - WFApi *w = WFApi::getInstance(); // ensure created on main thread - w->apiVersion();//shutup compiler - #endif Library::initialise(context->athlete->home->root()); QNetworkProxyQuery npq(QUrl("http://www.google.com")); QList listOfProxies = QNetworkProxyFactory::systemProxyForQuery(npq); diff --git a/src/Train/AddDeviceWizard.cpp b/src/Train/AddDeviceWizard.cpp index 6e848d004..f38fc76d9 100644 --- a/src/Train/AddDeviceWizard.cpp +++ b/src/Train/AddDeviceWizard.cpp @@ -153,12 +153,6 @@ DeviceScanner::run() active = true; bool result = false; -#ifdef GC_HAVE_WFAPI - void *pool; - // get an autorelease pool for this thread! - if (wizard->deviceTypes.Supported[wizard->current].connector == DEV_BTLE) pool = WFApi::getInstance()->getPool(); -#endif - for (int i=0; active && !result && i<10; i++) { // search for longer // better to wait a while, esp. if its just a USB device @@ -170,10 +164,6 @@ DeviceScanner::run() result = quickScan(false); } if (active) emit finished(result); // only signal if we weren't aborted! - -#ifdef GC_HAVE_WFAPI - WFApi::getInstance()->freePool(pool); -#endif } void @@ -208,8 +198,7 @@ DeviceScanner::quickScan(bool deep) // scan quickly or if true scan forever, as #endif case DEV_NULL : wizard->controller = new NullController(NULL, NULL); break; case DEV_ANTLOCAL : wizard->controller = new ANTlocalController(NULL, NULL); break; -#ifdef GC_HAVE_WFAPI - case DEV_KICKR : wizard->controller = new KickrController(NULL, NULL); break; +#ifdef QT_BLUETOOTH_LIB case DEV_BT40 : wizard->controller = new BT40Controller(NULL, NULL); break; #endif @@ -260,12 +249,6 @@ DeviceScanner::quickScan(bool deep) // scan quickly or if true scan forever, as } while (!isfound && deep && count++ < 2); -#ifdef GC_HAVE_WFAPI - // save away the device UUID, so we can choose it when connecting. - if (isfound && wizard->deviceTypes.Supported[wizard->current].connector == DEV_BTLE) - wizard->portSpec = ((KickrController*)(wizard->controller))->id(); -#endif - return isfound; } @@ -453,7 +436,6 @@ AddSearch::nextId() const case DEV_ANTLOCAL : return 50; break; // pair case DEV_BT40 : return 55; break; // pair BT devices default: - case DEV_KICKR : case DEV_CT : return 60; break; // confirm and add case DEV_MONARK : return 60; break; // confirm and add case DEV_KETTLER : return 60; break; // confirm and add @@ -887,10 +869,6 @@ AddPairBTLE::cleanupPage() void AddPairBTLE::initializePage() { -#ifdef GC_HAVE_WFAPI -qDebug()<<"found this many devices:"<deviceCount(); -#endif - // setup the controller and start it off so we can // manipulate it if (wizard->controller) delete wizard->controller; diff --git a/src/Train/AddDeviceWizard.h b/src/Train/AddDeviceWizard.h index 19fc6713a..576bc1822 100644 --- a/src/Train/AddDeviceWizard.h +++ b/src/Train/AddDeviceWizard.h @@ -24,8 +24,7 @@ #include "DeviceTypes.h" #include "Serial.h" #include "RealtimeController.h" -#ifdef GC_HAVE_WFAPI -#include "KickrController.h" +#ifdef QT_BLUETOOTH_LIB #include "BT40Controller.h" #endif #ifdef GC_HAVE_LIBUSB diff --git a/src/Train/BT40.cpp b/src/Train/BT40.cpp deleted file mode 100644 index dc8356795..000000000 --- a/src/Train/BT40.cpp +++ /dev/null @@ -1,276 +0,0 @@ -/* - * Copyright (c) 2013 Mark Liversedge (liversedge@gmail.com) - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., 51 - * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "BT40.h" - -BT40::BT40(QObject *parent, DeviceConfiguration *devConf) : QThread(parent) -{ - this->parent = parent; - this->devConf = devConf; - scanned = false; - mode = -1; - load = 100; - slope = 1.0; - - connect(WFApi::getInstance(), SIGNAL(discoveredDevices(int,bool)), this, SLOT(discoveredDevices(int,bool))); -} - -BT40::~BT40() -{ - stop(); -} - -// not required -void BT40::setDevice(QString) { } - -void BT40::setMode(int mode, double load, double gradient) -{ - pvars.lock(); - this->mode = mode; - this->load = load; - this->slope = gradient; - pvars.unlock(); -} - -void BT40::setLoad(double load) -{ - pvars.lock(); - if (load > 1500) load = 1500; - if (load < 50) load = 50; - this->load = load; - pvars.unlock(); -} - -void BT40::setGradient(double gradient) -{ - pvars.lock(); - this->slope = gradient; - pvars.unlock(); -} - - -int BT40::getMode() -{ - int tmp; - pvars.lock(); - tmp = mode; - pvars.unlock(); - return tmp; -} - -double BT40::getLoad() -{ - double tmp; - pvars.lock(); - tmp = load; - pvars.unlock(); - return tmp; -} - -double BT40::getGradient() -{ - double tmp; - pvars.lock(); - tmp = slope; - pvars.unlock(); - return tmp; -} - -void -BT40::getRealtimeData(RealtimeData &rtData) -{ - pvars.lock(); - rtData = rt; - pvars.unlock(); -} - -int -BT40::start() -{ - QThread::start(); - return 0; -} - -// does nothing - neither does pause -int BT40::restart() { return 0; } -int BT40::pause() { return 0; } - -int BT40::stop() -{ - running = false; - return 0; -} - -// used by thread to set variables and emit event if needed -// on unexpected exit -int BT40::quit(int code) -{ - // event code goes here! - exit(code); - return 0; // never gets here obviously but shuts up the compiler! -} - -/*---------------------------------------------------------------------- - * MAIN THREAD - READS TELEMETRY AND UPDATES LOAD/GRADIENT ON KICKR - *----------------------------------------------------------------------*/ -void BT40::run() -{ - int currentmode = -1; - int currentload = -1; - double currentslope= -1; - - // Connect to the device - if (connectBT40()) { - quit(2); - return; // open failed! - } - - running = true; - while(running) { - - // only get busy if we're actually connected - if (WFApi::getInstance()->isConnected(sd)) { - - // We ALWAYS set load for each loop. This is because - // even though the device reports as connected we need - // to wait before it really is. So we just keep on - // sending the current mode/load. It doesn't cost us - // anything since all devices are powered. - - // it does generate a few error messages though.. - // and the connection takes about 25 secs to get - // up to speed. - - // set load - reset it if generated watts don't match .. - if (mode == RT_MODE_ERGO) { - WFApi::getInstance()->setErgoMode(sd); - WFApi::getInstance()->setLoad(sd, load); - currentload = load; - currentmode = mode; - } - - // set slope - if (mode == RT_MODE_SLOPE && currentslope) { - WFApi::getInstance()->setSlopeMode(sd); - WFApi::getInstance()->setSlope(sd, slope); - currentslope = slope; - currentmode = mode; - } - } - - if (WFApi::getInstance()->hasData(sd)) { - pvars.lock(); - WFApi::getInstance()->getRealtimeData(sd, &rt); - - // set speed from wheelRpm and configured wheelsize - double x = rt.getWheelRpm(); - if (devConf) rt.setSpeed(x * devConf->wheelSize / 1000 * 60 / 1000); - else rt.setSpeed(x * 2.10 * 60 / 1000); - pvars.unlock(); - } - - // lets not hog cpu - msleep(100); - } - - disconnectBT40(); - quit(0); -} - -void -BT40::discoveredDevices(int n, bool finished) -{ - WFApi *w = WFApi::getInstance(); - - // need to emit signal with device uuid and type - // this is used by the add device wizard. - // but only emit as they are found, not at the end - // when search times out -- we want them as they - // arrive. - if (!finished && w->deviceSubType(n-1) != WFApi::WF_SENSOR_SUBTYPE_BIKE_POWER_KICKR) { - - for(int i=0; ideviceUUID(i) - <deviceType(i); - emit foundDevice(w->deviceUUID(i), w->deviceType(i)); - } - } -} - -bool -BT40::find() -{ - WFApi *w = WFApi::getInstance(); - - // do we even have BTLE hardware available? - if (w->isBTLEEnabled() ==false) { - - // lets try and enable it - // won't complete for a while but hopefully before next attempt to find is made - // by user or device scanner in AddDeviceWizard - w->enableBTLE(true, false); - - return false; - } - - // can we kick off a search? - if (w->discoverDevicesOfType(WFApi::WF_SENSORTYPE_NONE) == false) return false; - - // wait for it to return something, anything - QEventLoop loop; - connect(w, SIGNAL(discoverFinished()), &loop, SLOT(quit())); - loop.exec(); - - scanned = true; - - // what did we get? - if (w->deviceCount()) { - deviceUUID = w->deviceUUID(0); - return true; - } else return false; -} - -int -BT40::connectBT40() -{ - // get a pool for this thread - pool = WFApi::getInstance()->getPool(); - sd = WFApi::getInstance()->connectDevice(devConf->portSpec); - return 0; -} - -int -BT40::disconnectBT40() -{ - // disconnect - WFApi::getInstance()->disconnectDevice(sd); - connected = false; - - // clear that pool now we're done - WFApi::getInstance()->freePool(pool); - - return 0; -} - -// check to see of there is a port at the device specified -// returns true if the device exists and false if not -bool BT40::discover(QString) -{ - return false; -} diff --git a/src/Train/BT40.h b/src/Train/BT40.h deleted file mode 100644 index bca194620..000000000 --- a/src/Train/BT40.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (c) 2013 Mark Liversedge (liversedge@gmail.com) - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., 51 - * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef _GC_BT40_h -#define _GC_BT40_h 1 -#include "GoldenCheetah.h" - -#include -#include -#include -#include -#include -#include "RealtimeController.h" -#include "TrainSidebar.h" -#include "DeviceConfiguration.h" - -#include "WFApi.h" - -class BT40 : public QThread -{ - Q_OBJECT - -public: - BT40(QObject *parent=0, DeviceConfiguration * devConf=0); // pass device - ~BT40(); - - QObject *parent; - - // HIGH-LEVEL FUNCTIONS - int start(); // Calls QThread to start - int restart(); // restart after paused - int pause(); // pauses data collection, inbound telemetry is discarded - int stop(); // stops data collection thread - int quit(int error); // called by thread before exiting - bool discover(QString deviceFilename); // confirm CT is attached to device - - // SET - void setDevice(QString deviceFilename); // setup the device filename - void setLoad(double load); // set the load to generate in ERGOMODE - void setGradient(double gradient); // set the load to generate in SSMODE - void setMode(int mode, - double load=100, // set mode to CT_ERGOMODE or CT_SSMODE - double gradient=1); - - bool find(); - int connectBT40(); - int disconnectBT40(); - - int getMode(); - double getGradient(); - double getLoad(); - void getRealtimeData(RealtimeData &rtData); - - QString id() { return deviceUUID; } - -signals: - void foundDevice(QString uuid, int type); - -private slots: - void discoveredDevices(int,bool); - -private: - void run(); // called by start to kick off the CT comtrol thread - - // device configuration - DeviceConfiguration *devConf; - - // Mutex for controlling accessing private data - QMutex pvars; - - bool scanned, running, connected; - - volatile int mode; - volatile double load; - volatile double slope; - - QString deviceUUID; - int sd; // sensor descriptor aka an index into the connections array - // mimics the fd index used by open/close syscalls. - RealtimeData rt; - - void *pool; -}; - -#endif // _GC_BT40_h - diff --git a/src/Train/DeviceTypes.cpp b/src/Train/DeviceTypes.cpp index a620a24bf..1946018c7 100644 --- a/src/Train/DeviceTypes.cpp +++ b/src/Train/DeviceTypes.cpp @@ -42,15 +42,10 @@ DeviceTypes::DeviceTypes() "speed or cadence meters via a Garmin ANT+ USB1 or USB2 stick") , ":images/devices/garminusb.png" }, #endif -#ifdef GC_HAVE_WFAPI #if 0 //!!! Deferred until v3.1 or as an update to v3.0 when Wahoo support ANT+ { DEV_BT40, DEV_BTLE, (char *) "Bluetooth 4.0", true, false, tr("Bluetooth Low Energy devices such as KK Inride, Stages PM, Blue HR and Blue SC"), ":images/devices/btle.png" }, -#endif - { DEV_KICKR, DEV_BTLE, (char *) "Wahoo Kickr", true, false, - tr("The Wahoo Fitness Kickr cycling trainer via its Bluetooth smart interface. "), - ":images/devices/kickr.png" }, #endif { DEV_CT, DEV_SERIAL, (char *) "Racermate Computrainer",true, false, tr("Racermate Computrainer Lab or Pro bike trainer with the handlebar controller " diff --git a/src/Train/DeviceTypes.h b/src/Train/DeviceTypes.h index 56dccde26..d958c4197 100644 --- a/src/Train/DeviceTypes.h +++ b/src/Train/DeviceTypes.h @@ -34,8 +34,7 @@ #define DEV_GSERVER 0x0100 // NOT IMPLEMENTED IN THIS RELEASE XXX #define DEV_GCLIENT 0x0200 // NOT IMPLEMENTED IN THIS RELEASE XXX #define DEV_FORTIUS 0x0800 // Tacx Fortius -#define DEV_KICKR 0x1000 // Wahoo Kickr -#define DEV_BT40 0x2000 // Wahoo Kickr +#define DEV_BT40 0x2000 // QT Bluetooth support #define DEV_MONARK 0x4000 // Monark USB #define DEV_KETTLER 0x8000 // Kettler Serial diff --git a/src/Train/Kickr.cpp b/src/Train/Kickr.cpp deleted file mode 100644 index 495d5c800..000000000 --- a/src/Train/Kickr.cpp +++ /dev/null @@ -1,274 +0,0 @@ -/* - * Copyright (c) 2013 Mark Liversedge (liversedge@gmail.com) - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., 51 - * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "Kickr.h" - -Kickr::Kickr(QObject *parent, DeviceConfiguration *devConf) : QThread(parent) -{ - this->parent = parent; - this->devConf = devConf; - scanned = false; - mode = -1; - load = 100; - slope = 1.0; - - connect(WFApi::getInstance(), SIGNAL(discoveredDevices(int,bool)), this, SLOT(discoveredDevices(int,bool))); -} - -Kickr::~Kickr() -{ -} - -// not required -void Kickr::setDevice(QString) { } - -void Kickr::setMode(int mode, double load, double gradient) -{ - pvars.lock(); - this->mode = mode; - this->load = load; - this->slope = gradient; - pvars.unlock(); -} - -void Kickr::setLoad(double load) -{ - pvars.lock(); - if (load > 1500) load = 1500; - if (load < 50) load = 50; - this->load = load; - pvars.unlock(); -} - -void Kickr::setGradient(double gradient) -{ - pvars.lock(); - this->slope = gradient; - pvars.unlock(); -} - - -int Kickr::getMode() -{ - int tmp; - pvars.lock(); - tmp = mode; - pvars.unlock(); - return tmp; -} - -double Kickr::getLoad() -{ - double tmp; - pvars.lock(); - tmp = load; - pvars.unlock(); - return tmp; -} - -double Kickr::getGradient() -{ - double tmp; - pvars.lock(); - tmp = slope; - pvars.unlock(); - return tmp; -} - -void -Kickr::getRealtimeData(RealtimeData &rtData) -{ - pvars.lock(); - rtData = rt; - pvars.unlock(); -} - -int -Kickr::start() -{ - QThread::start(); - return 0; -} - -// does nothing - neither does pause -int Kickr::restart() { return 0; } -int Kickr::pause() { return 0; } - -int Kickr::stop() -{ - running = false; - return 0; -} - -// used by thread to set variables and emit event if needed -// on unexpected exit -int Kickr::quit(int code) -{ - // event code goes here! - exit(code); - return 0; // never gets here obviously but shuts up the compiler! -} - -/*---------------------------------------------------------------------- - * MAIN THREAD - READS TELEMETRY AND UPDATES LOAD/GRADIENT ON KICKR - *----------------------------------------------------------------------*/ -void Kickr::run() -{ - int currentmode = -1; - int currentload = -1; - double currentslope= -1; - - // Connect to the device - if (connectKickr()) { - quit(2); - return; // open failed! - } - - int connectionloops =0; - - running = true; - while(running) { - - // only get busy if we're actually connected - if (WFApi::getInstance()->isConnected(sd)) { - - connectionloops = 0; - - // We ALWAYS set load for each loop. This is because - // even though the device reports as connected we need - // to wait before it really is. So we just keep on - // sending the current mode/load. It doesn't cost us - // anything since all devices are powered. - - // it does generate a few error messages though.. - // and the connection takes about 25 secs to get - // up to speed. - - // set load - reset it if generated watts don't match .. - if (mode == RT_MODE_ERGO) { - WFApi::getInstance()->setErgoMode(sd); - WFApi::getInstance()->setLoad(sd, load); - currentload = load; - currentmode = mode; - } - - // set slope - if (mode == RT_MODE_SLOPE && currentslope) { - WFApi::getInstance()->setSlopeMode(sd); - WFApi::getInstance()->setSlope(sd, slope); - currentslope = slope; - currentmode = mode; - } - - // get telemetry - if (WFApi::getInstance()->hasData(sd)) { - pvars.lock(); - WFApi::getInstance()->getRealtimeData(sd, &rt); - - // set speed from wheelRpm and configured wheelsize - double x = rt.getWheelRpm(); - if (devConf) rt.setSpeed(x * devConf->wheelSize / 1000 * 60 / 1000); - else rt.setSpeed(x * 2.10 * 60 / 1000); - pvars.unlock(); - } - - } else { - // 100ms in each loop, 30secs is 300 loops - if (++connectionloops > 300) { - // give up waiting for connection - quit(-1); - } - } - // lets not hog cpu - msleep(100); - } - - disconnectKickr(); - quit(0); -} - -void -Kickr::discoveredDevices(int n, bool finished) -{ - WFApi *w = WFApi::getInstance(); - - // need to emit signal with device uuid and type - // this is used by the add device wizard. - // but only emit as they are found, not at the end - // when search times out -- we want them as they - // arrive. - if (!finished && w->deviceSubType(n-1) == WFApi::WF_SENSOR_SUBTYPE_BIKE_POWER_KICKR) { - qDebug()<<"KIKCR? discovered a device.." - <deviceUUID(n-1) - <deviceType(n-1); - emit foundDevice(w->deviceUUID(n-1), w->deviceType(n-1)); - } -} - -bool -Kickr::find() -{ - WFApi *w = WFApi::getInstance(); - - if (w->discoverDevicesOfType(WFApi::WF_SENSORTYPE_BIKE_POWER) == false) return false; - - QEventLoop loop; - connect(w, SIGNAL(discoveredDevices(int,bool)), &loop, SLOT(quit())); - loop.exec(); - - scanned = true; - - if (w->deviceCount()) { - deviceUUID = w->deviceUUID(0); - return true; - } else return false; -} - -int -Kickr::connectKickr() -{ - // is BTLE even enabled? - if (WFApi::getInstance()->isBTLEEnabled() == false) return -1; - - // get a pool for this thread - pool = WFApi::getInstance()->getPool(); - - // kick off connection and assume it is gonna be ok - sd = WFApi::getInstance()->connectDevice(devConf->portSpec); - return 0; -} - -int -Kickr::disconnectKickr() -{ - // disconnect - WFApi::getInstance()->disconnectDevice(sd); - connected = false; - - // clear that pool now we're done - WFApi::getInstance()->freePool(pool); - - return 0; -} - -// check to see of there is a port at the device specified -// returns true if the device exists and false if not -bool Kickr::discover(QString) -{ - return false; -} diff --git a/src/Train/Kickr.h b/src/Train/Kickr.h deleted file mode 100644 index 2480c4b4a..000000000 --- a/src/Train/Kickr.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (c) 2013 Mark Liversedge (liversedge@gmail.com) - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., 51 - * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef _GC_Kickr_h -#define _GC_Kickr_h 1 -#include "GoldenCheetah.h" - -#include -#include -#include -#include -#include -#include "RealtimeController.h" -#include "TrainSidebar.h" -#include "DeviceConfiguration.h" - -#include "WFApi.h" - -class Kickr : public QThread -{ - Q_OBJECT - -public: - Kickr(QObject *parent=0, DeviceConfiguration * devConf=0); // pass device - ~Kickr(); - - QObject *parent; - - // HIGH-LEVEL FUNCTIONS - int start(); // Calls QThread to start - int restart(); // restart after paused - int pause(); // pauses data collection, inbound telemetry is discarded - int stop(); // stops data collection thread - int quit(int error); // called by thread before exiting - bool discover(QString deviceFilename); // confirm CT is attached to device - - // SET - void setDevice(QString deviceFilename); // setup the device filename - void setLoad(double load); // set the load to generate in ERGOMODE - void setGradient(double gradient); // set the load to generate in SSMODE - void setMode(int mode, - double load=100, // set mode to CT_ERGOMODE or CT_SSMODE - double gradient=1); - - bool find(); - int connectKickr(); - int disconnectKickr(); - - int getMode(); - double getGradient(); - double getLoad(); - void getRealtimeData(RealtimeData &rtData); - - QString id() { return deviceUUID; } - -signals: - void foundDevice(QString uuid, int type); - -private slots: - void discoveredDevices(int,bool); - -private: - void run(); // called by start to kick off the CT comtrol thread - - // device configuration - DeviceConfiguration *devConf; - - // Mutex for controlling accessing private data - QMutex pvars; - - bool scanned, running, connected; - - volatile int mode; - volatile double load; - volatile double slope; - - QString deviceUUID; - int sd; // sensor descriptor aka an index into the connections array - // mimics the fd index used by open/close syscalls. - RealtimeData rt; - - void *pool; -}; - -#endif // _GC_Kickr_h - diff --git a/src/Train/KickrController.cpp b/src/Train/KickrController.cpp deleted file mode 100644 index c5c070b70..000000000 --- a/src/Train/KickrController.cpp +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (c) 2013 Mark Liversedge (liversedge@gmail.com) - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., 51 - * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include "KickrController.h" -#include "RealtimeData.h" - -KickrController::KickrController(TrainSidebar *parent, DeviceConfiguration *dc) : RealtimeController(parent, dc) -{ - myKickr = new Kickr(parent, dc); - connect(myKickr, SIGNAL(foundDevice(QString,int)), this, SIGNAL(foundDevice(QString,int))); -} - -void -KickrController::setDevice(QString) -{ - // not required -} - -int -KickrController::start() -{ - myKickr->start(); - return 0; -} - - -int -KickrController::restart() -{ - return myKickr->restart(); -} - - -int -KickrController::pause() -{ - return myKickr->pause(); -} - - -int -KickrController::stop() -{ - return myKickr->stop(); -} - -bool -KickrController::find() -{ - return myKickr->find(); -} - -bool -KickrController::discover(QString name) -{ - return myKickr->discover(name); -} - - -bool KickrController::doesPush() { return false; } -bool KickrController::doesPull() { return true; } -bool KickrController::doesLoad() { return true; } - -/* - * gets called from the GUI to get updated telemetry. - * so whilst we are at it we check button status too and - * act accordingly. - * - */ -void -KickrController::getRealtimeData(RealtimeData &rtData) -{ - if(!myKickr->isRunning()) - { - QMessageBox msgBox; - msgBox.setText(tr("Cannot Connect to Kickr")); - msgBox.setIcon(QMessageBox::Critical); - msgBox.exec(); - parent->Stop(1); - return; - } - // get latest telemetry - myKickr->getRealtimeData(rtData); - processRealtimeData(rtData); -} - -void KickrController::pushRealtimeData(RealtimeData &) { } // update realtime data with current values diff --git a/src/Train/KickrController.h b/src/Train/KickrController.h deleted file mode 100644 index 2f065c271..000000000 --- a/src/Train/KickrController.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2011 Mark Liversedge (liversedge@gmail.com) - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., 51 - * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ -#include "GoldenCheetah.h" - -#include "RealtimeController.h" -#include "DeviceConfiguration.h" -#include "ConfigDialog.h" - -#include "Kickr.h" - -#ifndef _GC_KickrController_h -#define _GC_KickrController_h 1 - -class KickrController : public RealtimeController -{ - Q_OBJECT - -public: - KickrController (TrainSidebar *parent =0, DeviceConfiguration *dc =0); - - Kickr *myKickr; // the device itself - - int start(); - int restart(); // restart after paused - int pause(); // pauses data collection, inbound telemetry is discarded - int stop(); // stops data collection thread - - bool find(); - bool discover(QString name); - void setDevice(QString); - - // telemetry push pull - bool doesPush(), doesPull(), doesLoad(); - void getRealtimeData(RealtimeData &rtData); - void pushRealtimeData(RealtimeData &rtData); - - void setLoad(double x) { myKickr->setLoad(x); } - void setGradient(double x) { myKickr->setGradient(x); } - void setMode(int x) { myKickr->setMode(x); } - - QString id() { return myKickr->id(); } - -signals: - void foundDevice(QString uuid, int type); - -private: - -}; - -#endif // _GC_KickrController_h diff --git a/src/Train/TrainSidebar.cpp b/src/Train/TrainSidebar.cpp index 85d427223..facc05606 100644 --- a/src/Train/TrainSidebar.cpp +++ b/src/Train/TrainSidebar.cpp @@ -46,8 +46,8 @@ #endif #include "ANTlocalController.h" #include "NullController.h" -#ifdef GC_HAVE_WFAPI -#include "KickrController.h" +#ifdef QT_BLUETOOTH_LIB +#include "BT40Controller.h" #endif #ifdef GC_HAVE_LIBUSB #include "FortiusController.h" @@ -641,9 +641,9 @@ TrainSidebar::configChanged(qint32) Devices[i].controller = new ANTlocalController(this, &Devices[i]); // connect slot for receiving remote control commands connect(Devices[i].controller, SIGNAL(remoteControl(uint16_t)), this, SLOT(remoteControl(uint16_t))); -#ifdef GC_HAVE_WFAPI - } else if (Devices.at(i).type == DEV_KICKR) { - Devices[i].controller = new KickrController(this, &Devices[i]); +#ifdef QT_BLUETOOTH_LIB + } else if (Devices.at(i).type == DEV_BT40) { + Devices[i].controller = new BT40Controller(this, &Devices[i]); #endif } } diff --git a/src/Train/WFApi.h b/src/Train/WFApi.h deleted file mode 100644 index 1c4e47a00..000000000 --- a/src/Train/WFApi.h +++ /dev/null @@ -1,226 +0,0 @@ -/* - * Copyright (c) 2013 Mark Liversedge (liversedge@gmail.com) - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRWFApiY; without even the implied warranty of MERCHWFApiABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., 51 - * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef gc_WFApi_h -#define gc_WFApi_h - -// GC -#include "GoldenCheetah.h" -#include "Settings.h" -#include "RealtimeData.h" -#include "DeviceConfiguration.h" -#include "RealtimeData.h" - -// QT -#include -#include - -// global singleton -class WFApi; -extern WFApi *_gc_wfapi; - -// declare the provate implementation for objc -#ifdef __OBJC__ -@class WFBridge; -#else -// irritating dependencies -#endif - -class WFApi : public QObject // QOBject for signals -{ - Q_OBJECT - -public: - WFApi(); // single instance - ~WFApi(); - - static WFApi *getInstance() { if (_gc_wfapi) return _gc_wfapi; - else return (_gc_wfapi = new WFApi); } // singleton - - // what version? - QString apiVersion(); - - // status of BTLE - bool hasBTLESupport(); - bool isBTLEEnabled(); - bool enableBTLE(bool enable, bool bondingmode); - bool isCommunicationHWReady(); - - // we don't use the WF API header "hardware_connector_types.h" because it - // references Objc types (NSUInteger) that fail when compiling C++. - // Instead we redeclare them here, but only the ones we absolutely need - // and hopefully they won't change too often - - // current state - typedef enum { - WFAPI_HWCONN_STATE_NOT_CONNECTED = 0, - WFAPI_HWCONN_STATE_CONNECTED = 0x01, - WFAPI_HWCONN_STATE_ACTIVE = 0x02, - WFAPI_HWCONN_STATE_RESET = 0x04, - WFAPI_HWCONN_STATE_BT40_ENABLED = 0x08, - WFAPI_HWCONN_STATE_BT_BONDING_MODE = 0x10 } _state; - int currentState(); - - // connection state - typedef enum { - WF_SENSOR_CONNECTION_STATUS_IDLE = 0, - WF_SENSOR_CONNECTION_STATUS_CONNECTING = 1, - WF_SENSOR_CONNECTION_STATUS_CONNECTED = 2, - WF_SENSOR_CONNECTION_STATUS_INTERRUPTED = 3, - WF_SENSOR_CONNECTION_STATUS_DISCONNECTING = 4 } _connstate; - int connectionStatus(int sd); - bool isConnected(int sd); - - // all the sensor types just the types we need - enum { - WF_SENSORTYPE_NONE = 0, - WF_SENSORTYPE_BIKE_POWER = 0x00000001, // kickr, inride etc - WF_SENSORTYPE_BIKE_SPEED = 0x00000002, - WF_SENSORTYPE_BIKE_CADENCE = 0x00000004, - WF_SENSORTYPE_BIKE_SPEED_CADENCE = 0x00000008, - WF_SENSORTYPE_FOOTPOD = 0x00000010, - WF_SENSORTYPE_HEARTRATE = 0x00000020, - WF_SENSORTYPE_WEIGHT_SCALE = 0x00000040, - WF_SENSORTYPE_ANT_FS = 0x00000080, - WF_SENSORTYPE_LOCATION = 0x00000100, - WF_SENSORTYPE_CALORIMETER = 0x00000200, - WF_SENSORTYPE_GEO_CACHE = 0x00000400, - WF_SENSORTYPE_FITNESS_EQUIPMENT = 0x00000800, - WF_SENSORTYPE_MULTISPORT_SPEED_DISTANCE = 0x00001000, - WF_SENSORTYPE_PROXIMITY = 0x00002000, - WF_SENSORTYPE_HEALTH_THERMOMETER = 0x00004000, - WF_SENSORTYPE_BLOOD_PRESSURE = 0x00008000, - WF_SENSORTYPE_BTLE_GLUCOSE = 0x00010000, - WF_SENSORTYPE_GLUCOSE = 0x00020000, - WF_SENSORTYPE_DISPLAY = 0x00800000 } _sensortypes; // rflkt - - const QString sensorDescription(int id, int sub) const { - QString returning(tr("Unknown")); - switch (id) { - case 0x0 : returning = tr("None"); break; - case 0x1 : - { - switch(sub) { - - case 0: - default: - returning = tr("Power Meter"); - break; - - case 1: - returning = tr("Wahoo KICKR trainer"); - break; - - case 2: - returning = tr("Stage ONE Crank Power Meter"); - break; - - case 3: - returning = tr("Kurt Kinetic InRide Power Meter"); - break; - } - } - break; - - case 0x2 : returning = tr("Bike Speed"); break; - case 0x4 : returning = tr("Bike Cadence"); break; - case 0x8 : returning = tr("Speed and Cadence"); break; - case 0x10 : returning = tr("FootPod"); break; - case 0x20 : returning = tr("Heart Rate"); break; - case 0x800000 : returning = tr("RFKLT Display"); break; - } - return returning; - } - - - // subtypes -- esp. power - enum { - WF_SENSOR_SUBTYPE_UNSPECIFIED = 0, - WF_SENSOR_SUBTYPE_BIKE_POWER_KICKR = 1, - WF_SENSOR_SUBTYPE_BIKE_POWER_STAGE_ONE = 2, - WF_SENSOR_SUBTYPE_BIKE_POWER_IN_RIDE = 3 } _sensorsubtype; - - // scan - bool discoverDevicesOfType(int eSensorType); - int deviceCount(); - QString deviceUUID(int); // return the UUID for device n - int deviceType(int); // return the device type - int deviceSubType(int); // return the subtype found - - // connect and disconnect - int connectDevice(QString uuid); // connect the device n - bool disconnectDevice(int sd); // disconnect - - // has data? - bool hasData(int sd); - void getRealtimeData(int sd, RealtimeData *p); - - // set slope or ergo mode - void setSlopeMode(int sd); - void setErgoMode(int sd); - - // set resistance slope or load - void setSlope(int sd, double slope); - void setLoad(int sd, int watts); - - // NOTE: There is an application wide NSAutoreleasePool maintained - // in cocoa initialiser, but it is only to support activity on - // the main thread. - // The application code (e.g. Kickr.cpp) needs to get and free a - // pool for each thread, this is why we have a getPool/freePool - // method in WFApi, but never allocate a pool ourselves. - void *getPool(); - void freePool(void*); - -signals: - void currentStateChanged(int); // hardware conncector state changed - void connectionStateChanged(int status); - void discoveredDevices(int,bool); - void discoverFinished(); - void connectionHasData(); - -public slots: - - // connecting... - void stateChanged(); - void connectionState(int status); - void connectionTimeout(); - - void connectedSensor(void*); - void didDiscoverDevices(int count, bool finished); - void disconnectedSensor(void*); - void hasFirmwareUpdateAvalableForConnection(); - void connectorHasData(); - -signals: - -public slots: - -public: - - // the native api bridge -- private implementation in - // WFApi.mm -- bridge between the QT/C++ world and the - // WF/Objc world -#ifdef __OBJC__ - WFBridge *wf; // when included in objc sources -#else /* __OBJC__ */ - void *wf; // when included in C++ sources -#endif /* __OBJC__ */ - QVector connections; -}; -#endif diff --git a/src/Train/WFApi.mm b/src/Train/WFApi.mm deleted file mode 100644 index fb412e4bd..000000000 --- a/src/Train/WFApi.mm +++ /dev/null @@ -1,327 +0,0 @@ -/* - * Copyright (c) 2013 Mark Liversedge (liversedge@gmail.com) - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRWFApiY; without even the implied warranty of MERCHWFApiABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., 51 - * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "WFApi.h" - -// WF API Headers -#import -#import -#import -#import -#import -#import -#import -#import - -// Utility -static QString toQString(const NSString *nsstr) -{ - NSRange range; - range.location = 0; - range.length = [nsstr length]; - QString result(range.length, QChar(0)); - - unichar *chars = new unichar[range.length]; - [nsstr getCharacters:chars range:range]; - result = QString::fromUtf16(chars, range.length); - delete[] chars; - return result; -} - -static inline NSString* fromQString(const QString &string) -{ - const QByteArray utf8 = string.toUtf8(); - const char* cString = utf8.constData(); - return [[NSString alloc] initWithUTF8String:cString]; -} - -// Thi source file contains the private objc interface (WFBridge) that -// sits atop the Wahoo Fitness APIs at the top of the source file. -// -// This is then follwoed by the C++ public interface implementation that -// sits atop that private interface (WFBridge) - -//---------------------------------------------------------------------- -// Objective C -- Private interface -//---------------------------------------------------------------------- - -@interface WFBridge : NSObject { -@public - QPointer qtw; // the QT QObject public class - NSMutableArray *discoveredSensors; -} - -@end - -@implementation WFBridge - -//============================================================================ -// Hardware Connector Methods -//============================================================================ - -// retreive the API version --(NSString *) apiVersion { return [[WFHardwareConnector sharedConnector] apiVersion]; } - -// BTLE state and enablement --(BOOL)hasBTLESupport { return [[WFHardwareConnector sharedConnector] hasBTLESupport]; } --(BOOL)isBTLEEnabled { return [[WFHardwareConnector sharedConnector] isBTLEEnabled]; } --(BOOL)enableBTLE:(BOOL)bEnable inBondingMode:(BOOL)bBondingMode { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init]; - bool result = [[WFHardwareConnector sharedConnector] enableBTLE:bEnable inBondingMode:bBondingMode]; - [pool drain]; - return result; -} --(BOOL)isCommunicationHWReady { return [[WFHardwareConnector sharedConnector] isCommunicationHWReady]; } --(int)currentState { return [[WFHardwareConnector sharedConnector] currentState]; } - -// Initialise the WFBridge singleton --(id)init -{ - // initialise - discoveredSensors = [[NSMutableArray alloc] init]; - [[WFHardwareConnector sharedConnector] setDelegate:self]; - [self enableBTLE:TRUE inBondingMode:false]; - return self; -} - -// scan for devices and stored details --(BOOL)discoverDevicesOfType:(WFSensorType_t)eSensorType onNetwork:(WFNetworkType_t)eNetworkType searchTimeout:(NSTimeInterval)timeout -{ - // get rid of past scans / stop any in progress - [discoveredSensors removeAllObjects]; - [[WFHardwareConnector sharedConnector] cancelDiscoveryOnNetwork:WF_NETWORKTYPE_BTLE]; - - // go looking - [[WFHardwareConnector sharedConnector] discoverDevicesOfType:eSensorType onNetwork:eNetworkType searchTimeout:timeout]; //XXX ignoringreturn - return true; -} --(int)deviceCount { return [discoveredSensors count]; } --(NSString*)deviceUUID:(int)n -{ - WFConnectionParams* connParams = (WFConnectionParams*)[discoveredSensors objectAtIndex:n]; - return connParams.device1.deviceUUIDString; -} --(int)deviceType:(int)n -{ - WFConnectionParams* connParams = (WFConnectionParams*)[discoveredSensors objectAtIndex:n]; - return (int)connParams.sensorType; -} --(int)deviceSubType:(int)n -{ - WFConnectionParams* connParams = (WFConnectionParams*)[discoveredSensors objectAtIndex:n]; - return (int)connParams.sensorSubType; -} - -//============================================================================ -// Sensor Connection Methods -//============================================================================ - -// connect and disconnect a device --(WFSensorConnection *)connectDevice: (NSString *)uuid -{ - // just in case there is a discovery in action, lets cancel it... - [[WFHardwareConnector sharedConnector] cancelDiscoveryOnNetwork:WF_NETWORKTYPE_BTLE]; - - WFDeviceParams* dev = [[WFDeviceParams alloc] init]; - dev.deviceUUIDString = uuid; - dev.networkType = WF_NETWORKTYPE_BTLE; - - WFConnectionParams* params = [[WFConnectionParams alloc] init]; - params.sensorType = WF_SENSORTYPE_BIKE_POWER; - params.networkType = WF_NETWORKTYPE_BTLE; - params.sensorSubType = WF_SENSOR_SUBTYPE_BIKE_POWER_KICKR; - params.searchTimeout = 5; - params.device1 = dev; - - // request the sensor connection. - WFSensorConnection *sensorConnection = (WFBikePowerConnection*)[[WFHardwareConnector sharedConnector] requestSensorConnection:params]; - - // set delegate to receive connection status changes. - sensorConnection.delegate = self; - - - return sensorConnection; -} --(int)connectionStatus:(WFSensorConnection*)sensorConnection { return (int)[sensorConnection connectionStatus]; } -- (BOOL)disconnectDevice:(WFSensorConnection*)sensorConnection { [sensorConnection disconnect]; return true; } -- (BOOL)isConnected:(WFSensorConnection*)sensorConnection { return [sensorConnection isConnected]; } - -// get telemetry -- (WFBikePowerData*) getData:(WFSensorConnection*)sensorConnection { return (WFBikePowerData*)[sensorConnection getData]; } - -// trainer setup / load -- (void) setSlopeMode:(WFBikePowerConnection*)sensorConnection { [sensorConnection trainerSetSimMode:85 rollingResistance:0.0004 windResistance:0.6]; } -- (void) setErgoMode:(WFBikePowerConnection*)sensorConnection { [sensorConnection trainerSetErgMode:100]; } -- (void) setSlope:(WFBikePowerConnection*)sensorConnection slope:(double)slope { [sensorConnection trainerSetGrade:slope]; } -- (void) setLoad:(WFBikePowerConnection*)sensorConnection load:(int)load { [sensorConnection trainerSetErgMode:load]; } - -//============================================================================ -// Sensor connection updates (delegate methods) -//============================================================================ - -// state changed -- (void)connection:(WFSensorConnection*)connectionInfo stateChanged:(WFSensorConnectionStatus_t)connState -{ Q_UNUSED(connectionInfo); - qtw->connectionState(connState); -} -// timed out -- (void)connectionDidTimeout:(WFSensorConnection*)connectionInfo -{ Q_UNUSED(connectionInfo); - qtw->connectionTimeout(); -} -// telemetry available -- (BOOL) hasData:(WFSensorConnection*)sensorConnection { return [sensorConnection hasData]; } - -// firmware available for this sensor --(void) hardwareConnector:(WFHardwareConnector*)hwConnector hasFirmwareUpdateAvailableForConnection:(WFSensorConnection*)connectionInfo required:(BOOL)required withWahooUtilityAppURL:(NSURL *)wahooUtilityAppURL -{ Q_UNUSED(hwConnector); - Q_UNUSED(connectionInfo); - Q_UNUSED(required); - Q_UNUSED(wahooUtilityAppURL); - qtw->hasFirmwareUpdateAvalableForConnection(); //XXX do what? -} - -//============================================================================ -// Hardware connector updates (delegate methods) -//============================================================================ - -// state changed on connector --(void)hardwareConnector:(WFHardwareConnector*)hwConnector stateChanged:(WFHardwareConnectorState_t)currentState -{ Q_UNUSED(hwConnector); - Q_UNUSED(currentState); - qtw->stateChanged(); -} - -// connection established --(void)hardwareConnector:(WFHardwareConnector*)hwConnector connectedSensor:(WFSensorConnection*)connectionInfo -{ Q_UNUSED(hwConnector); - qtw->connectedSensor(connectionInfo); -} - -// data has arrived on connector --(void)hardwareConnectorHasData { qtw->connectorHasData(); } - -// a sensor was disconnected --(void)hardwareConnector:(WFHardwareConnector*)hwConnector disconnectedSensor:(WFSensorConnection*)connectionInfo -{ Q_UNUSED(hwConnector); - qtw->disconnectedSensor(connectionInfo); -} - -// devices discovered --(void)hardwareConnector:(WFHardwareConnector*)hwConnector didDiscoverDevices:(NSSet*)connectionParams searchCompleted:(BOOL)bCompleted -{ Q_UNUSED(hwConnector); - - if (!bCompleted) { - // add discovered devices -- as they are discovered, not at the end. - for (WFConnectionParams* connParams in connectionParams) { - [discoveredSensors addObject:connParams]; - } - } - - qtw->didDiscoverDevices([discoveredSensors count], bCompleted); -} - --(NSAutoreleasePool*) getPool { return [[NSAutoreleasePool alloc] init]; } --(void) freePool:(NSAutoreleasePool*)pool { [pool release]; } -@end - -//---------------------------------------------------------------------- -// C++ PUBLIC Interface -//---------------------------------------------------------------------- - -// Singleton API class -WFApi *_gc_wfapi = NULL; -WFApi::WFApi() -{ - wf = [[WFBridge alloc] init]; - wf->qtw = this; -} -WFApi::~WFApi() { [wf release]; } - -//============================================================================ -// wrappers for methods in private implementation above -//============================================================================ -QString WFApi::apiVersion() { return toQString([wf apiVersion]); } -bool WFApi::isBTLEEnabled() { return [wf isBTLEEnabled]; } -bool WFApi::hasBTLESupport() { return [wf hasBTLESupport]; } -bool WFApi::isCommunicationHWReady() { return [wf isCommunicationHWReady]; } -bool WFApi::enableBTLE(bool enable, bool bondingmode) { - return [wf enableBTLE:enable inBondingMode:bondingmode]; -} -int WFApi::currentState() { return [wf currentState]; } - -bool -WFApi::discoverDevicesOfType(int eSensorType) -{ - // ignore ehat was passed for now... - return [wf discoverDevicesOfType:(WFSensorType_t)eSensorType onNetwork:WF_NETWORKTYPE_BTLE searchTimeout:15.00]; -} - -QString WFApi::deviceUUID(int n) -{ - if (n>=0 && n=0 && n=0 && nsetWatts((int)[data instantPower]); - rt->setCadence((int)[data instantCadence]); - rt->setWheelRpm((int)[data instantWheelRPM]); -} -void * WFApi::getPool() { return (void*)[wf getPool]; } -void WFApi::freePool(void *pool) { [wf freePool:(NSAutoreleasePool*)pool]; } diff --git a/src/gcconfig.pri.in b/src/gcconfig.pri.in index f9d3392ad..8a4b91dc3 100644 --- a/src/gcconfig.pri.in +++ b/src/gcconfig.pri.in @@ -244,9 +244,6 @@ macx { # Uncomment this line if you have SDK 10.7 or higher #DEFINES += GC_HAVE_LION - # Uncomment this line if you have the Mac OSX Wahoo API installed (Kickr) - #HAVE_WFAPI = true - #uncomment below if you are running on the 10.9 developer preview #INCLUDEPATH += /Library/Developer/CommandLineTools/SDKs/MacOSX10.9.sdk/usr/include/ } diff --git a/src/src.pro b/src/src.pro index 66529d3f0..34e3102cc 100644 --- a/src/src.pro +++ b/src/src.pro @@ -74,6 +74,11 @@ lessThan(QT_MAJOR_VERSION, 5) { } else { QT += multimedia multimediawidgets } + greaterThan(QT_MINOR_VERSION, 3) { + QT += bluetooth + HEADERS += Train/BT40Controller.h + SOURCES += Train/BT40Controller.cpp + } } ###=======================================================================