[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