mirror of
https://github.com/GoldenCheetah/GoldenCheetah.git
synced 2026-02-14 16:39:57 +00:00
Somehow this SrmData conflicts with the one in srm.h. I would have expected the compiler to flag that, but it didn't. Weird.
149 lines
4.5 KiB
C++
149 lines
4.5 KiB
C++
/*
|
|
* 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 "SrmDevice.h"
|
|
#include "SrmRideFile.h"
|
|
#include <srmio.h>
|
|
#include <QMessageBox>
|
|
#include <boost/scoped_ptr.hpp>
|
|
#include <boost/foreach.hpp>
|
|
#include <errno.h>
|
|
|
|
static bool srmRegistered = Device::addDevice("SRM", new SrmDevice());
|
|
|
|
QString
|
|
SrmDevice::downloadInstructions() const
|
|
{
|
|
return ""; // no particular instructions for SRM
|
|
}
|
|
|
|
static Device::StatusCallback cb;
|
|
|
|
static void
|
|
logfunc(const char *msg)
|
|
{
|
|
// XXX: better log function
|
|
// fprintf(stderr, "%s\n", msg);
|
|
cb(QString(msg).left(40));
|
|
}
|
|
|
|
static bool
|
|
get_tmpname(const QDir &tmpdir, QString &tmpname, QString &err)
|
|
{
|
|
QString tmpl = tmpdir.absoluteFilePath(".srmdl.XXXXXX.srm");
|
|
QTemporaryFile tmp(tmpl);
|
|
tmp.setAutoRemove(false);
|
|
if (!tmp.open()) {
|
|
err = "Failed to create temporary file "
|
|
+ tmpl + ": " + tmp.error();
|
|
return false;
|
|
}
|
|
tmpname = tmp.fileName(); // after close(), tmp.fileName() is ""
|
|
tmp.close();
|
|
return true;
|
|
}
|
|
|
|
struct SrmpcConn : public boost::noncopyable
|
|
{
|
|
srmpc_conn_t d;
|
|
SrmpcConn(const QString &path, srmpc_log_callback_t logfunc = NULL) {
|
|
int opt_force = 0; // setting this to 1 is potentially dangerous
|
|
d = srmpc_open(path.toAscii().constData(), opt_force, logfunc);
|
|
}
|
|
~SrmpcConn() { if (d) srmpc_close(d); }
|
|
};
|
|
|
|
struct SrmioData : public boost::noncopyable
|
|
{
|
|
srm_data_t d;
|
|
SrmioData(srm_data_t d) : d(d) {}
|
|
~SrmioData() { if (d) srm_data_free(d); }
|
|
};
|
|
|
|
static bool
|
|
dev2path(CommPortPtr dev, QString &path, QString &err)
|
|
{
|
|
// Read device path out of device name. Sketchy.
|
|
QRegExp rx("^Serial: (.+)$");
|
|
if (!rx.exactMatch(dev->name())) {
|
|
err = "SRM download not supported by device " + dev->name();
|
|
return false;
|
|
}
|
|
path = rx.cap(1);
|
|
return true;
|
|
}
|
|
|
|
bool
|
|
SrmDevice::download(CommPortPtr dev, const QDir &tmpdir,
|
|
QString &tmpname, QString &filename,
|
|
StatusCallback statusCallback, QString &err)
|
|
{
|
|
// Totally ghetto, proof-of-concept integration with srmio.
|
|
cb = statusCallback;
|
|
QString path;
|
|
if (!dev2path(dev, path, err))
|
|
return false;
|
|
if (!get_tmpname(tmpdir, tmpname, err))
|
|
return false;
|
|
SrmpcConn srm(path, logfunc);
|
|
if (!srm.d) {
|
|
err = "Couldn't open device " + path + ": " + strerror(errno);
|
|
return false;
|
|
}
|
|
int opt_all = 0; // XXX: what does this do?
|
|
int opt_fixup = 1; // fix bad data like srmwin.exe does
|
|
SrmioData srmdata(srmpc_get_data(srm.d, opt_all, opt_fixup));
|
|
if (!srmdata.d) {
|
|
err = "srmpc_get_data failed";
|
|
return false;
|
|
}
|
|
if (srm_data_write_srm7(srmdata.d, tmpname.toAscii().constData()) < 0) {
|
|
err = "Couldn't write to file " + tmpname + ": " + strerror(errno);
|
|
return false;
|
|
}
|
|
// Read it back in to get the ride start time.
|
|
SrmFileReader reader;
|
|
QStringList errs;
|
|
QFile file(tmpname);
|
|
QStringList errors;
|
|
boost::scoped_ptr<RideFile> ride(
|
|
RideFileFactory::instance().openRideFile(file, errors));
|
|
BOOST_FOREACH(QString err, errors)
|
|
fprintf(stderr, "error: %s\n", err.toAscii().constData());
|
|
filename = ride->startTime().toString("yyyy_MM_dd_hh_mm_ss") + ".srm";
|
|
return true;
|
|
}
|
|
|
|
void
|
|
SrmDevice::cleanup(CommPortPtr dev)
|
|
{
|
|
QString path, err;
|
|
if (!dev2path(dev, path, err))
|
|
assert(false);
|
|
if (QMessageBox::question(0, "Powercontrol",
|
|
"Erase downloaded ride from device memory?",
|
|
"&Erase", "&Save Only", "", 1, 1) == 0) {
|
|
SrmpcConn srm(path);
|
|
if(!srm.d || (srmpc_clear_chunks(srm.d) < 0)) {
|
|
QMessageBox::warning(0, "Error",
|
|
"Error communicating with device.");
|
|
}
|
|
}
|
|
}
|
|
|