[Pkg-running-devel] [openambit] 01/03: Imported Upstream version 0.3
Christian Perrier
bubulle at moszumanska.debian.org
Tue Sep 16 19:33:24 UTC 2014
This is an automated email from the git hooks/post-receive script.
bubulle pushed a commit to branch master
in repository openambit.
commit bcfa2d09a36e1e396c1b297f5f3c706a726b18d8
Author: Christian Perrier <bubulle at debian.org>
Date: Tue Sep 16 21:32:35 2014 +0200
Imported Upstream version 0.3
---
src/libambit/CMakeLists.txt | 2 +-
src/libambit/debian/changelog | 6 +
src/libambit/debian/control | 4 +-
src/libambit/libambit.c | 15 +-
src/libambit/libambit.h | 2 +-
src/openambit/CMakeLists.txt | 6 +-
src/openambit/debian/changelog | 6 +
src/openambit/debian/control | 5 +-
src/openambit/deployment/99-suunto-ambit.rules | 6 +
src/openambit/deployment/openambit.desktop | 2 +-
src/openambit/logentry.cpp | 2 +-
src/openambit/logstore.cpp | 7 +-
src/openambit/mainwindow.cpp | 9 +-
src/openambit/movescount/CMakeLists.txt | 2 +
src/openambit/movescount/movescount.cpp | 262 ++++++++++++--------
src/openambit/movescount/movescount.h | 31 ++-
src/openambit/movescount/movescountjson.cpp | 8 +
src/openambit/movescount/movescountlogchecker.cpp | 107 ++++++++
src/openambit/movescount/movescountlogchecker.h | 32 +++
src/openambit/movescount/movescountxml.cpp | 3 +-
tools/openambit2gpx.py | 263 ++++++++++++++++++++
wireshark_dissector/ambit-dissector.c | 289 ++++++++++++++++++++--
22 files changed, 909 insertions(+), 160 deletions(-)
diff --git a/src/libambit/CMakeLists.txt b/src/libambit/CMakeLists.txt
index e8283b8..e744510 100644
--- a/src/libambit/CMakeLists.txt
+++ b/src/libambit/CMakeLists.txt
@@ -38,7 +38,7 @@ target_link_libraries(
m
)
-set_target_properties(ambit PROPERTIES VERSION 0.2.0 SOVERSION 0)
+set_target_properties(ambit PROPERTIES VERSION 0.3.0 SOVERSION 0)
include_directories(
hidapi
diff --git a/src/libambit/debian/changelog b/src/libambit/debian/changelog
index 453223f..38c535a 100644
--- a/src/libambit/debian/changelog
+++ b/src/libambit/debian/changelog
@@ -1,3 +1,9 @@
+libambit (0.3-1) trusty; urgency=medium
+
+ * New upstream release including support for Ambit 2R
+
+ -- Emil Ljungdahl <emil at openambit.org> Mon, 15 Sep 2014 22:30:01 +0200
+
libambit (0.2-1) saucy; urgency=low
* Initial release
diff --git a/src/libambit/debian/control b/src/libambit/debian/control
index 0b72ecc..88de188 100644
--- a/src/libambit/debian/control
+++ b/src/libambit/debian/control
@@ -11,7 +11,7 @@ Homepage: http://openambit.org/
Package: libambit-dev
Section: libdevel
Architecture: any
-Depends: libambit0 (= ${binary:Version})
+Depends: libambit0 (= ${binary:Version}), ${misc:Depends}
Description: Communication library for Suunto Ambit series
Libambit is the driver library to communicate with the Suunto Ambit series
of sport watches. This is the -dev version of the package container
@@ -20,7 +20,7 @@ Description: Communication library for Suunto Ambit series
Package: libambit0
Section: libs
Architecture: any
-Depends: libudev1, libusb-1.0-0, ${shlibs:Depends}, ${misc:Pre-Depends}, ${misc:Depends}
+Depends: ${shlibs:Depends}, ${misc:Pre-Depends}, ${misc:Depends}
Description: Communication library for Suunto Ambit series
Libambit is the driver library to communicate with the Suunto Ambit series
of sport watches.
diff --git a/src/libambit/libambit.c b/src/libambit/libambit.c
index a7a00eb..deccfb2 100644
--- a/src/libambit/libambit.c
+++ b/src/libambit/libambit.c
@@ -59,9 +59,11 @@ static uint32_t version_number(const uint8_t version[4]);
* Static variables
*/
static ambit_known_device_t known_devices[] = {
+ { SUUNTO_USB_VENDOR_ID, 0x001c, "Finch", {0x00,0x00,0x00,0x00}, "Suunto Ambit3 Sport", false, 0x0400 },
+ { SUUNTO_USB_VENDOR_ID, 0x001b, "Emu", {0x00,0x00,0x00,0x00}, "Suunto Ambit3 Peak", false, 0x0400 },
+ { SUUNTO_USB_VENDOR_ID, 0x001d, "Greentit", {0x00,0x00,0x00,0x00}, "Suunto Ambit2 R", true, 0x0400 },
{ SUUNTO_USB_VENDOR_ID, 0x001a, "Colibri", {0x01,0x01,0x02,0x00}, "Suunto Ambit2 S", true, 0x0400 },
{ SUUNTO_USB_VENDOR_ID, 0x0019, "Duck", {0x01,0x01,0x02,0x00}, "Suunto Ambit2", true, 0x0400 },
- { SUUNTO_USB_VENDOR_ID, 0x001d, "Greentit", {0x00,0x00,0x00,0x00}, "Suunto Ambit2 R", true, 0x0400 },
{ SUUNTO_USB_VENDOR_ID, 0x001a, "Colibri", {0x00,0x02,0x03,0x00}, "Suunto Ambit2 S", false, 0x0400 },
{ SUUNTO_USB_VENDOR_ID, 0x0019, "Duck", {0x00,0x02,0x03,0x00}, "Suunto Ambit2", false, 0x0400 },
{ SUUNTO_USB_VENDOR_ID, 0x001a, "Colibri", {0x00,0x02,0x02,0x00}, "Suunto Ambit2 S (up to 0.2.2)", false, 0x0200 },
@@ -220,8 +222,8 @@ void libambit_sync_display_clear(ambit_object_t *object)
int libambit_date_time_set(ambit_object_t *object, struct tm *tm)
{
- uint8_t date_data[8];
- uint8_t time_data[8] = { 0x09, 0x00, 0x01, 0x00 };
+ uint8_t date_data[8] = { 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00 };
+ uint8_t time_data[8];
int ret = -1;
LOG_INFO("Writing date and time to clock");
@@ -230,9 +232,12 @@ int libambit_date_time_set(ambit_object_t *object, struct tm *tm)
*(uint16_t*)(&date_data[0]) = htole16(1900 + tm->tm_year);
date_data[2] = 1 + tm->tm_mon;
date_data[3] = tm->tm_mday;
- memset(&date_data[4], 0, 4); // ????? Unknown data
+ // byte[4-7] unknown (but set to 0x28000000 in moveslink)
- // Set time
+ // Set time (+date)
+ *(uint16_t*)(&time_data[0]) = htole16(1900 + tm->tm_year);
+ time_data[2] = 1 + tm->tm_mon;
+ time_data[3] = tm->tm_mday;
time_data[4] = tm->tm_hour;
time_data[5] = tm->tm_min;
*(uint16_t*)(&time_data[6]) = htole16(1000*tm->tm_sec);
diff --git a/src/libambit/libambit.h b/src/libambit/libambit.h
index 28d7ef2..02f1ed3 100644
--- a/src/libambit/libambit.h
+++ b/src/libambit/libambit.h
@@ -310,7 +310,7 @@ typedef struct ambit_log_header_s {
uint32_t heartrate_min_time; /* ms */
uint8_t peak_training_effect; /* effect scale 0.1 */
uint8_t activity_type;
- char activity_name[16+1];
+ char activity_name[16+1]; /* name of activity in ISO 8859-1 */
int16_t temperature_max; /* degree celsius scale 0.1 */
int16_t temperature_min; /* degree celsius scale 0.1 */
uint32_t temperature_max_time; /* ms */
diff --git a/src/openambit/CMakeLists.txt b/src/openambit/CMakeLists.txt
index 51706d5..79450ba 100644
--- a/src/openambit/CMakeLists.txt
+++ b/src/openambit/CMakeLists.txt
@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 2.8.5)
project (OPENAMBIT)
-set (OPENAMBIT_VERSION HEAD)
+set (OPENAMBIT_VERSION 0.3)
# Where to lookup modules
set(CMAKE_MODULE_PATH "${OPENAMBIT_SOURCE_DIR}/cmake")
@@ -21,8 +21,6 @@ include_directories (
${CMAKE_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}
${QT_QTCORE_INCLUDE_DIR}
${QT_QTGUI_INCLUDE_DIR}
- ${QT_QTCORE_INCLUDE_DIR}
- ${QT_QTGUI_INCLUDE_DIR}
${QT_QTNETWORK_INCLUDE_DIR}
${LIBAMBIT_INCLUDE_DIR}
)
@@ -86,7 +84,7 @@ add_definitions( -DAPP_VERSION="${OPENAMBIT_VERSION}" )
add_executable ( openambit ${openambit_SRCS} ${UIS} ${RSCS} ${TRS} ${MOCS} )
-target_link_libraries ( openambit ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY} ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY} ${QT_QTNETWORK_LIBRARY} ${LIBAMBIT_LIBS} ${UDEV_LIBS} ${ZLIB_LIBRARY} ${QJSON_LIBRARIES} )
+target_link_libraries ( openambit ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY} ${QT_QTNETWORK_LIBRARY} ${LIBAMBIT_LIBS} ${UDEV_LIBS} ${ZLIB_LIBRARY} ${QJSON_LIBRARIES} )
install ( TARGETS openambit DESTINATION ${CMAKE_INSTALL_BINDIR} )
install ( FILES ${OPENAMBIT_SOURCE_DIR}/deployment/99-suunto-ambit.rules
diff --git a/src/openambit/debian/changelog b/src/openambit/debian/changelog
index e8872fa..49b3547 100644
--- a/src/openambit/debian/changelog
+++ b/src/openambit/debian/changelog
@@ -1,3 +1,9 @@
+openambit (0.3-1) trusty; urgency=medium
+
+ * New upstream release
+
+ -- Emil Ljungdahl <emil at openambit.org> Mon, 15 Sep 2014 23:10:37 +0200
+
openambit (0.2-1) saucy; urgency=low
* Initial release
diff --git a/src/openambit/debian/control b/src/openambit/debian/control
index 0129a5b..0994f7b 100644
--- a/src/openambit/debian/control
+++ b/src/openambit/debian/control
@@ -2,7 +2,7 @@ Source: openambit
Priority: extra
Maintainer: Emil Ljungdahl <emil at openambit.org>
Build-Depends: debhelper (>= 9), cmake (>= 2.8.5), libudev-dev, libqjson-dev, zlib1g-dev,
- libambit-dev (= 0.2-1), libqt4-dev
+ libambit-dev (= 0.3-1), libqt4-dev
Standards-Version: 3.9.4
Section: utils
Homepage: http://openambit.org/
@@ -11,8 +11,7 @@ Homepage: http://openambit.org/
Package: openambit
Architecture: any
-Depends: libudev1, libqjson0, zlib1g, libambit0 (= 0.2-1),
- libqt4-core, libqt4-gui, libqt4-network, ${shlibs:Depends}, ${misc:Depends}
+Depends: libqt4-core, libqt4-gui, libqt4-network, ${shlibs:Depends}, ${misc:Depends}
Description: Synchronize your Suunto Ambit series device
Openambit is GUI application for synchronizing the Suunto Ambit series
of devices with your PC and Suuntos cloudservice movescount.com
diff --git a/src/openambit/deployment/99-suunto-ambit.rules b/src/openambit/deployment/99-suunto-ambit.rules
index 51b68de..edb4c78 100644
--- a/src/openambit/deployment/99-suunto-ambit.rules
+++ b/src/openambit/deployment/99-suunto-ambit.rules
@@ -12,5 +12,11 @@ SUBSYSTEMS=="usb", ATTRS{idVendor}=="1493", ATTRS{idProduct}=="0019", MODE="0666
# Colibri (a.k.a Suunto Ambit2 S)
SUBSYSTEMS=="usb", ATTRS{idVendor}=="1493", ATTRS{idProduct}=="001a", MODE="0666"
+# Emu (a.k.a Suunto Ambit3 Peak)
+SUBSYSTEMS=="usb", ATTRS{idVendor}=="1493", ATTRS{idProduct}=="001b", MODE="0666"
+
+# Finch (a.k.a Suunto Ambit3 Sport)
+SUBSYSTEMS=="usb", ATTRS{idVendor}=="1493", ATTRS{idProduct}=="001c", MODE="0666"
+
# Greentit (a.k.a Suunto Ambit2 R)
SUBSYSTEMS=="usb", ATTRS{idVendor}=="1493", ATTRS{idProduct}=="001d", MODE="0666"
diff --git a/src/openambit/deployment/openambit.desktop b/src/openambit/deployment/openambit.desktop
index ca75dc0..3b425d0 100644
--- a/src/openambit/deployment/openambit.desktop
+++ b/src/openambit/deployment/openambit.desktop
@@ -1,5 +1,5 @@
[Desktop Entry]
-Version=HEAD
+Version=0.3
Type=Application
Name=Openambit
Comment=Open source synchronization for Suunto Ambit series
diff --git a/src/openambit/logentry.cpp b/src/openambit/logentry.cpp
index 351585f..2190516 100644
--- a/src/openambit/logentry.cpp
+++ b/src/openambit/logentry.cpp
@@ -147,7 +147,7 @@ bool LogEntry::isUploaded(){
QString LogEntry::toHtml(){
QString log_html;
- log_html += "<h1>" + QString(this->logEntry->header.activity_name) + "</h1>";
+ log_html += "<h1>" + QString::fromLatin1(this->logEntry->header.activity_name) + "</h1>";
if (this->isUploaded()){
log_html += "<a href='http://www.movescount.com/moves/move" + this->movescountId + "'>see on movescount.com</a>";
}
diff --git a/src/openambit/logstore.cpp b/src/openambit/logstore.cpp
index 12eb85d..fe03fe3 100644
--- a/src/openambit/logstore.cpp
+++ b/src/openambit/logstore.cpp
@@ -79,6 +79,7 @@ typedef struct sample_lap_event_type_s {
} sample_lap_event_type_t;
static sample_lap_event_type_t sampleLapEventTypeNames[] = {
+ { 0x00, "Autolap" },
{ 0x01, "Manual" },
{ 0x14, "High Interval" },
{ 0x15, "Low Interval" },
@@ -207,7 +208,7 @@ LogEntry *LogStore::readInternal(QString path)
XMLReader reader(retEntry);
if (!reader.read(&logfile)) {
QString error = reader.errorString();
- qDebug() << error;
+ qDebug() << "Failed to read " << path << ": " << error;
delete retEntry;
retEntry = NULL;
}
@@ -626,7 +627,7 @@ void LogStore::XMLReader::readLogHeader()
logEntry->logEntry->header.activity_type = xml.readElementText().toUInt();
}
else if (xml.name() == "Activity") {
- QByteArray ba = xml.readElementText().toLocal8Bit();
+ QByteArray ba = xml.readElementText().toLatin1();
const char *c_str = ba.data();
strncpy(logEntry->logEntry->header.activity_name, c_str, 16);
logEntry->logEntry->header.activity_name[16] = 0;
@@ -1371,7 +1372,7 @@ bool LogStore::XMLWriter::writeLogEntry()
xml.writeEndElement();
xml.writeTextElement("PeakTrainingEffect", QString("%1").arg(logEntry->header.peak_training_effect));
xml.writeTextElement("ActivityType", QString("%1").arg(logEntry->header.activity_type));
- xml.writeTextElement("Activity", QString(logEntry->header.activity_name));
+ xml.writeTextElement("Activity", QString::fromLatin1(logEntry->header.activity_name));
xml.writeStartElement("Temperature");
xml.writeTextElement("Max", QString("%1").arg(logEntry->header.temperature_max));
xml.writeTextElement("Min", QString("%1").arg(logEntry->header.temperature_min));
diff --git a/src/openambit/mainwindow.cpp b/src/openambit/mainwindow.cpp
index 714e471..d170aeb 100644
--- a/src/openambit/mainwindow.cpp
+++ b/src/openambit/mainwindow.cpp
@@ -119,9 +119,12 @@ MainWindow::~MainWindow()
{
deviceWorkerThread.quit();
deviceWorkerThread.wait();
-
delete deviceManager;
+ if (movesCount != NULL) {
+ movesCount->exit();
+ }
+
delete trayIcon;
delete trayIconMinimizeRestoreAction;
delete trayIconSyncAction;
@@ -382,7 +385,9 @@ void MainWindow::logItemSelected(QListWidgetItem *current,QListWidgetItem *previ
if (current != NULL) {
logEntry = logStore.read(current->data(Qt::UserRole).toString());
- ui->logDetail->setHtml(logEntry->toHtml());
+ if (logEntry != NULL) {
+ ui->logDetail->setHtml(logEntry->toHtml());
+ }
delete logEntry;
}
diff --git a/src/openambit/movescount/CMakeLists.txt b/src/openambit/movescount/CMakeLists.txt
index 95b2947..c0a8c32 100644
--- a/src/openambit/movescount/CMakeLists.txt
+++ b/src/openambit/movescount/CMakeLists.txt
@@ -4,6 +4,7 @@ set ( openambit_SRCS
${CMAKE_CURRENT_SOURCE_DIR}/movescountjson.cpp
${CMAKE_CURRENT_SOURCE_DIR}/movescountlogdirentry.cpp
${CMAKE_CURRENT_SOURCE_DIR}/movescountxml.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/movescountlogchecker.cpp
PARENT_SCOPE
)
@@ -13,5 +14,6 @@ set ( openambit_MOCS
${CMAKE_CURRENT_SOURCE_DIR}/movescountjson.h
${CMAKE_CURRENT_SOURCE_DIR}/movescountlogdirentry.h
${CMAKE_CURRENT_SOURCE_DIR}/movescountxml.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/movescountlogchecker.h
PARENT_SCOPE
)
diff --git a/src/openambit/movescount/movescount.cpp b/src/openambit/movescount/movescount.cpp
index 1867f0d..94d3016 100644
--- a/src/openambit/movescount/movescount.cpp
+++ b/src/openambit/movescount/movescount.cpp
@@ -47,6 +47,24 @@ MovesCount* MovesCount::instance()
return m_Instance;
}
+void MovesCount::exit()
+{
+ static QMutex mutex;
+
+ exiting = true;
+
+ mutex.lock();
+ if (m_Instance) {
+ workerThread.quit();
+ workerThread.wait();
+
+ delete logChecker;
+
+ m_Instance = NULL;
+ }
+ mutex.unlock();
+}
+
void MovesCount::setBaseAddress(QString baseAddress)
{
this->baseAddress = baseAddress;
@@ -97,6 +115,134 @@ bool MovesCount::isAuthorized()
int MovesCount::getOrbitalData(u_int8_t **data)
{
int ret = -1;
+
+ if (&workerThread == QThread::currentThread()) {
+ ret = getOrbitalDataInThread(data);
+ }
+ else {
+ QMetaObject::invokeMethod(this, "getOrbitalDataInThread", Qt::BlockingQueuedConnection,
+ Q_RETURN_ARG(int, ret),
+ Q_ARG(u_int8_t **, data));
+ }
+
+ return ret;
+}
+
+int MovesCount::getPersonalSettings(ambit_personal_settings_t *settings)
+{
+ int ret = -1;
+
+ if (&workerThread == QThread::currentThread()) {
+ ret = getPersonalSettingsInThread(settings);
+ }
+ else {
+ QMetaObject::invokeMethod(this, "getPersonalSettingsInThread", Qt::BlockingQueuedConnection,
+ Q_RETURN_ARG(int, ret),
+ Q_ARG(ambit_personal_settings_t *, settings));
+ }
+
+ return ret;
+}
+
+void MovesCount::getDeviceSettings()
+{
+ QMetaObject::invokeMethod(this, "getDeviceSettingsInThread", Qt::AutoConnection);
+}
+
+QList<MovesCountLogDirEntry> MovesCount::getMovescountEntries(QDate startTime, QDate endTime)
+{
+ QList<MovesCountLogDirEntry> retList;
+
+ if (&workerThread == QThread::currentThread()) {
+ retList = getMovescountEntriesInThread(startTime, endTime);
+ }
+ else {
+ QMetaObject::invokeMethod(this, "getMovescountEntriesInThread", Qt::BlockingQueuedConnection,
+ Q_RETURN_ARG(QList<MovesCountLogDirEntry>, retList),
+ Q_ARG(QDate, startTime),
+ Q_ARG(QDate, endTime));
+ }
+
+ return retList;
+}
+
+void MovesCount::checkAuthorization()
+{
+ QMetaObject::invokeMethod(this, "checkAuthorizationInThread", Qt::AutoConnection);
+}
+
+void MovesCount::checkLatestFirmwareVersion()
+{
+ QMetaObject::invokeMethod(this, "checkLatestFirmwareVersionInThread", Qt::AutoConnection);
+}
+
+void MovesCount::writePersonalSettings(ambit_personal_settings_t *settings)
+{
+ if (&workerThread == QThread::currentThread()) {
+ writePersonalSettingsInThread(settings);
+ }
+ else {
+ QMetaObject::invokeMethod(this, "writePersonalSettingsInThread", Qt::BlockingQueuedConnection,
+ Q_ARG(ambit_personal_settings_t *, settings));
+ }
+}
+
+void MovesCount::writeLog(LogEntry *logEntry)
+{
+ if (&workerThread == QThread::currentThread()) {
+ writeLogInThread(logEntry);
+ }
+ else {
+ QMetaObject::invokeMethod(this, "writeLogInThread", Qt::BlockingQueuedConnection,
+ Q_ARG(LogEntry *, logEntry));
+ }
+}
+
+void MovesCount::authCheckFinished()
+{
+ if (authCheckReply != NULL) {
+ checkReplyAuthorization(authCheckReply);
+ authCheckReply->deleteLater();
+ authCheckReply = NULL;
+ }
+}
+
+void MovesCount::firmwareReplyFinished()
+{
+ u_int8_t fw_version[4];
+
+ if (firmwareCheckReply != NULL) {
+ if (firmwareCheckReply->error() == QNetworkReply::NoError) {
+ QByteArray data = firmwareCheckReply->readAll();
+ if (jsonParser.parseFirmwareVersionReply(data, fw_version) == 0) {
+ if (fw_version[0] > device_info.fw_version[0] ||
+ (fw_version[0] == device_info.fw_version[0] && (fw_version[1] > device_info.fw_version[1] ||
+ (fw_version[1] == device_info.fw_version[1] && ((fw_version[2] | (fw_version[3] << 8)) > (device_info.fw_version[2] | (device_info.fw_version[3] << 8))))))) {
+ emit newerFirmwareExists(QByteArray((const char*)fw_version, 4));
+ }
+ }
+ }
+
+ firmwareCheckReply->deleteLater();
+ firmwareCheckReply = NULL;
+ }
+}
+
+void MovesCount::recheckAuthorization()
+{
+ getDeviceSettings();
+}
+
+void MovesCount::handleAuthorizationSignal(bool authorized)
+{
+ if (authorized) {
+ logChecker->run();
+ }
+}
+
+int MovesCount::getOrbitalDataInThread(u_int8_t **data)
+{
+ int ret = -1;
QNetworkReply *reply;
reply = syncGET("/devices/gpsorbit/binary", "", false);
@@ -118,13 +264,13 @@ int MovesCount::getOrbitalData(u_int8_t **data)
return ret;
}
-int MovesCount::getPersonalSettings(ambit_personal_settings_t *settings)
+int MovesCount::getPersonalSettingsInThread(ambit_personal_settings_t *settings)
{
Q_UNUSED(settings);
return 0;
}
-int MovesCount::getDeviceSettings()
+void MovesCount::getDeviceSettingsInThread()
{
QNetworkReply *reply;
@@ -132,14 +278,10 @@ int MovesCount::getDeviceSettings()
if (checkReplyAuthorization(reply)) {
QByteArray _data = reply->readAll();
-
- return 0;
}
-
- return -1;
}
-QList<MovesCountLogDirEntry> MovesCount::getMovescountEntries(QDate startTime, QDate endTime)
+QList<MovesCountLogDirEntry> MovesCount::getMovescountEntriesInThread(QDate startTime, QDate endTime)
{
QNetworkReply *reply;
QList<MovesCountLogDirEntry> retList;
@@ -158,7 +300,7 @@ QList<MovesCountLogDirEntry> MovesCount::getMovescountEntries(QDate startTime, Q
return retList;
}
-void MovesCount::checkAuthorization()
+void MovesCount::checkAuthorizationInThread()
{
if (authCheckReply == NULL) {
authCheckReply = asyncGET("/members/private", "", true);
@@ -166,7 +308,7 @@ void MovesCount::checkAuthorization()
}
}
-void MovesCount::checkLatestFirmwareVersion()
+void MovesCount::checkLatestFirmwareVersionInThread()
{
if (firmwareCheckReply == NULL) {
firmwareCheckReply = asyncGET("/devices/" + QString("%1/%2.%3.%4")
@@ -178,12 +320,12 @@ void MovesCount::checkLatestFirmwareVersion()
}
}
-void MovesCount::writePersonalSettings(ambit_personal_settings_t *settings)
+void MovesCount::writePersonalSettingsInThread(ambit_personal_settings_t *settings)
{
Q_UNUSED(settings);
}
-void MovesCount::writeLog(LogEntry *logEntry)
+void MovesCount::writeLogInThread(LogEntry *logEntry)
{
QByteArray output;
QNetworkReply *reply;
@@ -204,53 +346,13 @@ void MovesCount::writeLog(LogEntry *logEntry)
}
}
-void MovesCount::authCheckFinished()
-{
- if (authCheckReply != NULL) {
- checkReplyAuthorization(authCheckReply);
- authCheckReply->deleteLater();
- authCheckReply = NULL;
- }
-}
-
-void MovesCount::firmwareReplyFinished()
-{
- u_int8_t fw_version[4];
-
- if (firmwareCheckReply != NULL) {
- if (firmwareCheckReply->error() == QNetworkReply::NoError) {
- QByteArray data = firmwareCheckReply->readAll();
- if (jsonParser.parseFirmwareVersionReply(data, fw_version) == 0) {
- if (fw_version[0] > device_info.fw_version[0] ||
- (fw_version[0] == device_info.fw_version[0] && (fw_version[1] > device_info.fw_version[1] ||
- (fw_version[1] == device_info.fw_version[1] && ((fw_version[2] | (fw_version[3] << 8)) > (device_info.fw_version[2] | (device_info.fw_version[3] << 8))))))) {
- emit newerFirmwareExists(QByteArray((const char*)fw_version, 4));
- }
- }
- }
-
- firmwareCheckReply->deleteLater();
- firmwareCheckReply = NULL;
- }
-}
-
-void MovesCount::recheckAuthorization()
-{
- getDeviceSettings();
-}
-
-void MovesCount::handleAuthorizationSignal(bool authorized)
-{
- if (authorized) {
- checkUploadedLogs();
- }
-}
-
MovesCount::MovesCount() :
- authorized(false), uploadedCheckRunning(false), firmwareCheckReply(NULL), authCheckReply(NULL)
+ exiting(false), authorized(false), firmwareCheckReply(NULL), authCheckReply(NULL)
{
this->manager = new QNetworkAccessManager(this);
+ this->logChecker = new MovesCountLogChecker();
+
this->moveToThread(&workerThread);
workerThread.start();
@@ -278,58 +380,6 @@ bool MovesCount::checkReplyAuthorization(QNetworkReply *reply)
return authorized;
}
-void MovesCount::checkUploadedLogs()
-{
- QDateTime firstUnknown = QDateTime::currentDateTime();
- QDateTime lastUnknown = QDateTime::fromTime_t(0);
- QList<LogEntry*> missingEntries;
-
- if (!uploadedCheckRunning) {
- uploadedCheckRunning = true;
-
- QList<LogStore::LogDirEntry> entries = logStore.dir();
- foreach(LogStore::LogDirEntry entry, entries) {
- LogEntry *logEntry = logStore.read(entry);
- if (logEntry->movescountId.length() == 0) {
- missingEntries.append(logEntry);
- if (logEntry->time < firstUnknown) {
- firstUnknown = logEntry->time;
- }
- if (logEntry->time > lastUnknown) {
- lastUnknown = logEntry->time;
- }
- }
- else {
- delete logEntry;
- }
- }
-
- if (missingEntries.count() > 0) {
- QList<MovesCountLogDirEntry> movescountEntries = getMovescountEntries(firstUnknown.date(), lastUnknown.date());
- foreach(MovesCountLogDirEntry entry, movescountEntries) {
- foreach(LogEntry *logEntry, missingEntries) {
- if (entry.time == logEntry->time) {
- missingEntries.removeOne(logEntry);
- logStore.storeMovescountId(logEntry->device, logEntry->time, entry.moveId);
- delete logEntry;
- break;
- }
- }
- }
-
- // Delete remaining entries
- while (missingEntries.count() > 0) {
- LogEntry *logEntry = missingEntries.first();
- writeLog(logEntry);
- missingEntries.removeOne(logEntry);
- delete logEntry;
- }
- }
-
- uploadedCheckRunning = false;
- }
-}
-
QNetworkReply *MovesCount::asyncGET(QString path, QString additionalHeaders, bool auth)
{
QNetworkRequest req;
diff --git a/src/openambit/movescount/movescount.h b/src/openambit/movescount/movescount.h
index 045481b..456a2a3 100644
--- a/src/openambit/movescount/movescount.h
+++ b/src/openambit/movescount/movescount.h
@@ -35,12 +35,14 @@
#include "logstore.h"
#include "movescountjson.h"
#include "movescountlogdirentry.h"
+#include "movescountlogchecker.h"
class MovesCount : public QObject
{
Q_OBJECT
public:
static MovesCount* instance();
+ void exit();
void setBaseAddress(QString baseAddress);
void setAppkey(QString appkey);
@@ -52,31 +54,40 @@ public:
bool isAuthorized();
int getOrbitalData(u_int8_t **data);
int getPersonalSettings(ambit_personal_settings_t *settings);
- int getDeviceSettings();
+ void getDeviceSettings();
QList<MovesCountLogDirEntry> getMovescountEntries(QDate startTime, QDate endTime);
-signals:
- void newerFirmwareExists(QByteArray fw_version);
- void movesCountAuth(bool authorized);
- void logMoveID(QString device, QDateTime time, QString moveID);
-
-public slots:
+
void checkAuthorization();
void checkLatestFirmwareVersion();
void writePersonalSettings(ambit_personal_settings_t *settings);
void writeLog(LogEntry *logEntry);
+signals:
+ void newerFirmwareExists(QByteArray fw_version);
+ void movesCountAuth(bool authorized);
+ void logMoveID(QString device, QDateTime time, QString moveID);
+
private slots:
void authCheckFinished();
void firmwareReplyFinished();
void recheckAuthorization();
void handleAuthorizationSignal(bool authorized);
+ int getOrbitalDataInThread(u_int8_t **data);
+ int getPersonalSettingsInThread(ambit_personal_settings_t *settings);
+ void getDeviceSettingsInThread();
+ QList<MovesCountLogDirEntry> getMovescountEntriesInThread(QDate startTime, QDate endTime);
+
+ void checkAuthorizationInThread();
+ void checkLatestFirmwareVersionInThread();
+ void writePersonalSettingsInThread(ambit_personal_settings_t *settings);
+ void writeLogInThread(LogEntry *logEntry);
+
private:
MovesCount();
~MovesCount();
bool checkReplyAuthorization(QNetworkReply *reply);
- void checkUploadedLogs();
QNetworkReply *asyncGET(QString path, QString additionalHeaders, bool auth);
QNetworkReply *syncGET(QString path, QString additionalHeaders, bool auth);
@@ -84,8 +95,8 @@ private:
QNetworkReply *asyncPOST(QString path, QString additionalHeaders, QByteArray &postData, bool auth);
QNetworkReply *syncPOST(QString path, QString additionalHeaders, QByteArray &postData, bool auth);
+ bool exiting;
bool authorized;
- bool uploadedCheckRunning;
QString baseAddress;
QString appkey;
@@ -103,6 +114,8 @@ private:
LogStore logStore;
+ MovesCountLogChecker *logChecker;
+
QThread workerThread;
};
diff --git a/src/openambit/movescount/movescountjson.cpp b/src/openambit/movescount/movescountjson.cpp
index bbb30b7..92f4c72 100644
--- a/src/openambit/movescount/movescountjson.cpp
+++ b/src/openambit/movescount/movescountjson.cpp
@@ -175,6 +175,14 @@ int MovesCountJSON::generateLogData(LogEntry *logEntry, QByteArray &output)
}
case ambit_log_sample_type_lapinfo:
switch (sample->u.lapinfo.event_type) {
+ case 0x00: /* autolap = 5 */
+ {
+ QVariantMap tmpMap;
+ tmpMap.insert("LocalTime", dateTimeString(localBaseTime.addMSecs(sample->time)));
+ tmpMap.insert("Type", 5);
+ marksContent.append(tmpMap);
+ break;
+ }
case 0x01: /* manual = 0 */
case 0x16: /* interval = 0 */
{
diff --git a/src/openambit/movescount/movescountlogchecker.cpp b/src/openambit/movescount/movescountlogchecker.cpp
new file mode 100644
index 0000000..57e54f6
--- /dev/null
+++ b/src/openambit/movescount/movescountlogchecker.cpp
@@ -0,0 +1,107 @@
+#include "movescountlogchecker.h"
+#include "movescount.h"
+
+MovesCountLogChecker::MovesCountLogChecker(QObject *parent) :
+ QObject(parent), running(false), cancelRun(false)
+{
+ this->moveToThread(&workerThread);
+ workerThread.start();
+}
+
+MovesCountLogChecker::~MovesCountLogChecker()
+{
+ cancel();
+ workerThread.exit();
+ workerThread.wait();
+}
+
+void MovesCountLogChecker::run()
+{
+ if (!running) {
+ QMetaObject::invokeMethod(this, "checkUploadedLogs", Qt::AutoConnection);
+ }
+}
+
+bool MovesCountLogChecker::isRunning()
+{
+ return running;
+}
+
+void MovesCountLogChecker::cancel()
+{
+ cancelRun = true;
+}
+
+void MovesCountLogChecker::checkUploadedLogs()
+{
+ QDateTime firstUnknown = QDateTime::currentDateTime();
+ QDateTime lastUnknown = QDateTime::fromTime_t(0);
+ QList<LogEntry*> missingEntries;
+ MovesCount *movescount = MovesCount::instance();
+
+ running = true;
+
+ QList<LogStore::LogDirEntry> entries = logStore.dir();
+ foreach(LogStore::LogDirEntry entry, entries) {
+ // This is a long operation, exit if application want to quit
+ if (cancelRun) {
+ cancelRun = false;
+ return;
+ }
+ LogEntry *logEntry = logStore.read(entry);
+ if (logEntry != NULL) {
+ if (logEntry->movescountId.length() == 0) {
+ missingEntries.append(logEntry);
+ if (logEntry->time < firstUnknown) {
+ firstUnknown = logEntry->time;
+ }
+ if (logEntry->time > lastUnknown) {
+ lastUnknown = logEntry->time;
+ }
+ }
+ else {
+ delete logEntry;
+ }
+ }
+ }
+
+ if (missingEntries.count() > 0) {
+ // This is a long operation, exit if application want to quit
+ if (cancelRun) {
+ cancelRun = false;
+ return;
+ }
+ QList<MovesCountLogDirEntry> movescountEntries = movescount->getMovescountEntries(firstUnknown.date(), lastUnknown.date());
+ foreach(MovesCountLogDirEntry entry, movescountEntries) {
+ // This is a long operation, exit if application want to quit
+ if (cancelRun) {
+ cancelRun = false;
+ return;
+ }
+ foreach(LogEntry *logEntry, missingEntries) {
+ if (entry.time == logEntry->time) {
+ missingEntries.removeOne(logEntry);
+ logStore.storeMovescountId(logEntry->device, logEntry->time, entry.moveId);
+ delete logEntry;
+ break;
+ }
+ }
+ }
+
+ // Delete remaining entries
+ while (missingEntries.count() > 0) {
+ // This is a long operation, exit if application want to quit
+ if (cancelRun) {
+ cancelRun = false;
+ return;
+ }
+ LogEntry *logEntry = missingEntries.first();
+ movescount->writeLog(logEntry);
+ missingEntries.removeOne(logEntry);
+ delete logEntry;
+ }
+ }
+
+ cancelRun = false;
+ running = false;
+}
diff --git a/src/openambit/movescount/movescountlogchecker.h b/src/openambit/movescount/movescountlogchecker.h
new file mode 100644
index 0000000..213dc71
--- /dev/null
+++ b/src/openambit/movescount/movescountlogchecker.h
@@ -0,0 +1,32 @@
+#ifndef MOVESCOUNTLOGCHECKER_H
+#define MOVESCOUNTLOGCHECKER_H
+
+#include <QObject>
+#include <QThread>
+
+#include <libambit.h>
+
+#include "logentry.h"
+#include "logstore.h"
+
+class MovesCountLogChecker : public QObject
+{
+ Q_OBJECT
+public:
+ explicit MovesCountLogChecker(QObject *parent = 0);
+ ~MovesCountLogChecker();
+ void run();
+ bool isRunning();
+ void cancel();
+private slots:
+ void checkUploadedLogs();
+
+private:
+ bool running;
+ bool cancelRun;
+
+ LogStore logStore;
+ QThread workerThread;
+};
+
+#endif // MOVESCOUNTLOGCHECKER_H
diff --git a/src/openambit/movescount/movescountxml.cpp b/src/openambit/movescount/movescountxml.cpp
index 523bfd1..6d1ea33 100644
--- a/src/openambit/movescount/movescountxml.cpp
+++ b/src/openambit/movescount/movescountxml.cpp
@@ -42,6 +42,7 @@ static typename_lookup_entry_t sampleAltitudeSourceNames[] = {
};
static typename_lookup_entry_t sampleLapEventTypeNames[] = {
+ { 0x00, "Distance" },
{ 0x01, "Manual" },
{ 0x14, "High Interval" },
{ 0x15, "Low Interval" },
@@ -240,7 +241,7 @@ bool MovesCountXML::XMLWriter::writeLogEntry()
xml.writeTextElement("PeakTrainingEffect", QString::number((double)logEntry->logEntry->header.peak_training_effect/10.0, 'g', 16));
}
xml.writeTextElement("ActivityType", QString("%1").arg(logEntry->logEntry->header.activity_type));
- xml.writeTextElement("Activity", QString(logEntry->logEntry->header.activity_name));
+ xml.writeTextElement("Activity", QString::fromLatin1(logEntry->logEntry->header.activity_name));
xml.writeStartElement("Temperature");
xml.writeTextElement("Max", QString::number((double)logEntry->logEntry->header.temperature_max/10.0 + 273.15, 'g', 16));
xml.writeTextElement("Min", QString::number((double)logEntry->logEntry->header.temperature_min/10.0 + 273.15, 'g', 16));
diff --git a/tools/openambit2gpx.py b/tools/openambit2gpx.py
new file mode 100644
index 0000000..4f7b813
--- /dev/null
+++ b/tools/openambit2gpx.py
@@ -0,0 +1,263 @@
+#!/usr/bin/python
+
+""" concerts the *.log files produced by openambit in ~/.openambit/ to standard gpx format.
+usage: ./openambit2gpx.py inputfile outputFile
+"""
+
+#from lxml import etree # does not allow namespace prefixes which are required for gpx extensions; everything else in this script would work otherwise with lxml
+import xml.etree.ElementTree as etree
+import math
+import sys
+
+##############################
+## getting input parameters ##
+##############################
+
+fileIn=sys.argv[1]
+fileOut=sys.argv[2]
+
+
+###########################################
+## setting variables up, starting output ##
+###########################################
+
+fOut=open(fileOut, 'w')
+
+fOut.write("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>\n\n")
+fOut.write('<gpx xmlns="http://www.topografix.com/GPX/1/1" version="1.1" creator="Ascent 1.11.9" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:gpxdata="http://www.cluetrust.com/XML/GPXDATA/1/0" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd http://www.cluetrust.com/XML/GPXDATA/1/0 http://www.cluetrust.com/Schemas/gpxdata10.xsd">')
+fOut.write(" <trk>\n")
+fOut.write(" <trkseg>\n")
+
+rootIn=etree.parse(fileIn)
+
+latLast=None
+lonLast=None
+timeLast=None
+altitudeLast=None
+hrLast=None
+cadenceLast=None
+speedLast=None
+tempLast=None
+airpressureLast=None
+latLatest=None
+lonLatest=None
+timeGPSLatest=None
+
+lapCount=0
+lapArray=[0]
+maxLap=0
+
+def utcSplitConvSeconds(utcTime):
+ """ Splits the UTC time code YYYY-MM-DDTHH:MM:SS.SSSZ, keeps only the time part and converts it into seconds.
+ """
+
+ import math
+ tmpTime=utcTime.split("T")[1].split("Z")[0].split(":")
+ tmpDay=int(utcTime.split("T")[0].split("-")[2])
+ secs=float(tmpDay)*24*3600 + float(tmpTime[0])*3600 + float(tmpTime[1])*60 + float(tmpTime[2])
+
+ return secs
+
+def timeDiff(utcTime1,utcTime2):
+ """ Computes the difference, in seconds, between an earlier (utcTime1) and a later date (utcTime2). Only safe for dates within the same month or less than 2 days apart if on the boundary of a month.
+ """
+
+ secs1=utcSplitConvSeconds(utcTime1)
+ secs2=utcSplitConvSeconds(utcTime2)
+
+ if int(utcTime2.split("T")[0].split("-")[2])==1:
+ secs1-=float(utcTime2.split("T")[0].split("-")[2])*24*3600 # if second date is on a first of a month, then the previous day gets reset to day 0 of the same month
+
+ return secs2-secs1
+
+
+###########################
+## getting activity data ##
+###########################
+
+for element in rootIn.iterfind("Log/Samples/Sample"):
+ trk=etree.Element("trkpt")
+
+ lat=element.findtext("Latitude")
+ lon=element.findtext("Longitude")
+ time=element.findtext("UTC")
+
+ altitude=element.findtext("Altitude") if element.findtext("Altitude")!=None else altitudeLast
+ hr=element.findtext("HR") if element.findtext("HR")!=None else hrLast
+ cadence=element.findtext("Cadence") if element.findtext("cadence")!=None else cadenceLast
+ speed=element.findtext("Speed") if element.findtext("Speed")!=None else speedLast
+ temp=str(float(element.findtext("Temperature"))/10) if element.findtext("Temperature")!=None else tempLast
+ airpressure=element.findtext("SeaLevelPressure") if element.findtext("SeaLevelPressure")!=None else airpressureLast
+
+ sampType=element.findtext("Type")
+ if sampType=="lap-info":
+ lapType=element.findtext("Lap/Type")
+ lapDate=element.findtext("Lap/DateTime")
+ lapDuration=element.findtext("Lap/Duration")
+ lapDistance=element.findtext("Lap/Distance")
+ lapUtc=element.findtext("UTC")
+ lapPreviousLat=latLatest
+ lapPreviousLon=lonLatest
+ lapPreviousTime=timeGPSLatest
+ lapCheck=1
+
+ if lapCount==0:
+ lapArray[0]=[lapType,lapDate,lapDuration,lapDistance,lapUtc,lapPreviousLat,lapPreviousLon,lapPreviousTime,0,0,0]
+ else:
+ lapArray.append([lapType,lapDate,lapDuration,lapDistance,lapUtc,lapPreviousLat,lapPreviousLon,lapPreviousTime,0,0,0])
+ lapCount+=1
+
+ maxLap=lapCount-1
+
+ if lat!=None and lon!=None:
+ lat=float(lat)/10000000
+ lon=float(lon)/10000000
+
+ trk.set("lat",str(lat))
+ trk.set("lon",str(lon))
+
+ latLatest=str(lat)
+ lonLatest=str(lon)
+ timeGPSLatest=time
+
+ if lapCheck==1:
+ lapArray[lapCount-1][8]=latLatest
+ lapArray[lapCount-1][9]=lonLatest
+ lapArray[lapCount-1][10]=timeGPSLatest
+ lapCheck=0
+
+ if altitude!=None:
+ etree.SubElement(trk,"ele").text=altitude
+ elif altitudeLast!=None:
+ etree.SubElement(trk,"ele").text=altitudeLast
+
+ if time!=None:
+ etree.SubElement(trk,"time").text=time
+ elif timeLast!=None:
+ etree.SubElement(trk,"time").text=timeLast
+
+ if hr!=None or cadence!=None or speed!=None or temp!=None or airpressure!=None:
+ extGpx=etree.SubElement(trk,"extensions")
+ if hr!=None: etree.SubElement(extGpx,"gpxdata:hr").text=hr
+ if cadence!=None: etree.SubElement(extGpx,"gpxdata:cadence").text=cadence
+ if temp!=None: etree.SubElement(extGpx,"gpxdata:atemp").text=temp
+ if speed!=None: etree.SubElement(extGpx,"gpxdata:speed").text=speed
+ if airpressure!=None: etree.SubElement(extGpx,"gpxdata:SeaLevelPressure").text=airpressure
+
+ fOut.write(" "+etree.tostring(trk)+"\n")
+
+ latLast=lat
+ lonLast=lon
+ timeLast=time
+ altitudeLast=altitude
+ hrLast=hr
+ cadenceLast=cadence
+ speedLast=speed
+ tempLast=temp
+ airpressureLast=airpressure
+
+ lat=None
+ lon=None
+ time=None
+ altitude=None
+ hr=None
+ cadence=None
+ speed=None
+ temp=None
+ airpressure=None
+
+fOut.write(" </trkseg>\n")
+fOut.write(" </trk>\n")
+
+
+#############################
+## getting lap information ##
+#############################
+
+lapCount=0
+previousEndTime=0
+
+fOut.write(" <extensions>\n")
+
+for i in range(0,len(lapArray)):
+ if lapArray[i][0]=='Manual':
+ lap=etree.Element("gpxdata:lap")
+ lap.set("xmlns","http://www.cluetrust.com/XML/GPXDATA/1/0")
+
+ startTime=lapArray[0][4] if lapCount==0 else previousEndTime
+ previousEndTime=lapArray[i][4]
+
+ etree.SubElement(lap,'index').text=str(lapCount)
+ etree.SubElement(lap,'startTime').text=startTime
+ etree.SubElement(lap,'elapsedTime').text=str(float(lapArray[i][2])/1000)
+ etree.SubElement(lap,'distance').text=lapArray[i][3]
+
+ latInterPolSP=lapArray[0][8] if lapCount==0 else previousLatEP
+ lonInterPolSP=lapArray[0][9] if lapCount==0 else previousLonEP
+
+ if i==maxLap:
+ latInterPolEP=lapArray[i][5]
+ else:
+ t=lapArray[i][4]
+ t1=lapArray[i][7]
+ t2=lapArray[i][10]
+ lat1=float(lapArray[i][5])
+ lat2=float(lapArray[i][8])
+ latInterPolEP=str( ((lat2-lat1)/timeDiff(t1,t2))*timeDiff(t1,t) + lat1 )
+ if i==maxLap:
+ lonInterPolEP=lapArray[i][6]
+ else:
+ t=lapArray[i][4]
+ t1=lapArray[i][7]
+ t2=lapArray[i][10]
+ lon1=float(lapArray[i][6])
+ lon2=float(lapArray[i][9])
+ lonInterPolEP=str( ((lon2-lon1)/timeDiff(t1,t2))*timeDiff(t1,t) + lon1 )
+ previousLatEP=latInterPolEP
+ previousLonEP=lonInterPolEP
+ SP=etree.SubElement(lap,'startPoint')
+ SP.text=' '
+ SP.set('lat',str(latInterPolSP))
+ SP.set('lon',str(lonInterPolSP))
+ EP=etree.SubElement(lap,'endPoint')
+ EP.text=' '
+ EP.set('lat',str(latInterPolEP))
+ EP.set('lon',str(lonInterPolEP))
+
+ etree.SubElement(lap,'intensity').text='active'
+ trigger=etree.SubElement(lap,'trigger')
+ trigger.text=' '
+ trigger.set('kind','manual')
+
+ #the elements below need to be added for the gpx file to be understood; data all set to 0
+ etree.SubElement(lap,'calories').text='0'
+ sumHrAvg=etree.SubElement(lap,'summary')
+ sumHrAvg.text='0'
+ sumHrAvg.set('kind','avg')
+ sumHrAvg.set('name','hr')
+ sumHrMax=etree.SubElement(lap,'summary')
+ sumHrMax.text='0'
+ sumHrMax.set('kind','max')
+ sumHrMax.set('name','hr')
+ sumCadAvg=etree.SubElement(lap,'summary')
+ sumCadAvg.text='0'
+ sumCadAvg.set('kind','avg')
+ sumCadAvg.set('name','cadence')
+ sumSpeedMax=etree.SubElement(lap,'summary')
+ sumSpeedMax.text='0'
+ sumSpeedMax.set('kind','max')
+ sumSpeedMax.set('name','speed')
+
+ lapCount+=1
+
+ fOut.write(" "+etree.tostring(lap)+"\n")
+
+fOut.write(" </extensions>\n")
+
+
+#########################
+## closing output file ##
+#########################
+
+fOut.write("</gpx>\n")
+fOut.close()
diff --git a/wireshark_dissector/ambit-dissector.c b/wireshark_dissector/ambit-dissector.c
index e9e5e77..f664607 100644
--- a/wireshark_dissector/ambit-dissector.c
+++ b/wireshark_dissector/ambit-dissector.c
@@ -14,9 +14,16 @@ typedef struct ambit_reassembly_entry {
guint32 frame_total;
guint32 size;
unsigned char *data;
- guint32 log_entry_size;
- unsigned char *log_entry;
- guint32 log_start_frame;
+ struct {
+ guint32 entry_size;
+ unsigned char *entry;
+ guint32 start_frame;
+ } log;
+ struct {
+ guint32 entry_size;
+ unsigned char *entry;
+ guint32 start_frame;
+ } log_header;
} ambit_reassembly_entry_t;
typedef struct ambit_protocol_type {
@@ -50,6 +57,16 @@ static gint dissect_ambit_log_data_get(tvbuff_t *tvb, packet_info *pinfo, proto_
static gint dissect_ambit_log_data_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_);
static gint dissect_ambit_log_data_content(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_, guint32 offset, guint32 length);
static gint dissect_ambit_log_data_sample(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_, guint32 offset, guint32 length, guint32 *sampleno, guint32 *periodic_sample_specifier);
+static gint dissect_ambit_lock_status_get(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_);
+static gint dissect_ambit_lock_status_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_);
+static gint dissect_ambit_lock_set(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_);
+static gint dissect_ambit_lock_set_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_);
+
+static gint dissect_ambit3_settings_get(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_);
+static gint dissect_ambit3_settings_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_);
+static gint dissect_ambit3_log_headers_get(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_);
+static gint dissect_ambit3_log_headers_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_);
+static gint dissect_ambit3_log_headers_content(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_, guint32 offset, guint32 length);
/* protocols and header fields */
#define D_AMBIT_USBID 0x3f
@@ -62,6 +79,7 @@ static int hf_ambit_msgsegs = -1;
static int hf_ambit_msgseg = -1;
static int hf_ambit_msgheaderchksum = -1;
static int hf_ambit_requestcmd = -1;
+static int hf_ambit_pktformat = -1;
static int hf_ambit_pktseqno = -1;
static int hf_ambit_pktlen = -1;
static int hf_ambit_payloadchksum = -1;
@@ -145,10 +163,12 @@ static int hf_ambit_log_header_time_first_fix = -1;
static int hf_ambit_log_header_battery_start = -1;
static int hf_ambit_log_header_battery_stop = -1;
static int hf_ambit_log_header_distance_before_calib = -1;
+static int hf_ambit_log_header_synced = -1;
static int hf_ambit_log_header_more = -1;
static int hf_ambit_log_count = -1;
+static int hf_ambit_unsynced_log_count = -1;
static int hf_ambit_log_data_addr_frame_ref = -1;
static int hf_ambit_log_data_address = -1;
@@ -225,6 +245,8 @@ static gint ett_ambit_data = -1;
static gint ett_ambit_log_data = -1;
static gint ett_ambit_log_samples = -1;
static gint ett_ambit_log_sample = -1;
+static gint ett_ambit3_log_headers = -1;
+static gint ett_ambit3_log_header = -1;
static ambit_reassembly_entry_t *reassembly_entries = NULL;
static guint32 reassembly_entries_alloc = 0;
@@ -309,6 +331,16 @@ static const ambit_protocol_type_t subdissectors[] = {
{ 0x0b0b0a00, "Log header reply", dissect_ambit_log_header_reply },
{ 0x0b170500, "Get log data", dissect_ambit_log_data_get },
{ 0x0b170a00, "Log data reply", dissect_ambit_log_data_reply },
+ { 0x0b190500, "Get lock status", dissect_ambit_lock_status_get },
+ { 0x0b190a00, "Lock status reply", dissect_ambit_lock_status_reply },
+ { 0x0b1a0500, "Lock set", dissect_ambit_lock_set },
+ { 0x0b1a0a00, "Lock set reply", dissect_ambit_lock_set_reply },
+ { 0x11000500, "Ambit3 - Get settings", dissect_ambit3_settings_get },
+ { 0x11000a00, "Ambit3 - Settings reply", dissect_ambit3_settings_reply },
+ { 0x11010500, "Ambit3 - Write settings", dissect_ambit3_settings_reply },
+ { 0x11010a00, "Ambit3 - Settings write reply", dissect_ambit3_settings_get },
+ { 0x12000500, "Ambit3 - Get log headers", dissect_ambit3_log_headers_get },
+ { 0x12000a00, "Ambit3 - Log headers reply", dissect_ambit3_log_headers_reply },
{ 0, NULL, NULL }
};
@@ -353,10 +385,13 @@ static gint dissect_ambit_date_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tr
static gint dissect_ambit_time_write(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
{
gint offset = 0;
+ guint16 year = tvb_get_letohs(tvb, 0);
+ guint8 month = tvb_get_guint8(tvb, 2);
+ guint8 day = tvb_get_guint8(tvb, 3);
guint8 hour = tvb_get_guint8(tvb, 4);
guint8 minute = tvb_get_guint8(tvb, 5);
guint16 seconds = tvb_get_letohs(tvb, 6) / 1000;
- dissect_ambit_add_unknown(tvb, pinfo, tree, offset, 4);
+ proto_tree_add_string_format_value(tree, hf_ambit_date, tvb, offset, 4, "Date", "%04d-%02d-%02d", year, month, day);
offset += 4;
proto_tree_add_string_format_value(tree, hf_ambit_time, tvb, offset, 4, "Time", "%02d:%02d:%02d", hour, minute, seconds);
offset += 4;
@@ -968,7 +1003,7 @@ static gint dissect_ambit_log_data_content(tvbuff_t *tvb, packet_info *pinfo, pr
if (offset + 4 >= length) return offset;
proto_tree_add_item(tree, hf_ambit_log_header_distance_before_calib, tvb, offset, 4, ENC_LITTLE_ENDIAN);
offset += 4;
- if (header_1_len == 913) { /* Long header */
+ if (header_1_len >= 913) { /* Long header */
if (offset + 24 >= length) return offset;
dissect_ambit_add_unknown(tvb, pinfo, tree, offset, 24);
offset += 24;
@@ -1477,6 +1512,149 @@ static gint dissect_ambit_log_data_sample(tvbuff_t *tvb, packet_info *pinfo, pro
return 0;
}
+static gint dissect_ambit_lock_status_get(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
+{
+}
+
+static gint dissect_ambit_lock_status_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
+{
+}
+
+static gint dissect_ambit_lock_set(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
+{
+}
+
+static gint dissect_ambit_lock_set_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
+{
+}
+
+static gint dissect_ambit3_settings_get(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
+{
+}
+
+static gint dissect_ambit3_settings_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
+{
+}
+
+static gint dissect_ambit3_log_headers_get(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
+{
+ dissect_ambit_add_unknown(tvb, pinfo, tree, 0, 18);
+}
+
+static gint dissect_ambit3_log_headers_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
+{
+ dissect_ambit_add_unknown(tvb, pinfo, tree, 0, 6);
+}
+
+static gint dissect_ambit3_log_headers_content(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_, guint32 offset, guint32 length)
+{
+ gint namelen = 0;
+ guint16 log_count = 0;
+ guint16 log_cntr = 0;
+ gint header_len = 0;
+ proto_item *logs_ti = NULL;
+ proto_tree *logs_tree = NULL;
+ proto_item *log_ti = NULL;
+ proto_tree *log_tree = NULL;
+ dissect_ambit_add_unknown(tvb, pinfo, tree, offset, 10);
+ offset += 10;
+ log_count = tvb_get_letohs(tvb, offset);
+ proto_tree_add_item(tree, hf_ambit_log_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ offset += 2;
+ dissect_ambit_add_unknown(tvb, pinfo, tree, offset, 2);
+ offset += 2;
+ proto_tree_add_item(tree, hf_ambit_unsynced_log_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ offset += 2;
+ logs_ti = proto_tree_add_text(tree, tvb, 0, 0, "Logs");
+ logs_tree = proto_item_add_subtree(logs_ti, ett_ambit3_log_headers);
+ while (offset + 2 < length) {
+ header_len = tvb_get_guint8(tvb, offset+1);
+ log_cntr++;
+ log_ti = proto_tree_add_text(logs_tree, tvb, offset, header_len + 2, "Header #%u", log_cntr);
+ log_tree = proto_item_add_subtree(log_ti, ett_ambit3_log_header);
+ dissect_ambit_add_unknown(tvb, pinfo, log_tree, offset, 1);
+ offset += 1;
+ proto_tree_add_item(log_tree, hf_ambit_log_header_length, tvb, offset, 1, ENC_LITTLE_ENDIAN);
+ offset += 1;
+ if (offset + header_len <= length) {
+ proto_tree_add_item(log_tree, hf_ambit_time, tvb, offset, 20, ENC_LITTLE_ENDIAN);
+ offset += 20;
+ proto_tree_add_item(log_tree, hf_ambit_log_header_synced, tvb, offset, 1, ENC_LITTLE_ENDIAN);
+ offset += 1;
+ proto_tree_add_item(log_tree, hf_ambit_log_data_address, tvb, offset, 4, ENC_LITTLE_ENDIAN);
+ offset += 4;
+ proto_tree_add_item(log_tree, hf_ambit_log_data_next_addr, tvb, offset, 4, ENC_LITTLE_ENDIAN);
+ offset += 4;
+ dissect_ambit_add_unknown(tvb, pinfo, log_tree, offset, 8);
+ offset += 8;
+ proto_tree_add_item(log_tree, hf_ambit_log_header_hr_min, tvb, offset, 1, ENC_LITTLE_ENDIAN);
+ offset += 1;
+ proto_tree_add_item(log_tree, hf_ambit_log_header_hr_avg, tvb, offset, 1, ENC_LITTLE_ENDIAN);
+ offset += 1;
+ proto_tree_add_item(log_tree, hf_ambit_log_header_hr_max, tvb, offset, 1, ENC_LITTLE_ENDIAN);
+ offset += 1;
+ proto_tree_add_item(log_tree, hf_ambit_log_header_hr_min_time, tvb, offset, 4, ENC_LITTLE_ENDIAN);
+ offset += 4;
+ proto_tree_add_item(log_tree, hf_ambit_log_header_hr_max_time, tvb, offset, 4, ENC_LITTLE_ENDIAN);
+ offset += 4;
+ dissect_ambit_add_unknown(tvb, pinfo, log_tree, offset, 2);
+ offset += 2;
+ proto_tree_add_item(log_tree, hf_ambit_log_header_temp_min_time, tvb, offset, 4, ENC_LITTLE_ENDIAN);
+ offset += 4;
+ proto_tree_add_item(log_tree, hf_ambit_log_header_temp_max_time, tvb, offset, 4, ENC_LITTLE_ENDIAN);
+ offset += 4;
+ proto_tree_add_item(log_tree, hf_ambit_log_header_altitude_min, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ offset += 2;
+ proto_tree_add_item(log_tree, hf_ambit_log_header_altitude_max, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ offset += 2;
+ proto_tree_add_item(log_tree, hf_ambit_log_header_alt_min_time, tvb, offset, 4, ENC_LITTLE_ENDIAN);
+ offset += 4;
+ proto_tree_add_item(log_tree, hf_ambit_log_header_alt_max_time, tvb, offset, 4, ENC_LITTLE_ENDIAN);
+ offset += 4;
+ proto_tree_add_item(log_tree, hf_ambit_log_header_cadence_avg, tvb, offset, 1, ENC_LITTLE_ENDIAN);
+ offset += 1;
+ proto_tree_add_item(log_tree, hf_ambit_log_header_cadence_max, tvb, offset, 1, ENC_LITTLE_ENDIAN);
+ offset += 1;
+ proto_tree_add_item(log_tree, hf_ambit_log_header_cadence_max_time, tvb, offset, 4, ENC_LITTLE_ENDIAN);
+ offset += 4;
+ proto_tree_add_item(log_tree, hf_ambit_log_header_avg_speed, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ offset += 2;
+ proto_tree_add_item(log_tree, hf_ambit_log_header_max_speed, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ offset += 2;
+ proto_tree_add_item(log_tree, hf_ambit_log_header_speed_max_time, tvb, offset, 4, ENC_LITTLE_ENDIAN);
+ offset += 4;
+ dissect_ambit_add_unknown(tvb, pinfo, log_tree, offset, 4);
+ offset += 4;
+ proto_tree_add_item(log_tree, hf_ambit_log_header_duration, tvb, offset, 4, ENC_LITTLE_ENDIAN);
+ offset += 4;
+ proto_tree_add_item(log_tree, hf_ambit_log_header_ascent, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ offset += 2;
+ proto_tree_add_item(log_tree, hf_ambit_log_header_descent, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ offset += 2;
+ proto_tree_add_item(log_tree, hf_ambit_log_header_ascent_time, tvb, offset, 4, ENC_LITTLE_ENDIAN);
+ offset += 4;
+ proto_tree_add_item(log_tree, hf_ambit_log_header_descent_time, tvb, offset, 4, ENC_LITTLE_ENDIAN);
+ offset += 4;
+ proto_tree_add_item(log_tree, hf_ambit_log_header_recovery, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ offset += 2;
+ proto_tree_add_item(log_tree, hf_ambit_log_header_peak_effect, tvb, offset, 1, ENC_LITTLE_ENDIAN);
+ offset += 1;
+ namelen = 0;
+ while (tvb_get_guint8(tvb, offset+namelen) != 0) {
+ namelen++;
+ }
+ proto_tree_add_item(log_tree, hf_ambit_log_header_activity_name, tvb, offset, namelen+1, ENC_LITTLE_ENDIAN);
+ offset += namelen + 1;
+ proto_tree_add_item(log_tree, hf_ambit_log_header_distance, tvb, offset, 4, ENC_LITTLE_ENDIAN);
+ offset += 4;
+ proto_tree_add_item(log_tree, hf_ambit_log_header_energy, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ offset += 2;
+ dissect_ambit_add_unknown(tvb, pinfo, log_tree, offset, 26);
+ offset += 26;
+ }
+ }
+}
+
static gint
dissect_ambit(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
{
@@ -1488,7 +1666,7 @@ dissect_ambit(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U
guint16 msg_count = tvb_get_letohs(tvb, 4);
guint32 command = tvb_get_ntohl(tvb, 8);
guint32 pkt_len = tvb_get_letohl(tvb, 16);
- tvbuff_t *new_tvb = NULL, *next_tvb = NULL, *log_tvb = NULL;
+ tvbuff_t *new_tvb = NULL, *next_tvb = NULL, *log_tvb = NULL, *log_header_tvb = NULL;
static guint32 fragments_start_frame;
static guint16 fragments_offset;
static guint16 fragments_data_len;
@@ -1500,6 +1678,9 @@ dissect_ambit(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U
static guint32 log_after_end_of_use = 0xffffffff;
static guint32 log_last_known_address;
+ static guint32 current_log_header_start_frame = 0xffffffff;
+ static guint32 current_log_header_end_found = 0;
+
if (usbid == D_AMBIT_USBID) {
if (msg_part == 0x5d) {
data_len = data_header_len - 12;
@@ -1581,13 +1762,13 @@ dissect_ambit(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U
if (b == 'M' && c == 'E' && d == 'M') {
if (current_log_start_frame != 0xffffffff) {
- reassembly_entries[current_log_start_frame].log_entry = g_realloc(reassembly_entries[current_log_start_frame].log_entry, reassembly_entries[current_log_start_frame].log_entry_size + i);
- tvb_memcpy(tvb, &reassembly_entries[current_log_start_frame].log_entry[reassembly_entries[current_log_start_frame].log_entry_size], data_offset, i);
- reassembly_entries[current_log_start_frame].log_entry_size += i;
+ reassembly_entries[current_log_start_frame].log.entry = g_realloc(reassembly_entries[current_log_start_frame].log.entry, reassembly_entries[current_log_start_frame].log.entry_size + i);
+ tvb_memcpy(tvb, &reassembly_entries[current_log_start_frame].log.entry[reassembly_entries[current_log_start_frame].log.entry_size], data_offset, i);
+ reassembly_entries[current_log_start_frame].log.entry_size += i;
}
- reassembly_entries[pinfo->fd->num].log_entry = (unsigned char*)g_malloc(data_len-i);
- tvb_memcpy(tvb, reassembly_entries[pinfo->fd->num].log_entry, data_offset+i, data_len-i);
- reassembly_entries[pinfo->fd->num].log_entry_size = data_len-i;
+ reassembly_entries[pinfo->fd->num].log.entry = (unsigned char*)g_malloc(data_len-i);
+ tvb_memcpy(tvb, reassembly_entries[pinfo->fd->num].log.entry, data_offset+i, data_len-i);
+ reassembly_entries[pinfo->fd->num].log.entry_size = data_len-i;
current_log_start_frame = pinfo->fd->num;
break;
}
@@ -1596,22 +1777,68 @@ dissect_ambit(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U
if (i == data_len && current_log_start_frame != 0xffffffff) {
// No new PMEM found
- reassembly_entries[current_log_start_frame].log_entry = g_realloc(reassembly_entries[current_log_start_frame].log_entry, reassembly_entries[current_log_start_frame].log_entry_size + data_len);
- tvb_memcpy(tvb, &reassembly_entries[current_log_start_frame].log_entry[reassembly_entries[current_log_start_frame].log_entry_size], data_offset, data_len);
+ reassembly_entries[current_log_start_frame].log.entry = g_realloc(reassembly_entries[current_log_start_frame].log.entry, reassembly_entries[current_log_start_frame].log.entry_size + data_len);
+ tvb_memcpy(tvb, &reassembly_entries[current_log_start_frame].log.entry[reassembly_entries[current_log_start_frame].log.entry_size], data_offset, data_len);
- reassembly_entries[current_log_start_frame].log_entry_size += data_len;
+ reassembly_entries[current_log_start_frame].log.entry_size += data_len;
}
// Increment address
log_last_known_address += data_len;
- reassembly_entries[pinfo->fd->num].log_start_frame = current_log_start_frame;
+ reassembly_entries[pinfo->fd->num].log.start_frame = current_log_start_frame;
if (log_last_known_address >= log_after_end_of_use) {
// If we are after end of file, reset log entry!
current_log_start_frame = 0xffffffff;
}
}
+
+ // Handle dissection of Ambit3 log headers
+ if (command == 0x12000a00) {
+ if (msg_part == 0x5d) {
+ // Check if this is the first packet of the last header chunk
+ if (tvb_get_guint8(tvb, data_offset) == 0x00 &&
+ tvb_get_guint8(tvb, data_offset+1) == 0x00 &&
+ tvb_get_guint8(tvb, data_offset+2) == 0x00 &&
+ tvb_get_guint8(tvb, data_offset+3) == 0x00 &&
+ tvb_get_guint8(tvb, data_offset+4) == 0x01 &&
+ tvb_get_guint8(tvb, data_offset+5) == 0x00) {
+ current_log_header_end_found = 1;
+ }
+
+ // Adjust data pointers for extra address and length fields
+ data_offset += 6;
+ data_len -= 6;
+ }
+
+ // Look for start of entry (at SBEM0102)
+ if (tvb_get_guint8(tvb, data_offset) == 'S' &&
+ tvb_get_guint8(tvb, data_offset+1) == 'B' &&
+ tvb_get_guint8(tvb, data_offset+2) == 'E' &&
+ tvb_get_guint8(tvb, data_offset+3) == 'M') {
+ reassembly_entries[pinfo->fd->num].log_header.entry = (unsigned char*)g_malloc(data_len);
+ tvb_memcpy(tvb, reassembly_entries[pinfo->fd->num].log_header.entry, data_offset, data_len);
+ reassembly_entries[pinfo->fd->num].log_header.entry_size = data_len;
+ current_log_header_start_frame = pinfo->fd->num;
+ }
+ else if (current_log_header_start_frame != 0xffffffff) {
+ // Append to current entry
+ reassembly_entries[current_log_header_start_frame].log_header.entry = g_realloc(reassembly_entries[current_log_header_start_frame].log_header.entry, reassembly_entries[current_log_header_start_frame].log_header.entry_size + data_len);
+ tvb_memcpy(tvb, &reassembly_entries[current_log_header_start_frame].log_header.entry[reassembly_entries[current_log_header_start_frame].log_header.entry_size], data_offset, data_len);
+
+ reassembly_entries[current_log_header_start_frame].log_header.entry_size += data_len;
+ }
+
+ reassembly_entries[pinfo->fd->num].log_header.start_frame = current_log_header_start_frame;
+
+ // If we have reached last packet in last chunk, reset "pointers"
+ if (reassembly_entries[pinfo->fd->num].frame_index + 1 == reassembly_entries[pinfo->fd->num].frame_total &&
+ current_log_header_end_found == 1) {
+ current_log_header_start_frame = 0xffffffff;
+ current_log_header_end_found = 0;
+ }
+ }
}
if (tree) { /* we are being asked for details */
@@ -1645,7 +1872,7 @@ dissect_ambit(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U
if (msg_part == 0x5d) {
proto_tree_add_item(ambit_tree, hf_ambit_requestcmd, tvb, offset, 4, ENC_BIG_ENDIAN);
offset += 4;
- dissect_ambit_add_unknown (tvb, pinfo, ambit_tree, offset, 2);
+ proto_tree_add_item(ambit_tree, hf_ambit_pktformat, tvb, offset, 2, ENC_LITTLE_ENDIAN);
offset += 2;
proto_tree_add_item(ambit_tree, hf_ambit_pktseqno, tvb, offset, 2, ENC_LITTLE_ENDIAN);
offset += 2;
@@ -1666,11 +1893,17 @@ dissect_ambit(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U
col_add_fstr(pinfo->cinfo, COL_INFO, " (#%u of #%u) Reassembled", reassembly_entries[pinfo->fd->num].frame_index + 1, reassembly_entries[pinfo->fd->num].frame_total);
- if (reassembly_entries[pinfo->fd->num].log_start_frame != 0xffffffff &&
- reassembly_entries[reassembly_entries[pinfo->fd->num].log_start_frame].log_entry != NULL) {
- log_tvb = tvb_new_real_data(reassembly_entries[reassembly_entries[pinfo->fd->num].log_start_frame].log_entry, reassembly_entries[reassembly_entries[pinfo->fd->num].log_start_frame].log_entry_size, reassembly_entries[reassembly_entries[pinfo->fd->num].log_start_frame].log_entry_size);
+ if (reassembly_entries[pinfo->fd->num].log.start_frame != 0xffffffff &&
+ reassembly_entries[reassembly_entries[pinfo->fd->num].log.start_frame].log.entry != NULL) {
+ log_tvb = tvb_new_real_data(reassembly_entries[reassembly_entries[pinfo->fd->num].log.start_frame].log.entry, reassembly_entries[reassembly_entries[pinfo->fd->num].log.start_frame].log.entry_size, reassembly_entries[reassembly_entries[pinfo->fd->num].log.start_frame].log.entry_size);
add_new_data_source(pinfo, log_tvb, "Log");
}
+
+ if (reassembly_entries[pinfo->fd->num].log_header.start_frame != 0xffffffff &&
+ reassembly_entries[reassembly_entries[pinfo->fd->num].log_header.start_frame].log_header.entry != NULL) {
+ log_header_tvb = tvb_new_real_data(reassembly_entries[reassembly_entries[pinfo->fd->num].log_header.start_frame].log_header.entry, reassembly_entries[reassembly_entries[pinfo->fd->num].log_header.start_frame].log_header.entry_size, reassembly_entries[reassembly_entries[pinfo->fd->num].log_header.start_frame].log_header.entry_size);
+ add_new_data_source(pinfo, log_header_tvb, "Log header");
+ }
}
else {
col_add_fstr(pinfo->cinfo, COL_INFO, " (#%u of #%u)", reassembly_entries[pinfo->fd->num].frame_index + 1, reassembly_entries[pinfo->fd->num].frame_total);
@@ -1698,7 +1931,13 @@ dissect_ambit(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U
if (log_tvb != NULL) {
data_ti = proto_tree_add_text(ambit_tree, new_tvb, 0, pkt_len, "Full log entry");
data_tree = proto_item_add_subtree(data_ti, ett_ambit_log_data);
- dissect_ambit_log_data_content(log_tvb, pinfo, data_tree, data, 0, reassembly_entries[reassembly_entries[pinfo->fd->num].log_start_frame].log_entry_size);
+ dissect_ambit_log_data_content(log_tvb, pinfo, data_tree, data, 0, reassembly_entries[reassembly_entries[pinfo->fd->num].log.start_frame].log.entry_size);
+ }
+
+ if (log_header_tvb != NULL) {
+ data_ti = proto_tree_add_text(ambit_tree, new_tvb, 0, pkt_len, "Full log headers");
+ data_tree = proto_item_add_subtree(data_ti, ett_ambit_log_data);
+ dissect_ambit3_log_headers_content(log_header_tvb, pinfo, data_tree, data, 0, reassembly_entries[reassembly_entries[pinfo->fd->num].log_header.start_frame].log_header.entry_size);
}
offset += data_len;
@@ -1738,6 +1977,8 @@ proto_register_ambit(void)
{ "msg header checksum", "ambit.msgheaderchksum", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } },
{ &hf_ambit_requestcmd,
{ "Command", "ambit.command", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL } },
+ { &hf_ambit_pktformat,
+ { "Packet format", "ambit.pktformat", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
{ &hf_ambit_pktseqno,
{ "Packet sequence no", "ambit.pktseqno", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
{ &hf_ambit_pktlen,
@@ -1897,12 +2138,16 @@ proto_register_ambit(void)
{ "Battery at end", "ambit.log_header.battery_stop", FT_UINT8, BASE_DEC, NULL, 0x0,NULL, HFILL } },
{ &hf_ambit_log_header_distance_before_calib,
{ "Distance before calibration", "ambit.log_header.distance_before_calib", FT_UINT32, BASE_DEC, NULL, 0x0,NULL, HFILL } },
+ { &hf_ambit_log_header_synced,
+ { "Syncronized", "ambit.log_header.synced", FT_UINT8, BASE_DEC, NULL, 0x0,NULL, HFILL } },
{ &hf_ambit_log_header_more,
{ "More values", "ambit.log_header.more", FT_UINT32, BASE_HEX, VALS(log_header_more_vals), 0, NULL, HFILL } },
{ &hf_ambit_log_count,
{ "Log count", "ambit.log.count", FT_UINT16, BASE_DEC, NULL, 0x0,NULL, HFILL } },
+ { &hf_ambit_unsynced_log_count,
+ { "Not synced log count", "ambit.log.unsynced.count", FT_UINT16, BASE_DEC, NULL, 0x0,NULL, HFILL } },
{ &hf_ambit_log_data_addr_frame_ref,
{ "In frame", "ambit.log_data.inframe", FT_FRAMENUM, BASE_NONE, NULL, 0, NULL, HFILL } },
@@ -2043,6 +2288,8 @@ proto_register_ambit(void)
&ett_ambit_log_data,
&ett_ambit_log_samples,
&ett_ambit_log_sample,
+ &ett_ambit3_log_headers,
+ &ett_ambit3_log_header
};
proto_ambit = proto_register_protocol (
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-running/openambit.git
More information about the Pkg-running-devel
mailing list