From 6dee00e5b838959680837980cd3fcd273a609ead Mon Sep 17 00:00:00 2001 From: Sean Rhea Date: Sun, 9 Aug 2009 11:12:39 -0700 Subject: [PATCH] move PT download code into PowerTapDevice.(h|cpp) --- src/DownloadRideDialog.cpp | 31 ++--- src/DownloadRideDialog.h | 3 +- src/PowerTapDevice.cpp | 230 ++++++++++++++++++++++++++++++++++++ src/PowerTapDevice.h | 42 +++++++ src/PowerTapUtil.cpp | 236 +++---------------------------------- src/PowerTapUtil.h | 24 +--- src/RawRideFile.cpp | 18 +-- src/src.pro | 2 + 8 files changed, 321 insertions(+), 265 deletions(-) create mode 100644 src/PowerTapDevice.cpp create mode 100644 src/PowerTapDevice.h diff --git a/src/DownloadRideDialog.cpp b/src/DownloadRideDialog.cpp index 9a7fb7b10..2b5f35adc 100644 --- a/src/DownloadRideDialog.cpp +++ b/src/DownloadRideDialog.cpp @@ -117,26 +117,27 @@ DownloadRideDialog::scanCommPorts() } bool -DownloadRideDialog::statusCallback(PowerTap::State state) +DownloadRideDialog::statusCallback(PowerTapDevice::State state) { - if (state == PowerTap::STATE_READING_VERSION) + if (state == PowerTapDevice::STATE_READING_VERSION) label->setText("Reading version..."); - else if (state == PowerTap::STATE_READING_HEADER) + else if (state == PowerTapDevice::STATE_READING_HEADER) label->setText(label->text() + "done.\nReading header..."); - else if (state == PowerTap::STATE_READING_DATA) { + else if (state == PowerTapDevice::STATE_READING_DATA) { label->setText(label->text() + "done.\nReading ride data...\n"); endingOffset = label->text().length(); } else { - assert(state == PowerTap::STATE_DATA_AVAILABLE); + assert(state == PowerTapDevice::STATE_DATA_AVAILABLE); unsigned char *buf = records.data(); - bool bIsVer81 = PowerTap::is_Ver81(buf); + bool bIsVer81 = PowerTapUtil::is_Ver81(buf); if (recIntSecs == 0.0) { for (int i = 0; i < records.size(); i += 6) { - if (PowerTap::is_config(buf + i, bIsVer81)) { + if (PowerTapUtil::is_config(buf + i, bIsVer81)) { unsigned unused1, unused2, unused3; - PowerTap::unpack_config(buf + i, &unused1, &unused2, - &recIntSecs, &unused3, bIsVer81); + PowerTapUtil::unpack_config(buf + i, &unused1, &unused2, + &recIntSecs, &unused3, + bIsVer81); } } } @@ -151,8 +152,8 @@ DownloadRideDialog::statusCallback(PowerTap::State state) if (filename == "") { struct tm time; for (int i = 0; i < records.size(); i += 6) { - if (PowerTap::is_time(buf + i, bIsVer81)) { - PowerTap::unpack_time(buf + i, &time, bIsVer81); + if (PowerTapUtil::is_time(buf + i, bIsVer81)) { + PowerTapUtil::unpack_time(buf + i, &time, bIsVer81); char tmp[32]; sprintf(tmp, "%04d_%02d_%02d_%02d_%02d_%02d.raw", time.tm_year + 1900, time.tm_mon + 1, @@ -201,7 +202,7 @@ DownloadRideDialog::downloadClicked() assert(dev); QString err; QByteArray version; - if (!PowerTap::download( + if (!PowerTapDevice::download( dev, version, records, boost::bind(&DownloadRideDialog::statusCallback, this, _1), err)) { @@ -242,7 +243,7 @@ DownloadRideDialog::downloadClicked() struct tm time; bool time_set = false; unsigned char *data = records.data(); - bool bIsVer81 = PowerTap::is_Ver81(data); + bool bIsVer81 = PowerTapUtil::is_Ver81(data); for (int i = 0; i < records.size(); i += 6) { if (data[i] == 0 && !bIsVer81) @@ -253,8 +254,8 @@ DownloadRideDialog::downloadClicked() os.setFieldWidth(1); os << ((j == 5) ? "\n" : " "); } - if (!time_set && PowerTap::is_time(data + i, bIsVer81)) { - PowerTap::unpack_time(data + i, &time, bIsVer81); + if (!time_set && PowerTapUtil::is_time(data + i, bIsVer81)) { + PowerTapUtil::unpack_time(data + i, &time, bIsVer81); time_set = true; } } diff --git a/src/DownloadRideDialog.h b/src/DownloadRideDialog.h index af658f8d6..a7c962e9a 100644 --- a/src/DownloadRideDialog.h +++ b/src/DownloadRideDialog.h @@ -20,6 +20,7 @@ #define _GC_DownloadRideDialog_h 1 #include +#include "PowerTapDevice.h" #include "PowerTapUtil.h" class MainWindow; @@ -33,7 +34,7 @@ class DownloadRideDialog : public QDialog DownloadRideDialog(MainWindow *mainWindow, const QDir &home); void downloadFinished(); - bool statusCallback(PowerTap::State state); + bool statusCallback(PowerTapDevice::State state); private slots: void downloadClicked(); diff --git a/src/PowerTapDevice.cpp b/src/PowerTapDevice.cpp new file mode 100644 index 000000000..f98869b7b --- /dev/null +++ b/src/PowerTapDevice.cpp @@ -0,0 +1,230 @@ +/* + * Copyright (c) 2008 Sean C. Rhea (srhea@srhea.net) + * + * 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 "PowerTapDevice.h" +#include "PowerTapUtil.h" +#include + +#define PT_DEBUG false + +static bool +hasNewline(const char *buf, int len) +{ + static char newline[] = { 0x0d, 0x0a }; + if (len < 2) + return false; + for (int i = 0; i < len; ++i) { + bool success = true; + for (int j = 0; j < 2; ++j) { + if (buf[i+j] != newline[j]) { + success = false; + break; + } + } + if (success) + return true; + } + return false; +} + +static QString +cEscape(const char *buf, int len) +{ + char *result = new char[4 * len + 1]; + char *tmp = result; + for (int i = 0; i < len; ++i) { + if (buf[i] == '"') + tmp += sprintf(tmp, "\\\""); + else if (isprint(buf[i])) + *(tmp++) = buf[i]; + else + tmp += sprintf(tmp, "\\x%02x", 0xff & (unsigned) buf[i]); + } + return result; +} + +static bool +doWrite(CommPortPtr dev, char c, bool hwecho, QString &err) +{ + if (PT_DEBUG) printf("writing '%c' to device\n", c); + int n = dev->write(&c, 1, err); + if (n != 1) { + if (n < 0) + err = QString("failed to write %1 to device: %2").arg(c).arg(err); + else + err = QString("timeout writing %1 to device").arg(c); + return false; + } + if (hwecho) { + char c; + int n = dev->read(&c, 1, err); + if (n != 1) { + if (n < 0) + err = QString("failed to read back hardware echo: %2").arg(err); + else + err = "timeout reading back hardware echo"; + return false; + } + } + return true; +} + +static int +readUntilNewline(CommPortPtr dev, char *buf, int len, QString &err) +{ + int sofar = 0; + while (!hasNewline(buf, sofar)) { + assert(sofar < len); + // Read one byte at a time to avoid waiting for timeout. + int n = dev->read(buf + sofar, 1, err); + if (n <= 0) { + err = (n < 0) ? ("read error: " + err) : "read timeout"; + err += QString(", read %1 bytes so far: \"%2\"") + .arg(sofar).arg(cEscape(buf, sofar)); + return -1; + } + sofar += n; + } + return sofar; +} + +bool +PowerTapDevice::download(CommPortPtr dev, QByteArray &version, + QVector &records, + StatusCallback statusCallback, QString &err) +{ + if (!dev->open(err)) { + err = "ERROR: open failed: " + err; + return false; + } + + if (!doWrite(dev, 0x56, false, err)) // 'V' + return false; + if (!statusCallback(STATE_READING_VERSION)) { + err = "download cancelled"; + return false; + } + char vbuf[256]; + int version_len = readUntilNewline(dev, vbuf, sizeof(vbuf), err); + if (version_len < 0) { + err = "Error reading version: " + err; + return false; + } + if (PT_DEBUG) { + printf("read version \"%s\"\n", + cEscape(vbuf, version_len).toAscii().constData()); + } + version = QByteArray(vbuf, version_len); + + // We expect the version string to be something like + // "VER 02.21 PRO...", so if we see two V's, it's probably + // because there's a hardware echo going on. + + int veridx = version.indexOf("VER"); + if (veridx < 0) { + err = QString("Unrecognized version \"%1\"") + .arg(cEscape(vbuf, version_len)); + return false; + } + bool hwecho = version.indexOf('V') < veridx; + if (PT_DEBUG) printf("hwecho=%s\n", hwecho ? "true" : "false"); + + if (!statusCallback(STATE_READING_HEADER)) { + err = "download cancelled"; + return false; + } + + if (!doWrite(dev, 0x44, hwecho, err)) // 'D' + return false; + unsigned char header[6]; + int header_len = dev->read(header, sizeof(header), err); + if (header_len != 6) { + if (header_len < 0) + err = "ERROR: reading header: " + err; + else + err = "ERROR: timeout reading header"; + return false; + } + if (PT_DEBUG) { + printf("read header \"%s\"\n", + cEscape((char*) header, + sizeof(header)).toAscii().constData()); + } + for (size_t i = 0; i < sizeof(header); ++i) + records.append(header[i]); + + if (!statusCallback(STATE_READING_DATA)) { + err = "download cancelled"; + return false; + } + + fflush(stdout); + while (true) { + if (PT_DEBUG) printf("reading block\n"); + unsigned char buf[256 * 6 + 1]; + int n = dev->read(buf, 2, err); + if (n < 2) { + if (n < 0) + err = "ERROR: reading first two: " + err; + else + err = "ERROR: timeout reading first two"; + return false; + } + if (PT_DEBUG) { + printf("read 2 bytes: \"%s\"\n", + cEscape((char*) buf, 2).toAscii().constData()); + } + if (hasNewline((char*) buf, 2)) + break; + unsigned count = 2; + while (count < sizeof(buf)) { + n = dev->read(buf + count, sizeof(buf) - count, err); + if (n < 0) { + err = "ERROR: reading block: " + err; + return false; + } + if (n == 0) { + err = "ERROR: timeout reading block"; + return false; + } + if (PT_DEBUG) { + printf("read %d bytes: \"%s\"\n", n, + cEscape((char*) buf + count, n).toAscii().constData()); + } + count += n; + } + unsigned csum = 0; + for (int i = 0; i < ((int) sizeof(buf)) - 1; ++i) + csum += buf[i]; + if ((csum % 256) != buf[sizeof(buf) - 1]) { + err = "ERROR: bad checksum"; + return false; + } + if (PT_DEBUG) printf("good checksum\n"); + for (size_t i = 0; i < sizeof(buf) - 1; ++i) + records.append(buf[i]); + if (!statusCallback(STATE_DATA_AVAILABLE)) { + err = "download cancelled"; + return false; + } + if (!doWrite(dev, 0x71, hwecho, err)) // 'q' + return false; + } + return true; +} + diff --git a/src/PowerTapDevice.h b/src/PowerTapDevice.h new file mode 100644 index 000000000..01c27600a --- /dev/null +++ b/src/PowerTapDevice.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2008 Sean C. Rhea (srhea@srhea.net) + * + * 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_PowerTapDevice_h +#define _GC_PowerTapDevice_h 1 + +#include "CommPort.h" +#include + +struct PowerTapDevice +{ + enum State { + STATE_READING_VERSION, + STATE_READING_HEADER, + STATE_READING_DATA, + STATE_DATA_AVAILABLE + }; + + typedef boost::function StatusCallback; + + static bool download(CommPortPtr dev, QByteArray &version, + QVector &records, + StatusCallback statusCallback, QString &err); +}; + +#endif // _GC_PowerTapDevice_h + diff --git a/src/PowerTapUtil.cpp b/src/PowerTapUtil.cpp index 047cd6a81..3408f98b9 100644 --- a/src/PowerTapUtil.cpp +++ b/src/PowerTapUtil.cpp @@ -17,218 +17,11 @@ */ #include "PowerTapUtil.h" +#include #include -#define PT_DEBUG false - -static bool -hasNewline(const char *buf, int len) -{ - static char newline[] = { 0x0d, 0x0a }; - if (len < 2) - return false; - for (int i = 0; i < len; ++i) { - bool success = true; - for (int j = 0; j < 2; ++j) { - if (buf[i+j] != newline[j]) { - success = false; - break; - } - } - if (success) - return true; - } - return false; -} - -static QString -cEscape(const char *buf, int len) -{ - char *result = new char[4 * len + 1]; - char *tmp = result; - for (int i = 0; i < len; ++i) { - if (buf[i] == '"') - tmp += sprintf(tmp, "\\\""); - else if (isprint(buf[i])) - *(tmp++) = buf[i]; - else - tmp += sprintf(tmp, "\\x%02x", 0xff & (unsigned) buf[i]); - } - return result; -} - -static bool -doWrite(CommPortPtr dev, char c, bool hwecho, QString &err) -{ - if (PT_DEBUG) printf("writing '%c' to device\n", c); - int n = dev->write(&c, 1, err); - if (n != 1) { - if (n < 0) - err = QString("failed to write %1 to device: %2").arg(c).arg(err); - else - err = QString("timeout writing %1 to device").arg(c); - return false; - } - if (hwecho) { - char c; - int n = dev->read(&c, 1, err); - if (n != 1) { - if (n < 0) - err = QString("failed to read back hardware echo: %2").arg(err); - else - err = "timeout reading back hardware echo"; - return false; - } - } - return true; -} - -static int -readUntilNewline(CommPortPtr dev, char *buf, int len, QString &err) -{ - int sofar = 0; - while (!hasNewline(buf, sofar)) { - assert(sofar < len); - // Read one byte at a time to avoid waiting for timeout. - int n = dev->read(buf + sofar, 1, err); - if (n <= 0) { - err = (n < 0) ? ("read error: " + err) : "read timeout"; - err += QString(", read %1 bytes so far: \"%2\"") - .arg(sofar).arg(cEscape(buf, sofar)); - return -1; - } - sofar += n; - } - return sofar; -} - -bool -PowerTap::download(CommPortPtr dev, QByteArray &version, - QVector &records, - StatusCallback statusCallback, QString &err) -{ - if (!dev->open(err)) { - err = "ERROR: open failed: " + err; - return false; - } - - if (!doWrite(dev, 0x56, false, err)) // 'V' - return false; - if (!statusCallback(STATE_READING_VERSION)) { - err = "download cancelled"; - return false; - } - char vbuf[256]; - int version_len = readUntilNewline(dev, vbuf, sizeof(vbuf), err); - if (version_len < 0) { - err = "Error reading version: " + err; - return false; - } - if (PT_DEBUG) { - printf("read version \"%s\"\n", - cEscape(vbuf, version_len).toAscii().constData()); - } - version = QByteArray(vbuf, version_len); - - // We expect the version string to be something like - // "VER 02.21 PRO...", so if we see two V's, it's probably - // because there's a hardware echo going on. - - int veridx = version.indexOf("VER"); - if (veridx < 0) { - err = QString("Unrecognized version \"%1\"") - .arg(cEscape(vbuf, version_len)); - return false; - } - bool hwecho = version.indexOf('V') < veridx; - if (PT_DEBUG) printf("hwecho=%s\n", hwecho ? "true" : "false"); - - if (!statusCallback(STATE_READING_HEADER)) { - err = "download cancelled"; - return false; - } - - if (!doWrite(dev, 0x44, hwecho, err)) // 'D' - return false; - unsigned char header[6]; - int header_len = dev->read(header, sizeof(header), err); - if (header_len != 6) { - if (header_len < 0) - err = "ERROR: reading header: " + err; - else - err = "ERROR: timeout reading header"; - return false; - } - if (PT_DEBUG) { - printf("read header \"%s\"\n", - cEscape((char*) header, - sizeof(header)).toAscii().constData()); - } - for (size_t i = 0; i < sizeof(header); ++i) - records.append(header[i]); - - if (!statusCallback(STATE_READING_DATA)) { - err = "download cancelled"; - return false; - } - - fflush(stdout); - while (true) { - if (PT_DEBUG) printf("reading block\n"); - unsigned char buf[256 * 6 + 1]; - int n = dev->read(buf, 2, err); - if (n < 2) { - if (n < 0) - err = "ERROR: reading first two: " + err; - else - err = "ERROR: timeout reading first two"; - return false; - } - if (PT_DEBUG) { - printf("read 2 bytes: \"%s\"\n", - cEscape((char*) buf, 2).toAscii().constData()); - } - if (hasNewline((char*) buf, 2)) - break; - unsigned count = 2; - while (count < sizeof(buf)) { - n = dev->read(buf + count, sizeof(buf) - count, err); - if (n < 0) { - err = "ERROR: reading block: " + err; - return false; - } - if (n == 0) { - err = "ERROR: timeout reading block"; - return false; - } - if (PT_DEBUG) { - printf("read %d bytes: \"%s\"\n", n, - cEscape((char*) buf + count, n).toAscii().constData()); - } - count += n; - } - unsigned csum = 0; - for (int i = 0; i < ((int) sizeof(buf)) - 1; ++i) - csum += buf[i]; - if ((csum % 256) != buf[sizeof(buf) - 1]) { - err = "ERROR: bad checksum"; - return false; - } - if (PT_DEBUG) printf("good checksum\n"); - for (size_t i = 0; i < sizeof(buf) - 1; ++i) - records.append(buf[i]); - if (!statusCallback(STATE_DATA_AVAILABLE)) { - err = "download cancelled"; - return false; - } - if (!doWrite(dev, 0x71, hwecho, err)) // 'q' - return false; - } - return true; -} - bool -PowerTap::is_ignore_record(unsigned char *buf, bool bVer81) +PowerTapUtil::is_ignore_record(unsigned char *buf, bool bVer81) { if (bVer81) return buf[0]==0 && buf[1]==0 && buf[2]==0; @@ -237,19 +30,19 @@ PowerTap::is_ignore_record(unsigned char *buf, bool bVer81) } bool -PowerTap::is_Ver81(unsigned char *buf) +PowerTapUtil::is_Ver81(unsigned char *buf) { return buf[3] == 0x81; } int -PowerTap::is_time(unsigned char *buf, bool bVer81) +PowerTapUtil::is_time(unsigned char *buf, bool bVer81) { return (bVer81 && buf[0] == 0x10) || (!bVer81 && buf[0] == 0x60); } time_t -PowerTap::unpack_time(unsigned char *buf, struct tm *time, bool bVer81) +PowerTapUtil::unpack_time(unsigned char *buf, struct tm *time, bool bVer81) { (void) bVer81; // unused memset(time, 0, sizeof(*time)); @@ -264,7 +57,7 @@ PowerTap::unpack_time(unsigned char *buf, struct tm *time, bool bVer81) } int -PowerTap::is_config(unsigned char *buf, bool bVer81) +PowerTapUtil::is_config(unsigned char *buf, bool bVer81) { return (bVer81 && buf[0] == 0x00) || (!bVer81 && buf[0] == 0x40); } @@ -273,9 +66,9 @@ const double TIME_UNIT_SEC = 0.021*60.0; const double TIME_UNIT_SEC_V81 = 0.01; int -PowerTap::unpack_config(unsigned char *buf, unsigned *interval, - unsigned *last_interval, double *rec_int_secs, - unsigned *wheel_sz_mm, bool bVer81) +PowerTapUtil::unpack_config(unsigned char *buf, unsigned *interval, + unsigned *last_interval, double *rec_int_secs, + unsigned *wheel_sz_mm, bool bVer81) { *wheel_sz_mm = (buf[1] << 8) | buf[2]; /* Data from device wraps interval after 9... */ @@ -298,7 +91,7 @@ PowerTap::unpack_config(unsigned char *buf, unsigned *interval, } int -PowerTap::is_data(unsigned char *buf, bool bVer81) +PowerTapUtil::is_data(unsigned char *buf, bool bVer81) { if (bVer81) return (buf[0] & 0x40) == 0x40; @@ -328,10 +121,11 @@ my_round(double x) #define BAD_KM_TO_MI 0.62 void -PowerTap::unpack_data(unsigned char *buf, int compat, double rec_int_secs, - unsigned wheel_sz_mm, double *time_secs, - double *torque_Nm, double *mph, double *watts, - double *dist_m, unsigned *cad, unsigned *hr, bool bVer81) +PowerTapUtil::unpack_data(unsigned char *buf, int compat, double rec_int_secs, + unsigned wheel_sz_mm, double *time_secs, + double *torque_Nm, double *mph, double *watts, + double *dist_m, unsigned *cad, unsigned *hr, + bool bVer81) { if (bVer81) { diff --git a/src/PowerTapUtil.h b/src/PowerTapUtil.h index 3594370d3..7fd95888b 100644 --- a/src/PowerTapUtil.h +++ b/src/PowerTapUtil.h @@ -16,27 +16,13 @@ * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef _GC_PT_PowerTap_h -#define _GC_PT_PowerTap_h 1 +#ifndef _GC_PowerTapUtil_h +#define _GC_PowerTapUtil_h 1 -#include "CommPort.h" -#include +#include -struct PowerTap +struct PowerTapUtil { - enum State { - STATE_READING_VERSION, - STATE_READING_HEADER, - STATE_READING_DATA, - STATE_DATA_AVAILABLE - }; - - typedef boost::function StatusCallback; - - static bool download(CommPortPtr dev, QByteArray &version, - QVector &records, - StatusCallback statusCallback, QString &err); - static bool is_Ver81(unsigned char *bufHeader); static bool is_ignore_record(unsigned char *buf, bool bVer81); @@ -56,5 +42,5 @@ struct PowerTap double *dist_m, unsigned *cad, unsigned *hr, bool bVer81); }; -#endif // _GC_PT_PowerTap_h +#endif // _GC_PowerTapUtil_h diff --git a/src/RawRideFile.cpp b/src/RawRideFile.cpp index 6c97acdd2..0cf1ff3e3 100644 --- a/src/RawRideFile.cpp +++ b/src/RawRideFile.cpp @@ -139,13 +139,13 @@ pt_read_raw(FILE *in, int compat, void *context, if (row == 1) { /* Serial number? */ - bIsVer81 = PowerTap::is_Ver81(buf); + bIsVer81 = PowerTapUtil::is_Ver81(buf); } - else if (PowerTap::is_ignore_record(buf, bIsVer81)) { + else if (PowerTapUtil::is_ignore_record(buf, bIsVer81)) { // do nothing } - else if (PowerTap::is_config(buf, bIsVer81)) { - if (PowerTap::unpack_config(buf, &interval, &last_interval, + else if (PowerTapUtil::is_config(buf, bIsVer81)) { + if (PowerTapUtil::unpack_config(buf, &interval, &last_interval, &rec_int_secs, &wheel_sz_mm, bIsVer81) < 0) { sprintf(ebuf, "Couldn't unpack config record."); if (error_cb) error_cb(ebuf, context); @@ -153,8 +153,8 @@ pt_read_raw(FILE *in, int compat, void *context, } if (config_cb) config_cb(interval, rec_int_secs, wheel_sz_mm, context); } - else if (PowerTap::is_time(buf, bIsVer81)) { - since_epoch = PowerTap::unpack_time(buf, &time, bIsVer81); + else if (PowerTapUtil::is_time(buf, bIsVer81)) { + since_epoch = PowerTapUtil::unpack_time(buf, &time, bIsVer81); bool ignore = false; if (start_secs == 0.0) start_secs = since_epoch; @@ -169,14 +169,14 @@ pt_read_raw(FILE *in, int compat, void *context, } if (time_cb && !ignore) time_cb(&time, since_epoch, context); } - else if (PowerTap::is_data(buf, bIsVer81)) { + else if (PowerTapUtil::is_data(buf, bIsVer81)) { if (wheel_sz_mm == 0) { sprintf(ebuf, "Read data row before wheel size set."); if (error_cb) error_cb(ebuf, context); return; } - PowerTap::unpack_data(buf, compat, rec_int_secs, wheel_sz_mm, &secs, - &nm, &mph, &watts, &meters, &cad, &hr, bIsVer81); + PowerTapUtil::unpack_data(buf, compat, rec_int_secs, wheel_sz_mm, &secs, + &nm, &mph, &watts, &meters, &cad, &hr, bIsVer81); if (compat) miles = round(meters) / 1000.0 * BAD_KM_TO_MI; else diff --git a/src/src.pro b/src/src.pro index 39ffd4970..f6b453345 100644 --- a/src/src.pro +++ b/src/src.pro @@ -50,6 +50,7 @@ HEADERS += \ LogTimeScaleDraw.h \ LogTimeScaleEngine.h \ Pages.h \ + PowerTapDevice.h \ PowerTapUtil.h \ Serial.h \ ToolsDialog.h \ @@ -94,6 +95,7 @@ SOURCES += \ LogTimeScaleDraw.cpp \ LogTimeScaleEngine.cpp \ Pages.cpp \ + PowerTapDevice.cpp \ PowerTapUtil.cpp \ Serial.cpp \ ToolsDialog.cpp \