pax_global_header00006660000000000000000000000064123276671750014532gustar00rootroot0000000000000052 comment=3d987455a9fb7b02f05aa9220257d8bdce3ab9e4 GarminPlugin-0.3.23/000077500000000000000000000000001232766717500142135ustar00rootroot00000000000000GarminPlugin-0.3.23/HISTORY000066400000000000000000000147251232766717500153100ustar00rootroot000000000000002014-04-28 - Version 0.3.23 - Bugfix: Plugin crashed on some fit files with empty laps - Bugfix: Incorrect default value for BackupWorkouts - Bugfix: bytesAvailable for MapUpdater on invalid pathes now returns correct value 2013-11-02 - Version 0.3.22 - Updated official garmin communicator plugin version number to 4.1.0 since Garmin changed it 2013-09-23 - Version 0.3.21 - Bugfix: Plugin crashed when trying to import a broken FIT file 2013-09-16 - Version 0.3.20 - Bugfix: Fixed broken "FindDevice" function from 0.3.19 (searched forever) - Now using a thread to search for devices (needed in future with ANT devices) - Feature: Added possibility to disable scanning of local devices 2013-08-29 - Version 0.3.19 - Bugfix: Fit2Tcx conversion problem fixed when GPS signal was lost/invalid 2013-07-05 - Version 0.3.18 - Added FIT->TCX converter now supporting websites that can not handle FIT files - Now supporting new TCX fields (Speed, MaxHeartRate, MaxCadence and AvgSpeed) 2013-05-07 - Version 0.3.17 - Added new feature to backup every uploaded file to a local directory - Bugfix: Now using case insensitive search for configuration file on device - Bugfix: Calculation of checksum failed after several hundreds of files (too many open files) 2012-11-16 - Version 0.3.16 - Updated official garmin communicator plugin version number to 4.0.4 since Garmin changed it 2012-11-04 - Version 0.3.15 - Bugfix: Fixed bug from 0.3.14, which deleted every downloaded file from the device - Increased speed for javascript routine overwriting Garmins browser/OS detection - Bugfix: Better filtering of incorrect device names returned by forerunner-tools - Bugfix: Response to messagebox "Overwrite file" did not always understand a "yes" 2012-09-12 - Version 0.3.14 - Bugfix: Updating the timezone information file is now possible through garmin update - Bugfix: Websites can now read directory information containing wildcards (*.gpx) - Bugfix: Opencaching.com is now supported - uses file reading behavior not described by the API 2012-07-16 - Version 0.3.13 - Bugfix: buffer overflow because of too small buffer for sprintf 2012-07-09 - Version 0.3.12 - Removed dependency to openssl due to licence issues 2012-07-01 - Version 0.3.11 - Updated version number of garmin plugin from 4.0.1.0 to 4.0.3.0 (no new functionality !?) 2012-04-16 - Version 0.3.10 - Bugfix: Minor bugfix to enable build on Arch Linux - no functionality change to 0.3.9 2012-01-27 - Version 0.3.9 - Bugfix: Downloading several URLs to the device failed for more than one download (eg. Updating Training Zones on Edge500) 2012-01-23 - Version 0.3.8 - Updated version number of garmin plugin from 3.0.1.0 to 4.0.1.0 (no new functionality !?) 2012-01-18 - Version 0.3.7 - Feature: Websites are now allowed to write files to the update directory of file based devices (which means you can perform an update) - Bugfix: Some people reported problems with incorrect upper/lowercase directory names in GarminDevice.xml. This will now be automatically corrected. 2011-11-18 - Version 0.3.6 - Bugfix: Fast opening and closing the plugin often crashed the plugin - Bugfix: Tcx Files with extensions caused problems while uploading 2011-11-04 - Version 0.3.5 - Bugfix: No more empty workouts in newer browsers 2011-08-30 - Version 0.3.4 - Feature: Added support for Forerunner 301 - Info: Updated plugin version number to 3.0.1.0 - added new function ParentDevice() - Bugfix: First time using the plugin often caused problems because of the "New configuration created" - the message was removed 2011-06-28 - Version 0.3.3 - Bugfix: Some sites do not provide a file extension, so saving a file to the device failed. The plugin now tries to detect the extension. 2011-06-17 - Version 0.3.2 - Bugfix: When uploading a single TCX file, the GPS points were unintentionally stripped from the upload 2011-05-09 - Version 0.3.1 - Bugfix: Canceling not running jobs is now working without javascript error (needed by write heart rate on connect.garmin.com) - Feature: Added plugin functionality DirectoryListing 2011-03-27 - Version 0.3.0 - Feature: All Filebased Garmin Devices should now be supported (with file GarminDevice.xml) - Feature: Reading of TcxProfile, Crs, CrsDir and Workout at filebased devices is now possible - Feature: Added progress bar change - Feature: Added new function ReadableFileListing - Bugfix: Sorting of fit file output - Bugfix: Now setting udev rule to access Edge305/Forerunner305 2011-01-05 - Version 0.2.8 - Added support for Edge 500 - Changed official garmin plugin version number to 2.9.3.0 2011-01-03 - Version 0.2.7 - Added support for Edge 800 - Manipulation of Garmin Javascript to disable browser check (no more User Agent setting necessary) - Removed dependency to libboost (Better portability) - Now working with Chrome 2010-10-16 - Version 0.2.6 - Bugfix: Edge305/Forerunner305 reported long/lat with only 4 positions after decimal point (which is not enough) 2010-10-04 - Version 0.2.5 - Bugfix: Edge305/Forerunner305 reported multiple laps in one lap 2010-09-29 - Version 0.2.4 - Bugfix: Edge305/Forerunner305 did not provide the complete route when (auto)pause function was used 2010-09-26 - Version 0.2.3 - Added support for Oregon/Dakota to read FitnessData from Device - Added support for gpsies.com (only Oregon/Dakota/Edge705/Edge305/Forerunner305) - Bugfix: Sometimes the compressed fitness data was corrupted - Added support for runningahead.com 2010-06-27 - Version 0.2.2 - Bugfix for Forerunner 305 used with a footpod. Used to report bike cadence, now reports run cadence - Update version number of garmin plugin from 2.9.1 to 2.9.2 2010-05-30 - Version 0.2.1 - Bugfix for devices like GPSmap 60CSx which turn itself of after a device scan using garmintools (device scan can now be switched of in the xml configuration) 2010-04-20 - Version 0.2.0 - Created repository in Launchpad PPA - Support for Hardy (8.04) to Lucid (10.04) - Bugfix for Vista HCx which crashed browser on autodetect of Garmin Edge 305 - Bugfix for Forerunner 205 - read fitness data did not work - Added support for connect.garmin.com 2010-03-25 - Version 0.2beta - Autodetect devices like Oregon 300, Edge 705, Edge 305 - Added garmintools to communicate with Edge 305 / Forerunner 305 - Read FitnessData of Edge 705, Edge 305 - Upload FitnessData to pages like www.cyclogz.com 2010-01-31 - Version 0.1 - Send GPX to filesystem (tested on www.geocaching.com) - Configure several devices using a xml configuration file - Execute a command after successfully storing a gpx file (like gpsbabel) GarminPlugin-0.3.23/README000066400000000000000000000077671232766717500151140ustar00rootroot00000000000000Short description: GarminPlugin is a browser plugin to support Garmin Devices on Linux. Currently (02.12.2010) there is no official browser plugin support for Linux from Garmin. This plugin has nothing to do with the company Garmin (http://www.garmin.com) Long description: This browser plugin has the same methods and properties as the official Garmin Communicator Plugin (http://www8.garmin.com/products/communicator/). It can be used to transfer GPX files (Geocache Descriptions) to your garmin device using the official Garmin Javascript API. Its functionality depends on the device you use. - Edge305/Forerunner305: ReadFitnessData, ReadGpsData, No write support - Edge705/Oregon/Dakota: ReadFitnessData, ReadGpsData, Write Gpx files - Edge800: ReadFitnessData, Write Gpx/Tcx Files - Other devices: Executes external command to write Gpx to device Motivation: Garmin introduced paperless geocaching a while ago on their devices. This works great using Windows and geocaching.com because a windows plugin is available that gives you the possibility to transfer geocaches with one click to the device. Having to boot Windows every time I wanted to go geocaching felt like a waste of time. I had many different ideas on how to best transfer geocaches to my garmin device, but they were all based on parsing the geocaching.com website because they do not offer an official API to access the geocaches. The idea of having to update my application every time they change their layout did stop me from going that approach. Writing a browser plugin that simulates the garmin plugin seemed to be the best idea. Using a javascript debugger soon revealed that the effort of writing such a plugin wasn't that huge - so I got started... Features: - Write a GPX file to disk - Call a script after the GPX file was written to disk - Read FitnessData from device GarminPlugin is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. GarminPlugin is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. This software was written by Andreas Diesner [ andreas.diesner [AT] gmx [DOT] de ] The project is hosted on http://www.andreas-diesner.de/garminplugin/ The source code is hosted on GitHub http://github.com/adiesner/GarminPlugin Dependencies to other projects: garmintools - http://code.google.com/p/garmintools/ libusb - http://www.libusb.org/ ticpp - http://code.google.com/p/ticpp/ zlib - http://www.zlib.net gcrypt - http://www.gnupg.org/ Thanks goes to - Christian Kurek - Bob Trower (http://base64.sourceforge.net) - Gray Watson (MD5-Code) (http://256.com/gray/) - Ralf Treinen (solving license issues) - The contributors of the above projects Howto compile GarminPlugin: # This example shows how to compile GarminPlugin on a 64bit Ubuntu System sudo apt-get install build-essential subversion git-core zlib1g-dev libusb-dev libgcrypt11-dev git clone http://github.com/adiesner/GarminPlugin.git svn export http://garmintools.googlecode.com/svn/trunk/ garmintools svn export http://ticpp.googlecode.com/svn/trunk/ ticpp wget http://downloads.sourceforge.net/project/premake/Premake/4.2.1/premake-4.2.1-linux.tar.gz?use_mirror=ignum # compile ticpp tar xvzf premake-4.2.1-linux.tar.gz cd ticpp ../premake4 --cc=gcc --os=linux --platform=x64 gmake # if you are not able to execute premake4 on a 64bit machine install ia32-libs and try again sed --in-place 's/$(CFLAGS)/$(CFLAGS) -fPIC/g' TiCPP.make make config=release64 cd .. # compile garmintools cd garmintools ./configure CXXFLAGS="-fPIC -g -O2" CFLAGS="-g -O2 -fPIC" make cd .. # compile GarminPlugin cd GarminPlugin ./configure make cd .. # Install the plugin sudo cp GarminPlugin/npGarminPlugin.so /usr/lib/mozilla/plugins GarminPlugin-0.3.23/build/000077500000000000000000000000001232766717500153125ustar00rootroot00000000000000GarminPlugin-0.3.23/build/debian/000077500000000000000000000000001232766717500165345ustar00rootroot00000000000000GarminPlugin-0.3.23/build/debian/createBuildEnv.sh000077500000000000000000000070521232766717500217730ustar00rootroot00000000000000#!/bin/sh # # The following packages are required before executing this script! # # apt-get update # apt-get install build-essential subversion git-core xulrunner-dev zlib1g-dev libusb-dev # DEBIANVERSION=$1 VERSION=$2 GITREPOSITORYDIR=`pwd` if [ -z $DEBIANVERSION"" ]; then echo "Please specify for which debian version you want to build" echo "Example: createBuildEnv.sh maverick 0.3.0" exit 1 fi if [ -f "$GITREPOSITORYDIR/$DEBIANVERSION/debian/control" ]; then echo "Using build environment from directory $GITREPOSITORYDIR/$DEBIANVERSION/" else echo "Build environment settings not found in directory $GITREPOSITORYDIR/$DEBIANVERSION/debian/" exit 1 fi if [ ! -n "$VERSION" ]; then # Determine last tag GITTAG=`git tag -l | tail -1` VERSION=`echo $GITTAG|cut -c2-` echo "Please specify which plugin version you want to build" echo "Example: createBuildEnv.sh maverick $VERSION" exit 1 fi ARCHITECTURE=`uname -i` echo "Creating build environment for version $VERSION - architecture $ARCHITECTURE" # Checkout last version #git checkout $GITTAG cd HOMEDIR=`pwd` # Create Build Environment cd "$GITREPOSITORYDIR/../.." mkdir "$GITREPOSITORYDIR/../../pbuilder" cd "$GITREPOSITORYDIR/../../pbuilder" mkdir "garminplugin-$VERSION" cp -r "$GITREPOSITORYDIR/$DEBIANVERSION/debian" "./garminplugin-$VERSION/debian" echo "Copying Sources..." cp -r "$GITREPOSITORYDIR/../../src" "./garminplugin-$VERSION/GarminPlugin" cd "garminplugin-$VERSION" TARGETDIR=`pwd` if [ -f "$GITREPOSITORYDIR/$DEBIANVERSION/buildEnv.sh" ]; then echo "Executing $DEBIANVERSION specific settings" "$GITREPOSITORYDIR/$DEBIANVERSION/buildEnv.sh" "$GITREPOSITORYDIR/$DEBIANVERSION" "$TARGETDIR" fi cd "$GITREPOSITORYDIR/../../pbuilder" # now write changelog file INFILE="$GITREPOSITORYDIR/../../HISTORY" CHANGELOGFILE="$GITREPOSITORYDIR/../../pbuilder/garminplugin-$VERSION/debian/changelog" echo "Creating changelog file $CHANGELOGFILE" DOOUTPUT="0" while read curline; do if [ "a$curline" != "a" ]; then FIRSTCHAR=`echo $curline|cut -b1` if [ "a$FIRSTCHAR" != "a-" ]; then VERSIONNUMBERENTRY=`echo $curline | cut -b22-` if [ "a$VERSIONNUMBERENTRY" != "a$VERSION" ]; then if [ "a$DOOUTPUT" != "a0" ]; then DOOUTPUT="0" echo "">>$CHANGELOGFILE echo " -- Andreas Diesner $DATE" echo " -- Andreas Diesner $DATE">>$CHANGELOGFILE fi else DATE=`echo $curline | cut -b-10` DATE=`date -R -d $DATE` DOOUTPUT="1" echo "garminplugin ($VERSION-1~$DEBIANVERSION) $DEBIANVERSION; urgency=low">$CHANGELOGFILE echo "garminplugin ($VERSION-1~$DEBIANVERSION) $DEBIANVERSION; urgency=low" echo "">>$CHANGELOGFILE fi else if [ "a$DOOUTPUT" != "a0" ]; then curline=`echo $curline | cut -b2-` echo " *$curline" >>$CHANGELOGFILE echo " *$curline" fi fi fi done < $INFILE # Build env is ready cd "$GITREPOSITORYDIR/../../pbuilder" LOCALDIR=`pwd` echo "********************************************************" echo "Build environment setup complete" echo "Now enter the following commands to start your build:" echo "" echo "cd '$LOCALDIR'" echo "dpkg-source -b garminplugin-$VERSION" echo "sudo DIST=$DEBIANVERSION ARCH=i386 pbuilder build garminplugin_$VERSION-1~$DEBIANVERSION.dsc" GarminPlugin-0.3.23/build/debian/hardy/000077500000000000000000000000001232766717500176435ustar00rootroot00000000000000GarminPlugin-0.3.23/build/debian/hardy/buildEnv.sh000077500000000000000000000022011232766717500217450ustar00rootroot00000000000000#!/bin/sh # # This file downloads additional files needed to build for lucid # # $1 = Directory where this file is located # $2 = Target directory # HOMEDIR=$1 TARGETDIR=$2 cd $TARGETDIR echo "Downloading tinyxml from Sourceforege" wget "http://downloads.sourceforge.net/project/tinyxml/tinyxml/2.6.1/tinyxml_2_6_1.tar.gz?r=http%3A%2F%2Fsourceforge.net%2Fprojects%2Ftinyxml%2Ffiles%2Ftinyxml%2F2.6.1%2F&ts=1301068190&use_mirror=heanet" -O tinyxml_2_6_1.tar.gz if [ -f "$TARGETDIR/tinyxml_2_6_1.tar.gz" ]; then tar xzf ./tinyxml_2_6_1.tar.gz rm ./tinyxml_2_6_1.tar.gz sed -i "s/DEBUG_CXXFLAGS := /DEBUG_CXXFLAGS := -fPIC /" tinyxml/Makefile sed -i "s/RELEASE_CXXFLAGS := /RELEASE_CXXFLAGS := -fPIC /" tinyxml/Makefile sed -i "s/TINYXML_USE_STL := NO/TINYXML_USE_STL := YES/" tinyxml/Makefile else echo "************ ERROR ERROR ************" echo "Unable to download tinyxml_2_6_1.tar.gz from Sourceforge using wget! Check your internet connection!" echo "************ ERROR ERROR ************" exit 1 fi cd $TARGETDIR echo "Fetching garmintools sources..." svn export http://garmintools.googlecode.com/svn/trunk/ garmintools GarminPlugin-0.3.23/build/debian/hardy/debian/000077500000000000000000000000001232766717500210655ustar00rootroot00000000000000GarminPlugin-0.3.23/build/debian/hardy/debian/compat000066400000000000000000000000021232766717500222630ustar00rootroot000000000000007 GarminPlugin-0.3.23/build/debian/hardy/debian/control000066400000000000000000000014701232766717500224720ustar00rootroot00000000000000Source: garminplugin Section: misc Priority: optional Maintainer: Andreas Diesner Build-Depends: debhelper (>= 7), libusb-0.1-4, zlib1g-dev, libgcc1, libc6, libusb-dev, pkg-config, libc6, garmin-forerunner-tools, libgcrypt11-dev Standards-Version: 3.8.1 Homepage: http://www.andreas-diesner.de/garminplugin Package: garminplugin Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends} Description: Garmin Communicator Plugin for Linux This Firefox/Chrome plugin allows you to access your garmin device using your browser. You can transfer GPX files to your device or read fitnessdata from the device and upload this data to certain websites like http://connect.garmin.com. This plugin is NOT an official product of the company Garmin (http://www.garmin.com). It is a fan product. GarminPlugin-0.3.23/build/debian/hardy/debian/copyright000066400000000000000000000012271232766717500230220ustar00rootroot00000000000000This package was debianized by Andreas Diesner on Thu, 15 Apr 2010 17:50:18 +0200. It was downloaded from http://www.andreas-diesner.de/garminplugin Upstream Author(s): Andreas Diesner Copyright: Copyright (C) 2010 Andreas Diesner License: GPL 3 or any later version The Debian packaging is: Copyright (C) 2010 Andreas Diesner and is licensed under the GPL version 3, see `/usr/share/common-licenses/GPL-3'. # Please also look if there are files or directories which have a # different copyright/license attached and list them here. GarminPlugin-0.3.23/build/debian/hardy/debian/dirs000066400000000000000000000000001232766717500217370ustar00rootroot00000000000000GarminPlugin-0.3.23/build/debian/hardy/debian/docs000066400000000000000000000000001232766717500217260ustar00rootroot00000000000000GarminPlugin-0.3.23/build/debian/hardy/debian/garminplugin.udev000066400000000000000000000001201232766717500244370ustar00rootroot00000000000000ATTRS{idVendor}=="091e", ATTRS{idProduct}=="0003", MODE="0666", GROUP="plugdev" GarminPlugin-0.3.23/build/debian/hardy/debian/rules000077500000000000000000000051611232766717500221500ustar00rootroot00000000000000#!/usr/bin/make -f # -*- makefile -*- # Sample debian/rules that uses debhelper. # This file was originally written by Joey Hess and Craig Small. # As a special exception, when this file is copied by dh-make into a # dh-make output file, you may use that output file without restriction. # This special exception was added by Craig Small in version 0.37 of dh-make. # Uncomment this to turn on verbose mode. #export DH_VERBOSE=1 LBITS := $(shell getconf LONG_BIT) configure: configure-stamp configure-stamp: dh_testdir # Add here commands to configure the package. cd garmintools && ./configure CXXFLAGS="-fPIC -g -O2" CFLAGS="-g -O2 -fPIC" touch configure-stamp build: build-stamp build-stamp: configure-stamp dh_testdir # Add here commands to compile the package. # Lucid does not have tinyxml package, we need to provide it if test -f tinyxml/Makefile; then cd tinyxml && make; fi cd garmintools && $(MAKE) cd GarminPlugin && ./configure cd GarminPlugin && $(MAKE) #docbook-to-man debian/garminplugin.sgml > garminplugin.1 touch $@ clean: dh_testdir dh_testroot rm -f build-stamp configure-stamp if test -f GarminPlugin/Makefile; then cd GarminPlugin && make clean; fi if test -f garmintools/Makefile; then cd garmintools && make clean; fi # Lucid does not have tinyxml package, we need to provide it if test -f tinyxml/Makefile; then cd tinyxml && make clean; fi # Add here commands to clean up after the build process. dh_clean install: build dh_testdir dh_testroot dh_prep dh_installdirs # Add here commands to install the package into debian/garminplugin. #mkdir -p $(CURDIR)/debian/garminplugin/usr/lib/mozilla/plugins #cp GarminPlugin/npGarminPlugin.so $(CURDIR)/debian/garminplugin/usr/lib/mozilla/plugins # Hardy mkdir -p $(CURDIR)/debian/garminplugin/usr/lib/firefox-addons/plugins cp GarminPlugin/npGarminPlugin.so $(CURDIR)/debian/garminplugin/usr/lib/firefox-addons/plugins # Build architecture-independent files here. binary-indep: install # We have nothing to do by default. # Build architecture-dependent files here. binary-arch: install dh_testdir dh_testroot # dh_installchangelogs # dh_installdocs # dh_installexamples # dh_install # dh_installmenu # dh_installdebconf # dh_installlogrotate # dh_installemacsen # dh_installpam # dh_installmime # dh_python # dh_installinit # dh_installcron # dh_installinfo # dh_installman dh_installudev dh_link dh_strip dh_compress dh_fixperms # dh_perl # dh_makeshlibs dh_installdeb dh_shlibdeps dh_gencontrol dh_md5sums dh_builddeb binary: binary-indep binary-arch .PHONY: build clean binary-indep binary-arch binary install configure GarminPlugin-0.3.23/build/debian/karmic/000077500000000000000000000000001232766717500200025ustar00rootroot00000000000000GarminPlugin-0.3.23/build/debian/karmic/buildEnv.sh000077500000000000000000000022001232766717500221030ustar00rootroot00000000000000#!/bin/sh # # This file downloads additional files needed to build for lucid # # $1 = Directory where this file is located # $2 = Target directory # HOMEDIR=$1 TARGETDIR=$2 cd $TARGETDIR echo "Downloading tinyxml from Sourceforege" wget "http://downloads.sourceforge.net/project/tinyxml/tinyxml/2.6.1/tinyxml_2_6_1.tar.gz?r=http%3A%2F%2Fsourceforge.net%2Fprojects%2Ftinyxml%2Ffiles%2Ftinyxml%2F2.6.1%2F&ts=1301068190&use_mirror=heanet" -O tinyxml_2_6_1.tar.gz if [ -f "$TARGETDIR/tinyxml_2_6_1.tar.gz" ]; then tar xzf ./tinyxml_2_6_1.tar.gz rm ./tinyxml_2_6_1.tar.gz sed -i "s/DEBUG_CXXFLAGS := /DEBUG_CXXFLAGS := -fPIC /" tinyxml/Makefile sed -i "s/RELEASE_CXXFLAGS := /RELEASE_CXXFLAGS := -fPIC /" tinyxml/Makefile sed -i "s/TINYXML_USE_STL := NO/TINYXML_USE_STL := YES/" tinyxml/Makefile else echo "************ ERROR ERROR ************" echo "Unable to download tinyxml_2_6_1.tar.gz from Sourceforge using wget! Check your internet connection!" echo "************ ERROR ERROR ************" exit 1 fi cd $TARGETDIR echo "Fetching garmintools sources..." svn export http://garmintools.googlecode.com/svn/trunk/ garmintools GarminPlugin-0.3.23/build/debian/karmic/debian/000077500000000000000000000000001232766717500212245ustar00rootroot00000000000000GarminPlugin-0.3.23/build/debian/karmic/debian/compat000066400000000000000000000000021232766717500224220ustar00rootroot000000000000007 GarminPlugin-0.3.23/build/debian/karmic/debian/control000066400000000000000000000014671232766717500226370ustar00rootroot00000000000000Source: garminplugin Section: misc Priority: optional Maintainer: Andreas Diesner Build-Depends: debhelper (>= 7), libusb-0.1-4, zlib1g-dev, libgcc1, libc6, libusb-dev, pkg-config, libc6, garmin-forerunner-tools, libgcrypt11-dev Standards-Version: 3.8.1 Homepage: http://www.andreas-diesner.de/garminplugin Package: garminplugin Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends} Description: Garmin Communicator Plugin for Linux This Firefox/Chrome plugin allows you to access your garmin device using your browser. You can transfer GPX files to your device or read fitnessdata from the device and upload this data to certain websites like http://connect.garmin.com. This plugin is NOT an official product of the company Garmin (http://www.garmin.com). It is a fan product. GarminPlugin-0.3.23/build/debian/karmic/debian/copyright000066400000000000000000000012271232766717500231610ustar00rootroot00000000000000This package was debianized by Andreas Diesner on Thu, 15 Apr 2010 17:50:18 +0200. It was downloaded from http://www.andreas-diesner.de/garminplugin Upstream Author(s): Andreas Diesner Copyright: Copyright (C) 2010 Andreas Diesner License: GPL 3 or any later version The Debian packaging is: Copyright (C) 2010 Andreas Diesner and is licensed under the GPL version 3, see `/usr/share/common-licenses/GPL-3'. # Please also look if there are files or directories which have a # different copyright/license attached and list them here. GarminPlugin-0.3.23/build/debian/karmic/debian/dirs000066400000000000000000000000001232766717500220760ustar00rootroot00000000000000GarminPlugin-0.3.23/build/debian/karmic/debian/docs000066400000000000000000000000001232766717500220650ustar00rootroot00000000000000GarminPlugin-0.3.23/build/debian/karmic/debian/garminplugin.udev000066400000000000000000000001201232766717500245760ustar00rootroot00000000000000ATTRS{idVendor}=="091e", ATTRS{idProduct}=="0003", MODE="0666", GROUP="plugdev" GarminPlugin-0.3.23/build/debian/karmic/debian/rules000077500000000000000000000051611232766717500223070ustar00rootroot00000000000000#!/usr/bin/make -f # -*- makefile -*- # Sample debian/rules that uses debhelper. # This file was originally written by Joey Hess and Craig Small. # As a special exception, when this file is copied by dh-make into a # dh-make output file, you may use that output file without restriction. # This special exception was added by Craig Small in version 0.37 of dh-make. # Uncomment this to turn on verbose mode. #export DH_VERBOSE=1 LBITS := $(shell getconf LONG_BIT) configure: configure-stamp configure-stamp: dh_testdir # Add here commands to configure the package. cd garmintools && ./configure CXXFLAGS="-fPIC -g -O2" CFLAGS="-g -O2 -fPIC" touch configure-stamp build: build-stamp build-stamp: configure-stamp dh_testdir # Add here commands to compile the package. # Lucid does not have tinyxml package, we need to provide it if test -f tinyxml/Makefile; then cd tinyxml && make; fi cd garmintools && $(MAKE) cd GarminPlugin && ./configure cd GarminPlugin && $(MAKE) #docbook-to-man debian/garminplugin.sgml > garminplugin.1 touch $@ clean: dh_testdir dh_testroot rm -f build-stamp configure-stamp if test -f GarminPlugin/Makefile; then cd GarminPlugin && make clean; fi if test -f garmintools/Makefile; then cd garmintools && make clean; fi # Lucid does not have tinyxml package, we need to provide it if test -f tinyxml/Makefile; then cd tinyxml && make clean; fi # Add here commands to clean up after the build process. dh_clean install: build dh_testdir dh_testroot dh_prep dh_installdirs # Add here commands to install the package into debian/garminplugin. mkdir -p $(CURDIR)/debian/garminplugin/usr/lib/mozilla/plugins cp GarminPlugin/npGarminPlugin.so $(CURDIR)/debian/garminplugin/usr/lib/mozilla/plugins # Hardy #mkdir -p $(CURDIR)/debian/garminplugin/usr/lib/firefox-addons/plugins #cp GarminPlugin/npGarminPlugin.so $(CURDIR)/debian/garminplugin/usr/lib/firefox-addons/plugins # Build architecture-independent files here. binary-indep: install # We have nothing to do by default. # Build architecture-dependent files here. binary-arch: install dh_testdir dh_testroot # dh_installchangelogs # dh_installdocs # dh_installexamples # dh_install # dh_installmenu # dh_installdebconf # dh_installlogrotate # dh_installemacsen # dh_installpam # dh_installmime # dh_python # dh_installinit # dh_installcron # dh_installinfo # dh_installman dh_installudev dh_link dh_strip dh_compress dh_fixperms # dh_perl # dh_makeshlibs dh_installdeb dh_shlibdeps dh_gencontrol dh_md5sums dh_builddeb binary: binary-indep binary-arch .PHONY: build clean binary-indep binary-arch binary install configure GarminPlugin-0.3.23/build/debian/lucid/000077500000000000000000000000001232766717500176345ustar00rootroot00000000000000GarminPlugin-0.3.23/build/debian/lucid/buildEnv.sh000077500000000000000000000020051232766717500217400ustar00rootroot00000000000000#!/bin/sh # # This file downloads additional files needed to build for lucid # # $1 = Directory where this file is located # $2 = Target directory # HOMEDIR=$1 TARGETDIR=$2 cd $TARGETDIR echo "Downloading tinyxml from Sourceforege" wget "http://downloads.sourceforge.net/project/tinyxml/tinyxml/2.6.1/tinyxml_2_6_1.tar.gz?r=http%3A%2F%2Fsourceforge.net%2Fprojects%2Ftinyxml%2Ffiles%2Ftinyxml%2F2.6.1%2F&ts=1301068190&use_mirror=heanet" -O tinyxml_2_6_1.tar.gz if [ -f "$TARGETDIR/tinyxml_2_6_1.tar.gz" ]; then tar xzf ./tinyxml_2_6_1.tar.gz rm ./tinyxml_2_6_1.tar.gz sed -i "s/DEBUG_CXXFLAGS := /DEBUG_CXXFLAGS := -fPIC /" tinyxml/Makefile sed -i "s/RELEASE_CXXFLAGS := /RELEASE_CXXFLAGS := -fPIC /" tinyxml/Makefile sed -i "s/TINYXML_USE_STL := NO/TINYXML_USE_STL := YES/" tinyxml/Makefile else echo "************ ERROR ERROR ************" echo "Unable to download tinyxml_2_6_1.tar.gz from Sourceforge using wget! Check your internet connection!" echo "************ ERROR ERROR ************" exit 1 fi GarminPlugin-0.3.23/build/debian/lucid/debian/000077500000000000000000000000001232766717500210565ustar00rootroot00000000000000GarminPlugin-0.3.23/build/debian/lucid/debian/compat000066400000000000000000000000021232766717500222540ustar00rootroot000000000000007 GarminPlugin-0.3.23/build/debian/lucid/debian/control000066400000000000000000000014671232766717500224710ustar00rootroot00000000000000Source: garminplugin Section: misc Priority: optional Maintainer: Andreas Diesner Build-Depends: debhelper (>= 7), libusb-0.1-4, zlib1g-dev, libgcc1, libc6, libusb-dev, pkg-config, libc6, garmin-forerunner-tools, libgcrypt11-dev Standards-Version: 3.8.1 Homepage: http://www.andreas-diesner.de/garminplugin Package: garminplugin Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends} Description: Garmin Communicator Plugin for Linux This Firefox/Chrome plugin allows you to access your garmin device using your browser. You can transfer GPX files to your device or read fitnessdata from the device and upload this data to certain websites like http://connect.garmin.com. This plugin is NOT an official product of the company Garmin (http://www.garmin.com). It is a fan product. GarminPlugin-0.3.23/build/debian/lucid/debian/copyright000066400000000000000000000012271232766717500230130ustar00rootroot00000000000000This package was debianized by Andreas Diesner on Thu, 15 Apr 2010 17:50:18 +0200. It was downloaded from http://www.andreas-diesner.de/garminplugin Upstream Author(s): Andreas Diesner Copyright: Copyright (C) 2010 Andreas Diesner License: GPL 3 or any later version The Debian packaging is: Copyright (C) 2010 Andreas Diesner and is licensed under the GPL version 3, see `/usr/share/common-licenses/GPL-3'. # Please also look if there are files or directories which have a # different copyright/license attached and list them here. GarminPlugin-0.3.23/build/debian/lucid/debian/dirs000066400000000000000000000000001232766717500217300ustar00rootroot00000000000000GarminPlugin-0.3.23/build/debian/lucid/debian/docs000066400000000000000000000000001232766717500217170ustar00rootroot00000000000000GarminPlugin-0.3.23/build/debian/lucid/debian/garminplugin.udev000066400000000000000000000001201232766717500244300ustar00rootroot00000000000000ATTRS{idVendor}=="091e", ATTRS{idProduct}=="0003", MODE="0666", GROUP="plugdev" GarminPlugin-0.3.23/build/debian/lucid/debian/rules000077500000000000000000000047561232766717500221520ustar00rootroot00000000000000#!/usr/bin/make -f # -*- makefile -*- # Sample debian/rules that uses debhelper. # This file was originally written by Joey Hess and Craig Small. # As a special exception, when this file is copied by dh-make into a # dh-make output file, you may use that output file without restriction. # This special exception was added by Craig Small in version 0.37 of dh-make. # Uncomment this to turn on verbose mode. #export DH_VERBOSE=1 LBITS := $(shell getconf LONG_BIT) configure: configure-stamp configure-stamp: dh_testdir # Add here commands to configure the package. touch configure-stamp build: build-stamp build-stamp: configure-stamp dh_testdir # Add here commands to compile the package. # Lucid does not have tinyxml package, we need to provide it if test -f tinyxml/Makefile; then cd tinyxml && make; fi cd GarminPlugin && ZLIB_CFLAGS="-I/usr/include" ZLIB_LIBS="-lz" ./configure cd GarminPlugin && $(MAKE) #docbook-to-man debian/garminplugin.sgml > garminplugin.1 touch $@ clean: dh_testdir dh_testroot rm -f build-stamp configure-stamp if test -f GarminPlugin/Makefile; then cd GarminPlugin && make clean; fi # Lucid does not have tinyxml package, we need to provide it if test -f tinyxml/Makefile; then cd tinyxml && make clean; fi # Add here commands to clean up after the build process. dh_clean install: build dh_testdir dh_testroot dh_prep dh_installdirs # Add here commands to install the package into debian/garminplugin. mkdir -p $(CURDIR)/debian/garminplugin/usr/lib/mozilla/plugins cp GarminPlugin/npGarminPlugin.so $(CURDIR)/debian/garminplugin/usr/lib/mozilla/plugins # Hardy #mkdir -p $(CURDIR)/debian/garminplugin/usr/lib/firefox-addons/plugins #cp GarminPlugin/npGarminPlugin.so $(CURDIR)/debian/garminplugin/usr/lib/firefox-addons/plugins # Build architecture-independent files here. binary-indep: install # We have nothing to do by default. # Build architecture-dependent files here. binary-arch: install dh_testdir dh_testroot # dh_installchangelogs # dh_installdocs # dh_installexamples # dh_install # dh_installmenu # dh_installdebconf # dh_installlogrotate # dh_installemacsen # dh_installpam # dh_installmime # dh_python # dh_installinit # dh_installcron # dh_installinfo # dh_installman dh_installudev dh_link dh_strip dh_compress dh_fixperms # dh_perl # dh_makeshlibs dh_installdeb dh_shlibdeps dh_gencontrol dh_md5sums dh_builddeb binary: binary-indep binary-arch .PHONY: build clean binary-indep binary-arch binary install configure GarminPlugin-0.3.23/build/debian/maverick/000077500000000000000000000000001232766717500203355ustar00rootroot00000000000000GarminPlugin-0.3.23/build/debian/maverick/debian/000077500000000000000000000000001232766717500215575ustar00rootroot00000000000000GarminPlugin-0.3.23/build/debian/maverick/debian/compat000066400000000000000000000000021232766717500227550ustar00rootroot000000000000007 GarminPlugin-0.3.23/build/debian/maverick/debian/control000066400000000000000000000015071232766717500231650ustar00rootroot00000000000000Source: garminplugin Section: misc Priority: optional Maintainer: Andreas Diesner Build-Depends: debhelper (>= 7), libusb-0.1-4, zlib1g-dev, libgcc1, libc6, libusb-dev, libtinyxml-dev, pkg-config, libc6, garmin-forerunner-tools, libgcrypt11-dev Standards-Version: 3.8.1 Homepage: http://www.andreas-diesner.de/garminplugin Package: garminplugin Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends} Description: Garmin Communicator Plugin for Linux This Firefox/Chrome plugin allows you to access your garmin device using your browser. You can transfer GPX files to your device or read fitnessdata from the device and upload this data to certain websites like http://connect.garmin.com. This plugin is NOT an official product of the company Garmin (http://www.garmin.com). It is a fan product. GarminPlugin-0.3.23/build/debian/maverick/debian/copyright000066400000000000000000000012271232766717500235140ustar00rootroot00000000000000This package was debianized by Andreas Diesner on Thu, 15 Apr 2010 17:50:18 +0200. It was downloaded from http://www.andreas-diesner.de/garminplugin Upstream Author(s): Andreas Diesner Copyright: Copyright (C) 2010 Andreas Diesner License: GPL 3 or any later version The Debian packaging is: Copyright (C) 2010 Andreas Diesner and is licensed under the GPL version 3, see `/usr/share/common-licenses/GPL-3'. # Please also look if there are files or directories which have a # different copyright/license attached and list them here. GarminPlugin-0.3.23/build/debian/maverick/debian/dirs000066400000000000000000000000001232766717500224310ustar00rootroot00000000000000GarminPlugin-0.3.23/build/debian/maverick/debian/docs000066400000000000000000000000001232766717500224200ustar00rootroot00000000000000GarminPlugin-0.3.23/build/debian/maverick/debian/garminplugin.udev000066400000000000000000000001201232766717500251310ustar00rootroot00000000000000ATTRS{idVendor}=="091e", ATTRS{idProduct}=="0003", MODE="0666", GROUP="plugdev" GarminPlugin-0.3.23/build/debian/maverick/debian/rules000077500000000000000000000045001232766717500226360ustar00rootroot00000000000000#!/usr/bin/make -f # -*- makefile -*- # Sample debian/rules that uses debhelper. # This file was originally written by Joey Hess and Craig Small. # As a special exception, when this file is copied by dh-make into a # dh-make output file, you may use that output file without restriction. # This special exception was added by Craig Small in version 0.37 of dh-make. # Uncomment this to turn on verbose mode. #export DH_VERBOSE=1 LBITS := $(shell getconf LONG_BIT) configure: configure-stamp configure-stamp: dh_testdir # Add here commands to configure the package. touch configure-stamp build: build-stamp build-stamp: configure-stamp dh_testdir # Add here commands to compile the package. # Lucid does not have tinyxml package, we need to provide it if test -f tinyxml/Makefile; then cd tinyxml && make; fi cd GarminPlugin && ./configure cd GarminPlugin && $(MAKE) #docbook-to-man debian/garminplugin.sgml > garminplugin.1 touch $@ clean: dh_testdir dh_testroot rm -f build-stamp configure-stamp if test -f GarminPlugin/Makefile; then cd GarminPlugin && make clean; fi # Add here commands to clean up after the build process. dh_clean install: build dh_testdir dh_testroot dh_prep dh_installdirs # Add here commands to install the package into debian/garminplugin. mkdir -p $(CURDIR)/debian/garminplugin/usr/lib/mozilla/plugins cp GarminPlugin/npGarminPlugin.so $(CURDIR)/debian/garminplugin/usr/lib/mozilla/plugins # Hardy #mkdir -p $(CURDIR)/debian/garminplugin/usr/lib/firefox-addons/plugins #cp GarminPlugin/npGarminPlugin.so $(CURDIR)/debian/garminplugin/usr/lib/firefox-addons/plugins # Build architecture-independent files here. binary-indep: install # We have nothing to do by default. # Build architecture-dependent files here. binary-arch: install dh_testdir dh_testroot # dh_installchangelogs # dh_installdocs # dh_installexamples # dh_install # dh_installmenu # dh_installdebconf # dh_installlogrotate # dh_installemacsen # dh_installpam # dh_installmime # dh_python # dh_installinit # dh_installcron # dh_installinfo # dh_installman dh_installudev dh_link dh_strip dh_compress dh_fixperms # dh_perl # dh_makeshlibs dh_installdeb dh_shlibdeps dh_gencontrol dh_md5sums dh_builddeb binary: binary-indep binary-arch .PHONY: build clean binary-indep binary-arch binary install configure GarminPlugin-0.3.23/build/debian/natty/000077500000000000000000000000001232766717500176735ustar00rootroot00000000000000GarminPlugin-0.3.23/build/debian/natty/debian/000077500000000000000000000000001232766717500211155ustar00rootroot00000000000000GarminPlugin-0.3.23/build/debian/natty/debian/compat000066400000000000000000000000021232766717500223130ustar00rootroot000000000000007 GarminPlugin-0.3.23/build/debian/natty/debian/control000066400000000000000000000015071232766717500225230ustar00rootroot00000000000000Source: garminplugin Section: misc Priority: optional Maintainer: Andreas Diesner Build-Depends: debhelper (>= 7), libusb-0.1-4, zlib1g-dev, libgcc1, libc6, libusb-dev, libtinyxml-dev, pkg-config, libc6, garmin-forerunner-tools, libgcrypt11-dev Standards-Version: 3.8.1 Homepage: http://www.andreas-diesner.de/garminplugin Package: garminplugin Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends} Description: Garmin Communicator Plugin for Linux This Firefox/Chrome plugin allows you to access your garmin device using your browser. You can transfer GPX files to your device or read fitnessdata from the device and upload this data to certain websites like http://connect.garmin.com. This plugin is NOT an official product of the company Garmin (http://www.garmin.com). It is a fan product. GarminPlugin-0.3.23/build/debian/natty/debian/copyright000066400000000000000000000012271232766717500230520ustar00rootroot00000000000000This package was debianized by Andreas Diesner on Thu, 15 Apr 2010 17:50:18 +0200. It was downloaded from http://www.andreas-diesner.de/garminplugin Upstream Author(s): Andreas Diesner Copyright: Copyright (C) 2010 Andreas Diesner License: GPL 3 or any later version The Debian packaging is: Copyright (C) 2010 Andreas Diesner and is licensed under the GPL version 3, see `/usr/share/common-licenses/GPL-3'. # Please also look if there are files or directories which have a # different copyright/license attached and list them here. GarminPlugin-0.3.23/build/debian/natty/debian/dirs000066400000000000000000000000001232766717500217670ustar00rootroot00000000000000GarminPlugin-0.3.23/build/debian/natty/debian/docs000066400000000000000000000000001232766717500217560ustar00rootroot00000000000000GarminPlugin-0.3.23/build/debian/natty/debian/garminplugin.udev000066400000000000000000000001201232766717500244670ustar00rootroot00000000000000ATTRS{idVendor}=="091e", ATTRS{idProduct}=="0003", MODE="0666", GROUP="plugdev" GarminPlugin-0.3.23/build/debian/natty/debian/rules000077500000000000000000000045001232766717500221740ustar00rootroot00000000000000#!/usr/bin/make -f # -*- makefile -*- # Sample debian/rules that uses debhelper. # This file was originally written by Joey Hess and Craig Small. # As a special exception, when this file is copied by dh-make into a # dh-make output file, you may use that output file without restriction. # This special exception was added by Craig Small in version 0.37 of dh-make. # Uncomment this to turn on verbose mode. #export DH_VERBOSE=1 LBITS := $(shell getconf LONG_BIT) configure: configure-stamp configure-stamp: dh_testdir # Add here commands to configure the package. touch configure-stamp build: build-stamp build-stamp: configure-stamp dh_testdir # Add here commands to compile the package. # Lucid does not have tinyxml package, we need to provide it if test -f tinyxml/Makefile; then cd tinyxml && make; fi cd GarminPlugin && ./configure cd GarminPlugin && $(MAKE) #docbook-to-man debian/garminplugin.sgml > garminplugin.1 touch $@ clean: dh_testdir dh_testroot rm -f build-stamp configure-stamp if test -f GarminPlugin/Makefile; then cd GarminPlugin && make clean; fi # Add here commands to clean up after the build process. dh_clean install: build dh_testdir dh_testroot dh_prep dh_installdirs # Add here commands to install the package into debian/garminplugin. mkdir -p $(CURDIR)/debian/garminplugin/usr/lib/mozilla/plugins cp GarminPlugin/npGarminPlugin.so $(CURDIR)/debian/garminplugin/usr/lib/mozilla/plugins # Hardy #mkdir -p $(CURDIR)/debian/garminplugin/usr/lib/firefox-addons/plugins #cp GarminPlugin/npGarminPlugin.so $(CURDIR)/debian/garminplugin/usr/lib/firefox-addons/plugins # Build architecture-independent files here. binary-indep: install # We have nothing to do by default. # Build architecture-dependent files here. binary-arch: install dh_testdir dh_testroot # dh_installchangelogs # dh_installdocs # dh_installexamples # dh_install # dh_installmenu # dh_installdebconf # dh_installlogrotate # dh_installemacsen # dh_installpam # dh_installmime # dh_python # dh_installinit # dh_installcron # dh_installinfo # dh_installman dh_installudev dh_link dh_strip dh_compress dh_fixperms # dh_perl # dh_makeshlibs dh_installdeb dh_shlibdeps dh_gencontrol dh_md5sums dh_builddeb binary: binary-indep binary-arch .PHONY: build clean binary-indep binary-arch binary install configure GarminPlugin-0.3.23/build/debian/oneiric/000077500000000000000000000000001232766717500201645ustar00rootroot00000000000000GarminPlugin-0.3.23/build/debian/oneiric/debian/000077500000000000000000000000001232766717500214065ustar00rootroot00000000000000GarminPlugin-0.3.23/build/debian/oneiric/debian/compat000066400000000000000000000000021232766717500226040ustar00rootroot000000000000007 GarminPlugin-0.3.23/build/debian/oneiric/debian/control000066400000000000000000000015001232766717500230050ustar00rootroot00000000000000Source: garminplugin Section: misc Priority: optional Maintainer: Andreas Diesner Build-Depends: debhelper (>= 7), libusb-0.1-4, zlib1g-dev, libgcc1, libc6, libusb-dev, libtinyxml-dev, pkg-config, garmin-forerunner-tools, libgcrypt11-dev Standards-Version: 3.8.1 Homepage: http://www.andreas-diesner.de/garminplugin Package: garminplugin Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends} Description: Garmin Communicator Plugin for Linux This Firefox/Chrome plugin allows you to access your garmin device using your browser. You can transfer GPX files to your device or read fitnessdata from the device and upload this data to certain websites like http://connect.garmin.com. This plugin is NOT an official product of the company Garmin (http://www.garmin.com). It is a fan product. GarminPlugin-0.3.23/build/debian/oneiric/debian/copyright000066400000000000000000000012271232766717500233430ustar00rootroot00000000000000This package was debianized by Andreas Diesner on Thu, 15 Apr 2010 17:50:18 +0200. It was downloaded from http://www.andreas-diesner.de/garminplugin Upstream Author(s): Andreas Diesner Copyright: Copyright (C) 2010 Andreas Diesner License: GPL 3 or any later version The Debian packaging is: Copyright (C) 2010 Andreas Diesner and is licensed under the GPL version 3, see `/usr/share/common-licenses/GPL-3'. # Please also look if there are files or directories which have a # different copyright/license attached and list them here. GarminPlugin-0.3.23/build/debian/oneiric/debian/dirs000066400000000000000000000000001232766717500222600ustar00rootroot00000000000000GarminPlugin-0.3.23/build/debian/oneiric/debian/docs000066400000000000000000000000001232766717500222470ustar00rootroot00000000000000GarminPlugin-0.3.23/build/debian/oneiric/debian/garminplugin.udev000066400000000000000000000001201232766717500247600ustar00rootroot00000000000000ATTRS{idVendor}=="091e", ATTRS{idProduct}=="0003", MODE="0666", GROUP="plugdev" GarminPlugin-0.3.23/build/debian/oneiric/debian/rules000077500000000000000000000047011232766717500224700ustar00rootroot00000000000000#!/usr/bin/make -f # -*- makefile -*- # Sample debian/rules that uses debhelper. # This file was originally written by Joey Hess and Craig Small. # As a special exception, when this file is copied by dh-make into a # dh-make output file, you may use that output file without restriction. # This special exception was added by Craig Small in version 0.37 of dh-make. # Uncomment this to turn on verbose mode. #export DH_VERBOSE=1 LBITS := $(shell getconf LONG_BIT) configure: configure-stamp configure-stamp: dh_testdir # Add here commands to configure the package. touch configure-stamp build: build-stamp build-stamp: configure-stamp dh_testdir # Add here commands to compile the package. # Lucid does not have tinyxml package, we need to provide it if test -f tinyxml/Makefile; then cd tinyxml && make; fi cd GarminPlugin && ./configure cd GarminPlugin && $(MAKE) #docbook-to-man debian/garminplugin.sgml > garminplugin.1 touch $@ clean: dh_testdir dh_testroot rm -f build-stamp configure-stamp if test -f GarminPlugin/Makefile; then cd GarminPlugin && make clean; fi # Lucid does not have tinyxml package, we need to provide it if test -f tinyxml/Makefile; then cd tinyxml && make clean; fi # Add here commands to clean up after the build process. dh_clean install: build dh_testdir dh_testroot dh_prep dh_installdirs # Add here commands to install the package into debian/garminplugin. mkdir -p $(CURDIR)/debian/garminplugin/usr/lib/mozilla/plugins cp GarminPlugin/npGarminPlugin.so $(CURDIR)/debian/garminplugin/usr/lib/mozilla/plugins # Hardy #mkdir -p $(CURDIR)/debian/garminplugin/usr/lib/firefox-addons/plugins #cp GarminPlugin/npGarminPlugin.so $(CURDIR)/debian/garminplugin/usr/lib/firefox-addons/plugins # Build architecture-independent files here. binary-indep: install # We have nothing to do by default. # Build architecture-dependent files here. binary-arch: install dh_testdir dh_testroot # dh_installchangelogs # dh_installdocs # dh_installexamples # dh_install # dh_installmenu # dh_installdebconf # dh_installlogrotate # dh_installemacsen # dh_installpam # dh_installmime # dh_python # dh_installinit # dh_installcron # dh_installinfo # dh_installman dh_installudev dh_link dh_strip dh_compress dh_fixperms # dh_perl # dh_makeshlibs dh_installdeb dh_shlibdeps dh_gencontrol dh_md5sums dh_builddeb binary: binary-indep binary-arch .PHONY: build clean binary-indep binary-arch binary install configure GarminPlugin-0.3.23/build/debian/precise/000077500000000000000000000000001232766717500201665ustar00rootroot00000000000000GarminPlugin-0.3.23/build/debian/precise/debian/000077500000000000000000000000001232766717500214105ustar00rootroot00000000000000GarminPlugin-0.3.23/build/debian/precise/debian/compat000066400000000000000000000000021232766717500226060ustar00rootroot000000000000007 GarminPlugin-0.3.23/build/debian/precise/debian/control000066400000000000000000000015001232766717500230070ustar00rootroot00000000000000Source: garminplugin Section: misc Priority: optional Maintainer: Andreas Diesner Build-Depends: debhelper (>= 7), libusb-0.1-4, zlib1g-dev, libgcc1, libc6, libusb-dev, libtinyxml-dev, pkg-config, garmin-forerunner-tools, libgcrypt11-dev Standards-Version: 3.8.1 Homepage: http://www.andreas-diesner.de/garminplugin Package: garminplugin Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends} Description: Garmin Communicator Plugin for Linux This Firefox/Chrome plugin allows you to access your garmin device using your browser. You can transfer GPX files to your device or read fitnessdata from the device and upload this data to certain websites like http://connect.garmin.com. This plugin is NOT an official product of the company Garmin (http://www.garmin.com). It is a fan product. GarminPlugin-0.3.23/build/debian/precise/debian/copyright000066400000000000000000000012271232766717500233450ustar00rootroot00000000000000This package was debianized by Andreas Diesner on Thu, 15 Apr 2010 17:50:18 +0200. It was downloaded from http://www.andreas-diesner.de/garminplugin Upstream Author(s): Andreas Diesner Copyright: Copyright (C) 2010 Andreas Diesner License: GPL 3 or any later version The Debian packaging is: Copyright (C) 2010 Andreas Diesner and is licensed under the GPL version 3, see `/usr/share/common-licenses/GPL-3'. # Please also look if there are files or directories which have a # different copyright/license attached and list them here. GarminPlugin-0.3.23/build/debian/precise/debian/dirs000066400000000000000000000000001232766717500222620ustar00rootroot00000000000000GarminPlugin-0.3.23/build/debian/precise/debian/docs000066400000000000000000000000001232766717500222510ustar00rootroot00000000000000GarminPlugin-0.3.23/build/debian/precise/debian/garminplugin.udev000066400000000000000000000001201232766717500247620ustar00rootroot00000000000000ATTRS{idVendor}=="091e", ATTRS{idProduct}=="0003", MODE="0666", GROUP="plugdev" GarminPlugin-0.3.23/build/debian/precise/debian/rules000077500000000000000000000047011232766717500224720ustar00rootroot00000000000000#!/usr/bin/make -f # -*- makefile -*- # Sample debian/rules that uses debhelper. # This file was originally written by Joey Hess and Craig Small. # As a special exception, when this file is copied by dh-make into a # dh-make output file, you may use that output file without restriction. # This special exception was added by Craig Small in version 0.37 of dh-make. # Uncomment this to turn on verbose mode. #export DH_VERBOSE=1 LBITS := $(shell getconf LONG_BIT) configure: configure-stamp configure-stamp: dh_testdir # Add here commands to configure the package. touch configure-stamp build: build-stamp build-stamp: configure-stamp dh_testdir # Add here commands to compile the package. # Lucid does not have tinyxml package, we need to provide it if test -f tinyxml/Makefile; then cd tinyxml && make; fi cd GarminPlugin && ./configure cd GarminPlugin && $(MAKE) #docbook-to-man debian/garminplugin.sgml > garminplugin.1 touch $@ clean: dh_testdir dh_testroot rm -f build-stamp configure-stamp if test -f GarminPlugin/Makefile; then cd GarminPlugin && make clean; fi # Lucid does not have tinyxml package, we need to provide it if test -f tinyxml/Makefile; then cd tinyxml && make clean; fi # Add here commands to clean up after the build process. dh_clean install: build dh_testdir dh_testroot dh_prep dh_installdirs # Add here commands to install the package into debian/garminplugin. mkdir -p $(CURDIR)/debian/garminplugin/usr/lib/mozilla/plugins cp GarminPlugin/npGarminPlugin.so $(CURDIR)/debian/garminplugin/usr/lib/mozilla/plugins # Hardy #mkdir -p $(CURDIR)/debian/garminplugin/usr/lib/firefox-addons/plugins #cp GarminPlugin/npGarminPlugin.so $(CURDIR)/debian/garminplugin/usr/lib/firefox-addons/plugins # Build architecture-independent files here. binary-indep: install # We have nothing to do by default. # Build architecture-dependent files here. binary-arch: install dh_testdir dh_testroot # dh_installchangelogs # dh_installdocs # dh_installexamples # dh_install # dh_installmenu # dh_installdebconf # dh_installlogrotate # dh_installemacsen # dh_installpam # dh_installmime # dh_python # dh_installinit # dh_installcron # dh_installinfo # dh_installman dh_installudev dh_link dh_strip dh_compress dh_fixperms # dh_perl # dh_makeshlibs dh_installdeb dh_shlibdeps dh_gencontrol dh_md5sums dh_builddeb binary: binary-indep binary-arch .PHONY: build clean binary-indep binary-arch binary install configure GarminPlugin-0.3.23/build/debian/quantal/000077500000000000000000000000001232766717500202015ustar00rootroot00000000000000GarminPlugin-0.3.23/build/debian/quantal/debian/000077500000000000000000000000001232766717500214235ustar00rootroot00000000000000GarminPlugin-0.3.23/build/debian/quantal/debian/compat000066400000000000000000000000021232766717500226210ustar00rootroot000000000000007 GarminPlugin-0.3.23/build/debian/quantal/debian/control000066400000000000000000000015001232766717500230220ustar00rootroot00000000000000Source: garminplugin Section: misc Priority: optional Maintainer: Andreas Diesner Build-Depends: debhelper (>= 7), libusb-0.1-4, zlib1g-dev, libgcc1, libc6, libusb-dev, libtinyxml-dev, pkg-config, garmin-forerunner-tools, libgcrypt11-dev Standards-Version: 3.8.1 Homepage: http://www.andreas-diesner.de/garminplugin Package: garminplugin Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends} Description: Garmin Communicator Plugin for Linux This Firefox/Chrome plugin allows you to access your garmin device using your browser. You can transfer GPX files to your device or read fitnessdata from the device and upload this data to certain websites like http://connect.garmin.com. This plugin is NOT an official product of the company Garmin (http://www.garmin.com). It is a fan product. GarminPlugin-0.3.23/build/debian/quantal/debian/copyright000066400000000000000000000012271232766717500233600ustar00rootroot00000000000000This package was debianized by Andreas Diesner on Thu, 15 Apr 2010 17:50:18 +0200. It was downloaded from http://www.andreas-diesner.de/garminplugin Upstream Author(s): Andreas Diesner Copyright: Copyright (C) 2010 Andreas Diesner License: GPL 3 or any later version The Debian packaging is: Copyright (C) 2010 Andreas Diesner and is licensed under the GPL version 3, see `/usr/share/common-licenses/GPL-3'. # Please also look if there are files or directories which have a # different copyright/license attached and list them here. GarminPlugin-0.3.23/build/debian/quantal/debian/dirs000066400000000000000000000000001232766717500222750ustar00rootroot00000000000000GarminPlugin-0.3.23/build/debian/quantal/debian/docs000066400000000000000000000000001232766717500222640ustar00rootroot00000000000000GarminPlugin-0.3.23/build/debian/quantal/debian/garminplugin.udev000066400000000000000000000001201232766717500247750ustar00rootroot00000000000000ATTRS{idVendor}=="091e", ATTRS{idProduct}=="0003", MODE="0666", GROUP="plugdev" GarminPlugin-0.3.23/build/debian/quantal/debian/rules000077500000000000000000000047011232766717500225050ustar00rootroot00000000000000#!/usr/bin/make -f # -*- makefile -*- # Sample debian/rules that uses debhelper. # This file was originally written by Joey Hess and Craig Small. # As a special exception, when this file is copied by dh-make into a # dh-make output file, you may use that output file without restriction. # This special exception was added by Craig Small in version 0.37 of dh-make. # Uncomment this to turn on verbose mode. #export DH_VERBOSE=1 LBITS := $(shell getconf LONG_BIT) configure: configure-stamp configure-stamp: dh_testdir # Add here commands to configure the package. touch configure-stamp build: build-stamp build-stamp: configure-stamp dh_testdir # Add here commands to compile the package. # Lucid does not have tinyxml package, we need to provide it if test -f tinyxml/Makefile; then cd tinyxml && make; fi cd GarminPlugin && ./configure cd GarminPlugin && $(MAKE) #docbook-to-man debian/garminplugin.sgml > garminplugin.1 touch $@ clean: dh_testdir dh_testroot rm -f build-stamp configure-stamp if test -f GarminPlugin/Makefile; then cd GarminPlugin && make clean; fi # Lucid does not have tinyxml package, we need to provide it if test -f tinyxml/Makefile; then cd tinyxml && make clean; fi # Add here commands to clean up after the build process. dh_clean install: build dh_testdir dh_testroot dh_prep dh_installdirs # Add here commands to install the package into debian/garminplugin. mkdir -p $(CURDIR)/debian/garminplugin/usr/lib/mozilla/plugins cp GarminPlugin/npGarminPlugin.so $(CURDIR)/debian/garminplugin/usr/lib/mozilla/plugins # Hardy #mkdir -p $(CURDIR)/debian/garminplugin/usr/lib/firefox-addons/plugins #cp GarminPlugin/npGarminPlugin.so $(CURDIR)/debian/garminplugin/usr/lib/firefox-addons/plugins # Build architecture-independent files here. binary-indep: install # We have nothing to do by default. # Build architecture-dependent files here. binary-arch: install dh_testdir dh_testroot # dh_installchangelogs # dh_installdocs # dh_installexamples # dh_install # dh_installmenu # dh_installdebconf # dh_installlogrotate # dh_installemacsen # dh_installpam # dh_installmime # dh_python # dh_installinit # dh_installcron # dh_installinfo # dh_installman dh_installudev dh_link dh_strip dh_compress dh_fixperms # dh_perl # dh_makeshlibs dh_installdeb dh_shlibdeps dh_gencontrol dh_md5sums dh_builddeb binary: binary-indep binary-arch .PHONY: build clean binary-indep binary-arch binary install configure GarminPlugin-0.3.23/build/debian/raring/000077500000000000000000000000001232766717500200165ustar00rootroot00000000000000GarminPlugin-0.3.23/build/debian/raring/debian/000077500000000000000000000000001232766717500212405ustar00rootroot00000000000000GarminPlugin-0.3.23/build/debian/raring/debian/compat000066400000000000000000000000021232766717500224360ustar00rootroot000000000000007 GarminPlugin-0.3.23/build/debian/raring/debian/control000066400000000000000000000015001232766717500226370ustar00rootroot00000000000000Source: garminplugin Section: misc Priority: optional Maintainer: Andreas Diesner Build-Depends: debhelper (>= 7), libusb-0.1-4, zlib1g-dev, libgcc1, libc6, libusb-dev, libtinyxml-dev, pkg-config, garmin-forerunner-tools, libgcrypt11-dev Standards-Version: 3.8.1 Homepage: http://www.andreas-diesner.de/garminplugin Package: garminplugin Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends} Description: Garmin Communicator Plugin for Linux This Firefox/Chrome plugin allows you to access your garmin device using your browser. You can transfer GPX files to your device or read fitnessdata from the device and upload this data to certain websites like http://connect.garmin.com. This plugin is NOT an official product of the company Garmin (http://www.garmin.com). It is a fan product. GarminPlugin-0.3.23/build/debian/raring/debian/copyright000066400000000000000000000012271232766717500231750ustar00rootroot00000000000000This package was debianized by Andreas Diesner on Thu, 15 Apr 2010 17:50:18 +0200. It was downloaded from http://www.andreas-diesner.de/garminplugin Upstream Author(s): Andreas Diesner Copyright: Copyright (C) 2010 Andreas Diesner License: GPL 3 or any later version The Debian packaging is: Copyright (C) 2010 Andreas Diesner and is licensed under the GPL version 3, see `/usr/share/common-licenses/GPL-3'. # Please also look if there are files or directories which have a # different copyright/license attached and list them here. GarminPlugin-0.3.23/build/debian/raring/debian/dirs000066400000000000000000000000001232766717500221120ustar00rootroot00000000000000GarminPlugin-0.3.23/build/debian/raring/debian/docs000066400000000000000000000000001232766717500221010ustar00rootroot00000000000000GarminPlugin-0.3.23/build/debian/raring/debian/garminplugin.udev000066400000000000000000000001201232766717500246120ustar00rootroot00000000000000ATTRS{idVendor}=="091e", ATTRS{idProduct}=="0003", MODE="0666", GROUP="plugdev" GarminPlugin-0.3.23/build/debian/raring/debian/rules000077500000000000000000000047011232766717500223220ustar00rootroot00000000000000#!/usr/bin/make -f # -*- makefile -*- # Sample debian/rules that uses debhelper. # This file was originally written by Joey Hess and Craig Small. # As a special exception, when this file is copied by dh-make into a # dh-make output file, you may use that output file without restriction. # This special exception was added by Craig Small in version 0.37 of dh-make. # Uncomment this to turn on verbose mode. #export DH_VERBOSE=1 LBITS := $(shell getconf LONG_BIT) configure: configure-stamp configure-stamp: dh_testdir # Add here commands to configure the package. touch configure-stamp build: build-stamp build-stamp: configure-stamp dh_testdir # Add here commands to compile the package. # Lucid does not have tinyxml package, we need to provide it if test -f tinyxml/Makefile; then cd tinyxml && make; fi cd GarminPlugin && ./configure cd GarminPlugin && $(MAKE) #docbook-to-man debian/garminplugin.sgml > garminplugin.1 touch $@ clean: dh_testdir dh_testroot rm -f build-stamp configure-stamp if test -f GarminPlugin/Makefile; then cd GarminPlugin && make clean; fi # Lucid does not have tinyxml package, we need to provide it if test -f tinyxml/Makefile; then cd tinyxml && make clean; fi # Add here commands to clean up after the build process. dh_clean install: build dh_testdir dh_testroot dh_prep dh_installdirs # Add here commands to install the package into debian/garminplugin. mkdir -p $(CURDIR)/debian/garminplugin/usr/lib/mozilla/plugins cp GarminPlugin/npGarminPlugin.so $(CURDIR)/debian/garminplugin/usr/lib/mozilla/plugins # Hardy #mkdir -p $(CURDIR)/debian/garminplugin/usr/lib/firefox-addons/plugins #cp GarminPlugin/npGarminPlugin.so $(CURDIR)/debian/garminplugin/usr/lib/firefox-addons/plugins # Build architecture-independent files here. binary-indep: install # We have nothing to do by default. # Build architecture-dependent files here. binary-arch: install dh_testdir dh_testroot # dh_installchangelogs # dh_installdocs # dh_installexamples # dh_install # dh_installmenu # dh_installdebconf # dh_installlogrotate # dh_installemacsen # dh_installpam # dh_installmime # dh_python # dh_installinit # dh_installcron # dh_installinfo # dh_installman dh_installudev dh_link dh_strip dh_compress dh_fixperms # dh_perl # dh_makeshlibs dh_installdeb dh_shlibdeps dh_gencontrol dh_md5sums dh_builddeb binary: binary-indep binary-arch .PHONY: build clean binary-indep binary-arch binary install configure GarminPlugin-0.3.23/build/debian/saucy/000077500000000000000000000000001232766717500176605ustar00rootroot00000000000000GarminPlugin-0.3.23/build/debian/saucy/debian/000077500000000000000000000000001232766717500211025ustar00rootroot00000000000000GarminPlugin-0.3.23/build/debian/saucy/debian/compat000066400000000000000000000000021232766717500223000ustar00rootroot000000000000007 GarminPlugin-0.3.23/build/debian/saucy/debian/control000066400000000000000000000015001232766717500225010ustar00rootroot00000000000000Source: garminplugin Section: misc Priority: optional Maintainer: Andreas Diesner Build-Depends: debhelper (>= 7), libusb-0.1-4, zlib1g-dev, libgcc1, libc6, libusb-dev, libtinyxml-dev, pkg-config, garmin-forerunner-tools, libgcrypt11-dev Standards-Version: 3.8.1 Homepage: http://www.andreas-diesner.de/garminplugin Package: garminplugin Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends} Description: Garmin Communicator Plugin for Linux This Firefox/Chrome plugin allows you to access your garmin device using your browser. You can transfer GPX files to your device or read fitnessdata from the device and upload this data to certain websites like http://connect.garmin.com. This plugin is NOT an official product of the company Garmin (http://www.garmin.com). It is a fan product. GarminPlugin-0.3.23/build/debian/saucy/debian/copyright000066400000000000000000000012271232766717500230370ustar00rootroot00000000000000This package was debianized by Andreas Diesner on Thu, 15 Apr 2010 17:50:18 +0200. It was downloaded from http://www.andreas-diesner.de/garminplugin Upstream Author(s): Andreas Diesner Copyright: Copyright (C) 2010 Andreas Diesner License: GPL 3 or any later version The Debian packaging is: Copyright (C) 2010 Andreas Diesner and is licensed under the GPL version 3, see `/usr/share/common-licenses/GPL-3'. # Please also look if there are files or directories which have a # different copyright/license attached and list them here. GarminPlugin-0.3.23/build/debian/saucy/debian/dirs000066400000000000000000000000001232766717500217540ustar00rootroot00000000000000GarminPlugin-0.3.23/build/debian/saucy/debian/docs000066400000000000000000000000001232766717500217430ustar00rootroot00000000000000GarminPlugin-0.3.23/build/debian/saucy/debian/garminplugin.udev000066400000000000000000000001201232766717500244540ustar00rootroot00000000000000ATTRS{idVendor}=="091e", ATTRS{idProduct}=="0003", MODE="0666", GROUP="plugdev" GarminPlugin-0.3.23/build/debian/saucy/debian/rules000077500000000000000000000047011232766717500221640ustar00rootroot00000000000000#!/usr/bin/make -f # -*- makefile -*- # Sample debian/rules that uses debhelper. # This file was originally written by Joey Hess and Craig Small. # As a special exception, when this file is copied by dh-make into a # dh-make output file, you may use that output file without restriction. # This special exception was added by Craig Small in version 0.37 of dh-make. # Uncomment this to turn on verbose mode. #export DH_VERBOSE=1 LBITS := $(shell getconf LONG_BIT) configure: configure-stamp configure-stamp: dh_testdir # Add here commands to configure the package. touch configure-stamp build: build-stamp build-stamp: configure-stamp dh_testdir # Add here commands to compile the package. # Lucid does not have tinyxml package, we need to provide it if test -f tinyxml/Makefile; then cd tinyxml && make; fi cd GarminPlugin && ./configure cd GarminPlugin && $(MAKE) #docbook-to-man debian/garminplugin.sgml > garminplugin.1 touch $@ clean: dh_testdir dh_testroot rm -f build-stamp configure-stamp if test -f GarminPlugin/Makefile; then cd GarminPlugin && make clean; fi # Lucid does not have tinyxml package, we need to provide it if test -f tinyxml/Makefile; then cd tinyxml && make clean; fi # Add here commands to clean up after the build process. dh_clean install: build dh_testdir dh_testroot dh_prep dh_installdirs # Add here commands to install the package into debian/garminplugin. mkdir -p $(CURDIR)/debian/garminplugin/usr/lib/mozilla/plugins cp GarminPlugin/npGarminPlugin.so $(CURDIR)/debian/garminplugin/usr/lib/mozilla/plugins # Hardy #mkdir -p $(CURDIR)/debian/garminplugin/usr/lib/firefox-addons/plugins #cp GarminPlugin/npGarminPlugin.so $(CURDIR)/debian/garminplugin/usr/lib/firefox-addons/plugins # Build architecture-independent files here. binary-indep: install # We have nothing to do by default. # Build architecture-dependent files here. binary-arch: install dh_testdir dh_testroot # dh_installchangelogs # dh_installdocs # dh_installexamples # dh_install # dh_installmenu # dh_installdebconf # dh_installlogrotate # dh_installemacsen # dh_installpam # dh_installmime # dh_python # dh_installinit # dh_installcron # dh_installinfo # dh_installman dh_installudev dh_link dh_strip dh_compress dh_fixperms # dh_perl # dh_makeshlibs dh_installdeb dh_shlibdeps dh_gencontrol dh_md5sums dh_builddeb binary: binary-indep binary-arch .PHONY: build clean binary-indep binary-arch binary install configure GarminPlugin-0.3.23/build/debian/trusty/000077500000000000000000000000001232766717500201065ustar00rootroot00000000000000GarminPlugin-0.3.23/build/debian/trusty/debian/000077500000000000000000000000001232766717500213305ustar00rootroot00000000000000GarminPlugin-0.3.23/build/debian/trusty/debian/compat000066400000000000000000000000021232766717500225260ustar00rootroot000000000000007 GarminPlugin-0.3.23/build/debian/trusty/debian/control000066400000000000000000000015001232766717500227270ustar00rootroot00000000000000Source: garminplugin Section: misc Priority: optional Maintainer: Andreas Diesner Build-Depends: debhelper (>= 7), libusb-0.1-4, zlib1g-dev, libgcc1, libc6, libusb-dev, libtinyxml-dev, pkg-config, garmin-forerunner-tools, libgcrypt11-dev Standards-Version: 3.8.1 Homepage: http://www.andreas-diesner.de/garminplugin Package: garminplugin Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends} Description: Garmin Communicator Plugin for Linux This Firefox/Chrome plugin allows you to access your garmin device using your browser. You can transfer GPX files to your device or read fitnessdata from the device and upload this data to certain websites like http://connect.garmin.com. This plugin is NOT an official product of the company Garmin (http://www.garmin.com). It is a fan product. GarminPlugin-0.3.23/build/debian/trusty/debian/copyright000066400000000000000000000012271232766717500232650ustar00rootroot00000000000000This package was debianized by Andreas Diesner on Thu, 15 Apr 2010 17:50:18 +0200. It was downloaded from http://www.andreas-diesner.de/garminplugin Upstream Author(s): Andreas Diesner Copyright: Copyright (C) 2010 Andreas Diesner License: GPL 3 or any later version The Debian packaging is: Copyright (C) 2010 Andreas Diesner and is licensed under the GPL version 3, see `/usr/share/common-licenses/GPL-3'. # Please also look if there are files or directories which have a # different copyright/license attached and list them here. GarminPlugin-0.3.23/build/debian/trusty/debian/dirs000066400000000000000000000000001232766717500222020ustar00rootroot00000000000000GarminPlugin-0.3.23/build/debian/trusty/debian/docs000066400000000000000000000000001232766717500221710ustar00rootroot00000000000000GarminPlugin-0.3.23/build/debian/trusty/debian/garminplugin.udev000066400000000000000000000001201232766717500247020ustar00rootroot00000000000000ATTRS{idVendor}=="091e", ATTRS{idProduct}=="0003", MODE="0666", GROUP="plugdev" GarminPlugin-0.3.23/build/debian/trusty/debian/rules000077500000000000000000000047011232766717500224120ustar00rootroot00000000000000#!/usr/bin/make -f # -*- makefile -*- # Sample debian/rules that uses debhelper. # This file was originally written by Joey Hess and Craig Small. # As a special exception, when this file is copied by dh-make into a # dh-make output file, you may use that output file without restriction. # This special exception was added by Craig Small in version 0.37 of dh-make. # Uncomment this to turn on verbose mode. #export DH_VERBOSE=1 LBITS := $(shell getconf LONG_BIT) configure: configure-stamp configure-stamp: dh_testdir # Add here commands to configure the package. touch configure-stamp build: build-stamp build-stamp: configure-stamp dh_testdir # Add here commands to compile the package. # Lucid does not have tinyxml package, we need to provide it if test -f tinyxml/Makefile; then cd tinyxml && make; fi cd GarminPlugin && ./configure cd GarminPlugin && $(MAKE) #docbook-to-man debian/garminplugin.sgml > garminplugin.1 touch $@ clean: dh_testdir dh_testroot rm -f build-stamp configure-stamp if test -f GarminPlugin/Makefile; then cd GarminPlugin && make clean; fi # Lucid does not have tinyxml package, we need to provide it if test -f tinyxml/Makefile; then cd tinyxml && make clean; fi # Add here commands to clean up after the build process. dh_clean install: build dh_testdir dh_testroot dh_prep dh_installdirs # Add here commands to install the package into debian/garminplugin. mkdir -p $(CURDIR)/debian/garminplugin/usr/lib/mozilla/plugins cp GarminPlugin/npGarminPlugin.so $(CURDIR)/debian/garminplugin/usr/lib/mozilla/plugins # Hardy #mkdir -p $(CURDIR)/debian/garminplugin/usr/lib/firefox-addons/plugins #cp GarminPlugin/npGarminPlugin.so $(CURDIR)/debian/garminplugin/usr/lib/firefox-addons/plugins # Build architecture-independent files here. binary-indep: install # We have nothing to do by default. # Build architecture-dependent files here. binary-arch: install dh_testdir dh_testroot # dh_installchangelogs # dh_installdocs # dh_installexamples # dh_install # dh_installmenu # dh_installdebconf # dh_installlogrotate # dh_installemacsen # dh_installpam # dh_installmime # dh_python # dh_installinit # dh_installcron # dh_installinfo # dh_installman dh_installudev dh_link dh_strip dh_compress dh_fixperms # dh_perl # dh_makeshlibs dh_installdeb dh_shlibdeps dh_gencontrol dh_md5sums dh_builddeb binary: binary-indep binary-arch .PHONY: build clean binary-indep binary-arch binary install configure GarminPlugin-0.3.23/build/fedora/000077500000000000000000000000001232766717500165525ustar00rootroot00000000000000GarminPlugin-0.3.23/build/fedora/13/000077500000000000000000000000001232766717500167755ustar00rootroot00000000000000GarminPlugin-0.3.23/build/fedora/13/SPECS/000077500000000000000000000000001232766717500176525ustar00rootroot00000000000000GarminPlugin-0.3.23/build/fedora/13/SPECS/GarminPlugin.spec000066400000000000000000000033501232766717500231230ustar00rootroot00000000000000Name: GarminPlugin Version: §§§VERSION§§§ Release: 1%{?dist} Summary: Garmin Communicator Plugin port for Linux License: GPLv2+ Group: Other URL: http://www.andreas-diesner.de/garminplugin/ Source: http://github.com/adiesner/GarminPlugin/GarminPlugin-§§§VERSION§§§.tar.gz BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) BuildArch: §§§ARCHITECTURE§§§ BuildRequires: tinyxml-devel BuildRequires: garmintools-devel BuildRequires: libusb-devel BuildRequires: zlib-devel BuildRequires: xulrunner-devel BuildRequires: libgcrypt-devel %description This browser plugin has the same methods and properties as the official Garmin Communicator Plugin (http://www8.garmin.com/products/communicator/). It can be used to transfer GPX files (Geocache Descriptions) to your garmin device using the official Garmin Javascript API. Its functionality depends on the device you use. - Edge305/Forerunner305: ReadFitnessData, ReadGpsData, No write support - Edge705/Oregon/Dakota: ReadFitnessData, ReadGpsData, Write Gpx files - Edge800: ReadFitnessData, Write Gpx/Tcx Files - Other devices: Executes external command to write Gpx to device %prep %setup -q %build %configure --with-ticpp-libdir=%{_libdir} --with-ticpp-incdir=%{_includedir} --with-garmintools-incdir=%{_includedir} --with-garmintools-libdir=%{_libdir} make %install rm -rf %{buildroot} mkdir -p %{buildroot}%{_libdir}/mozilla/plugins cp -p %{_builddir}/%{buildsubdir}/npGarminPlugin.so %{buildroot}%{_libdir}/mozilla/plugins %clean rm -rf %{buildroot} %post /sbin/ldconfig %postun -p /sbin/ldconfig %files %defattr(-,root,root,-) %{_libdir}/mozilla/plugins/*.so %changelog GarminPlugin-0.3.23/build/fedora/14/000077500000000000000000000000001232766717500167765ustar00rootroot00000000000000GarminPlugin-0.3.23/build/fedora/14/SPECS/000077500000000000000000000000001232766717500176535ustar00rootroot00000000000000GarminPlugin-0.3.23/build/fedora/14/SPECS/GarminPlugin.spec000066400000000000000000000033501232766717500231240ustar00rootroot00000000000000Name: GarminPlugin Version: §§§VERSION§§§ Release: 1%{?dist} Summary: Garmin Communicator Plugin port for Linux License: GPLv2+ Group: Other URL: http://www.andreas-diesner.de/garminplugin/ Source: http://github.com/adiesner/GarminPlugin/GarminPlugin-§§§VERSION§§§.tar.gz BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) BuildArch: §§§ARCHITECTURE§§§ BuildRequires: tinyxml-devel BuildRequires: garmintools-devel BuildRequires: libusb-devel BuildRequires: zlib-devel BuildRequires: xulrunner-devel BuildRequires: libgcrypt-devel %description This browser plugin has the same methods and properties as the official Garmin Communicator Plugin (http://www8.garmin.com/products/communicator/). It can be used to transfer GPX files (Geocache Descriptions) to your garmin device using the official Garmin Javascript API. Its functionality depends on the device you use. - Edge305/Forerunner305: ReadFitnessData, ReadGpsData, No write support - Edge705/Oregon/Dakota: ReadFitnessData, ReadGpsData, Write Gpx files - Edge800: ReadFitnessData, Write Gpx/Tcx Files - Other devices: Executes external command to write Gpx to device %prep %setup -q %build %configure --with-ticpp-libdir=%{_libdir} --with-ticpp-incdir=%{_includedir} --with-garmintools-incdir=%{_includedir} --with-garmintools-libdir=%{_libdir} make %install rm -rf %{buildroot} mkdir -p %{buildroot}%{_libdir}/mozilla/plugins cp -p %{_builddir}/%{buildsubdir}/npGarminPlugin.so %{buildroot}%{_libdir}/mozilla/plugins %clean rm -rf %{buildroot} %post /sbin/ldconfig %postun -p /sbin/ldconfig %files %defattr(-,root,root,-) %{_libdir}/mozilla/plugins/*.so %changelog GarminPlugin-0.3.23/build/fedora/16/000077500000000000000000000000001232766717500170005ustar00rootroot00000000000000GarminPlugin-0.3.23/build/fedora/16/SPECS/000077500000000000000000000000001232766717500176555ustar00rootroot00000000000000GarminPlugin-0.3.23/build/fedora/16/SPECS/GarminPlugin.spec000066400000000000000000000033101232766717500231220ustar00rootroot00000000000000Name: GarminPlugin Version: §§§VERSION§§§ Release: 1%{?dist} Summary: Garmin Communicator Plugin port for Linux License: GPLv2+ Group: Other URL: http://www.andreas-diesner.de/garminplugin/ Source: http://github.com/adiesner/GarminPlugin/GarminPlugin-§§§VERSION§§§.tar.gz BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) BuildArch: §§§ARCHITECTURE§§§ BuildRequires: tinyxml-devel BuildRequires: garmintools-devel BuildRequires: libusb-devel BuildRequires: zlib-devel BuildRequires: libgcrypt-devel %description This browser plugin has the same methods and properties as the official Garmin Communicator Plugin (http://www8.garmin.com/products/communicator/). It can be used to transfer GPX files (Geocache Descriptions) to your garmin device using the official Garmin Javascript API. Its functionality depends on the device you use. - Edge305/Forerunner305: ReadFitnessData, ReadGpsData, No write support - Edge705/Oregon/Dakota: ReadFitnessData, ReadGpsData, Write Gpx files - Edge800: ReadFitnessData, Write Gpx/Tcx Files - Other devices: Executes external command to write Gpx to device %prep %setup -q %build %configure --with-ticpp-libdir=%{_libdir} --with-ticpp-incdir=%{_includedir} --with-garmintools-incdir=%{_includedir} --with-garmintools-libdir=%{_libdir} make %install rm -rf %{buildroot} mkdir -p %{buildroot}%{_libdir}/mozilla/plugins cp -p %{_builddir}/%{buildsubdir}/npGarminPlugin.so %{buildroot}%{_libdir}/mozilla/plugins %clean rm -rf %{buildroot} %post /sbin/ldconfig %postun -p /sbin/ldconfig %files %defattr(-,root,root,-) %{_libdir}/mozilla/plugins/*.so %changelog GarminPlugin-0.3.23/build/fedora/createBuildEnv.sh000066400000000000000000000065711232766717500220130ustar00rootroot00000000000000#!/bin/sh # # The following packages are required before executing this script! # # yum -y update # yum -y install rpmdevtools tinyxml-devel zlib-devel libusb-devel garmintools-devel xulrunner-devel openssl-devel # yum -y groupinstall "Development Tools" # FEDORAVERSION=$1 VERSION=$2 GITREPOSITORYDIR=`pwd` if [ -z $FEDORAVERSION"" ]; then echo "Please specify for which fedora version you want to build" echo "Example: createBuildEnv.sh 14 0.3.0" exit 1 fi if [ -d "$GITREPOSITORYDIR/$FEDORAVERSION/SPECS/" ]; then echo "Using build environment from directory $GITREPOSITORYDIR/$FEDORAVERSION/SPECS/" else echo "Build environment settings not found in directory $GITREPOSITORYDIR/$FEDORAVERSION/SPECS/" exit 1 fi if [ ! -n "$VERSION" ]; then # Determine last tag GITTAG=`git tag -l | tail -1` VERSION=`echo $GITTAG|cut -c2-` echo "Please specify which plugin version you want to build" echo "Example: createBuildEnv.sh 14 $VERSION" exit 1 fi ARCHITECTURE=`uname -i` echo "Creating build environment for version $VERSION - architecture $ARCHITECTURE" # Checkout last version #git checkout $GITTAG cd HOMEDIR=`pwd` # Create Build Environment rpmdev-setuptree if [ -d "$HOMEDIR/rpmbuild/SOURCES/" ]; then echo "Build environment created $HOMEDIR/rpmbuild/SOURCES/" else echo "Failed to create build environment. Missing directory $HOMEDIR/rpmbuild/SOURCES/" exit 1 fi echo "Copying Sources to build dir $HOMEDIR/rpmbuild/SOURCES" if [ -d "$HOMEDIR/rpmbuild/SOURCES/GarminPlugin-$VERSION" ]; then echo "Removing previously created directory $HOMEDIR/rpmbuild/SOURCES/GarminPlugin-$VERSION" rm -r "$HOMEDIR/rpmbuild/SOURCES/GarminPlugin-$VERSION" fi cp -r "$GITREPOSITORYDIR/../../src" "$HOMEDIR/rpmbuild/SOURCES/GarminPlugin-$VERSION" if [ -f "$HOMEDIR/rpmbuild/SOURCES/GarminPlugin-$VERSION.tar.gz" ]; then echo "Removing previously created tar $HOMEDIR/rpmbuild/SOURCES/GarminPlugin-$VERSION.tar.gz" rm "$HOMEDIR/rpmbuild/SOURCES/GarminPlugin-$VERSION.tar.gz" fi cd "$HOMEDIR/rpmbuild/SOURCES/" tar cvzf "GarminPlugin-$VERSION.tar.gz" "GarminPlugin-$VERSION" # removing no longer needed directory with sources rm -r "$HOMEDIR/rpmbuild/SOURCES/GarminPlugin-$VERSION" # Building rpms # http://www.deaconsworld.org.uk/2009/02/05/building-rpms-as-a-normal-user/ SPECFILE="$HOMEDIR/rpmbuild/SPECS/GarminPlugin.spec" cp "$GITREPOSITORYDIR/$FEDORAVERSION/SPECS/GarminPlugin.spec" "$SPECFILE" # Replace Version and architecture in file sed -i "s/§§§VERSION§§§/$VERSION/g" "$SPECFILE" sed -i "s/§§§ARCHITECTURE§§§/$ARCHITECTURE/g" "$SPECFILE" INFILE="$GITREPOSITORYDIR/../../HISTORY" while read curline; do if [ "x$curline" != "x" ]; then FIRSTCHAR=`echo $curline|cut -b1` if [ "$FIRSTCHAR" != "-" ]; then DATE=`echo $curline | cut -b-10` DATE=`date "+%a %b %d %Y" -d $DATE` echo "* $DATE Andreas Diesner " >>$SPECFILE else echo $curline >>$SPECFILE fi fi done < $INFILE rm "$HOMEDIR/rpmbuild/RPMS/GarminPlugin-$VERSION*" cd $HOMEDIR/rpmbuild/SPECS # Build env is ready echo "********************************************************" echo "Build environment setup complete" echo "Now enter the following commands to start your build:" echo "" echo "cd '$HOMEDIR/rpmbuild/SPECS'" echo "rpmbuild --clean GarminPlugin.spec" echo "rpmbuild -bb GarminPlugin.spec" GarminPlugin-0.3.23/build/opensuse-build/000077500000000000000000000000001232766717500202505ustar00rootroot00000000000000GarminPlugin-0.3.23/build/opensuse-build/GarminPlugin.spec000066400000000000000000000051611232766717500235230ustar00rootroot00000000000000Name: GarminPlugin Version: 0.3.4 Release: 1 Summary: Garmin Communicator Plugin port for Linux License: GPLv3+ %if 0%{?fedora} > 13 Group: Other %endif %if 0%{?suse_version} >= 1020 Group: Productivity/Networking/Web/Browsers %endif URL: http://www.andreas-diesner.de/garminplugin/ #Source: https://github.com/adiesner/GarminPlugin/tarball/V0.3.3 Source: GarminPlugin-0.3.4.tar.gz BuildRoot: %{_tmppath}/%{name}-%{version}-build %if 0%{?suse_version} >= 1020 BuildRequires: gcc BuildRequires: gcc-c++ BuildRequires: libusb-compat-devel BuildRequires: mozilla-xulrunner192-devel BuildRequires: tinyxml-devel BuildRequires: libgarmintools4-devel BuildRequires: zlib-devel BuildRequires: pkg-config BuildRequires: libgcrypt-devel %endif %if 0%{?fedora} > 13 BuildRequires: gcc BuildRequires: gcc-c++ BuildRequires: tinyxml-devel BuildRequires: garmintools-devel BuildRequires: libusb-devel BuildRequires: zlib-devel BuildRequires: xulrunner-devel # is here because of error "have choice for desktop-notification-daemon needed by libnotify: kdebase-runtime notification-daemon xfce4-notifyd" BuildRequires: notification-daemon BuildRequires: libgcrypt-devel %endif %description This browser plugin has the same methods and properties as the official Garmin Communicator Plugin (http://www8.garmin.com/products/communicator/). It can be used to transfer GPX files (Geocache Descriptions) to your garmin device using the official Garmin Javascript API. Its functionality depends on the device you use. - Edge305/Forerunner305: ReadFitnessData, ReadGpsData, No write support - Edge705/Oregon/Dakota: ReadFitnessData, ReadGpsData, Write Gpx files - Edge800: ReadFitnessData, Write Gpx/Tcx Files - Other devices: Executes external command to write Gpx to device %prep %setup -q %build cd src %configure --with-ticpp-libdir=%{_libdir} --with-ticpp-incdir=%{_includedir} --with-garmintools-incdir=%{_includedir} --with-garmintools-libdir=%{_libdir} make %install %if 0%{?suse_version} >= 1020 install -D -m 0755 %{_builddir}/%{buildsubdir}/src/npGarminPlugin.so %{buildroot}%{_libdir}/browser-plugins/npGarminPlugin.so %endif %if 0%{?fedora} > 13 install -D -m 0755 %{_builddir}/%{buildsubdir}/src/npGarminPlugin.so %{buildroot}%{_libdir}/mozilla/plugins/npGarminPlugin.so %endif %clean rm -rf %{buildroot} %post -p /sbin/ldconfig %postun -p /sbin/ldconfig %files %defattr(-,root,root,-) %doc HISTORY README %if 0%{?suse_version} >= 1020 %{_libdir}/browser-plugins/*.so %endif %if 0%{?fedora} > 13 %{_libdir}/mozilla/plugins/*.so %endif %changelog GarminPlugin-0.3.23/src/000077500000000000000000000000001232766717500150025ustar00rootroot00000000000000GarminPlugin-0.3.23/src/Fit2TcxConverter.cpp000066400000000000000000000335001232766717500206620ustar00rootroot00000000000000/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */ /* * Fit2Tcx * Copyright (C) Andreas Diesner 2011 * * Fit2Tcx is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Fit2Tcx is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #include "Fit2TcxConverter.h" #include "gpsFunctions.h" #include "fit/fitDefines.hpp" #define DEGREES 180.0 #define SEMICIRCLES 0x80000000 #define SEMI2DEG(a) (double)(a) * DEGREES / SEMICIRCLES Fit2TcxConverter::Fit2TcxConverter() : tcxBase(NULL), tcxActivities(NULL), tcxActivity(NULL), tcxAuthor(NULL), tcxLap(NULL), tcxTrack(NULL), tcxCreator(NULL) { } Fit2TcxConverter::~Fit2TcxConverter() { // TODO Auto-generated destructor stub } void Fit2TcxConverter::fitMsgReceived(FitMsg *msg) { if (msg == NULL) { return; } if (this->tcxBase == NULL) { tcxBase = new TcxBase(); tcxActivities = new TcxActivities(); *(tcxBase) << tcxActivities; tcxActivity = new TcxActivity("dummy"); *(tcxActivities) << tcxActivity; tcxCreator = new TcxCreator(); (*tcxActivity)<< tcxCreator; tcxAuthor = new TcxAuthor(); (*tcxBase) << tcxAuthor; } if (msg->GetType() == FIT_MESSAGE_FILE_ID) { FitMsg_File_ID *fileid = dynamic_cast (msg); if (fileid != NULL) { handle_File_ID(fileid); } } else if (msg->GetType() == FIT_MESSAGE_FILE_CREATOR) { FitMsg_File_Creator *filecreator = dynamic_cast (msg); if (filecreator != NULL) { handle_File_Creator(filecreator); } } else if (msg->GetType() == FIT_MESSAGE_LAP) { FitMsg_Lap *filelap = dynamic_cast (msg); if (filelap != NULL) { handle_Lap(filelap); } } else if (msg->GetType() == FIT_MESSAGE_ACTIVITY) { FitMsg_Activity *fileact = dynamic_cast (msg); if (fileact != NULL) { handle_Activity(fileact); } } else if (msg->GetType() == FIT_MESSAGE_RECORD) { FitMsg_Record *filerec = dynamic_cast (msg); if (filerec != NULL) { handle_Record(filerec); } } else if (msg->GetType() == FIT_MESSAGE_SESSION) { FitMsg_Session *session = dynamic_cast (msg); if (session != NULL) { handle_Session(session); } } else if (msg->GetType() == FIT_MESSAGE_DEVICE_INFO) { FitMsg_DeviceInfo *deviceInfo = dynamic_cast (msg); if (deviceInfo != NULL) { handle_DeviceInfo(deviceInfo); } } else { // received a message we are not interested in } } void Fit2TcxConverter::fitDebugMsg(string msg) { std::cout << msg << std::endl; } void Fit2TcxConverter::handle_Activity(FitMsg_Activity *activity) { /* * Nothing of interest available here * activity->getEvent(); activity->getEventGroup(); activity->getEventType(); activity->getLocalTimestamp(); activity->getNumSessions(); activity->getTotalTimerTime(); activity->getType(); */ } void Fit2TcxConverter::handle_Record(FitMsg_Record *record) { // Create new lap if needed if (tcxLap == NULL) { trackpointList.clear(); tcxLap = new TcxLap(); *(tcxActivity) << tcxLap; tcxTrack = new TcxTrack(); *(tcxLap) << tcxTrack; } string timeId = GpsFunctions::print_dtime(record->getTimestamp()); TcxTrackpoint * point; if ((record->getPositionLat() != FIT_POSITION_INVALID) && (record->getPositionLong() != FIT_POSITION_INVALID)) { stringstream lat; lat.precision(10); // default 4 decimal chars which is not enough stringstream lon; lon.precision(10); // default 4 decimal chars which is not enough lat << SEMI2DEG(record->getPositionLat()); lon << SEMI2DEG(record->getPositionLong()); point = new TcxTrackpoint(timeId, lat.str(), lon.str()); } else { point = new TcxTrackpoint(timeId); } *(tcxTrack) << point; trackpointList.push_back(point); stringstream ss; ss << record->getAltitude(); point->setAltitudeMeters(ss.str()); ss.str(""); ss << record->getDistance(); point->setDistanceMeters(ss.str()); if (((int)record->getHeartRate()) > 0) { ss.str(""); ss << (int)record->getHeartRate(); point->setHeartRateBpm(ss.str()); } if (((int)record->getCadence()) > 0) { ss.str(""); ss << (int)record->getCadence(); point->setCadence(ss.str()); } ss.str(""); ss << record->getSpeed(); point->setSpeed(ss.str()); /* * There is no place for these in a tcx file record->getAccumulatedPower(); record->getCalories(); record->getCadence256(); record->getCombinedPedalSmoothness(); record->getTemperature(); */ } void Fit2TcxConverter::handle_Lap(FitMsg_Lap *lap) { // A new lap comes always after the record data of this lap // Create new lap if needed if (tcxLap == NULL) { trackpointList.clear(); tcxLap = new TcxLap(); *(tcxActivity) << tcxLap; tcxTrack = new TcxTrack(); *(tcxLap) << tcxTrack; } stringstream ss; // 999km is a randomly choosen maximum, because I observed values like (1.84467e+17) // If DistanceMeters is not set, the tcxLap will calculate it itself before output if ((lap->getTotalDistance() >0) && (lap->getTotalDistance() < 999000)) { ss << lap->getTotalDistance(); this->tcxLap->setDistanceMeters(ss.str()); } if ((((int)lap->getAvgHeartRate()) > 0) && (((int)lap->getAvgHeartRate()) != 255)) { ss.str(""); ss << (int)lap->getAvgHeartRate(); this->tcxLap->setAverageHeartRateBpm(ss.str()); } if (((int)lap->getAvgCadence()) > 0) { ss.str(""); ss << (int)lap->getAvgCadence(); this->tcxLap->setCadence(ss.str()); } if (((int)lap->getMaxCadence()) > 0) { ss.str(""); ss << (int)lap->getMaxCadence(); this->tcxLap->setMaxCadence(ss.str()); } if (lap->getAvgSpeed() > 0) { ss.str(""); ss << lap->getAvgSpeed(); this->tcxLap->setAvgSpeed(ss.str()); } if (((int)lap->getMaxHeartRate() > 0) && ((int)lap->getMaxHeartRate() < 255)) { ss.str(""); ss << (int)lap->getMaxHeartRate(); this->tcxLap->setMaximumHeartRateBpm(ss.str()); } if (lap->getMaxSpeed() > 0) { ss.str(""); ss << lap->getMaxSpeed(); this->tcxLap->setMaximumSpeed(ss.str()); } if (lap->getTotalCalories() > 0) { ss.str(""); ss << lap->getTotalCalories(); this->tcxLap->setCalories(ss.str()); } ss.str(""); ss << lap->getTotalTimerTime(); this->tcxLap->setTotalTimeSeconds(ss.str()); switch (lap->getIntensity()) { case INTENSITY_REST: this->tcxLap->setIntensity(TrainingCenterDatabase::Resting); break; default: this->tcxLap->setIntensity(TrainingCenterDatabase::Active); break; } switch (lap->getLapTrigger()) { case LAP_TRIGGER_MANUAL: this->tcxLap->setTriggerMethod(TrainingCenterDatabase::Manual); break; case LAP_TRIGGER_DISTANCE: this->tcxLap->setTriggerMethod(TrainingCenterDatabase::Distance); break; case LAP_TRIGGER_POSITION_START: case LAP_TRIGGER_POSITION_MARKED: case LAP_TRIGGER_POSITION_LAP: case LAP_TRIGGER_POSITION_WAYPOINT: this->tcxLap->setTriggerMethod(TrainingCenterDatabase::Location); break; default: break; } switch (lap->getSport()) { case SPORT_CYCLING : this->tcxActivity->setSportType(TrainingCenterDatabase::Biking); this->tcxLap->setCadenceSensorType(TrainingCenterDatabase::Bike); setTrackpointCadenceType(TrainingCenterDatabase::Bike); break; case SPORT_RUNNING: this->tcxActivity->setSportType(TrainingCenterDatabase::Running); this->tcxLap->setCadenceSensorType(TrainingCenterDatabase::Footpod); setTrackpointCadenceType(TrainingCenterDatabase::Footpod); if (lap->getTotalCycles() > 0) { ss.str(""); ss << (lap->getTotalCycles() * 2); this->tcxLap->setSteps(ss.str()); } break; default: break; } // Next RECORD Entry will create tcxLap again this->tcxLap = NULL; } void Fit2TcxConverter::handle_File_Creator(FitMsg_File_Creator *filecreator) { unsigned short minor = filecreator->getSoftwareVersion() % 100; unsigned short major = 0; if (filecreator->getSoftwareVersion() > 100) { major = (filecreator->getSoftwareVersion() - minor ) / 100; } stringstream ssMaj; stringstream ssMin; ssMaj << major; ssMin << minor; tcxCreator->setVersion(ssMaj.str(), ssMin.str()); } void Fit2TcxConverter::handle_File_ID(FitMsg_File_ID *fileid) { if (fileid->getType() != FIT_FILE_ACTIVITY) { string type = "Unknown"; switch (fileid->getType()) { case FIT_FILE_DEVICE: type="DEVICE"; break; case FIT_FILE_SETTINGS: type="SETTINGS"; break; case FIT_FILE_SPORT: type="SPORT"; break; case FIT_FILE_ACTIVITY: type="ACTIVITY"; break; case FIT_FILE_WORKOUT: type="WORKOUT"; break; case FIT_FILE_COURSE: type="COURSE"; break; case FIT_FILE_SCHEDULES: type="SCHEDULES"; break; case FIT_FILE_WEIGHT: type="WEIGHT"; break; case FIT_FILE_TOTALS: type="TOTALS"; break; case FIT_FILE_GOALS: type="GOALS"; break; case FIT_FILE_BLOOD_PRESSURE: type="BLOOD_PRESSURE"; break; case FIT_FILE_MONITORING: type="MONITORING"; break; case FIT_FILE_ACTIVITY_SUMMARY: type="SUMMARY"; break; case FIT_FILE_MONITORING_DAILY: type="MONITORING_DAILY"; break; case FIT_FILE_INVALID: type="INVALID"; break; } FitFileException exc("Wrong FIT file type. Expected ACTIVITY, but found: "+type); throw exc; } string manufacturer="Unknown"; string product="Unknown"; if (FIT_MANUFACTURER_GARMIN == fileid->getManufacturer()) { manufacturer = "Garmin"; switch (fileid->getProduct()) { case FIT_GARMIN_PRODUCT_HRM1: product="HRM1"; break; // ?? case FIT_GARMIN_PRODUCT_AXH01: product="AXH01"; break; // AXH01 HRM chipset case FIT_GARMIN_PRODUCT_AXB01: product="AXB01"; break; // ?? case FIT_GARMIN_PRODUCT_AXB02: product="AXB02"; break; // ?? case FIT_GARMIN_PRODUCT_HRM2SS: product="HRM2SS"; break; // ?? case FIT_GARMIN_PRODUCT_DSI_ALF02: product="DSI_ALF02"; break; // ?? case FIT_GARMIN_PRODUCT_FR405: product="Forerunner 405"; break; case FIT_GARMIN_PRODUCT_FR50: product="Forerunner 50"; break; case FIT_GARMIN_PRODUCT_FR60: product="Forerunner 60"; break; case FIT_GARMIN_PRODUCT_DSI_ALF01: product="DSI_ALF01"; break; // ?? case FIT_GARMIN_PRODUCT_FR310XT: product="Forerunner 310xt"; break; case FIT_GARMIN_PRODUCT_EDGE500: product="Edge 500"; break; case FIT_GARMIN_PRODUCT_FR110: product="Forerunner 110"; break; case FIT_GARMIN_PRODUCT_EDGE800: product="Edge 800"; break; case FIT_GARMIN_PRODUCT_CHIRP: product="CHIRP"; break; // ?? case FIT_GARMIN_PRODUCT_EDGE200: product="Edge 200"; break; case FIT_GARMIN_PRODUCT_FR910XT: product="Forerunner 910XT"; break; case FIT_GARMIN_PRODUCT_ALF04: product="ALF04"; break; // ?? case FIT_GARMIN_PRODUCT_FR610: product="Forerunner 610"; break; case FIT_GARMIN_PRODUCT_FR70: product="Forerunner 70"; break; case FIT_GARMIN_PRODUCT_FR310XT_4T: product="Forerunner 310xt_4t"; break; case FIT_GARMIN_PRODUCT_AMX: product="AMX"; break; // ?? case FIT_GARMIN_PRODUCT_SDM4: product="SDM4 footpod"; break; case FIT_GARMIN_PRODUCT_TRAINING_CENTER: product="Training Center"; break; case FIT_GARMIN_PRODUCT_CONNECT: product="Connect website"; break; default: break; } } if (manufacturer.compare("Unknown")==0) { tcxCreator->setName(product); } else { tcxCreator->setName(manufacturer+" "+product); } stringstream ss; ss << fileid->getSerialNumber(); tcxCreator->setUnitId(ss.str()); ss.str(""); ss << fileid->getProduct(); tcxCreator->setProductId(ss.str()); /* * Unknown where to place... fileid->getNumber(); fileid->getTimeCreated(); */ } TiXmlDocument * Fit2TcxConverter::getTiXmlDocument(bool readTrackData, string fitnessDetailId) { tcxAuthor->setName("Fit2Tcx"); TiXmlDocument * output = this->tcxBase->getTcxDocument(readTrackData, fitnessDetailId); return output; } string Fit2TcxConverter::getTcxContent(bool readTrackData, string fitnessDetailId) { tcxAuthor->setName("Fit2Tcx"); TiXmlDocument * output = this->tcxBase->getTcxDocument(readTrackData, fitnessDetailId); TiXmlPrinter printer; printer.SetIndent( " " ); output->Accept( &printer ); string fitnessXml = printer.Str(); delete(output); return fitnessXml; } void Fit2TcxConverter::setTrackpointCadenceType(TrainingCenterDatabase::CadenceSensorType_t type) { vector::iterator it; for ( it=trackpointList.begin() ; it < trackpointList.end(); ++it ) { TcxTrackpoint* trackpoint = *it; trackpoint->setCadenceSensorType(type); } } void Fit2TcxConverter::handle_Session(FitMsg_Session *session) { switch (session->getSport()) { case SPORT_CYCLING : this->tcxActivity->setSportType(TrainingCenterDatabase::Biking); break; case SPORT_RUNNING: this->tcxActivity->setSportType(TrainingCenterDatabase::Running); break; default: this->tcxActivity->setSportType(TrainingCenterDatabase::Other); break; } this->tcxActivity->setId(GpsFunctions::print_dtime(session->getStartTime())); } void Fit2TcxConverter::handle_DeviceInfo(FitMsg_DeviceInfo *deviceInfo) { /* std::cout << "DEVICE INFO RECEIVED " << std::endl; std::cout << "Hardware Version : " << (int)deviceInfo->getHardwareVersion() << endl; std::cout << "Serial Number: " << deviceInfo->getSerialNumber() << endl; std::cout << "Software Version : " << deviceInfo->getSoftwareVersion() << endl; */ } GarminPlugin-0.3.23/src/Fit2TcxConverter.h000066400000000000000000000046471232766717500203410ustar00rootroot00000000000000/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */ /* * Fit2Tcx * Copyright (C) Andreas Diesner 2011 * * Fit2Tcx is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Fit2Tcx is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #ifndef FIT2TCXCONVERTER_H_ #define FIT2TCXCONVERTER_H_ #include "fit/fitMsg_Listener.hpp" #include "fit/fitReader.hpp" #include "fit/fitMsg.hpp" #include "fit/fitMsg_File_ID.hpp" #include "fit/fitMsg_File_Creator.hpp" #include "fit/fitMsg_Lap.hpp" #include "fit/fitMsg_Record.hpp" #include "fit/fitMsg_Activity.hpp" #include "fit/fitMsg_Session.hpp" #include "fit/fitMsg_DeviceInfo.hpp" #include "fit/fitFileException.hpp" #include "TcxBuilder/TcxBase.h" class Fit2TcxConverter: public FitMsg_Listener { public: Fit2TcxConverter(); virtual ~Fit2TcxConverter(); /** * Overwrite to receive fit messages */ virtual void fitMsgReceived(FitMsg *msg); /** * Overwrite and enable debug to receive debug messages */ virtual void fitDebugMsg(string msg); string getTcxContent(bool readTrackData, string fitnessDetailId); TiXmlDocument * getTiXmlDocument(bool readTrackData, string fitnessDetailId); private: void handle_File_ID(FitMsg_File_ID *fileid); void handle_File_Creator(FitMsg_File_Creator *filecreator); void handle_Lap(FitMsg_Lap *filelap); void handle_Activity(FitMsg_Activity *fileact); void handle_Record(FitMsg_Record *filerec); void handle_Session(FitMsg_Session *session); void handle_DeviceInfo(FitMsg_DeviceInfo *deviceInfo); void setTrackpointCadenceType(TrainingCenterDatabase::CadenceSensorType_t type); TcxBase *tcxBase; TcxActivities *tcxActivities; TcxActivity * tcxActivity; TcxAuthor *tcxAuthor; TcxLap *tcxLap; TcxTrack *tcxTrack; TcxCreator *tcxCreator; vector trackpointList; }; #endif /* FIT2TCXCONVERTER_H_ */ GarminPlugin-0.3.23/src/Makefile.in000066400000000000000000000035231232766717500170520ustar00rootroot00000000000000# -*- mode: Makefile; -*- # ----------------------------------------- # project GarminPlugin # ----------------------------------------- GCC = @CC@ TINYXML_CFLAGS = @TINYXML_CFLAGS@ TINYXML_LIBS = @TINYXML_LIBS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ GARMINTOOLS_CPPFLAGS = @GARMINTOOLS_CPPFLAGS@ GARMINTOOLS_LDFLAGS = @GARMINTOOLS_LDFLAGS@ GCRYPT_CFLAGS = @GCRYPT_CFLAGS@ GCRYPT_LIBS = @GCRYPT_LIBS@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ CFLAGS += -Wall -O2 -fPIC -Os -DTIXML_USE_STL INCLUDES = $(CPPFLAGS) $(TINYXML_CFLAGS) $(GARMINTOOLS_CPPFLAGS) $(ZLIB_CFLAGS) $(LIBUSB_CFLAGS) $(LIBCRYPTO_CFLAGS) $(GCRYPT_CFLAGS) LDFLAGS += -s $(CREATE_LIB) $(CREATE_DEF) LDLIBS = $(T_LDLIBS) -lm $(ZLIB_LIBS) $(TINYXML_LIBS) $(GARMINTOOLS_LDFLAGS) $(LIBUSB_LIBS) $(GCRYPT_LIBS) -lpthread -lstdc++ LINK_dll = $(GCC) -o $@ $^ $(LDLIBS) -shared $(LDFLAGS) LINK_lib = rm -f $@ && ar rcs $@ $^ COMPILE_cpp = $(GCC) $(CFLAGS) -o $@ -c $< $(MAKEDEP) $(INCLUDES) CPP_FILES := $(wildcard *.cpp) \ $(wildcard TcxBuilder/*.cpp) \ $(wildcard fit/*.cpp) OBJ_FILES := $(CPP_FILES:.cpp=.o) DEP_FILES := $(CPP_FILES:.cpp=.d) %.o : %.cpp ; $(COMPILE_cpp) .SUFFIXES: .o .d .cpp all: all.before all.targets all.after all.before : - all.after : $(FIRST_TARGET) all.targets : Release_target clean : rm -fv $(clean.OBJ) rm -fv $(DEP_FILES) .PHONY: all clean distclean # ----------------------------------------- # Release_target Release_target.BIN = npGarminPlugin.so Release_target.OBJ = $(OBJ_FILES) DEP_FILES += $(DEP_FILES) clean.OBJ += $(Release_target.BIN) $(Release_target.OBJ) Release_target : Release_target.before $(Release_target.BIN) Release_target.after_always Release_target.before : Release_target.after_always : $(Release_target.BIN) $(Release_target.BIN) : $(Release_target.OBJ) $(LINK_dll) GarminPlugin-0.3.23/src/TcxBuilder/000077500000000000000000000000001232766717500170475ustar00rootroot00000000000000GarminPlugin-0.3.23/src/TcxBuilder/TcxActivities.cpp000066400000000000000000000051661232766717500223460ustar00rootroot00000000000000/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */ /* * GarminPlugin * Copyright (C) Andreas Diesner 2011 * * GarminPlugin is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GarminPlugin is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #include "TcxActivities.h" // needed for sort #include TcxActivities::TcxActivities() { } TcxActivities::~TcxActivities() { vector::iterator it; for ( it=activityList.begin() ; it < activityList.end(); ++it ) { TcxActivity* activity = *it; delete(activity); } activityList.clear(); } void TcxActivities::addActivity(TcxActivity* activity) { this->activityList.push_back(activity); } /** * Sort two TcxActivity */ bool activitySorter (TcxActivity * a,TcxActivity * b) { string aId=a->getId(); string bId=b->getId(); return (aId.compare(bId) > 0); } TiXmlElement * TcxActivities::getTiXml(bool readTrackData, string fitnessDetailId) { TiXmlElement * xmlActivities = new TiXmlElement("Activities"); // sort activities, newest on top sort (activityList.begin(), activityList.end(), activitySorter); vector::iterator it; for ( it=activityList.begin() ; it < activityList.end(); ++it ) { TcxActivity* activity = *it; if (!activity->isEmpty()) { if ((fitnessDetailId.length() == 0) || (fitnessDetailId.compare(activity->getId())==0)) { xmlActivities->LinkEndChild( activity->getTiXml(readTrackData) ); } } } return xmlActivities; } vector TcxActivities::getGpxTiXml() { vector trkElements; vector::iterator it; for ( it=activityList.begin() ; it < activityList.end(); ++it ) { TcxActivity* activity = *it; if (!activity->isEmpty()) { trkElements.push_back(activity->getGpxTiXml()); } } return trkElements; } TcxActivities& operator<<(TcxActivities& activities, TcxActivity* activity) { activities.addActivity(activity); return activities; } GarminPlugin-0.3.23/src/TcxBuilder/TcxActivities.h000066400000000000000000000025351232766717500220100ustar00rootroot00000000000000/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */ /* * GarminPlugin * Copyright (C) Andreas Diesner 2011 * * GarminPlugin is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GarminPlugin is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #ifndef TCXACTIVITIES_H_INCLUDED #define TCXACTIVITIES_H_INCLUDED #include #include "TcxActivity.h" using namespace std; class TcxActivities { public: TcxActivities(); ~TcxActivities(); void addActivity(TcxActivity* activity); TiXmlElement * getTiXml(bool readTrackData, string fitnessDetailId); vector getGpxTiXml(); friend TcxActivities& operator<<(TcxActivities& base, TcxActivity* activity); private: vector activityList; }; #endif // TCXACTIVITIES_H_INCLUDED GarminPlugin-0.3.23/src/TcxBuilder/TcxActivity.cpp000066400000000000000000000100501232766717500220220ustar00rootroot00000000000000/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */ /* * GarminPlugin * Copyright (C) Andreas Diesner 2011 * * GarminPlugin is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GarminPlugin is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #include "TcxActivity.h" TcxActivity::TcxActivity(string id) { this->id = id; this->creator = NULL; this->sportType = TrainingCenterDatabase::Other; } TcxActivity::~TcxActivity() { vector::iterator it; for ( it=lapList.begin() ; it < lapList.end(); ++it ) { TcxLap* lap = *it; delete(lap); } lapList.clear(); if (this->creator != NULL) { delete(this->creator); } } void TcxActivity::addLap(TcxLap* lap) { this->lapList.push_back(lap); } TiXmlElement * TcxActivity::getTiXml(bool readTrackData) { TiXmlElement * xmlActivity = new TiXmlElement("Activity"); switch (this->sportType) { case TrainingCenterDatabase::Running: xmlActivity->SetAttribute("Sport","Running"); break; case TrainingCenterDatabase::Biking: xmlActivity->SetAttribute("Sport","Biking"); break; default: xmlActivity->SetAttribute("Sport","Other"); break; } TiXmlElement * xmlId = new TiXmlElement("Id"); xmlActivity->LinkEndChild(xmlId); xmlId->LinkEndChild(new TiXmlText(this->id)); vector::iterator it; TcxLap* previousLap=NULL; for ( it=lapList.begin() ; it < lapList.end(); ++it ) { TcxLap* lap = *it; lap->correctMissingStartTime(previousLap); xmlActivity->LinkEndChild( lap->getTiXml(readTrackData) ); previousLap = lap; } if (this->creator != NULL) { xmlActivity->LinkEndChild(this->creator->getTiXml()); } return xmlActivity; } TiXmlElement * TcxActivity::getGpxTiXml() { TiXmlElement* trk = new TiXmlElement("trk"); TiXmlElement * gpxname = new TiXmlElement("name"); trk->LinkEndChild(gpxname); gpxname->LinkEndChild(new TiXmlText(this->id)); vector::iterator it; TcxLap* previousLap=NULL; for ( it=lapList.begin() ; it < lapList.end(); ++it ) { TcxLap* lap = *it; lap->correctMissingStartTime(previousLap); trk->LinkEndChild( lap->getGpxTiXml() ); previousLap=lap; } return trk; } string TcxActivity::getId() { return this->id; } TcxActivity& operator<<(TcxActivity& activity, TcxLap* lap) { activity.addLap(lap); return activity; } TcxActivity& operator<<(TcxActivity& activity, TcxCreator* creator) { if (activity.creator != NULL) { delete activity.creator; } activity.creator = creator; return activity; } void TcxActivity::setSportType(TrainingCenterDatabase::Sport_t type) { this->sportType = type; } void TcxActivity::setId(string id) { this->id = id; } bool TcxActivity::isEmpty() { vector::iterator it; for ( it=lapList.begin() ; it < lapList.end(); ++it ) { TcxLap* lap = *it; if (!lap->isEmpty()) { return false; } } return true; } string TcxActivity::getOverview() { stringstream ss; ss << this->id; ss << " Laps: " << lapList.size() << "("; vector::iterator it; for ( it=lapList.begin() ; it < lapList.end(); ++it ) { TcxLap* lap = *it; ss << lap->getDistance(); if ((it+1) < lapList.end()) { ss << ","; } } ss << ")"; return ss.str(); } GarminPlugin-0.3.23/src/TcxBuilder/TcxActivity.h000066400000000000000000000033211232766717500214720ustar00rootroot00000000000000/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */ /* * GarminPlugin * Copyright (C) Andreas Diesner 2011 * * GarminPlugin is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GarminPlugin is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #ifndef TCXACTIVITY_H_INCLUDED #define TCXACTIVITY_H_INCLUDED #include "TcxLap.h" #include "TcxCreator.h" #include "TcxTypes.h" using namespace std; class TcxActivity { public: TcxActivity(string id); ~TcxActivity(); void addLap(TcxLap* lap); string getId(); TiXmlElement * getTiXml(bool readTrackData); TiXmlElement * getGpxTiXml(); void setSportType(TrainingCenterDatabase::Sport_t type); void setId(string id); bool isEmpty(); /** * Returns a string with information about this activity (debug purpose) */ string getOverview(); friend TcxActivity& operator<<(TcxActivity& activity, TcxLap* lap); friend TcxActivity& operator<<(TcxActivity& activity, TcxCreator* creator); private: string id; TrainingCenterDatabase::Sport_t sportType; vector lapList; TcxCreator* creator; }; #endif // TCXACTIVITY_H_INCLUDED GarminPlugin-0.3.23/src/TcxBuilder/TcxAuthor.cpp000066400000000000000000000101711232766717500214740ustar00rootroot00000000000000/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */ /* * GarminPlugin * Copyright (C) Andreas Diesner 2011 * * GarminPlugin is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GarminPlugin is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #include "TcxAuthor.h" TcxAuthor::TcxAuthor() { this->name = "Garmin Communicator Plug-In"; this->versionMajor = "2"; this->versionMinor = "9"; this->buildMajor = "1"; this->buildMinor = "0"; this->partNumber = "006-A0160-00"; this->type = "Release"; this->langId = "EN"; } TcxAuthor::~TcxAuthor() { } TiXmlElement * TcxAuthor::getTiXml() { TiXmlElement * xmlAuthor = new TiXmlElement("Author"); xmlAuthor->SetAttribute("xsi:type","Application_t"); TiXmlElement * xmlName = new TiXmlElement("Name"); xmlName->LinkEndChild(new TiXmlText(this->name)); xmlAuthor->LinkEndChild(xmlName); TiXmlElement * xmlBuild = new TiXmlElement("Build"); xmlAuthor->LinkEndChild(xmlBuild); TiXmlElement * xmlLangId = new TiXmlElement("LangID"); xmlLangId->LinkEndChild(new TiXmlText(this->langId)); xmlAuthor->LinkEndChild(xmlLangId); TiXmlElement * xmlPartNumber = new TiXmlElement("PartNumber"); xmlPartNumber->LinkEndChild(new TiXmlText(this->partNumber)); xmlAuthor->LinkEndChild(xmlPartNumber); TiXmlElement * xmlVersion = new TiXmlElement("Version"); TiXmlElement * xmlVerMajor = new TiXmlElement("VersionMajor"); xmlVerMajor->LinkEndChild(new TiXmlText(this->versionMajor)); TiXmlElement * xmlVerMinor = new TiXmlElement("VersionMinor"); xmlVerMinor->LinkEndChild(new TiXmlText(this->versionMinor)); xmlVersion->LinkEndChild(xmlVerMajor); xmlVersion->LinkEndChild(xmlVerMinor); xmlBuild->LinkEndChild(xmlVersion); if (this->type.length() > 0) { TiXmlElement * xmlType = new TiXmlElement("Type"); xmlType->LinkEndChild(new TiXmlText(this->type)); xmlBuild->LinkEndChild(xmlType); } if (this->buildMajor.length() > 0) { TiXmlElement * xmlBuildMajor = new TiXmlElement("BuildMajor"); xmlBuildMajor->LinkEndChild(new TiXmlText(this->buildMajor)); TiXmlElement * xmlBuildMinor = new TiXmlElement("BuildMinor"); xmlBuildMinor->LinkEndChild(new TiXmlText(this->buildMinor)); xmlVersion->LinkEndChild(xmlBuildMajor); xmlVersion->LinkEndChild(xmlBuildMinor); } return xmlAuthor; } void TcxAuthor::setName(string name) { this->name = name; } void TcxAuthor::setVersion(string version) { unsigned int cutAt = version.find_first_of("."); if ((cutAt != version.npos ) && (cutAt > 0)) { this->versionMajor = version.substr(0,cutAt); this->versionMinor = version.substr(cutAt+1); } else { this->versionMajor = version; this->versionMinor = "0"; } } void TcxAuthor::setVersion(string major, string minor) { this->versionMajor = major; this->versionMinor = minor; } void TcxAuthor::setBuild(string build) { unsigned int cutAt = build.find_first_of("."); if ((cutAt != build.npos ) && (cutAt > 0)) { this->buildMajor = build.substr(0,cutAt); this->buildMinor = build.substr(cutAt+1); } else { this->buildMajor = build; this->buildMinor = "0"; } } void TcxAuthor::setBuild(string major, string minor) { this->buildMajor = major; this->buildMinor = minor; } void TcxAuthor::setType(string type) { this->type = type; } void TcxAuthor::setPartNumber(string number) { this->partNumber = number; } void TcxAuthor::setLangId(string id) { this->langId = id; } GarminPlugin-0.3.23/src/TcxBuilder/TcxAuthor.h000066400000000000000000000030401232766717500211360ustar00rootroot00000000000000/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */ /* * GarminPlugin * Copyright (C) Andreas Diesner 2011 * * GarminPlugin is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GarminPlugin is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #ifndef TCXAUTHOR_H_INCLUDED #define TCXAUTHOR_H_INCLUDED #include #include "tinyxml.h" using namespace std; class TcxAuthor { public: TcxAuthor(); ~TcxAuthor(); TiXmlElement * getTiXml(); void setName(string name); void setVersion(string version); void setVersion(string major, string minor); void setBuild(string build); void setBuild(string major, string minor); void setType(string type); void setPartNumber(string number); void setLangId(string id); private: string name; string versionMajor; string versionMinor; string buildMajor; string buildMinor; string partNumber; string type; string langId; }; #endif // TCXAUTHOR_H_INCLUDED GarminPlugin-0.3.23/src/TcxBuilder/TcxBase.cpp000066400000000000000000000101601232766717500211020ustar00rootroot00000000000000/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */ /* * GarminPlugin * Copyright (C) Andreas Diesner 2011 * * GarminPlugin is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GarminPlugin is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #include "TcxBase.h" TcxBase::TcxBase() { this->author = NULL; } TcxBase::~TcxBase() { vector::iterator it; for ( it=activitiesList.begin() ; it < activitiesList.end(); ++it ) { TcxActivities* activities = *it; delete(activities); } activitiesList.clear(); } void TcxBase::addActivities(TcxActivities* activities) { this->activitiesList.push_back(activities); } TcxBase& operator<<(TcxBase& base, TcxActivities* activities) { base.addActivities(activities); return base; } TcxBase& operator<<(TcxBase& base, TcxAuthor* author) { if (base.author != NULL) { delete(base.author); } base.author = author; return base; } TiXmlDocument * TcxBase::getTcxDocument(bool readTrackData, string fitnessDetailId) { TiXmlDocument * doc = new TiXmlDocument(); TiXmlDeclaration * decl = new TiXmlDeclaration( "1.0", "UTF-8", "no"); doc->LinkEndChild( decl ); TiXmlElement * train = new TiXmlElement( "TrainingCenterDatabase" ); train->SetAttribute("xmlns","http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2"); train->SetAttribute("xmlns:xsi","http://www.w3.org/2001/XMLSchema-instance"); train->SetAttribute("xsi:schemaLocation","http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2 http://www.garmin.com/xmlschemas/TrainingCenterDatabasev2.xsd http://www.garmin.com/xmlschemas/ActivityExtension/v2 http://www.garmin.com/xmlschemas/ActivityExtensionv2.xsd"); doc->LinkEndChild( train ); vector::iterator it; for ( it=activitiesList.begin() ; it < activitiesList.end(); ++it ) { TcxActivities* activities = *it; train->LinkEndChild( activities->getTiXml(readTrackData, fitnessDetailId) ); } if (this->author != NULL) { train->LinkEndChild(this->author->getTiXml()); } return doc; } TiXmlDocument * TcxBase::getGpxDocument() { TiXmlDocument * doc = new TiXmlDocument(); TiXmlDeclaration * decl = new TiXmlDeclaration( "1.0", "UTF-8", "no"); doc->LinkEndChild( decl ); TiXmlElement * gpx = new TiXmlElement( "gpx" ); gpx->SetAttribute("xmlns","http://www.topografix.com/GPX/1/1"); gpx->SetAttribute("xmlns:gpxx","http://www.garmin.com/xmlschemas/GpxExtensions/v3"); gpx->SetAttribute("xmlns:gpxtpx","http://www.garmin.com/xmlschemas/TrackPointExtension/v1"); gpx->SetAttribute("xmlns:xsi","http://www.w3.org/2001/XMLSchema-instance"); gpx->SetAttribute("creator","GarminPlugin"); gpx->SetAttribute("version","1.1"); gpx->SetAttribute("xsi:schemaLocation","http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd http://www.garmin.com/xmlschemas/GpxExtensions/v3 http://www.garmin.com/xmlschemas/GpxExtensionsv3.xsd http://www.garmin.com/xmlschemas/TrackPointExtension/v1 http://www.garmin.com/xmlschemas/TrackPointExtensionv1.xsd"); doc->LinkEndChild( gpx ); vector::iterator it; for ( it=activitiesList.begin() ; it < activitiesList.end(); ++it ) { TcxActivities* activities = *it; vector trkElem = activities->getGpxTiXml(); vector::iterator it; for ( it=trkElem.begin() ; it < trkElem.end(); ++it ) { TiXmlElement* elem = *it; gpx->LinkEndChild( elem ); } } return doc; } GarminPlugin-0.3.23/src/TcxBuilder/TcxBase.h000066400000000000000000000026671232766717500205640ustar00rootroot00000000000000/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */ /* * GarminPlugin * Copyright (C) Andreas Diesner 2011 * * GarminPlugin is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GarminPlugin is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #ifndef TCXBASE_H_INCLUDED #define TCXBASE_H_INCLUDED #include #include "TcxActivities.h" #include "TcxAuthor.h" using namespace std; class TcxBase { public: TcxBase(); ~TcxBase(); void addActivities(TcxActivities* activities); TiXmlDocument * getTcxDocument(bool readTrackData, string fitnessDetailId); TiXmlDocument * getGpxDocument(); friend TcxBase& operator<<(TcxBase& base, TcxActivities* activities); friend TcxBase& operator<<(TcxBase& base, TcxAuthor* author); private: vector activitiesList; TcxAuthor * author; }; #endif // TCXBASE_H_INCLUDED GarminPlugin-0.3.23/src/TcxBuilder/TcxCreator.cpp000066400000000000000000000075201232766717500216350ustar00rootroot00000000000000/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */ /* * GarminPlugin * Copyright (C) Andreas Diesner 2011 * * GarminPlugin is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GarminPlugin is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #include "TcxCreator.h" TcxCreator::TcxCreator() { this->name = "Unknown"; this->unitId = "3549600474"; // A random unit id found on the web for the Edge 705 this->productId = "625"; // A random product id found on the web for the Edge 705 this->versionMajor = "0"; this->versionMinor = "0"; this->buildMajor = ""; this->buildMinor = ""; } TcxCreator::~TcxCreator() { } TiXmlElement * TcxCreator::getTiXml() { TiXmlElement * xmlCreator = new TiXmlElement("Creator"); xmlCreator->SetAttribute("xsi:type","Device_t"); TiXmlElement * xmlName = new TiXmlElement("Name"); xmlName->LinkEndChild(new TiXmlText(this->name)); xmlCreator->LinkEndChild(xmlName); TiXmlElement * xmlUnitId = new TiXmlElement("UnitId"); xmlUnitId->LinkEndChild(new TiXmlText(this->unitId)); xmlCreator->LinkEndChild(xmlUnitId); TiXmlElement * xmlProductId = new TiXmlElement("ProductID"); xmlProductId->LinkEndChild(new TiXmlText(this->productId)); xmlCreator->LinkEndChild(xmlProductId); TiXmlElement * xmlVersion = new TiXmlElement("Version"); TiXmlElement * xmlVerMajor = new TiXmlElement("VersionMajor"); xmlVerMajor->LinkEndChild(new TiXmlText(this->versionMajor)); TiXmlElement * xmlVerMinor = new TiXmlElement("VersionMinor"); xmlVerMinor->LinkEndChild(new TiXmlText(this->versionMinor)); xmlVersion->LinkEndChild(xmlVerMajor); xmlVersion->LinkEndChild(xmlVerMinor); xmlCreator->LinkEndChild(xmlVersion); if (this->buildMajor.length() > 0) { TiXmlElement * xmlBuildMajor = new TiXmlElement("BuildMajor"); xmlBuildMajor->LinkEndChild(new TiXmlText(this->buildMajor)); TiXmlElement * xmlBuildMinor = new TiXmlElement("BuildMinor"); xmlBuildMinor->LinkEndChild(new TiXmlText(this->buildMinor)); xmlVersion->LinkEndChild(xmlBuildMajor); xmlVersion->LinkEndChild(xmlBuildMinor); } return xmlCreator; } void TcxCreator::setName(string name) { this->name = name; } void TcxCreator::setUnitId(string id) { this->unitId = id; } void TcxCreator::setProductId(string id) { this->productId = id; } void TcxCreator::setVersion(string version) { unsigned int cutAt = version.find_first_of("."); if ((cutAt != version.npos ) && (cutAt > 0)) { this->versionMajor = version.substr(0,cutAt); this->versionMinor = version.substr(cutAt+1); } else { this->versionMajor = version; this->versionMinor = "0"; } } void TcxCreator::setVersion(string major, string minor) { this->versionMajor = major; this->versionMinor = minor; } void TcxCreator::setBuild(string build) { unsigned int cutAt = build.find_first_of("."); if ((cutAt != build.npos ) && (cutAt > 0)) { this->buildMajor = build.substr(0,cutAt); this->buildMinor = build.substr(cutAt+1); } else { this->buildMajor = build; this->buildMinor = "0"; } } void TcxCreator::setBuild(string major, string minor) { this->buildMajor = major; this->buildMinor = minor; } GarminPlugin-0.3.23/src/TcxBuilder/TcxCreator.h000066400000000000000000000027571232766717500213110ustar00rootroot00000000000000/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */ /* * GarminPlugin * Copyright (C) Andreas Diesner 2011 * * GarminPlugin is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GarminPlugin is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #ifndef TCXCREATOR_H_INCLUDED #define TCXCREATOR_H_INCLUDED #include #include "tinyxml.h" using namespace std; class TcxCreator { public: TcxCreator(); ~TcxCreator(); TiXmlElement * getTiXml(); void setName(string name); void setUnitId(string id); void setProductId(string id); void setVersion(string version); void setVersion(string major, string minor); void setBuild(string build); void setBuild(string major, string minor); private: string name; string unitId; string productId; string versionMajor; string versionMinor; string buildMajor; string buildMinor; }; #endif // TCXCREATOR_H_INCLUDED GarminPlugin-0.3.23/src/TcxBuilder/TcxLap.cpp000066400000000000000000000324651232766717500207600ustar00rootroot00000000000000/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */ /* * GarminPlugin * Copyright (C) Andreas Diesner 2011 * * GarminPlugin is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GarminPlugin is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #include "TcxLap.h" #include "TcxTypes.h" TcxLap::TcxLap() { this->totalTimeSeconds=""; this->distanceMeters=""; this->maximumSpeed=""; this->calories = ""; this->averageHeartRateBpm = ""; this->maximumHeartRateBpm = ""; this->intensity = TrainingCenterDatabase::Resting; this->cadence = ""; this->triggerMethod = TrainingCenterDatabase::Manual; this->notes = ""; this->cadenceSensorType = TrainingCenterDatabase::UndefinedCadenceType; this->maxCadence=""; this->avgSpeed=""; this->startTime="1970-01-01T00:00:00Z"; } TcxLap::~TcxLap() { vector::iterator it; for ( it=trackList.begin() ; it < trackList.end(); ++it ) { TcxTrack* track = *it; delete(track); } trackList.clear(); } void TcxLap::addTrack(TcxTrack* track) { this->trackList.push_back(track); } TiXmlElement * TcxLap::getTiXml(bool readTrackData) { TiXmlElement * xmlLap = new TiXmlElement("Lap"); xmlLap->SetAttribute("StartTime",getStartTime()); if (this->totalTimeSeconds.length() == 0) { calculateTotalTimeSeconds(); } TiXmlElement * xmlTotalTimeSeconds = new TiXmlElement("TotalTimeSeconds"); xmlTotalTimeSeconds->LinkEndChild(new TiXmlText(this->totalTimeSeconds)); xmlLap->LinkEndChild(xmlTotalTimeSeconds); if (this->distanceMeters.length() == 0) { calculateDistanceMeters(); } TiXmlElement * xmlDistanceMeters = new TiXmlElement("DistanceMeters"); xmlDistanceMeters->LinkEndChild(new TiXmlText(this->distanceMeters)); xmlLap->LinkEndChild(xmlDistanceMeters); if (this->maximumSpeed.length() > 0) { TiXmlElement * xmlMaxSpeed = new TiXmlElement("MaximumSpeed"); xmlMaxSpeed->LinkEndChild(new TiXmlText(this->maximumSpeed)); xmlLap->LinkEndChild(xmlMaxSpeed); } if (this->calories.length() == 0) { calculateCalories(); } TiXmlElement * xmlCalories = new TiXmlElement("Calories"); xmlCalories->LinkEndChild(new TiXmlText(this->calories)); xmlLap->LinkEndChild(xmlCalories); if (this->averageHeartRateBpm.length() > 0) { //TODO: Think about calculating averageHeartRateBpm value TiXmlElement * xmlAvgHeart = new TiXmlElement("AverageHeartRateBpm"); //xmlAvgHeart->SetAttribute("xsi:type","HeartRateInBeatsPerMinute_t"); TiXmlElement * xmlValue = new TiXmlElement("Value"); this->averageHeartRateBpm = TrainingCenterDatabase::limitIntValue(this->averageHeartRateBpm, 0,255); xmlValue->LinkEndChild(new TiXmlText(this->averageHeartRateBpm)); xmlAvgHeart->LinkEndChild(xmlValue); xmlLap->LinkEndChild(xmlAvgHeart); } if (this->maximumHeartRateBpm.length() == 0) { calculateMaximumHeartRateBpm(); } if (this->maximumHeartRateBpm.length() > 0) { TiXmlElement * xmlAvgHeart = new TiXmlElement("MaximumHeartRateBpm"); //xmlAvgHeart->SetAttribute("xsi:type","HeartRateInBeatsPerMinute_t"); TiXmlElement * xmlValue = new TiXmlElement("Value"); this->maximumHeartRateBpm = TrainingCenterDatabase::limitIntValue(this->maximumHeartRateBpm, 0,255); xmlValue->LinkEndChild(new TiXmlText(this->maximumHeartRateBpm)); xmlAvgHeart->LinkEndChild(xmlValue); xmlLap->LinkEndChild(xmlAvgHeart); } TiXmlElement * xmlIntensity = new TiXmlElement("Intensity"); xmlIntensity->LinkEndChild(new TiXmlText(getIntensity(this->intensity))); xmlLap->LinkEndChild(xmlIntensity); if ((this->cadence.length() > 0) && (this->cadenceSensorType != TrainingCenterDatabase::UndefinedCadenceType)) { this->cadence = TrainingCenterDatabase::limitIntValue(this->cadence, 0,255); if (this->cadence != "255") { if (this->cadenceSensorType == TrainingCenterDatabase::Bike) { TiXmlElement * xmlCadence = new TiXmlElement("Cadence"); xmlCadence->LinkEndChild(new TiXmlText(this->cadence)); xmlLap->LinkEndChild(xmlCadence); } } } TiXmlElement * xmlTriggerMethod = new TiXmlElement("TriggerMethod"); xmlTriggerMethod->LinkEndChild(new TiXmlText(getTriggerMethod(this->triggerMethod))); xmlLap->LinkEndChild(xmlTriggerMethod); if (readTrackData) { vector::iterator it; for ( it=trackList.begin() ; it < trackList.end(); ++it ) { TcxTrack* track = *it; if (!track->isEmpty()) { xmlLap->LinkEndChild(track->getTiXml()); } } } TiXmlElement * xmlLapExtensions = NULL; if ((this->cadence.length() > 0) && (this->cadenceSensorType != TrainingCenterDatabase::UndefinedCadenceType)) { if (this->cadence != "255") { if (this->cadenceSensorType != TrainingCenterDatabase::Bike) { if (xmlLapExtensions == NULL) { xmlLapExtensions = new TiXmlElement("Extensions"); xmlLap->LinkEndChild(xmlLapExtensions); } TiXmlElement * xmlLX = new TiXmlElement("LX"); xmlLX->SetAttribute("xmlns","http://www.garmin.com/xmlschemas/ActivityExtension/v2"); xmlLapExtensions->LinkEndChild(xmlLX); TiXmlElement * xmlAvgRunCadence = new TiXmlElement("AvgRunCadence"); xmlAvgRunCadence->LinkEndChild(new TiXmlText(this->cadence)); xmlLX->LinkEndChild(xmlAvgRunCadence); } } } if (this->maxCadence.length() > 0) { if (xmlLapExtensions == NULL) { xmlLapExtensions = new TiXmlElement("Extensions"); xmlLap->LinkEndChild(xmlLapExtensions); } string name = "MaxBikeCadence"; if (this->cadenceSensorType == TrainingCenterDatabase::Footpod) { name = "MaxRunCadence"; } TiXmlElement * xmlLX = new TiXmlElement("LX"); xmlLX->SetAttribute("xmlns","http://www.garmin.com/xmlschemas/ActivityExtension/v2"); xmlLapExtensions->LinkEndChild(xmlLX); TiXmlElement * xmlMaxCadence = new TiXmlElement(name); xmlMaxCadence->LinkEndChild(new TiXmlText(this->maxCadence)); xmlLX->LinkEndChild(xmlMaxCadence); } if (this->avgSpeed.length() > 0) { if (xmlLapExtensions == NULL) { xmlLapExtensions = new TiXmlElement("Extensions"); xmlLap->LinkEndChild(xmlLapExtensions); } TiXmlElement * xmlLX = new TiXmlElement("LX"); xmlLX->SetAttribute("xmlns","http://www.garmin.com/xmlschemas/ActivityExtension/v2"); xmlLapExtensions->LinkEndChild(xmlLX); TiXmlElement * xmlAvgSpeed = new TiXmlElement("AvgSpeed"); xmlAvgSpeed->LinkEndChild(new TiXmlText(this->avgSpeed)); xmlLX->LinkEndChild(xmlAvgSpeed); } if (this->steps.length() > 0) { if (xmlLapExtensions == NULL) { xmlLapExtensions = new TiXmlElement("Extensions"); xmlLap->LinkEndChild(xmlLapExtensions); } TiXmlElement * xmlLX = new TiXmlElement("LX"); xmlLX->SetAttribute("xmlns","http://www.garmin.com/xmlschemas/ActivityExtension/v2"); xmlLapExtensions->LinkEndChild(xmlLX); TiXmlElement * xmlSteps = new TiXmlElement("Steps"); xmlSteps->LinkEndChild(new TiXmlText(this->steps)); xmlLX->LinkEndChild(xmlSteps); } return xmlLap; } TiXmlElement * TcxLap::getGpxTiXml() { TiXmlElement * segment = new TiXmlElement("trkseg"); vector::iterator it; for ( it=trackList.begin() ; it < trackList.end(); ++it ) { TcxTrack* track = *it; vector trkPointList = track->getGpxTiXml(); vector::iterator it; for ( it=trkPointList.begin() ; it < trkPointList.end(); ++it ) { TiXmlElement * elem = *it; segment->LinkEndChild(elem); } } return segment; } void TcxLap::setTotalTimeSeconds(string time) { this->totalTimeSeconds=time; } void TcxLap::setDistanceMeters(string distance) { this->distanceMeters=distance; } void TcxLap::setMaximumSpeed(string speed) { this->maximumSpeed=speed; } void TcxLap::setCalories(string calories) { this->calories = calories; } void TcxLap::setAverageHeartRateBpm(string averageBpm) { this->averageHeartRateBpm = averageBpm; } void TcxLap::setMaximumHeartRateBpm(string maximumBpm) { this->maximumHeartRateBpm = maximumBpm; } void TcxLap::setIntensity(TrainingCenterDatabase::Intensity_t intensitiy) { this->intensity = intensitiy; } void TcxLap::setCadence(string cadence) { this->cadence = cadence; } void TcxLap::setTriggerMethod(TrainingCenterDatabase::TriggerMethod_t method) { this->triggerMethod = method; } void TcxLap::setNotes(string note) { this->notes = note; } void TcxLap::setAvgSpeed(string speed) { this->avgSpeed = speed; } void TcxLap::setMaxCadence(string cadence) { this->maxCadence = cadence; } void TcxLap::setSteps(string steps) { this->steps = steps; } void TcxLap::calculateTotalTimeSeconds() { double totalTime = 0; vector::iterator it; for ( it=trackList.begin() ; it < trackList.end(); ++it ) { TcxTrack* track = *it; totalTime += track->calculateTotalTime(); } char totalTimeBuf[50]; snprintf(&totalTimeBuf[0], sizeof(totalTimeBuf), "%.2f", totalTime); this->totalTimeSeconds=totalTimeBuf; } void TcxLap::calculateDistanceMeters() { double totalDistanceMeters = 0; vector::iterator it; for ( it=trackList.begin() ; it < trackList.end(); ++it ) { TcxTrack* track = *it; totalDistanceMeters += track->calculateDistanceMeters(); } char totalDistanceBuf[50]; snprintf(&totalDistanceBuf[0], sizeof(totalDistanceBuf), "%.2f", totalDistanceMeters); this->distanceMeters=totalDistanceBuf; } void TcxLap::calculateCalories() { //TODO: Calculate Calories this->calories = "0"; } void TcxLap::calculateMaximumHeartRateBpm() { vector::iterator it; int maxHeartRate = 0; for ( it=trackList.begin() ; it < trackList.end(); ++it ) { TcxTrack* track = *it; int currentMaxHeartRate = track->getMaxHeartRate(); maxHeartRate = (currentMaxHeartRate > maxHeartRate) ? currentMaxHeartRate : maxHeartRate; } if (maxHeartRate > 0) { stringstream ss; ss << maxHeartRate; this->maximumHeartRateBpm=ss.str(); } } string TcxLap::getIntensity(TrainingCenterDatabase::Intensity_t intensity) { if (intensity == TrainingCenterDatabase::Active) { return "Active"; } return "Resting"; } string TcxLap::getTriggerMethod(TrainingCenterDatabase::TriggerMethod_t method) { switch(method) { case TrainingCenterDatabase::Manual: return "Manual"; case TrainingCenterDatabase::Distance: return "Distance"; case TrainingCenterDatabase::Location: return "Location"; case TrainingCenterDatabase::Time: return "Time"; case TrainingCenterDatabase::HeartRate: return "HeartRate"; } return ""; } void TcxLap::setCadenceSensorType(TrainingCenterDatabase::CadenceSensorType_t type) { this->cadenceSensorType = type; } TcxLap& operator<<(TcxLap& lap, TcxTrack* track) { lap.addTrack(track); return lap; } string TcxLap::getStartTime() { vector::iterator it; for ( it=trackList.begin() ; it < trackList.end(); ++it ) { TcxTrack* track = *it; string startTime = track->getStartTime(); if (startTime.length() > 0) { this->startTime = startTime; return startTime; } } return this->startTime; } bool TcxLap::isEmpty() { vector::iterator it; for ( it=trackList.begin() ; it < trackList.end(); ++it ) { TcxTrack* track = *it; if (!track->isEmpty()) { return false; } } return true; } string TcxLap::getDistance() { if (this->distanceMeters.length() == 0) { calculateDistanceMeters(); } return this->distanceMeters; } void TcxLap::correctMissingStartTime(TcxLap * previousLap) { if (previousLap == NULL) { return; } if (this->startTime.compare("1970-01-01T00:00:00Z")==0) { this->startTime = previousLap->getEndTime(); } } string TcxLap::getEndTime() { string endTime=""; vector::reverse_iterator it; for ( it=trackList.rbegin() ; it != trackList.rend(); ++it ) { TcxTrack* track = *it; endTime = track->getEndTime(); if (endTime.length() > 0) { return endTime; } } return this->startTime; } GarminPlugin-0.3.23/src/TcxBuilder/TcxLap.h000066400000000000000000000057561232766717500204300ustar00rootroot00000000000000/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */ /* * GarminPlugin * Copyright (C) Andreas Diesner 2011 * * GarminPlugin is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GarminPlugin is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #ifndef TCXLAP_H_INCLUDED #define TCXLAP_H_INCLUDED #include #include #include "TcxTrack.h" #include "TcxTypes.h" using namespace std; class TcxLap { public: TcxLap(); ~TcxLap(); void addTrack(TcxTrack* track); TiXmlElement * getTiXml(bool readTrackData); TiXmlElement * getGpxTiXml(); void setTotalTimeSeconds(string time); void setDistanceMeters(string distance); void setMaximumSpeed(string speed); void setCalories(string calories); void setAverageHeartRateBpm(string averageBpm); void setMaximumHeartRateBpm(string maximumBpm); void setIntensity(TrainingCenterDatabase::Intensity_t intensitiy); void setCadence(string cadence); void setTriggerMethod(TrainingCenterDatabase::TriggerMethod_t method); void setNotes(string note); void setCadenceSensorType(TrainingCenterDatabase::CadenceSensorType_t type); void setAvgSpeed(string speed); void setMaxCadence(string cadence); void setSteps(string steps); /** * Returns the distance of this lap - used for debug output * Do not call before all tracks and trackpoints are added to the lap */ string getDistance(); bool isEmpty(); friend TcxLap& operator<<(TcxLap& base, TcxTrack* track); void correctMissingStartTime(TcxLap * previousLap); private: vector trackList; void calculateTotalTimeSeconds(); void calculateDistanceMeters(); void calculateCalories(); void calculateMaximumHeartRateBpm(); string getTriggerMethod(TrainingCenterDatabase::TriggerMethod_t method); string getIntensity(TrainingCenterDatabase::Intensity_t intensity); string getStartTime(); string getEndTime(); string totalTimeSeconds; string distanceMeters; string maximumSpeed; string calories; string averageHeartRateBpm; string maximumHeartRateBpm; TrainingCenterDatabase::Intensity_t intensity; string cadence; string maxCadence; string avgSpeed; TrainingCenterDatabase::TriggerMethod_t triggerMethod; string notes; TrainingCenterDatabase::CadenceSensorType_t cadenceSensorType; string startTime; string steps; }; #endif // TCXLAP_H_INCLUDED GarminPlugin-0.3.23/src/TcxBuilder/TcxTrack.cpp000066400000000000000000000111241232766717500212750ustar00rootroot00000000000000/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */ /* * GarminPlugin * Copyright (C) Andreas Diesner 2011 * * GarminPlugin is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GarminPlugin is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #include "TcxTrack.h" TcxTrack::TcxTrack() { } TcxTrack::~TcxTrack() { vector::iterator it; for ( it=trackpointList.begin() ; it < trackpointList.end(); ++it ) { TcxTrackpoint* trackpoint = *it; delete(trackpoint); } trackpointList.clear(); } void TcxTrack::addTrackpoint(TcxTrackpoint* point) { this->trackpointList.push_back(point); } TiXmlElement * TcxTrack::getTiXml() { TiXmlElement * xmlTrack = new TiXmlElement("Track"); vector::iterator it; for ( it=trackpointList.begin() ; it < trackpointList.end(); ++it ) { TcxTrackpoint* trackpoint = *it; xmlTrack->LinkEndChild(trackpoint->getTiXml()); } return xmlTrack; } vector TcxTrack::getGpxTiXml() { vector pointList; vector::iterator it; for ( it=trackpointList.begin() ; it < trackpointList.end(); ++it ) { TcxTrackpoint* trackpoint = *it; if (trackpoint->hasCoordinates()) { pointList.push_back(trackpoint->getGpxTiXml()); } } return pointList; } TcxTrack& operator<<(TcxTrack& track, TcxTrackpoint* point) { track.addTrackpoint(point); return track; } string TcxTrack::getStartTime() { vector::iterator it; string startTime = ""; for ( it=trackpointList.begin() ; it < trackpointList.end(); ++it ) { TcxTrackpoint* trackpoint = *it; startTime = trackpoint->getTime(); if (startTime.length() > 0) { break; } } return startTime; } string TcxTrack::getEndTime() { vector::reverse_iterator it; string startTime = ""; for ( it=trackpointList.rbegin() ; it != trackpointList.rend(); ++it ) { TcxTrackpoint* trackpoint = *it; startTime = trackpoint->getTime(); if (startTime.length() > 0) { break; } } return startTime; } double TcxTrack::calculateDistanceMeters() { double totalDistance = 0; vector::iterator it; TcxTrackpoint* lastTrackpoint = NULL; for ( it=trackpointList.begin() ; it < trackpointList.end(); ++it ) { TcxTrackpoint* trackpoint = *it; if (NULL != lastTrackpoint) { totalDistance += lastTrackpoint->calculateDistanceTo(totalDistance, trackpoint); } lastTrackpoint = trackpoint; } // Set total distance to last point if (NULL != lastTrackpoint) { lastTrackpoint->calculateDistanceTo(totalDistance, lastTrackpoint); } return totalDistance; } double TcxTrack::calculateTotalTime() { double totalTimeSeconds = 0; if ((trackpointList.front() != NULL) && (trackpointList.back() != NULL)) { struct tm start={0,0,0,0,0,0,0,0,0}; struct tm end={0,0,0,0,0,0,0,0,0}; if ((strptime(trackpointList.front()->getTime().c_str(), "%FT%TZ",&start) != NULL) && (strptime(trackpointList.back()->getTime().c_str(), "%FT%TZ",&end) != NULL)) { time_t tstart, tend; tstart = mktime(&start); tend = mktime(&end); totalTimeSeconds = difftime (tend,tstart); } } return totalTimeSeconds; } int TcxTrack::getMaxHeartRate() { int maxHeartRate = 0; vector::iterator it; for ( it=trackpointList.begin() ; it < trackpointList.end(); ++it ) { TcxTrackpoint* trackpoint = *it; string heartRate = trackpoint->getHeartRateBpm(); if (heartRate.length()>0) { stringstream ss(heartRate); int currentRate; ss >> currentRate; maxHeartRate = (currentRate > maxHeartRate) ? currentRate : maxHeartRate; } } return maxHeartRate; } bool TcxTrack::isEmpty() { return trackpointList.empty(); } GarminPlugin-0.3.23/src/TcxBuilder/TcxTrack.h000066400000000000000000000027031232766717500207450ustar00rootroot00000000000000/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */ /* * GarminPlugin * Copyright (C) Andreas Diesner 2011 * * GarminPlugin is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GarminPlugin is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #ifndef TCXTRACK_H_INCLUDED #define TCXTRACK_H_INCLUDED #include "TcxTrackpoint.h" #include using namespace std; class TcxTrack { public: TcxTrack(); ~TcxTrack(); void addTrackpoint(TcxTrackpoint* track); TiXmlElement * getTiXml(); vector getGpxTiXml(); friend TcxTrack& operator<<(TcxTrack& base, TcxTrackpoint* track); string getStartTime(); string getEndTime(); double calculateDistanceMeters(); double calculateTotalTime(); int getMaxHeartRate(); bool isEmpty(); private: vector trackpointList; }; #endif // TCXTRACK_H_INCLUDED GarminPlugin-0.3.23/src/TcxBuilder/TcxTrackpoint.cpp000066400000000000000000000207501232766717500223540ustar00rootroot00000000000000/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */ /* * GarminPlugin * Copyright (C) Andreas Diesner 2011 * * GarminPlugin is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GarminPlugin is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #include "TcxTrackpoint.h" #include "../gpsFunctions.h" void TcxTrackpoint::initializeVariables() { this->longitude = ""; this->latitude = ""; this->altitudeMeters = ""; this->distanceMeters = ""; this->heartRateBpm = ""; this->cadence = ""; this->speed = ""; this->sensorState = TrainingCenterDatabase::UndefinedSensorState; this->cadenceSensorType = TrainingCenterDatabase::UndefinedCadenceType; } TcxTrackpoint::TcxTrackpoint(string time, string latitude, string longitude) { initializeVariables(); this->time = time; this->longitude = longitude; this->latitude = latitude; } TcxTrackpoint::TcxTrackpoint(string time) { initializeVariables(); this->time = time; } TcxTrackpoint::~TcxTrackpoint() { } void TcxTrackpoint::setPosition(string latitude, string longitude) { this->longitude = longitude; this->latitude = latitude; } void TcxTrackpoint::setAltitudeMeters(string altitude) { this->altitudeMeters = altitude; } void TcxTrackpoint::setDistanceMeters(string distance) { this->distanceMeters = distance; } void TcxTrackpoint::setHeartRateBpm(string heartrate) { this->heartRateBpm = heartrate; } string TcxTrackpoint::getHeartRateBpm() { return this->heartRateBpm; } void TcxTrackpoint::setCadence(string cadence) { this->cadence = cadence; } void TcxTrackpoint::setSpeed(string speed) { this->speed = speed; } void TcxTrackpoint::setSensorState(TrainingCenterDatabase::SensorState_t state) { this->sensorState = state; } void TcxTrackpoint::setCadenceSensorType(TrainingCenterDatabase::CadenceSensorType_t type) { this->cadenceSensorType = type; } TiXmlElement * TcxTrackpoint::getTiXml() { TiXmlElement * xmlTrackPoint = new TiXmlElement("Trackpoint"); TiXmlElement * xmlTime = new TiXmlElement("Time"); xmlTime->LinkEndChild(new TiXmlText(this->time)); xmlTrackPoint->LinkEndChild(xmlTime); TiXmlElement * xmlTrackPointExtensions = NULL; if ((this->latitude.length() > 0) && (this->longitude.length() > 0)) { TiXmlElement * xmlPosition = new TiXmlElement("Position"); TiXmlElement * xmlLat = new TiXmlElement("LatitudeDegrees"); xmlLat->LinkEndChild(new TiXmlText(this->latitude)); TiXmlElement * xmlLon = new TiXmlElement("LongitudeDegrees"); xmlLon->LinkEndChild(new TiXmlText(this->longitude)); xmlPosition->LinkEndChild(xmlLat); xmlPosition->LinkEndChild(xmlLon); xmlTrackPoint->LinkEndChild(xmlPosition); } if (this->altitudeMeters.length() > 0) { TiXmlElement * xmlAlt = new TiXmlElement("AltitudeMeters"); xmlAlt->LinkEndChild(new TiXmlText(this->altitudeMeters)); xmlTrackPoint->LinkEndChild(xmlAlt); } if (this->distanceMeters.length() > 0) { TiXmlElement * xmlDist = new TiXmlElement("DistanceMeters"); xmlDist->LinkEndChild(new TiXmlText(this->distanceMeters)); xmlTrackPoint->LinkEndChild(xmlDist); } if (this->heartRateBpm.length() > 0) { TiXmlElement * xmlHeart = new TiXmlElement("HeartRateBpm"); //xmlHeart->SetAttribute("xsi:type","HeartRateInBeatsPerMinute_t"); TiXmlElement * xmlValue = new TiXmlElement("Value"); this->heartRateBpm = TrainingCenterDatabase::limitIntValue(this->heartRateBpm, 0,255); xmlValue->LinkEndChild(new TiXmlText(this->heartRateBpm)); xmlHeart->LinkEndChild(xmlValue); xmlTrackPoint->LinkEndChild(xmlHeart); } if ((this->cadence.length() > 0) && ((this->cadenceSensorType != TrainingCenterDatabase::UndefinedCadenceType))) { this->cadence = TrainingCenterDatabase::limitIntValue(this->cadence, 0,255); if (this->cadence != "255") { if (this->cadenceSensorType == TrainingCenterDatabase::Bike) { TiXmlElement * xmlCad = new TiXmlElement("Cadence"); xmlCad->LinkEndChild(new TiXmlText(this->cadence)); xmlTrackPoint->LinkEndChild(xmlCad); } } } if (this->sensorState != TrainingCenterDatabase::UndefinedSensorState) { TiXmlElement * xmlSensor = new TiXmlElement("SensorState"); string state = "Absent"; if (this->sensorState == TrainingCenterDatabase::Present) { state = "Present"; } xmlSensor->LinkEndChild(new TiXmlText(state)); xmlTrackPoint->LinkEndChild(xmlSensor); } if ((this->cadence.length() > 0) && ((this->cadenceSensorType == TrainingCenterDatabase::Footpod))) { if (this->cadence != "255") { if (xmlTrackPointExtensions == NULL) { xmlTrackPointExtensions = new TiXmlElement("Extensions"); xmlTrackPoint->LinkEndChild(xmlTrackPointExtensions); } TiXmlElement * xmlExtensionTPX = new TiXmlElement("TPX"); xmlExtensionTPX->SetAttribute("xmlns","http://www.garmin.com/xmlschemas/ActivityExtension/v2"); xmlTrackPointExtensions->LinkEndChild(xmlExtensionTPX); string cadType = "Unknown"; if (this->cadenceSensorType == TrainingCenterDatabase::Bike) { cadType = "Bike"; } else if (this->cadenceSensorType == TrainingCenterDatabase::Footpod) { cadType = "Footpod"; } xmlExtensionTPX->SetAttribute("CadenceSensor",cadType); if (this->cadenceSensorType == TrainingCenterDatabase::Footpod) { TiXmlElement * xmlRunCad = new TiXmlElement("RunCadence"); xmlRunCad->LinkEndChild(new TiXmlText(this->cadence)); xmlExtensionTPX->LinkEndChild(xmlRunCad); } } } if (this->speed.length() > 0) { if (xmlTrackPointExtensions == NULL) { xmlTrackPointExtensions = new TiXmlElement("Extensions"); xmlTrackPoint->LinkEndChild(xmlTrackPointExtensions); } TiXmlElement * xmlExtensionTPX = new TiXmlElement("TPX"); xmlExtensionTPX->SetAttribute("xmlns","http://www.garmin.com/xmlschemas/ActivityExtension/v2"); xmlTrackPointExtensions->LinkEndChild(xmlExtensionTPX); TiXmlElement * xmlSpeed = new TiXmlElement("Speed"); xmlSpeed->LinkEndChild(new TiXmlText(this->speed)); xmlExtensionTPX->LinkEndChild(xmlSpeed); } return xmlTrackPoint; } TiXmlElement * TcxTrackpoint::getGpxTiXml() { TiXmlElement * xmlTrackPoint = new TiXmlElement("trkpt"); if (this->latitude.length() > 0) { xmlTrackPoint->SetAttribute("lat",this->latitude); } if (this->longitude.length() > 0) { xmlTrackPoint->SetAttribute("lon",this->longitude); } if (this->altitudeMeters.length() > 0) { TiXmlElement * xmlAlt = new TiXmlElement("ele"); xmlAlt->LinkEndChild(new TiXmlText(this->altitudeMeters)); xmlTrackPoint->LinkEndChild(xmlAlt); } TiXmlElement * xmlTime = new TiXmlElement("time"); xmlTime->LinkEndChild(new TiXmlText(this->time)); xmlTrackPoint->LinkEndChild(xmlTime); return xmlTrackPoint; } string TcxTrackpoint::getTime() { return this->time; } double TcxTrackpoint::calculateDistanceTo(double totalTrackDistance, TcxTrackpoint * nextPoint) { double distance = 0; if ((this->latitude.length() > 0) && (this->longitude.length() > 0) && (nextPoint->latitude.length() > 0) && (nextPoint->longitude.length() > 0)) { distance = GpsFunctions::haversine_m_str(this->latitude, this->longitude, nextPoint->latitude, nextPoint->longitude); char distanceBuf[50]; snprintf(&distanceBuf[0], sizeof(distanceBuf), "%.2f", totalTrackDistance); this->distanceMeters = distanceBuf; } return distance; } bool TcxTrackpoint::hasCoordinates() { if ((this->longitude.length() > 0) && (this->latitude.length() > 0)) { return true; } return false; } GarminPlugin-0.3.23/src/TcxBuilder/TcxTrackpoint.h000066400000000000000000000041701232766717500220170ustar00rootroot00000000000000/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */ /* * GarminPlugin * Copyright (C) Andreas Diesner 2011 * * GarminPlugin is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GarminPlugin is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #ifndef TCXTRACKPOINT_H_INCLUDED #define TCXTRACKPOINT_H_INCLUDED #include "tinyxml.h" #include #include "TcxTypes.h" using namespace std; class TcxTrackpoint { public: TcxTrackpoint(string time, string latitude, string longitude); TcxTrackpoint(string time); ~TcxTrackpoint(); void setPosition(string latitude, string longitude); void setAltitudeMeters(string altitude); void setDistanceMeters(string distance); void setHeartRateBpm(string heartrate); string getHeartRateBpm(); void setCadence(string cadence); void setSpeed(string speed); void setSensorState(TrainingCenterDatabase::SensorState_t state); void setCadenceSensorType(TrainingCenterDatabase::CadenceSensorType_t type); string getTime(); double calculateDistanceTo(double totalTrackDistance, TcxTrackpoint * nextPoint); bool hasCoordinates(); TiXmlElement * getTiXml(); TiXmlElement * getGpxTiXml(); private: void initializeVariables(); string time; string longitude; string latitude; string altitudeMeters; string distanceMeters; string heartRateBpm; string cadence; string speed; TrainingCenterDatabase::SensorState_t sensorState; TrainingCenterDatabase::CadenceSensorType_t cadenceSensorType; }; #endif // TCXTRACKPOINT_H_INCLUDED GarminPlugin-0.3.23/src/TcxBuilder/TcxTypes.h000066400000000000000000000040211232766717500210000ustar00rootroot00000000000000/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */ /* * GarminPlugin * Copyright (C) Andreas Diesner 2011 * * GarminPlugin is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GarminPlugin is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #ifndef TCXTYPES_H_INCLUDED #define TCXTYPES_H_INCLUDED #include #include using namespace std; class TrainingCenterDatabase { public: enum Intensity_t { Active, Resting }; enum TriggerMethod_t { Manual, Distance, Location, Time, HeartRate }; enum CadenceSensorType_t { Footpod, Bike, UndefinedCadenceType }; enum SensorState_t { Present, Absent, UndefinedSensorState }; enum Sport_t { Running, Biking, Other }; static string limitIntValue(string value, int min, int max) { stringstream newValue; int intValue; std::istringstream ss( value ); ss >> intValue; if (intValue < min) { newValue << min; } else if (intValue > max) { newValue << max; } else { newValue << value; } return newValue.str(); }; }; #endif // TCXTYPES_H_INCLUDED GarminPlugin-0.3.23/src/config.h.in000066400000000000000000000063731232766717500170360ustar00rootroot00000000000000/* config.h.in. Generated from configure.ac by autoheader. */ /* Define to 1 if you have the `getmntent' function. */ #undef HAVE_GETMNTENT /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H /* Define to 1 if you have the `localtime_r' function. */ #undef HAVE_LOCALTIME_R /* Define to 1 if you have the `memmove' function. */ #undef HAVE_MEMMOVE /* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H /* Define to 1 if you have the `mkdir' function. */ #undef HAVE_MKDIR /* Define to 1 if you have the header file. */ #undef HAVE_MNTENT_H /* Define to 1 if using libxul 1.9.2 or higher */ #undef HAVE_NEW_XULRUNNER /* Define to 1 if you have the header file. */ #undef HAVE_NPAPI_H /* Define to 1 if you have the header file. */ #undef HAVE_NPFUNCTIONS_H /* Define to 1 if you have the header file. */ #undef HAVE_NPRUNTIME_H /* Define to 1 if you have the header file. */ #undef HAVE_PRTYPES_H /* Define to 1 if stdbool.h conforms to C99. */ #undef HAVE_STDBOOL_H /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H /* Define to 1 if you have the header file. */ #undef HAVE_STRINGS_H /* Define to 1 if you have the header file. */ #undef HAVE_STRING_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H /* Define to 1 if you have the header file. */ #undef HAVE_ZIPSTUB_H /* Define to 1 if the system has the type `_Bool'. */ #undef HAVE__BOOL /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT /* Define to the full name of this package. */ #undef PACKAGE_NAME /* Define to the full name and version of this package. */ #undef PACKAGE_STRING /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME /* Define to the home page for this package. */ #undef PACKAGE_URL /* Define to the version of this package. */ #undef PACKAGE_VERSION /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS /* Define for Solaris 2.5.1 so the uint32_t typedef from , , or is not used. If the typedef were allowed, the #define below would cause a syntax error. */ #undef _UINT32_T /* Define to the type of a signed integer type of width exactly 16 bits if such a type exists and the standard includes do not define it. */ #undef int16_t /* Define to the type of a signed integer type of width exactly 32 bits if such a type exists and the standard includes do not define it. */ #undef int32_t /* Define to `unsigned int' if does not define. */ #undef size_t /* Define to the type of an unsigned integer type of width exactly 16 bits if such a type exists and the standard includes do not define it. */ #undef uint16_t /* Define to the type of an unsigned integer type of width exactly 32 bits if such a type exists and the standard includes do not define it. */ #undef uint32_t GarminPlugin-0.3.23/src/configManager.cpp000066400000000000000000000135101232766717500202460ustar00rootroot00000000000000/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */ /* * GarminPlugin * Copyright (C) Andreas Diesner 2010 * * GarminPlugin is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GarminPlugin is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #include "configManager.h" #include #include #include "log.h" ConfigManager::ConfigManager() : configuration(NULL), createdNew(false) { } ConfigManager::~ConfigManager() { Log::dbg("ConfigManager destructor"); if (this->configuration != NULL) { delete this->configuration; } } void ConfigManager::readConfiguration() { string homeDir = getenv ("HOME"); this->configurationFile = homeDir + "/.config/garminplugin/garminplugin.xml"; if (this->configuration != NULL) { delete (this->configuration); this->configuration = NULL; } this->configuration = new TiXmlDocument(this->configurationFile ); if (this->configuration->LoadFile()) { return; } this->configurationFile = homeDir + "/.garminplugin.xml"; this->configuration = new TiXmlDocument(this->configurationFile ); if (this->configuration->LoadFile()) { return; } configuration = createNewConfiguration(); } TiXmlDocument * ConfigManager::getConfiguration() { return this->configuration; } TiXmlDocument * ConfigManager::createNewConfiguration() { if (Log::enabledDbg()) Log::dbg("Creating new initial configuration"); createdNew = true; string homeDir = getenv ("HOME"); string storagePath = homeDir + "/.config"; struct stat st; if(stat(storagePath.c_str(),&st) == 0) { // directory exists storagePath += "/garminplugin"; if(stat(storagePath.c_str(),&st) == 0) { // directory already exists storagePath += "/"; } else { if(mkdir(storagePath.c_str(), 0755) == -1) { if (Log::enabledErr()) Log::err("Failed to create directory "+storagePath); storagePath = homeDir+"/."; } else { storagePath += "/"; } } } else { storagePath = homeDir+"/."; } string configFile = storagePath + "garminplugin.xml"; TiXmlDocument * doc = new TiXmlDocument(); TiXmlDeclaration * decl = new TiXmlDeclaration( "1.0", "UTF-8", "no" ); doc->LinkEndChild( decl ); /* My Oregon 300 /tmp */ TiXmlElement * plugin = new TiXmlElement( "GarminPlugin" ); plugin->SetAttribute("logfile", ""); plugin->SetAttribute("level", "ERROR"); doc->LinkEndChild( plugin ); TiXmlElement * devices = new TiXmlElement( "Devices" ); plugin->LinkEndChild( devices ); TiXmlElement * device = new TiXmlElement( "Device" ); device->SetAttribute("enabled", "false"); devices->LinkEndChild( device ); TiXmlElement * name = new TiXmlElement( "Name" ); name->LinkEndChild(new TiXmlText("Home Directory "+homeDir)); device->LinkEndChild( name ); TiXmlElement * storePath = new TiXmlElement( "StoragePath" ); storePath->LinkEndChild(new TiXmlText(homeDir)); device->LinkEndChild( storePath ); TiXmlElement * storageCmd = new TiXmlElement( "StorageCommand" ); storageCmd->LinkEndChild(new TiXmlText("")); device->LinkEndChild( storageCmd ); TiXmlElement * fitnessPath = new TiXmlElement( "FitnessDataPath" ); fitnessPath->LinkEndChild(new TiXmlText("")); device->LinkEndChild( fitnessPath ); TiXmlElement * gpxPath = new TiXmlElement( "GpxDataPath" ); gpxPath->LinkEndChild(new TiXmlText("")); device->LinkEndChild( gpxPath ); /* */ TiXmlElement * settings = new TiXmlElement( "Settings" ); plugin->LinkEndChild( settings ); TiXmlElement * scanMounted = new TiXmlElement( "ScanMounted" ); settings->LinkEndChild( scanMounted ); scanMounted->SetAttribute("enabled", "true"); TiXmlElement * forerunnertools = new TiXmlElement( "ForerunnerTools" ); settings->LinkEndChild( forerunnertools ); forerunnertools->SetAttribute("enabled", "true"); TiXmlElement * backupWorkouts = new TiXmlElement( "BackupWorkouts" ); settings->LinkEndChild( backupWorkouts ); backupWorkouts->SetAttribute("enabled", "false"); backupWorkouts->SetAttribute("path", homeDir + "/Dropbox/Workouts/[YEAR]/[MONTH]/"); doc->SaveFile(configFile); configurationFile = configFile; return doc; } MessageBox * ConfigManager::getMessage() { // New configuration created message is unnecessary and created problems with some devices // A message is not always fetched when FinishState = 2 is returned to the javascript so // this message made the plugin not usable until the browser was restarted // if (!this->createdNew) return NULL; // // return new MessageBox(Question, "A new configuration was created at "+this->configurationFile, BUTTON_OK, BUTTON_OK, NULL); return NULL; } GarminPlugin-0.3.23/src/configManager.h000066400000000000000000000040471232766717500177200ustar00rootroot00000000000000/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */ /* * GarminPlugin * Copyright (C) Andreas Diesner 2010 * * GarminPlugin is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GarminPlugin is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #ifndef CONFIGMANAGER_H_INCLUDED #define CONFIGMANAGER_H_INCLUDED #include #include "messageBox.h" #include "tinyxml.h" using namespace std; class ConfigManager { public: /** * Creates a new instance of the ConfigManager */ ConfigManager(); /** * The desctructor which frees the configuration xml tree */ ~ConfigManager(); /** * Reads the configuration from the disk */ void readConfiguration(); /** * Returns the current configuration in memory. * @return The current configuration as XML tree */ TiXmlDocument * getConfiguration(); /** * Returns a message for the user in case of configuration problems * @return Messagebox object to be passed to the user */ MessageBox * getMessage(); private: /** * Creates and stores a new configuration * @return the new configuration as XML tree */ TiXmlDocument * createNewConfiguration(); /** * Stores the current configuration in memory */ TiXmlDocument * configuration; /** * Stores the current configuration file on disk */ string configurationFile; /** * Is set to true when the configuration had to be created new */ bool createdNew; }; #endif // CONFIGMANAGER_H_INCLUDED GarminPlugin-0.3.23/src/configure000077500000000000000000005206301232766717500167170ustar00rootroot00000000000000#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.68 for GarminPlugin 0.2. # # Report bugs to . # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, # 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software # Foundation, Inc. # # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi " as_required="as_fn_return () { (exit \$1); } as_fn_success () { as_fn_return 0; } as_fn_failure () { as_fn_return 1; } as_fn_ret_success () { return 0; } as_fn_ret_failure () { return 1; } exitcode=0 as_fn_success || { exitcode=1; echo as_fn_success failed.; } as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : else exitcode=1; echo positional parameters were not saved. fi test x\$exitcode = x0 || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 test \$(( 1 + 1 )) = 2 || exit 1" if (eval "$as_required") 2>/dev/null; then : as_have_required=yes else as_have_required=no fi if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. as_found=: case $as_dir in #( /*) for as_base in sh bash ksh sh5; do # Try only shells that exist, to save several forks. as_shell=$as_dir/$as_base if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : CONFIG_SHELL=$as_shell as_have_required=yes if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : break 2 fi fi done;; esac as_found=false done $as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : CONFIG_SHELL=$SHELL as_have_required=yes fi; } IFS=$as_save_IFS if test "x$CONFIG_SHELL" != x; then : # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV export CONFIG_SHELL case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec "$CONFIG_SHELL" $as_opts "$as_myself" ${1+"$@"} fi if test x$as_have_required = xno; then : $as_echo "$0: This script requires a shell more modern than all" $as_echo "$0: the shells that I found on your system." if test x${ZSH_VERSION+set} = xset ; then $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" $as_echo "$0: be upgraded to zsh 4.3.4 or later." else $as_echo "$0: Please tell bug-autoconf@gnu.org and $0: garminplugin@andreas-diesner.de about your system, $0: including any error possibly output before this $0: message. Then install a modern shell, or manually run $0: the script under such a shell if you do have one." fi exit 1 fi fi fi SHELL=${CONFIG_SHELL-/bin/sh} export SHELL # Unset more variables known to interfere with behavior of common tools. CLICOLOR_FORCE= GREP_OPTIONS= unset CLICOLOR_FORCE GREP_OPTIONS ## --------------------- ## ## M4sh Shell Functions. ## ## --------------------- ## # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits as_lineno_1=$LINENO as_lineno_1a=$LINENO as_lineno_2=$LINENO as_lineno_2a=$LINENO eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -p'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -p' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi if test -x / >/dev/null 2>&1; then as_test_x='test -x' else if ls -dL / >/dev/null 2>&1; then as_ls_L_option=L else as_ls_L_option= fi as_test_x=' eval sh -c '\'' if test -d "$1"; then test -d "$1/."; else case $1 in #( -*)set "./$1";; esac; case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( ???[sx]*):;;*)false;;esac;fi '\'' sh ' fi as_executable_p=$as_test_x # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" test -n "$DJDIR" || exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= # Identity of this package. PACKAGE_NAME='GarminPlugin' PACKAGE_TARNAME='garminplugin' PACKAGE_VERSION='0.2' PACKAGE_STRING='GarminPlugin 0.2' PACKAGE_BUGREPORT='garminplugin@andreas-diesner.de' PACKAGE_URL='' ac_unique_file="main.cpp" # Factoring default headers for most tests. ac_includes_default="\ #include #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_STAT_H # include #endif #ifdef STDC_HEADERS # include # include #else # ifdef HAVE_STDLIB_H # include # endif #endif #ifdef HAVE_STRING_H # if !defined STDC_HEADERS && defined HAVE_MEMORY_H # include # endif # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_STDINT_H # include #endif #ifdef HAVE_UNISTD_H # include #endif" ac_subst_vars='LTLIBOBJS LIBOBJS EGREP GREP CPP GARMINTOOLS_LDFLAGS GARMINTOOLS_CPPFLAGS GCRYPT_LIBS GCRYPT_CFLAGS TINYXML_LIBS TINYXML_CFLAGS ZLIB_LIBS ZLIB_CFLAGS LIBUSB_LIBS LIBUSB_CFLAGS PKG_CONFIG_LIBDIR PKG_CONFIG_PATH PKG_CONFIG ac_ct_CC CFLAGS CC OBJEXT EXEEXT ac_ct_CXX CPPFLAGS LDFLAGS CXXFLAGS CXX target_alias host_alias build_alias LIBS ECHO_T ECHO_N ECHO_C DEFS mandir localedir libdir psdir pdfdir dvidir htmldir infodir docdir oldincludedir includedir localstatedir sharedstatedir sysconfdir datadir datarootdir libexecdir sbindir bindir program_transform_name prefix exec_prefix PACKAGE_URL PACKAGE_BUGREPORT PACKAGE_STRING PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking with_tinyxml_libdir with_tinyxml_incdir with_libgcrypt_prefix with_garmintools_libdir with_garmintools_incdir ' ac_precious_vars='build_alias host_alias target_alias CXX CXXFLAGS LDFLAGS LIBS CPPFLAGS CCC CC CFLAGS PKG_CONFIG PKG_CONFIG_PATH PKG_CONFIG_LIBDIR LIBUSB_CFLAGS LIBUSB_LIBS ZLIB_CFLAGS ZLIB_LIBS TINYXML_CFLAGS TINYXML_LIBS CPP' # Initialize some variables set by options. ac_init_help= ac_init_version=false ac_unrecognized_opts= ac_unrecognized_sep= # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval $ac_prev=\$ac_option ac_prev= continue fi case $ac_option in *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *=) ac_optarg= ;; *) ac_optarg=yes ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=\$ac_optarg ;; -without-* | --without-*) ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) as_fn_error $? "unrecognized option: \`$ac_option' Try \`$0 --help' for more information" ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. case $ac_envvar in #( '' | [0-9]* | *[!_$as_cr_alnum]* ) as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; esac eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` as_fn_error $? "missing argument to $ac_option" fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi # Check all directory arguments for consistency. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir do eval ac_val=\$$ac_var # Remove trailing slashes. case $ac_val in */ ) ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` eval $ac_var=\$ac_val;; esac # Be sure to have absolute directory names. case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe $as_echo "$as_me: WARNING: if you wanted to set the --build type, don't use --host. If a cross compiler is detected then cross compile mode will be used" >&2 elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || as_fn_error $? "working directory cannot be determined" test "X$ac_ls_di" = "X$ac_pwd_ls_di" || as_fn_error $? "pwd does not report name of working directory" # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$as_myself" || $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_myself" : 'X\(//\)[^/]' \| \ X"$as_myself" : 'X\(//\)$' \| \ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_myself" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures GarminPlugin 0.2 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking ...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/garminplugin] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF _ACEOF fi if test -n "$ac_init_help"; then case $ac_init_help in short | recursive ) echo "Configuration of GarminPlugin 0.2:";; esac cat <<\_ACEOF Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-tinyxml-libdir=DIR specify where to find tinyxml library (libtinyxml.so) --with-tinyxml-incdir=DIR specify where to find tinyxml header files (tinyxml.h) --with-libgcrypt-prefix=DIR define libgcrypt prefix, default /usr --with-garmintools-libdir=DIR specify where to find garmintools library (libgarmintools.a) --with-garmintools-incdir=DIR specify where to find garmintools header files (garmin.h) Some influential environment variables: CXX C++ compiler command CXXFLAGS C++ compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory LIBS libraries to pass to the linker, e.g. -l CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory CC C compiler command CFLAGS C compiler flags PKG_CONFIG path to pkg-config utility PKG_CONFIG_PATH directories to add to pkg-config's search path PKG_CONFIG_LIBDIR path overriding pkg-config's built-in search path LIBUSB_CFLAGS C compiler flags for LIBUSB, overriding pkg-config LIBUSB_LIBS linker flags for LIBUSB, overriding pkg-config ZLIB_CFLAGS C compiler flags for ZLIB, overriding pkg-config ZLIB_LIBS linker flags for ZLIB, overriding pkg-config TINYXML_CFLAGS C compiler flags for TINYXML, overriding pkg-config TINYXML_LIBS linker flags for TINYXML, overriding pkg-config CPP C preprocessor Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to . _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for guested configure. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF GarminPlugin configure 0.2 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi ## ------------------------ ## ## Autoconf initialization. ## ## ------------------------ ## # ac_fn_cxx_try_compile LINENO # ---------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_cxx_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_compile # ac_fn_c_try_compile LINENO # -------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_compile # ac_fn_c_try_cpp LINENO # ---------------------- # Try to preprocess conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_cpp () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } > conftest.i && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_cpp # ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists, giving a warning if it cannot be compiled using # the include files in INCLUDES and setting the cache variable VAR # accordingly. ac_fn_c_check_header_mongrel () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if eval \${$3+:} false; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 $as_echo_n "checking $2 usability... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_header_compiler=yes else ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 $as_echo_n "checking $2 presence... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <$2> _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : ac_header_preproc=yes else ac_header_preproc=no fi rm -f conftest.err conftest.i conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( yes:no: ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; no:yes:* ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ( $as_echo "## ---------------------------------------------- ## ## Report this to garminplugin@andreas-diesner.de ## ## ---------------------------------------------- ##" ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=\$ac_header_compiler" fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_mongrel # ac_fn_c_try_run LINENO # ---------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. Assumes # that executables *can* be run. ac_fn_c_try_run () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then : ac_retval=0 else $as_echo "$as_me: program exited with status $ac_status" >&5 $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=$ac_status fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_run # ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists and can be compiled using the include files in # INCLUDES, setting the cache variable VAR accordingly. ac_fn_c_check_header_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_compile # ac_fn_c_check_type LINENO TYPE VAR INCLUDES # ------------------------------------------- # Tests whether TYPE exists after having included INCLUDES, setting cache # variable VAR accordingly. ac_fn_c_check_type () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=no" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { if (sizeof ($2)) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { if (sizeof (($2))) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else eval "$3=yes" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_type # ac_fn_c_find_intX_t LINENO BITS VAR # ----------------------------------- # Finds a signed integer type with width BITS, setting cache variable VAR # accordingly. ac_fn_c_find_intX_t () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for int$2_t" >&5 $as_echo_n "checking for int$2_t... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=no" # Order is important - never check a type that is potentially smaller # than half of the expected target width. for ac_type in int$2_t 'int' 'long int' \ 'long long int' 'short int' 'signed char'; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default enum { N = $2 / 2 - 1 }; int main () { static int test_array [1 - 2 * !(0 < ($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 1))]; test_array [0] = 0 ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default enum { N = $2 / 2 - 1 }; int main () { static int test_array [1 - 2 * !(($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 1) < ($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 2))]; test_array [0] = 0 ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else case $ac_type in #( int$2_t) : eval "$3=yes" ;; #( *) : eval "$3=\$ac_type" ;; esac fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if eval test \"x\$"$3"\" = x"no"; then : else break fi done fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_find_intX_t # ac_fn_c_find_uintX_t LINENO BITS VAR # ------------------------------------ # Finds an unsigned integer type with width BITS, setting cache variable VAR # accordingly. ac_fn_c_find_uintX_t () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for uint$2_t" >&5 $as_echo_n "checking for uint$2_t... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=no" # Order is important - never check a type that is potentially smaller # than half of the expected target width. for ac_type in uint$2_t 'unsigned int' 'unsigned long int' \ 'unsigned long long int' 'unsigned short int' 'unsigned char'; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default int main () { static int test_array [1 - 2 * !((($ac_type) -1 >> ($2 / 2 - 1)) >> ($2 / 2 - 1) == 3)]; test_array [0] = 0 ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : case $ac_type in #( uint$2_t) : eval "$3=yes" ;; #( *) : eval "$3=\$ac_type" ;; esac fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if eval test \"x\$"$3"\" = x"no"; then : else break fi done fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_find_uintX_t # ac_fn_c_try_link LINENO # ----------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_link # ac_fn_c_check_func LINENO FUNC VAR # ---------------------------------- # Tests whether FUNC exists, setting the cache variable VAR accordingly ac_fn_c_check_func () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Define $2 to an innocuous variant, in case declares $2. For example, HP-UX 11i declares gettimeofday. */ #define $2 innocuous_$2 /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $2 (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $2 /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $2 (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$2 || defined __stub___$2 choke me #endif int main () { return $2 (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_func cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by GarminPlugin $as_me 0.2, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. $as_echo "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; 2) as_fn_append ac_configure_args1 " '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi as_fn_append ac_configure_args " '$ac_arg'" ;; esac done done { ac_configure_args0=; unset ac_configure_args0;} { ac_configure_args1=; unset ac_configure_args1;} # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo $as_echo "## ---------------- ## ## Cache variables. ## ## ---------------- ##" echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo $as_echo "## ----------------- ## ## Output variables. ## ## ----------------- ##" echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then $as_echo "## ------------------- ## ## File substitutions. ## ## ------------------- ##" echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then $as_echo "## ----------- ## ## confdefs.h. ## ## ----------- ##" echo cat confdefs.h echo fi test "$ac_signal" != 0 && $as_echo "$as_me: caught signal $ac_signal" $as_echo "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h $as_echo "/* confdefs.h */" > confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_URL "$PACKAGE_URL" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. ac_site_file1=NONE ac_site_file2=NONE if test -n "$CONFIG_SITE"; then # We do not want a PATH search for config.site. case $CONFIG_SITE in #(( -*) ac_site_file1=./$CONFIG_SITE;; */*) ac_site_file1=$CONFIG_SITE;; *) ac_site_file1=./$CONFIG_SITE;; esac elif test "x$prefix" != xNONE; then ac_site_file1=$prefix/share/config.site ac_site_file2=$prefix/etc/config.site else ac_site_file1=$ac_default_prefix/share/config.site ac_site_file2=$ac_default_prefix/etc/config.site fi for ac_site_file in "$ac_site_file1" "$ac_site_file2" do test "x$ac_site_file" = xNONE && continue if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 $as_echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" \ || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "failed to load site script $ac_site_file See \`config.log' for more details" "$LINENO" 5; } fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special files # actually), so we avoid doing that. DJGPP emulates it as a regular file. if test /dev/null != "$cache_file" && test -f "$cache_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 $as_echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 $as_echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then # differences in whitespace do not lead to failure. ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 $as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 $as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 $as_echo "$as_me: former value: \`$ac_old_val'" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 $as_echo "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) as_fn_append ac_configure_args " '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 $as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## ## -------------------- ## ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu # Checks for programs. ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu if test -z "$CXX"; then if test -n "$CCC"; then CXX=$CCC else if test -n "$ac_tool_prefix"; then for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CXX+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CXX"; then ac_cv_prog_CXX="$CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CXX=$ac_cv_prog_CXX if test -n "$CXX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 $as_echo "$CXX" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CXX" && break done fi if test -z "$CXX"; then ac_ct_CXX=$CXX for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CXX+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CXX"; then ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CXX="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CXX=$ac_cv_prog_ac_ct_CXX if test -n "$ac_ct_CXX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 $as_echo "$ac_ct_CXX" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CXX" && break done if test "x$ac_ct_CXX" = x; then CXX="g++" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CXX=$ac_ct_CXX fi fi fi fi # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C++ compiler works" >&5 $as_echo_n "checking whether the C++ compiler works... " >&6; } ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # The possible output files: ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; * ) ac_rmfiles="$ac_rmfiles $ac_file";; esac done rm -f $ac_rmfiles if { { ac_try="$ac_link_default" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link_default") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. for ac_file in $ac_files '' do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi # We set ac_cv_exeext here because the later test for it is not # safe: cross compilers may not add the suffix if given an `-o' # argument, so we may need to know it at that point already. # Even if this section looks crufty: it has the advantage of # actually working. break;; * ) break;; esac done test "$ac_cv_exeext" = no && ac_cv_exeext= else ac_file='' fi if test -z "$ac_file"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "C++ compiler cannot create executables See \`config.log' for more details" "$LINENO" 5; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler default output file name" >&5 $as_echo_n "checking for C++ compiler default output file name... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 $as_echo "$ac_file" >&6; } ac_exeext=$ac_cv_exeext rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 $as_echo_n "checking for suffix of executables... " >&6; } if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of executables: cannot compile and link See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest conftest$ac_cv_exeext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 $as_echo "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { FILE *f = fopen ("conftest.out", "w"); return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF ac_clean_files="$ac_clean_files conftest.out" # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 $as_echo_n "checking whether we are cross compiling... " >&6; } if test "$cross_compiling" != yes; then { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if { ac_try='./conftest$ac_cv_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run C++ compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details" "$LINENO" 5; } fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 $as_echo "$cross_compiling" >&6; } rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 $as_echo_n "checking for suffix of object files... " >&6; } if ${ac_cv_objext+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of object files: cannot compile See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 $as_echo "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5 $as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; } if ${ac_cv_cxx_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_cxx_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 $as_echo "$ac_cv_cxx_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GXX=yes else GXX= fi ac_test_CXXFLAGS=${CXXFLAGS+set} ac_save_CXXFLAGS=$CXXFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 $as_echo_n "checking whether $CXX accepts -g... " >&6; } if ${ac_cv_prog_cxx_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_cxx_werror_flag=$ac_cxx_werror_flag ac_cxx_werror_flag=yes ac_cv_prog_cxx_g=no CXXFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_prog_cxx_g=yes else CXXFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : else ac_cxx_werror_flag=$ac_save_cxx_werror_flag CXXFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_prog_cxx_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cxx_werror_flag=$ac_save_cxx_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5 $as_echo "$ac_cv_prog_cxx_g" >&6; } if test "$ac_test_CXXFLAGS" = set; then CXXFLAGS=$ac_save_CXXFLAGS elif test $ac_cv_prog_cxx_g = yes; then if test "$GXX" = yes; then CXXFLAGS="-g -O2" else CXXFLAGS="-g" fi else if test "$GXX" = yes; then CXXFLAGS="-O2" else CXXFLAGS= fi fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } if ${ac_cv_c_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 $as_echo "$ac_cv_c_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } if ${ac_cv_prog_cc_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes else CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 $as_echo "$ac_cv_prog_cc_g" >&6; } if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } if ${ac_cv_prog_cc_c89+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac if test "x$ac_cv_prog_cc_c89" != xno; then : fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu # Checks for libraries. if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_PKG_CONFIG+:} false; then : $as_echo_n "(cached) " >&6 else case $PKG_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi PKG_CONFIG=$ac_cv_path_PKG_CONFIG if test -n "$PKG_CONFIG"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 $as_echo "$PKG_CONFIG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_path_PKG_CONFIG"; then ac_pt_PKG_CONFIG=$PKG_CONFIG # Extract the first word of "pkg-config", so it can be a program name with args. set dummy pkg-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_pt_PKG_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG if test -n "$ac_pt_PKG_CONFIG"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5 $as_echo "$ac_pt_PKG_CONFIG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_pt_PKG_CONFIG" = x; then PKG_CONFIG="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac PKG_CONFIG=$ac_pt_PKG_CONFIG fi else PKG_CONFIG="$ac_cv_path_PKG_CONFIG" fi fi if test -n "$PKG_CONFIG"; then _pkg_min_version=0.9.0 { $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5 $as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; } if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } PKG_CONFIG="" fi fi pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for LIBUSB" >&5 $as_echo_n "checking for LIBUSB... " >&6; } if test -n "$LIBUSB_CFLAGS"; then pkg_cv_LIBUSB_CFLAGS="$LIBUSB_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libusb\""; } >&5 ($PKG_CONFIG --exists --print-errors "libusb") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_LIBUSB_CFLAGS=`$PKG_CONFIG --cflags "libusb" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test -n "$LIBUSB_LIBS"; then pkg_cv_LIBUSB_LIBS="$LIBUSB_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libusb\""; } >&5 ($PKG_CONFIG --exists --print-errors "libusb") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_LIBUSB_LIBS=`$PKG_CONFIG --libs "libusb" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test $pkg_failed = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then LIBUSB_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libusb" 2>&1` else LIBUSB_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libusb" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$LIBUSB_PKG_ERRORS" >&5 as_fn_error $? "Package requirements (libusb) were not met: $LIBUSB_PKG_ERRORS Consider adjusting the PKG_CONFIG_PATH environment variable if you installed software in a non-standard prefix. Alternatively, you may set the environment variables LIBUSB_CFLAGS and LIBUSB_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details." "$LINENO" 5 elif test $pkg_failed = untried; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full path to pkg-config. Alternatively, you may set the environment variables LIBUSB_CFLAGS and LIBUSB_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details. To get pkg-config, see . See \`config.log' for more details" "$LINENO" 5; } else LIBUSB_CFLAGS=$pkg_cv_LIBUSB_CFLAGS LIBUSB_LIBS=$pkg_cv_LIBUSB_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ZLIB" >&5 $as_echo_n "checking for ZLIB... " >&6; } if test -n "$ZLIB_CFLAGS"; then pkg_cv_ZLIB_CFLAGS="$ZLIB_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"zlib\""; } >&5 ($PKG_CONFIG --exists --print-errors "zlib") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_ZLIB_CFLAGS=`$PKG_CONFIG --cflags "zlib" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test -n "$ZLIB_LIBS"; then pkg_cv_ZLIB_LIBS="$ZLIB_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"zlib\""; } >&5 ($PKG_CONFIG --exists --print-errors "zlib") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_ZLIB_LIBS=`$PKG_CONFIG --libs "zlib" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test $pkg_failed = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then ZLIB_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "zlib" 2>&1` else ZLIB_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "zlib" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$ZLIB_PKG_ERRORS" >&5 as_fn_error $? "Package requirements (zlib) were not met: $ZLIB_PKG_ERRORS Consider adjusting the PKG_CONFIG_PATH environment variable if you installed software in a non-standard prefix. Alternatively, you may set the environment variables ZLIB_CFLAGS and ZLIB_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details." "$LINENO" 5 elif test $pkg_failed = untried; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full path to pkg-config. Alternatively, you may set the environment variables ZLIB_CFLAGS and ZLIB_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details. To get pkg-config, see . See \`config.log' for more details" "$LINENO" 5; } else ZLIB_CFLAGS=$pkg_cv_ZLIB_CFLAGS ZLIB_LIBS=$pkg_cv_ZLIB_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi if pkg-config --exists tinyxml; then pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for TINYXML" >&5 $as_echo_n "checking for TINYXML... " >&6; } if test -n "$TINYXML_CFLAGS"; then pkg_cv_TINYXML_CFLAGS="$TINYXML_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"tinyxml\""; } >&5 ($PKG_CONFIG --exists --print-errors "tinyxml") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_TINYXML_CFLAGS=`$PKG_CONFIG --cflags "tinyxml" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test -n "$TINYXML_LIBS"; then pkg_cv_TINYXML_LIBS="$TINYXML_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"tinyxml\""; } >&5 ($PKG_CONFIG --exists --print-errors "tinyxml") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_TINYXML_LIBS=`$PKG_CONFIG --libs "tinyxml" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test $pkg_failed = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then TINYXML_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "tinyxml" 2>&1` else TINYXML_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "tinyxml" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$TINYXML_PKG_ERRORS" >&5 as_fn_error $? "Package requirements (tinyxml) were not met: $TINYXML_PKG_ERRORS Consider adjusting the PKG_CONFIG_PATH environment variable if you installed software in a non-standard prefix. Alternatively, you may set the environment variables TINYXML_CFLAGS and TINYXML_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details." "$LINENO" 5 elif test $pkg_failed = untried; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full path to pkg-config. Alternatively, you may set the environment variables TINYXML_CFLAGS and TINYXML_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details. To get pkg-config, see . See \`config.log' for more details" "$LINENO" 5; } else TINYXML_CFLAGS=$pkg_cv_TINYXML_CFLAGS TINYXML_LIBS=$pkg_cv_TINYXML_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi else # # Check for tinyxml (pgk info is not available on many distros) # { $as_echo "$as_me:${as_lineno-$LINENO}: checking for tinyxml" >&5 $as_echo_n "checking for tinyxml... " >&6; } # Check whether --with-tinyxml-libdir was given. if test "${with_tinyxml_libdir+set}" = set; then : withval=$with_tinyxml_libdir; tinyxml_libdir=$withval else tinyxml_libdir="" fi # Check whether --with-tinyxml-incdir was given. if test "${with_tinyxml_incdir+set}" = set; then : withval=$with_tinyxml_incdir; tinyxml_incdir=$withval else tinyxml_incdir="" fi if test "x$tinyxml_incdir" != "x" ; then TINYXML_CFLAGS="-I$tinyxml_incdir" elif test -f "../tinyxml/tinyxml.h" ; then TINYXML_CFLAGS="-I../tinyxml/" elif test -f "/usr/include/tinyxml.h" ; then TINYXML_CFLAGS="-I/usr/include" elif test -f "tinyxml/tinyxml.h" ; then TINYXML_CFLAGS="-Itinyxml" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } as_fn_error $? "Unable to find tinyxml header file (tinyxml.h). Try 'apt-get install tinyxml-dev' or use --with-tinyxml-incdir=DIR" "$LINENO" 5 fi if test "x$tinyxml_libdir" != "x" ; then if test -f "$tinyxml_libdir/libtinyxml.so" ; then TINYXML_LIBS="$tinyxml_libdir/libtinyxml.so" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } as_fn_error $? "Unable to find libtinyxml.so in $tinyxml_libdir. Is tinyxml compiled?" "$LINENO" 5 fi elif test -f "/usr/lib64/libtinyxml.so" ; then TINYXML_LIBS="/usr/lib64/libtinyxml.so" elif test -f "/usr/lib/libtinyxml.so" ; then TINYXML_LIBS="/usr/lib/libtinyxml.so" elif test -f "../tinyxml/libtinyxml.so" ; then TINYXML_LIBS="../tinyxml/libtinyxml.so" elif test -f "../tinyxml/tinyxml.o" ; then TINYXML_LIBS="../tinyxml/tinyxml.o ../tinyxml/tinystr.o ../tinyxml/tinyxmlerror.o ../tinyxml/tinyxmlparser.o" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } as_fn_error $? "Unable to find libtinyxml.so. Try 'apt-get install tinyxml' and compile source or use --with-tinyxml-libdir=DIR" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi # # Check for GNU Crypt library # # Check whether --with-libgcrypt-prefix was given. if test "${with_libgcrypt_prefix+set}" = set; then : withval=$with_libgcrypt_prefix; else with_libgcrypt_prefix="/usr" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for libgcrypt" >&5 $as_echo_n "checking for libgcrypt... " >&6; } if ! test -x "${with_libgcrypt_prefix}/bin/libgcrypt-config"; then as_fn_error $? "Cannot locate libgcrypt" "$LINENO" 5 else { $as_echo "$as_me:${as_lineno-$LINENO}: result: found" >&5 $as_echo "found" >&6; } GCRYPT_CFLAGS=`"${with_libgcrypt_prefix}/bin/libgcrypt-config" --cflags` GCRYPT_LIBS=`"${with_libgcrypt_prefix}/bin/libgcrypt-config" --libs` fi # # Check GarminTools # { $as_echo "$as_me:${as_lineno-$LINENO}: checking for garmintools" >&5 $as_echo_n "checking for garmintools... " >&6; } # Check whether --with-garmintools-libdir was given. if test "${with_garmintools_libdir+set}" = set; then : withval=$with_garmintools_libdir; garmintools_libdir=$withval else garmintools_libdir="" fi # Check whether --with-garmintools-incdir was given. if test "${with_garmintools_incdir+set}" = set; then : withval=$with_garmintools_incdir; garmintools_incdir=$withval else garmintools_incdir="" fi if test "x$garmintools_incdir" != "x" ; then GARMINTOOLS_CPPFLAGS="-I$garmintools_incdir" elif test -f "/usr/include/garmin.h" ; then GARMINTOOLS_CPPFLAGS="-I/usr/include/" elif test -f "../garmintools/src/garmin.h" ; then GARMINTOOLS_CPPFLAGS="-I../garmintools/src/" elif test -f "../garmintools-read-only/src/garmin.h" ; then GARMINTOOLS_CPPFLAGS="-I../garmintools-read-only/src" elif test -f "garmintools-read-only/src/garmin.h" ; then GARMINTOOLS_CPPFLAGS="-Igarmintools-read-only/src" elif test -f "garmintools/src/garmin.h" ; then GARMINTOOLS_CPPFLAGS="-Igarmintools/src" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } as_fn_error $? "Unable to find garmintools header files. Try 'svn export http://garmintools.googlecode.com/svn/trunk/ garmintools' or use --with-garmintools-incdir=DIR" "$LINENO" 5 fi if test "x$garmintools_libdir" != "x" ; then if test -f "$garmintools_libdir/libgarmintools.a" ; then GARMINTOOLS_LDFLAGS="$garmintools_libdir/libgarmintools.a" elif test -f "$garmintools_libdir/libgarmintools.so" ; then GARMINTOOLS_LDFLAGS="$garmintools_libdir/libgarmintools.so" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } as_fn_error $? "Unable to find libgarmintools.a in $garmintools_libdir. Is garmintools compiled?" "$LINENO" 5 fi elif test -f "../garmintools/src/.libs/libgarmintools.a" ; then GARMINTOOLS_LDFLAGS="../garmintools/src/.libs/libgarmintools.a" elif test -f "garmintools/src/.libs/libgarmintools.a" ; then GARMINTOOLS_LDFLAGS="garmintools/src/.libs/libgarmintools.a" elif test -f "../garmintools-read-only/src/.libs/libgarmintools.a" ; then GARMINTOOLS_LDFLAGS="../garmintools-read-only/src/.libs/libgarmintools.a" elif test -f "garmintools-read-only/src/.libs/libgarmintools.a" ; then GARMINTOOLS_LDFLAGS="garmintools-read-only/src/.libs/libgarmintools.a" elif test -f "garmintools-read-only/libgarmintools.a" ; then GARMINTOOLS_LDFLAGS="garmintools-read-only/libgarmintools.a" elif test -f "../garmintools-read-only/libgarmintools.a" ; then GARMINTOOLS_LDFLAGS="../garmintools-read-only/libgarmintools.a" elif test -f "garmintools/libgarmintools.a" ; then GARMINTOOLS_LDFLAGS="garmintools/libgarmintools.a" elif test -f "../garmintools/libgarmintools.a" ; then GARMINTOOLS_LDFLAGS="../garmintools/libgarmintools.a" elif test -f "/usr/lib/libgarmintools.so" ; then GARMINTOOLS_LDFLAGS="/usr/lib/libgarmintools.so" elif test -f "/usr/lib64/libgarmintools.so" ; then GARMINTOOLS_LDFLAGS="/usr/lib64/libgarmintools.so" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } as_fn_error $? "Unable to find libgarmintools.a. Try 'svn export http://garmintools.googlecode.com/svn/trunk/ garmintools' and compile source or use --with-garmintools-libdir=DIR" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } # Checks for header files. ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 $as_echo_n "checking how to run the C preprocessor... " >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if ${ac_cv_prog_CPP+:} false; then : $as_echo_n "(cached) " >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 $as_echo "$CPP" >&6; } ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 $as_echo_n "checking for grep that handles long lines and -e... " >&6; } if ${ac_cv_path_GREP+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$GREP"; then ac_path_GREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in grep ggrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in *GNU*) ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'GREP' >> "conftest.nl" "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_GREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_GREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_GREP"; then as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_GREP=$GREP fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 $as_echo "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 $as_echo_n "checking for egrep... " >&6; } if ${ac_cv_path_EGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else if test -z "$EGREP"; then ac_path_EGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in egrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in *GNU*) ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'EGREP' >> "conftest.nl" "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_EGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_EGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_EGREP"; then as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_EGREP=$EGREP fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 $as_echo "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if ${ac_cv_header_stdc+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_stdc=yes else ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : : else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : else ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then $as_echo "#define STDC_HEADERS 1" >>confdefs.h fi # On IRIX 5.3, sys/types and inttypes.h are conflicting. for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default " if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in mntent.h stdlib.h unistd.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in zipstub.h do : ac_fn_c_check_header_mongrel "$LINENO" "zipstub.h" "ac_cv_header_zipstub_h" "$ac_includes_default" if test "x$ac_cv_header_zipstub_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_ZIPSTUB_H 1 _ACEOF fi done for ac_header in prtypes.h do : ac_fn_c_check_header_mongrel "$LINENO" "prtypes.h" "ac_cv_header_prtypes_h" "$ac_includes_default" if test "x$ac_cv_header_prtypes_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_PRTYPES_H 1 _ACEOF fi done { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } # Checks for typedefs, structures, and compiler characteristics. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdbool.h that conforms to C99" >&5 $as_echo_n "checking for stdbool.h that conforms to C99... " >&6; } if ${ac_cv_header_stdbool_h+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #ifndef bool "error: bool is not defined" #endif #ifndef false "error: false is not defined" #endif #if false "error: false is not 0" #endif #ifndef true "error: true is not defined" #endif #if true != 1 "error: true is not 1" #endif #ifndef __bool_true_false_are_defined "error: __bool_true_false_are_defined is not defined" #endif struct s { _Bool s: 1; _Bool t; } s; char a[true == 1 ? 1 : -1]; char b[false == 0 ? 1 : -1]; char c[__bool_true_false_are_defined == 1 ? 1 : -1]; char d[(bool) 0.5 == true ? 1 : -1]; /* See body of main program for 'e'. */ char f[(_Bool) 0.0 == false ? 1 : -1]; char g[true]; char h[sizeof (_Bool)]; char i[sizeof s.t]; enum { j = false, k = true, l = false * true, m = true * 256 }; /* The following fails for HP aC++/ANSI C B3910B A.05.55 [Dec 04 2003]. */ _Bool n[m]; char o[sizeof n == m * sizeof n[0] ? 1 : -1]; char p[-1 - (_Bool) 0 < 0 && -1 - (bool) 0 < 0 ? 1 : -1]; /* Catch a bug in an HP-UX C compiler. See http://gcc.gnu.org/ml/gcc-patches/2003-12/msg02303.html http://lists.gnu.org/archive/html/bug-coreutils/2005-11/msg00161.html */ _Bool q = true; _Bool *pq = &q; int main () { bool e = &s; *pq |= q; *pq |= ! q; /* Refer to every declared value, to avoid compiler optimizations. */ return (!a + !b + !c + !d + !e + !f + !g + !h + !i + !!j + !k + !!l + !m + !n + !o + !p + !q + !pq); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_stdbool_h=yes else ac_cv_header_stdbool_h=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdbool_h" >&5 $as_echo "$ac_cv_header_stdbool_h" >&6; } ac_fn_c_check_type "$LINENO" "_Bool" "ac_cv_type__Bool" "$ac_includes_default" if test "x$ac_cv_type__Bool" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE__BOOL 1 _ACEOF fi if test $ac_cv_header_stdbool_h = yes; then $as_echo "#define HAVE_STDBOOL_H 1" >>confdefs.h fi ac_fn_c_find_intX_t "$LINENO" "16" "ac_cv_c_int16_t" case $ac_cv_c_int16_t in #( no|yes) ;; #( *) cat >>confdefs.h <<_ACEOF #define int16_t $ac_cv_c_int16_t _ACEOF ;; esac ac_fn_c_find_intX_t "$LINENO" "32" "ac_cv_c_int32_t" case $ac_cv_c_int32_t in #( no|yes) ;; #( *) cat >>confdefs.h <<_ACEOF #define int32_t $ac_cv_c_int32_t _ACEOF ;; esac ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" if test "x$ac_cv_type_size_t" = xyes; then : else cat >>confdefs.h <<_ACEOF #define size_t unsigned int _ACEOF fi ac_fn_c_find_uintX_t "$LINENO" "16" "ac_cv_c_uint16_t" case $ac_cv_c_uint16_t in #( no|yes) ;; #( *) cat >>confdefs.h <<_ACEOF #define uint16_t $ac_cv_c_uint16_t _ACEOF ;; esac ac_fn_c_find_uintX_t "$LINENO" "32" "ac_cv_c_uint32_t" case $ac_cv_c_uint32_t in #( no|yes) ;; #( *) $as_echo "#define _UINT32_T 1" >>confdefs.h cat >>confdefs.h <<_ACEOF #define uint32_t $ac_cv_c_uint32_t _ACEOF ;; esac # Checks for library functions. # getmntent is in the standard C library on UNICOS, in -lsun on Irix 4, # -lseq on Dynix/PTX, -lgen on Unixware. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing getmntent" >&5 $as_echo_n "checking for library containing getmntent... " >&6; } if ${ac_cv_search_getmntent+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char getmntent (); int main () { return getmntent (); ; return 0; } _ACEOF for ac_lib in '' sun seq gen; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO"; then : ac_cv_search_getmntent=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if ${ac_cv_search_getmntent+:} false; then : break fi done if ${ac_cv_search_getmntent+:} false; then : else ac_cv_search_getmntent=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_getmntent" >&5 $as_echo "$ac_cv_search_getmntent" >&6; } ac_res=$ac_cv_search_getmntent if test "$ac_res" != no; then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" ac_cv_func_getmntent=yes $as_echo "#define HAVE_GETMNTENT 1" >>confdefs.h else ac_cv_func_getmntent=no fi for ac_func in getmntent localtime_r memmove mkdir do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done ac_config_headers="$ac_config_headers config.h" ac_config_files="$ac_config_files Makefile" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes: double-quote # substitution turns \\\\ into \\, and sed turns \\ into \. sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then if test "x$cache_file" != "x/dev/null"; then { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} if test ! -f "$cache_file" || test -h "$cache_file"; then cat confcache >"$cache_file" else case $cache_file in #( */* | ?:*) mv -f confcache "$cache_file"$$ && mv -f "$cache_file"$$ "$cache_file" ;; #( *) mv -f confcache "$cache_file" ;; esac fi fi else { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' DEFS=-DHAVE_CONFIG_H ac_libobjs= ac_ltlibobjs= U= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`$as_echo "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 $as_echo "$as_me: creating $CONFIG_STATUS" >&6;} as_write_fail=0 cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -p'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -p' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi if test -x / >/dev/null 2>&1; then as_test_x='test -x' else if ls -dL / >/dev/null 2>&1; then as_ls_L_option=L else as_ls_L_option= fi as_test_x=' eval sh -c '\'' if test -d "$1"; then test -d "$1/."; else case $1 in #( -*)set "./$1";; esac; case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( ???[sx]*):;;*)false;;esac;fi '\'' sh ' fi as_executable_p=$as_test_x # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 ## ----------------------------------- ## ## Main body of $CONFIG_STATUS script. ## ## ----------------------------------- ## _ASEOF test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Save the log message, to keep $0 and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by GarminPlugin $as_me 0.2, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF case $ac_config_files in *" "*) set x $ac_config_files; shift; ac_config_files=$*;; esac case $ac_config_headers in *" "*) set x $ac_config_headers; shift; ac_config_headers=$*;; esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" config_headers="$ac_config_headers" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ \`$as_me' instantiates files and other configuration actions from templates according to the current configuration. Unless the files and actions are specified as TAGs, all are instantiated by default. Usage: $0 [OPTION]... [TAG]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit --config print configuration, then exit -q, --quiet, --silent do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE --header=FILE[:TEMPLATE] instantiate the configuration header FILE Configuration files: $config_files Configuration headers: $config_headers Report bugs to ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ GarminPlugin config.status 0.2 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" Copyright (C) 2010 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' test -n "\$AWK" || AWK=awk _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # The default lists apply if the user does not specify any file. ac_need_defaults=: while test $# != 0 do case $1 in --*=?*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; --*=) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg= ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) $as_echo "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) $as_echo "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; '') as_fn_error $? "missing file argument" ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append CONFIG_HEADERS " '$ac_optarg'" ac_need_defaults=false;; --he | --h) # Conflict between --help and --header as_fn_error $? "ambiguous option: \`$1' Try \`$0 --help' for more information.";; --help | --hel | -h ) $as_echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) as_fn_error $? "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' export CONFIG_SHELL exec "\$@" fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX $as_echo "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= ac_tmp= trap 'exit_status=$? : "${ac_tmp:=$tmp}" { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 ac_tmp=$tmp # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. # This happens for instance with `./config.status config.h'. if test -n "$CONFIG_FILES"; then ac_cr=`echo X | tr X '\015'` # On cygwin, bash can eat \r inside `` if the user requested igncr. # But we know of no other shell where ac_cr would be empty at this # point, so we can use a bashism as a fallback. if test "x$ac_cr" = x; then eval ac_cr=\$\'\\r\' fi ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ac_cs_awk_cr='\\r' else ac_cs_awk_cr=$ac_cr fi echo 'BEGIN {' >"$ac_tmp/subs1.awk" && _ACEOF { echo "cat >conf$$subs.awk <<_ACEOF" && echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h s/^/S["/; s/!.*/"]=/ p g s/^[^!]*!// :repl t repl s/'"$ac_delim"'$// t delim :nl h s/\(.\{148\}\)..*/\1/ t more1 s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ p n b repl :more1 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t nl :delim h s/\(.\{148\}\)..*/\1/ t more2 s/["\\]/\\&/g; s/^/"/; s/$/"/ p b :more2 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t delim ' >$CONFIG_STATUS || ac_write_fail=1 rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" } { line = $ 0 nfields = split(line, field, "@") substed = 0 len = length(field[1]) for (i = 2; i < nfields; i++) { key = field[i] keylen = length(key) if (S_is_set[key]) { value = S[key] line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) len += length(value) + length(field[++i]) substed = 1 } else len += 1 + keylen } print line } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF # VPATH may cause trouble with some makes, so we remove sole $(srcdir), # ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ h s/// s/^/:/ s/[ ]*$/:/ s/:\$(srcdir):/:/g s/:\${srcdir}:/:/g s/:@srcdir@:/:/g s/^:*// s/:*$// x s/\(=[ ]*\).*/\1/ G s/\n// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" # Set up the scripts for CONFIG_HEADERS section. # No need to generate them if there are no CONFIG_HEADERS. # This happens for instance with `./config.status Makefile'. if test -n "$CONFIG_HEADERS"; then cat >"$ac_tmp/defines.awk" <<\_ACAWK || BEGIN { _ACEOF # Transform confdefs.h into an awk script `defines.awk', embedded as # here-document in config.status, that substitutes the proper values into # config.h.in to produce config.h. # Create a delimiter string that does not exist in confdefs.h, to ease # handling of long lines. ac_delim='%!_!# ' for ac_last_try in false false :; do ac_tt=`sed -n "/$ac_delim/p" confdefs.h` if test -z "$ac_tt"; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done # For the awk script, D is an array of macro values keyed by name, # likewise P contains macro parameters if any. Preserve backslash # newline sequences. ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* sed -n ' s/.\{148\}/&'"$ac_delim"'/g t rset :rset s/^[ ]*#[ ]*define[ ][ ]*/ / t def d :def s/\\$// t bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3"/p s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p d :bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3\\\\\\n"\\/p t cont s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p t cont d :cont n s/.\{148\}/&'"$ac_delim"'/g t clear :clear s/\\$// t bsnlc s/["\\]/\\&/g; s/^/"/; s/$/"/p d :bsnlc s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p b cont ' >$CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 for (key in D) D_is_set[key] = 1 FS = "" } /^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { line = \$ 0 split(line, arg, " ") if (arg[1] == "#") { defundef = arg[2] mac1 = arg[3] } else { defundef = substr(arg[1], 2) mac1 = arg[2] } split(mac1, mac2, "(") #) macro = mac2[1] prefix = substr(line, 1, index(line, defundef) - 1) if (D_is_set[macro]) { # Preserve the white space surrounding the "#". print prefix "define", macro P[macro] D[macro] next } else { # Replace #undef with comments. This is necessary, for example, # in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. if (defundef == "undef") { print "/*", prefix defundef, macro, "*/" next } } } { print } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 fi # test -n "$CONFIG_HEADERS" eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS " shift for ac_tag do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$ac_tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 $as_echo "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`$as_echo "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac case $ac_tag in *:-:* | *:-) cat >"$ac_tmp/stdin" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir="$ac_dir"; as_fn_mkdir_p ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= ac_sed_dataroot=' /datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 $as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_sed_extra="$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s|@configure_input@|$ac_sed_conf_input|;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@top_build_prefix@&$ac_top_build_prefix&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ "$ac_tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} rm -f "$ac_tmp/stdin" case $ac_file in -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; :H) # # CONFIG_HEADER # if test x"$ac_file" != x-; then { $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" } >"$ac_tmp/config.h" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 $as_echo "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" mv "$ac_tmp/config.h" "$ac_file" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 fi else $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ || as_fn_error $? "could not create -" "$LINENO" 5 fi ;; esac done # for ac_tag as_fn_exit 0 _ACEOF ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || as_fn_exit 1 fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi GarminPlugin-0.3.23/src/configure.ac000066400000000000000000000154601232766717500172760ustar00rootroot00000000000000# -*- Autoconf -*- # Process this file with autoconf to produce a configure script. AC_MSG_NOTICE([Hinweis]) AC_MSG_WARN([Warnung]) AC_MSG_ERROR([Fehler]) AC_PREREQ([2.64]) AC_INIT(GarminPlugin, 0.2, garminplugin@andreas-diesner.de) AC_CONFIG_SRCDIR(main.cpp) # Checks for programs. AC_PROG_CXX AC_PROG_CC # Checks for libraries. PKG_PROG_PKG_CONFIG() PKG_CHECK_MODULES([LIBUSB], [libusb]) AC_SUBST(LIBUSB_CFLAGS) AC_SUBST(LIBUSB_LIBS) PKG_CHECK_MODULES([ZLIB], [zlib]) AC_SUBST(ZLIB_CFLAGS) AC_SUBST(ZLIB_LIBS) if pkg-config --exists tinyxml; then PKG_CHECK_MODULES([TINYXML], [tinyxml]) AC_SUBST(TINYXML_CFLAGS) AC_SUBST(TINYXML_LIBS) else # # Check for tinyxml (pgk info is not available on many distros) # AC_MSG_CHECKING([for tinyxml]) AC_ARG_WITH([tinyxml-libdir], AS_HELP_STRING([--with-tinyxml-libdir=DIR], [specify where to find tinyxml library (libtinyxml.so)]), [tinyxml_libdir=$withval], [tinyxml_libdir=""]) AC_ARG_WITH([tinyxml-incdir], AS_HELP_STRING([--with-tinyxml-incdir=DIR], [specify where to find tinyxml header files (tinyxml.h)]), [tinyxml_incdir=$withval], [tinyxml_incdir=""]) if test "x$tinyxml_incdir" != "x" ; then TINYXML_CFLAGS="-I$tinyxml_incdir" elif test -f "../tinyxml/tinyxml.h" ; then TINYXML_CFLAGS="-I../tinyxml/" elif test -f "/usr/include/tinyxml.h" ; then TINYXML_CFLAGS="-I/usr/include" elif test -f "tinyxml/tinyxml.h" ; then TINYXML_CFLAGS="-Itinyxml" else AC_MSG_RESULT([no]) AC_MSG_ERROR([Unable to find tinyxml header file (tinyxml.h). Try 'apt-get install tinyxml-dev' or use --with-tinyxml-incdir=DIR]) fi if test "x$tinyxml_libdir" != "x" ; then if test -f "$tinyxml_libdir/libtinyxml.so" ; then TINYXML_LIBS="$tinyxml_libdir/libtinyxml.so" else AC_MSG_RESULT([no]) AC_MSG_ERROR([Unable to find libtinyxml.so in $tinyxml_libdir. Is tinyxml compiled?]) fi elif test -f "/usr/lib64/libtinyxml.so" ; then TINYXML_LIBS="/usr/lib64/libtinyxml.so" elif test -f "/usr/lib/libtinyxml.so" ; then TINYXML_LIBS="/usr/lib/libtinyxml.so" elif test -f "../tinyxml/libtinyxml.so" ; then TINYXML_LIBS="../tinyxml/libtinyxml.so" elif test -f "../tinyxml/tinyxml.o" ; then TINYXML_LIBS="../tinyxml/tinyxml.o ../tinyxml/tinystr.o ../tinyxml/tinyxmlerror.o ../tinyxml/tinyxmlparser.o" else AC_MSG_RESULT([no]) AC_MSG_ERROR([Unable to find libtinyxml.so. Try 'apt-get install tinyxml' and compile source or use --with-tinyxml-libdir=DIR]) fi AC_SUBST(TINYXML_CFLAGS) AC_SUBST(TINYXML_LIBS) AC_MSG_RESULT([yes]) fi # # Check for GNU Crypt library # AC_ARG_WITH( [libgcrypt-prefix], [AC_HELP_STRING([--with-libgcrypt-prefix=DIR], [define libgcrypt prefix, default /usr])], , [with_libgcrypt_prefix="/usr" ] ) AC_MSG_CHECKING([for libgcrypt]) if ! test -x "${with_libgcrypt_prefix}/bin/libgcrypt-config"; then AC_MSG_ERROR([Cannot locate libgcrypt]) else AC_MSG_RESULT([found]) GCRYPT_CFLAGS=`"${with_libgcrypt_prefix}/bin/libgcrypt-config" --cflags` GCRYPT_LIBS=`"${with_libgcrypt_prefix}/bin/libgcrypt-config" --libs` AC_SUBST(GCRYPT_CFLAGS) AC_SUBST(GCRYPT_LIBS) fi # # Check GarminTools # AC_MSG_CHECKING([for garmintools]) AC_ARG_WITH([garmintools-libdir], AS_HELP_STRING([--with-garmintools-libdir=DIR], [specify where to find garmintools library (libgarmintools.a)]), [garmintools_libdir=$withval], [garmintools_libdir=""]) AC_ARG_WITH([garmintools-incdir], AS_HELP_STRING([--with-garmintools-incdir=DIR], [specify where to find garmintools header files (garmin.h)]), [garmintools_incdir=$withval], [garmintools_incdir=""]) if test "x$garmintools_incdir" != "x" ; then GARMINTOOLS_CPPFLAGS="-I$garmintools_incdir" elif test -f "/usr/include/garmin.h" ; then GARMINTOOLS_CPPFLAGS="-I/usr/include/" elif test -f "../garmintools/src/garmin.h" ; then GARMINTOOLS_CPPFLAGS="-I../garmintools/src/" elif test -f "../garmintools-read-only/src/garmin.h" ; then GARMINTOOLS_CPPFLAGS="-I../garmintools-read-only/src" elif test -f "garmintools-read-only/src/garmin.h" ; then GARMINTOOLS_CPPFLAGS="-Igarmintools-read-only/src" elif test -f "garmintools/src/garmin.h" ; then GARMINTOOLS_CPPFLAGS="-Igarmintools/src" else AC_MSG_RESULT([no]) AC_MSG_ERROR([Unable to find garmintools header files. Try 'svn export http://garmintools.googlecode.com/svn/trunk/ garmintools' or use --with-garmintools-incdir=DIR]) fi if test "x$garmintools_libdir" != "x" ; then if test -f "$garmintools_libdir/libgarmintools.a" ; then GARMINTOOLS_LDFLAGS="$garmintools_libdir/libgarmintools.a" elif test -f "$garmintools_libdir/libgarmintools.so" ; then GARMINTOOLS_LDFLAGS="$garmintools_libdir/libgarmintools.so" else AC_MSG_RESULT([no]) AC_MSG_ERROR([Unable to find libgarmintools.a in $garmintools_libdir. Is garmintools compiled?]) fi elif test -f "../garmintools/src/.libs/libgarmintools.a" ; then GARMINTOOLS_LDFLAGS="../garmintools/src/.libs/libgarmintools.a" elif test -f "garmintools/src/.libs/libgarmintools.a" ; then GARMINTOOLS_LDFLAGS="garmintools/src/.libs/libgarmintools.a" elif test -f "../garmintools-read-only/src/.libs/libgarmintools.a" ; then GARMINTOOLS_LDFLAGS="../garmintools-read-only/src/.libs/libgarmintools.a" elif test -f "garmintools-read-only/src/.libs/libgarmintools.a" ; then GARMINTOOLS_LDFLAGS="garmintools-read-only/src/.libs/libgarmintools.a" elif test -f "garmintools-read-only/libgarmintools.a" ; then GARMINTOOLS_LDFLAGS="garmintools-read-only/libgarmintools.a" elif test -f "../garmintools-read-only/libgarmintools.a" ; then GARMINTOOLS_LDFLAGS="../garmintools-read-only/libgarmintools.a" elif test -f "garmintools/libgarmintools.a" ; then GARMINTOOLS_LDFLAGS="garmintools/libgarmintools.a" elif test -f "../garmintools/libgarmintools.a" ; then GARMINTOOLS_LDFLAGS="../garmintools/libgarmintools.a" elif test -f "/usr/lib/libgarmintools.so" ; then GARMINTOOLS_LDFLAGS="/usr/lib/libgarmintools.so" elif test -f "/usr/lib64/libgarmintools.so" ; then GARMINTOOLS_LDFLAGS="/usr/lib64/libgarmintools.so" else AC_MSG_RESULT([no]) AC_MSG_ERROR([Unable to find libgarmintools.a. Try 'svn export http://garmintools.googlecode.com/svn/trunk/ garmintools' and compile source or use --with-garmintools-libdir=DIR]) fi AC_SUBST(GARMINTOOLS_CPPFLAGS) AC_SUBST(GARMINTOOLS_LDFLAGS) AC_MSG_RESULT([yes]) # Checks for header files. AC_CHECK_HEADERS([mntent.h stdlib.h unistd.h]) AC_CHECK_HEADERS([zipstub.h],[],[],[]) AC_CHECK_HEADERS([prtypes.h],[],[],[]) AC_MSG_RESULT([yes]) # Checks for typedefs, structures, and compiler characteristics. AC_HEADER_STDBOOL AC_TYPE_INT16_T AC_TYPE_INT32_T AC_TYPE_SIZE_T AC_TYPE_UINT16_T AC_TYPE_UINT32_T # Checks for library functions. AC_FUNC_GETMNTENT AC_CHECK_FUNCS([getmntent localtime_r memmove mkdir]) AC_CONFIG_HEADERS([config.h]) AC_CONFIG_FILES([Makefile]) AC_OUTPUT GarminPlugin-0.3.23/src/deviceManager.cpp000066400000000000000000000515341232766717500202500ustar00rootroot00000000000000/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */ /* * GarminPlugin * Copyright (C) Andreas Diesner 2010 * * GarminPlugin is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GarminPlugin is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #include "deviceManager.h" #include "log.h" #include #include #include "garminFilebasedDevice.h" #include "edge305Device.h" #include "gpsFunctions.h" #include #include DeviceManager::DeviceManager() :configuration(0) { } DeviceManager::~DeviceManager() { if (Log::enabledDbg()) Log::dbg("DeviceManager destructor"); while (gpsDeviceList.size() > 0) { GpsDevice *dev = gpsDeviceList.back(); gpsDeviceList.pop_back(); delete(dev); } } const std::string DeviceManager::getDevicesXML() { // \n\n\n\n TiXmlDocument doc; TiXmlDeclaration * decl = new TiXmlDeclaration( "1.0", "UTF-8", "no" ); TiXmlElement * devices = new TiXmlElement( "Devices" ); devices->SetAttribute("xmlns", "http://www.garmin.com/xmlschemas/PluginAPI/v1"); int deviceCount = 0; vector::iterator it=gpsDeviceList.begin(); while(it != gpsDeviceList.end()){ // Delete devices that are no longer available if( !(*it)->isDeviceAvailable() ){ delete *it; it = gpsDeviceList.erase(it); continue; } else { TiXmlElement *device = new TiXmlElement ( "Device" ); device->SetAttribute("DisplayName", (*it)->getDisplayName()); device->SetAttribute("Number", deviceCount); devices->LinkEndChild( device ); deviceCount++; } ++it; } if (Log::enabledDbg()) { std::ostringstream dbgOut; dbgOut << "getDeviceXML returns " << deviceCount << " devices"; Log::dbg(dbgOut.str()); } doc.LinkEndChild( decl ); doc.LinkEndChild( devices ); TiXmlPrinter printer; printer.SetIndent( "\t" ); doc.Accept( &printer ); string str = printer.Str(); return str; } void DeviceManager::startFindDevices() { this->findDeviceState=1; int code = pthread_create(&(this->threadId), NULL, DeviceManager::findDeviceThread, (void*)this); if (code != 0) { Log::err("Creation of findDevices thread failed!"); this->findDeviceState=0; return; // Not really able to continue :-( } } /*static*/ void * DeviceManager::findDeviceThread(void * pthis) { DeviceManager *mgm = (DeviceManager*)pthis; if (mgm!=NULL) { mgm->findDevices(); } return NULL; } void DeviceManager::findDevices() { // Remove active devices while (!gpsDeviceList.empty()) { GpsDevice *dev = gpsDeviceList.back(); gpsDeviceList.pop_back(); delete(dev); } bool scanMounted = true; bool searchGarmin = true; string backupPath = ""; if (this->configuration != NULL) { TiXmlElement * pRoot = this->configuration->FirstChildElement( "GarminPlugin" ); TiXmlElement * settings = NULL; TiXmlElement * mounted = NULL; TiXmlElement * ftools = NULL; TiXmlElement * backup = NULL; if (pRoot != NULL) { settings = pRoot->FirstChildElement("Settings"); } if (settings != NULL) { mounted = settings->FirstChildElement("ScanMounted"); ftools = settings->FirstChildElement("ForerunnerTools"); backup = settings->FirstChildElement("BackupWorkouts"); } else { Log::dbg("settings is null!"); } if (ftools != NULL) { searchGarmin = getXmlBoolAttribute(ftools, "enabled", true); } else { Log::dbg("Xml Element ForerunnerTools is null!"); } if (mounted != NULL) { scanMounted = getXmlBoolAttribute(mounted, "enabled", true); } else { Log::dbg("Xml Element ScanMounted is null!"); } if (backup != NULL) { bool doBackup = getXmlBoolAttribute(backup, "enabled", false); if (doBackup) { backupPath = backup->Attribute("path"); } else { backupPath = ""; } } else { Log::dbg("Xml Element BackupWorkouts is null!"); } } if (scanMounted) { FILE *mounts = NULL; struct mntent *ent = NULL; mounts = setmntent("/etc/mtab", "r"); Log::dbg("Searching for Edge705/Oregon300/..."); while ( (ent = getmntent(mounts)) != NULL ) { string filesystype = ent->mnt_type; string mountPath = ent->mnt_dir; if (filesystype.compare("vfat") == 0) { Log::dbg("Searching on ["+mountPath+"] ["+filesystype+"]"); GpsDevice *dev = createGarminDeviceFromPath(mountPath, NULL); if (dev != NULL) { dev->setBackupPath(backupPath); gpsDeviceList.push_back(dev); } } else { Log::dbg("Not searching on ["+mountPath+"] ["+filesystype+"] - wrong fstype."); } } } else { Log::dbg("Scanning for mounted devices is disabled!"); } string deviceName; if (searchGarmin) { // Search for garmin 305 deviceName = Edge305Device::getAttachedDeviceName(); if (deviceName.length() > 0) { // Found a device Log::dbg("Found device via garmintools: "+deviceName); Edge305Device * device = new Edge305Device(deviceName); device->setBackupPath(backupPath); gpsDeviceList.push_back(device); } } else { Log::dbg("Search via garmintools is disabled!"); } // Now create virtual devices devices from configuration if (this->configuration != NULL) { TiXmlElement * pRoot = this->configuration->FirstChildElement( "GarminPlugin" ); if (pRoot != NULL) { TiXmlElement * devices = pRoot->FirstChildElement("Devices"); TiXmlElement * device = devices->FirstChildElement("Device"); while ( device != NULL ) { bool deviceEnabled = getXmlBoolAttribute(device, "enabled", true);; string storagePath = ""; string storageCmd = ""; string fitnessPath = ""; string gpxPath = ""; TiXmlElement * dir = device->FirstChildElement("StoragePath"); if ((dir) && (dir->GetText() != NULL)) { storagePath = dir->GetText(); } TiXmlElement * cmd = device->FirstChildElement("StorageCommand"); if ((cmd) && (cmd->GetText() != NULL)) { storageCmd = cmd->GetText(); } TiXmlElement * fitness = device->FirstChildElement("FitnessDataPath"); if ((fitness) && (fitness->GetText() != NULL)) { fitnessPath = fitness->GetText(); } TiXmlElement * gpxData = device->FirstChildElement("GpxDataPath"); if ((gpxData) && (gpxData->GetText() != NULL)) { gpxPath = gpxData->GetText(); } GpsDevice * currentDevice = NULL; TiXmlElement * name = device->FirstChildElement("Name"); if ((!deviceEnabled) && (Log::enabledDbg())) { if ((name!=NULL) && (name->GetText() != NULL)) { string outputName = name->GetText(); Log::dbg("Found disabled device "+outputName+" in configuration."); } else { Log::dbg("Found disabled device with no name in configuration."); } } if ((deviceEnabled) && (name!=NULL)) { if (name->GetText() != NULL) { string devName = name->GetText(); for(unsigned int i=0; i < gpsDeviceList.size(); i++) { // Device exists, and is configured in configuration if (gpsDeviceList[i]->getDisplayName().compare(name->GetText()) == 0) { currentDevice = gpsDeviceList[i]; } } if (currentDevice == NULL) { // no device found Log::dbg("Creating device "+devName+" from configuration."); currentDevice = createGarminDeviceFromPath(storagePath, NULL); if (currentDevice == NULL) { if (Log::enabledDbg()) { Log::dbg("Device from configuration - no XML found for "+devName); } //TODO: Create a pseudo configuration file for this device TiXmlDocument *doc = createMinimalGarminConfig(devName); if (fitnessPath.length() > 0) { doc = addTcxProfile(doc, fitnessPath); } if (gpxPath.length() > 0) { doc = addGpxProfile(doc, gpxPath); } else if ((gpxPath.length() == 0) && (fitnessPath.length() == 0) && (storageCmd.length() > 0)) { // Probably an old configuration. Required to add GpxProfile with empty path doc = addGpxProfile(doc, "."); } currentDevice = createGarminDeviceFromPath(storagePath, doc); delete(doc); } else { Log::dbg("Created device "+devName+" from existing GarminDevice.xml configuration."); } if (currentDevice != NULL) { currentDevice->setBackupPath(backupPath); gpsDeviceList.push_back(currentDevice); } } else { Log::dbg("Ignoring device "+devName+" from configuration - existing device with same name exists."); } } } if ((storageCmd.length() > 0) && (currentDevice!=NULL)) { Log::dbg("Setting Storage Command for "+currentDevice->getDisplayName()+": "+storageCmd); currentDevice->setStorageCommand(storageCmd); } device = device->NextSiblingElement( "Device" ); } } } std::ostringstream infoOut; infoOut << "Number of devices found: " << gpsDeviceList.size(); Log::info(infoOut.str()); this->findDeviceState = 3; } void DeviceManager::setConfiguration(TiXmlDocument * config) { // Memory will be freed from configManager this->configuration = config; } void DeviceManager::cancelFindDevices() { Log::dbg("Cancel findDevice thread in DeviceManager"); if (this->threadId > 0) { pthread_cancel(this->threadId); this->threadId = 0; } this->findDeviceState = 0; } int DeviceManager::finishedFindDevices() { return this->findDeviceState; } GpsDevice * DeviceManager::getGpsDevice(int number) { if (number < (int)gpsDeviceList.size()) { return gpsDeviceList[number]; } return NULL; } bool DeviceManager::getXmlBoolAttribute(TiXmlElement *xmlElement, string attrName, bool defaultValue) { if (xmlElement == NULL) { return defaultValue; } const char * boolStringValue = xmlElement->Attribute(attrName.c_str()); if (boolStringValue != NULL) { string trueFalseStr = boolStringValue; transform(trueFalseStr.begin(), trueFalseStr.end(), trueFalseStr.begin(), ::tolower ); if ((trueFalseStr == "yes") || (trueFalseStr == "true") || (trueFalseStr == "1")) { return true; } else if ((trueFalseStr == "no") || (trueFalseStr == "false") || (trueFalseStr == "0")) { return false; } else { return defaultValue; } } else { return defaultValue; } } GpsDevice * DeviceManager::createGarminDeviceFromPath(string devicepath, TiXmlDocument *doc) { bool deleteXmlDoc = false; GpsDevice * device = NULL; if (doc == NULL) { DIR *dp; struct dirent *dirp; if((dp = opendir(devicepath.c_str())) == NULL) { Log::err("Error opening directory: "+devicepath); return NULL; } bool garminDirFound = false; string dirname = ""; while ((dirp = readdir(dp)) != NULL) { dirname = string(dirp->d_name); if (GpsFunctions::iequals(dirname, "Garmin")) { garminDirFound = true; break; } } closedir(dp); if (garminDirFound) { string basePath = devicepath + "/" + dirname; string fullPath = basePath +"/GarminDevice.xml"; // Ignore case search for file GarminDevice.xml if((dp = opendir(basePath.c_str())) != NULL) { while ((dirp = readdir(dp)) != NULL) { string entry = string(dirp->d_name); if (GpsFunctions::iequals(entry, "GarminDevice.xml")) { fullPath = basePath + "/" + entry; break; } } closedir(dp); } doc = new TiXmlDocument(fullPath); deleteXmlDoc = true; if (!doc->LoadFile()) { deleteXmlDoc = false; delete(doc); doc = NULL; Log::info("Unable to load xml file "+fullPath); } } else { Log::dbg("Garmin directory not found at "+devicepath); } } if (doc != NULL) { TiXmlElement * node = doc->FirstChildElement("Device"); if (node!=NULL) { node = node->FirstChildElement("Model"); } if (node!=NULL) { node = node->FirstChildElement("Description"); } if (node!=NULL) { // Perfect, seems to be a Garmin Device string deviceName = node->GetText(); GarminFilebasedDevice *fileDev = new GarminFilebasedDevice(); fileDev->setBaseDirectory(devicepath); fileDev->setDeviceDescription(doc); fileDev->setDisplayName(deviceName); device = fileDev; Log::dbg("Found "+deviceName+" at "+devicepath); } else { Log::err("GarminDevice.xml has unexpected format!"); } } if (deleteXmlDoc) { delete(doc); doc = NULL; } return device; } TiXmlDocument * DeviceManager::createMinimalGarminConfig(string name) { TiXmlDocument *doc = new TiXmlDocument(); TiXmlDeclaration * decl = new TiXmlDeclaration( "1.0", "UTF-8", "no" ); doc->LinkEndChild( decl ); /**/ TiXmlElement * device = new TiXmlElement( "Device" ); device->SetAttribute("xmlns", "http://www.garmin.com/xmlschemas/GarminDevice/v2"); device->SetAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance"); device->SetAttribute("xsi:schemaLocation", "http://www.garmin.com/xmlschemas/GarminDevice/v2 http://www.garmin.com/xmlschemas/GarminDevicev2.xsd"); doc->LinkEndChild( device ); /* 006-B0000-00 0 An SD Card */ TiXmlElement * model = new TiXmlElement( "Model" ); TiXmlElement * partnumber = new TiXmlElement( "PartNumber" ); partnumber->LinkEndChild(new TiXmlText("006-B0000-00")); TiXmlElement * version = new TiXmlElement( "SoftwareVersion" ); version->LinkEndChild(new TiXmlText("0")); TiXmlElement * descr = new TiXmlElement( "Description" ); descr->LinkEndChild(new TiXmlText(name)); model->LinkEndChild(partnumber); model->LinkEndChild(version); model->LinkEndChild(descr); device->LinkEndChild( model ); /* 4294967295 */ TiXmlElement * id = new TiXmlElement( "Id" ); id->LinkEndChild(new TiXmlText("4294967295")); device->LinkEndChild(id); /* Removable Disk (F:\\)*/ TiXmlElement * dispName = new TiXmlElement( "DisplayName" ); dispName->LinkEndChild(new TiXmlText(name)); device->LinkEndChild(dispName); TiXmlElement * massStorage = new TiXmlElement( "MassStorageMode" ); device->LinkEndChild(massStorage); return doc; } TiXmlDocument * DeviceManager::addTcxProfile(TiXmlDocument * doc, string tcxpath) { /* FitnessHistory Garmin tcx InputOutput */ if (doc == NULL) { return NULL; } TiXmlElement * massStorage=NULL; TiXmlElement * node = doc->FirstChildElement("Device"); if (node!=NULL) { massStorage = node->FirstChildElement("MassStorageMode"); } if (massStorage == NULL) { return doc; } TiXmlElement * dataTypes = new TiXmlElement( "DataType" ); massStorage->LinkEndChild(dataTypes); TiXmlElement * name = new TiXmlElement( "Name" ); name->LinkEndChild(new TiXmlText("FitnessHistory")); dataTypes->LinkEndChild(name); TiXmlElement * file = new TiXmlElement( "File" ); dataTypes->LinkEndChild(file); TiXmlElement * loc = new TiXmlElement( "Location" ); file->LinkEndChild(loc); TiXmlElement * filePath = new TiXmlElement( "Path" ); filePath->LinkEndChild(new TiXmlText(tcxpath)); loc->LinkEndChild(filePath); TiXmlElement * fileEx = new TiXmlElement( "FileExtension" ); fileEx->LinkEndChild(new TiXmlText("tcx")); loc->LinkEndChild(fileEx); TiXmlElement * transferDir = new TiXmlElement( "TransferDirection" ); transferDir->LinkEndChild(new TiXmlText("InputOutput")); file->LinkEndChild(transferDir); return doc; } TiXmlDocument * DeviceManager::addGpxProfile(TiXmlDocument * doc, string gpxpath) { /* GPSData http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd Garmin gpx InputToUnit */ if (doc == NULL) { return NULL; } TiXmlElement * massStorage=NULL; TiXmlElement * node = doc->FirstChildElement("Device"); if (node!=NULL) { massStorage = node->FirstChildElement("MassStorageMode"); } if (massStorage == NULL) { return doc; } TiXmlElement * dataTypes = new TiXmlElement( "DataType" ); massStorage->LinkEndChild(dataTypes); TiXmlElement * name = new TiXmlElement( "Name" ); name->LinkEndChild(new TiXmlText("GPSData")); dataTypes->LinkEndChild(name); TiXmlElement * file = new TiXmlElement( "File" ); dataTypes->LinkEndChild(file); TiXmlElement * spec = new TiXmlElement( "Specification" ); file->LinkEndChild(spec); TiXmlElement * identifier = new TiXmlElement( "Identifier" ); identifier->LinkEndChild(new TiXmlText("http://www.topografix.com/GPX/1/1")); spec->LinkEndChild(identifier); TiXmlElement * docu = new TiXmlElement( "Documentation" ); docu->LinkEndChild(new TiXmlText("http://www.topografix.com/GPX/1/1/gpx.xsd")); spec->LinkEndChild(docu); TiXmlElement * loc = new TiXmlElement( "Location" ); file->LinkEndChild(loc); TiXmlElement * filePath = new TiXmlElement( "Path" ); filePath->LinkEndChild(new TiXmlText(gpxpath)); loc->LinkEndChild(filePath); TiXmlElement * fileEx = new TiXmlElement( "FileExtension" ); fileEx->LinkEndChild(new TiXmlText("gpx")); loc->LinkEndChild(fileEx); TiXmlElement * transferDir = new TiXmlElement( "TransferDirection" ); transferDir->LinkEndChild(new TiXmlText("InputToUnit")); file->LinkEndChild(transferDir); return doc; } GarminPlugin-0.3.23/src/deviceManager.h000066400000000000000000000102001232766717500176760ustar00rootroot00000000000000/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */ /* * GarminPlugin * Copyright (C) Andreas Diesner 2010 * * GarminPlugin is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GarminPlugin is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #ifndef DEVICEMANAGER_H_INCLUDED #define DEVICEMANAGER_H_INCLUDED #include #include #include #include "gpsDevice.h" #include "tinyxml.h" using namespace std; class DeviceManager { public: DeviceManager(); ~DeviceManager(); /** * Returns an xml string that describes all attached gps devices * Devices that return false on isDeviceAvailable() will not be listed * @return string with xml description */ const std::string getDevicesXML(); /** * Triggers a search for new devices. */ void startFindDevices(); /** * Cancels a search for new devices. */ void cancelFindDevices(); /** * Checks if the search for devices has finished * @return returns 1 if search was finished */ int finishedFindDevices(); /** * Returns an instance of an attached GPS device * @param number that identifies the device (listed in getDevicesXML() * @return returns the device or null */ GpsDevice * getGpsDevice(int number); /** * Sets the configuration that has been loaded from disk and initializes the attached devices * @param XML document with configuration */ void setConfiguration(TiXmlDocument * ); private: /** * Stores all configured devices */ vector gpsDeviceList; TiXmlDocument * configuration; /** * Searches for an attribute with the name attrName in xmlElement * If attribute is found, it is checked for true/false values * If not exists or unknown value, defaultValue will be returned */ bool getXmlBoolAttribute(TiXmlElement * xmlElement, string attrName, bool defaultValue); /** * Creates a device if configuration is given or Garmin/GarminDevice.xml exists * @param path - Path on disk * @param doc - if null a Garmin/GarminDevice.xml must exist on the given path. * @return Returns the created device */ GpsDevice * createGarminDeviceFromPath(string path, TiXmlDocument *doc); /** * Creates a minimalistic garmin device configuration * @param name - device name * @return Xml document (in the format of GarminDevice.xml) */ TiXmlDocument * createMinimalGarminConfig(string name); /** * Adds a tcx profile for read and write to a configuration * @param doc - must contain an already valid GarminDevice.xml format * @param tcxpath - relative path to tcx data * @return Xml document (in the format of GarminDevice.xml) */ TiXmlDocument * addTcxProfile(TiXmlDocument * doc, string tcxpath); /** * Adds a gpx profile for read and write to a configuration * @param doc - must contain an already valid GarminDevice.xml format * @param gpxpath - relative path to gpx data * @return Xml document (in the format of GarminDevice.xml) */ TiXmlDocument * addGpxProfile(TiXmlDocument * doc, string gpxpath); /** * Stores the thread id */ pthread_t threadId; /** * Stores the status of the thread * 0 = idle 1 = working 2 = waiting 3 = finished */ int findDeviceState; /** * Thread gets called to search for devices */ static void * findDeviceThread(void * pthis); /** * Thread that actually searches for a device */ void findDevices(); }; #endif // DEVICEMANAGER_H_INCLUDED GarminPlugin-0.3.23/src/edge305Device.cpp000066400000000000000000001213331232766717500177650ustar00rootroot00000000000000/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */ /* * GarminPlugin * Copyright (C) Andreas Diesner 2010 * * GarminPlugin is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GarminPlugin is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #include "gpsDevice.h" #include "log.h" #include "edge305Device.h" #include Edge305Device::Edge305Device() : GpsDevice("Edge305") , transferSuccessful(false) , runType(0) , fitnessData(NULL) { } Edge305Device::Edge305Device(string name) : GpsDevice(name) , transferSuccessful(false) , runType(0) , fitnessData(NULL) { } Edge305Device::~Edge305Device() { if (this->fitnessData != NULL) { delete(this->fitnessData); this->fitnessData = NULL; } } int Edge305Device::startReadFitnessData(string dataTypeName) { if (Log::enabledDbg()) Log::dbg("Starting thread to read from garmin device: "+this->displayName); this->workType = READFITNESS; this->threadState = 1; if (startThread()) { return 1; } return 0; } int Edge305Device::finishReadFitnessData() { return getThreadState(); } void Edge305Device::doWork() { if (this->workType == WRITEGPX) { Log::err("Write GPX to Edge305 not yet implemented!"); } else if (this->workType == READFITNESS) { this->readFitnessDataFromDevice(true, ""); } else if (this->workType == READFITNESSDIR) { this->readFitnessDataFromDevice(false, ""); } else if (this->workType == READFITNESSDETAIL) { this->readFitnessDataFromDevice(true, readFitnessDetailId); } else if (this->workType == READFROMGPS) { this->readGpxDataFromDevice(); } else { Log::err("Work Type not implemented!"); } } void Edge305Device::readGpxDataFromDevice() { if (Log::enabledDbg()) { Log::dbg("Thread readGpxData started"); } /* Thread-Status 0 = idle 1 = working 2 = waiting 3 = finished */ lockVariables(); this->threadState = 1; this->transferSuccessful = false; unlockVariables(); string gpxDataXml = readGpxData(); lockVariables(); this->threadState = 3; this->gpxDataGpsXml = gpxDataXml; unlockVariables(); if (Log::enabledDbg()) { Log::dbg("Thread readFitnessData finished"); } } void Edge305Device::readFitnessDataFromDevice(bool readTrackData, string fitnessDetailId) { Log::dbg("Thread readFitnessData started"); /* Thread-Status 0 = idle 1 = working 2 = waiting 3 = finished */ lockVariables(); this->threadState = 1; this->transferSuccessful = false; unlockVariables(); string fitnessDataXml = readFitnessData(readTrackData, fitnessDetailId); // Write to backup directory if needed if ((readTrackData) && (fitnessDetailId.length()>0)) { time_t startTime = GpsFunctions::getStartTimestampFromXml(fitnessDataXml); backupWorkout(fitnessDataXml, "tcx", startTime); } lockVariables(); this->threadState = 3; fitnessDataTcdXml = fitnessDataXml; unlockVariables(); if (Log::enabledDbg()) { Log::dbg("Thread readFitnessData finished"); } } string Edge305Device::getFitnessData() { return fitnessDataTcdXml; } string Edge305Device::readGpxData() { if (this->fitnessData == NULL) { this->fitnessData = readFitnessDataFromGarmin(); } if (this->fitnessData != NULL) { transferSuccessful = true; TiXmlDocument * output = this->fitnessData->getGpxDocument(); TiXmlPrinter printer; printer.SetIndent( " " ); output->Accept( &printer ); string fitnessXml = printer.Str(); delete(output); return fitnessXml; } else { transferSuccessful = false; return ""; } } string Edge305Device::readFitnessData(bool readTrackData, string fitnessDetailId) { if (this->fitnessData == NULL) { this->fitnessData = readFitnessDataFromGarmin(); } if (this->fitnessData != NULL) { transferSuccessful = true; TiXmlDocument * output = this->fitnessData->getTcxDocument(readTrackData, fitnessDetailId); TiXmlPrinter printer; printer.SetIndent( " " ); output->Accept( &printer ); string fitnessXml = printer.Str(); delete(output); return fitnessXml; } else { transferSuccessful = false; return ""; } } TcxBase * Edge305Device::readFitnessDataFromGarmin() { TcxBase * fitData = NULL; garmin_unit garmin; garmin_data * data0; garmin_data * data1; garmin_data * data2; garmin_list * runs = NULL; garmin_list * laps = NULL; garmin_list * tracks = NULL; if ( garmin_init(&garmin,0) != 0 ) { Log::dbg("Extracting data from Garmin "+this->displayName); garmin_data * fitnessdata = garmin_get(&garmin,GET_RUNS); //garmin_data * fitnessdata = garmin_load("/workout/2010/02/20100227T152346.gmn"); //Testing only if (fitnessdata != NULL ) { Log::dbg("Received data from Garmin, processing data..."); fitData = new TcxBase(); // Add author information TcxAuthor * author = new TcxAuthor(); *(fitData)<data != NULL) && data1 != NULL && (laps = (garmin_list*)data1->data) != NULL && data2 != NULL && (tracks = (garmin_list*)data2->data) != NULL ) { if (data0->type == data_Dlist) { runs = (garmin_list*)(data0->data); } else { runs = garmin_list_append(NULL,data0); } *(fitData) << printActivities(runs, laps, tracks, garmin); if (data0->type != data_Dlist) { garmin_free_list_only(runs); } Log::dbg("Done processing data..."); } else { Log::err("Some of the data read from the device was null (runs/laps/tracks)"); } } else { Log::err("Unable to extract any data!"); } garmin_free_data(fitnessdata); garmin_close(&garmin); } else { Log::err("Unable to open garmin device. Is it connected?"); } return fitData; } TcxActivities * Edge305Device::printActivities(garmin_list * runList, garmin_list * lap, garmin_list * track, const garmin_unit garmin) { TcxActivities * activities = new TcxActivities(); garmin_list_node * runNode = runList->head; while (runNode != NULL) { garmin_data *run = runNode->data; if ((run != NULL) && (run->data != NULL)) { uint32 track_index; uint32 first_lap_index; uint32 last_lap_index; uint8 sport_type; if ( _get_run_track_lap_info(run,&track_index,&first_lap_index,&last_lap_index,&sport_type) != 0 ) { if (Log::enabledDbg()) { stringstream ss; ss << "This run goes from lap id " << first_lap_index << " to " << last_lap_index << " with track id: " << track_index; Log::dbg(ss.str()); } TcxActivity * singleActivity = new TcxActivity(""); *activities << singleActivity; *singleActivity << getCreator(garmin); switch (sport_type) { case D1000_running: this->runType = 1; singleActivity->setSportType(TrainingCenterDatabase::Running); break; case D1000_biking: singleActivity->setSportType(TrainingCenterDatabase::Biking); this->runType = 0; break; default: singleActivity->setSportType(TrainingCenterDatabase::Other); this->runType = 2; break; } bool firstLap = true; for ( garmin_list_node * n = lap->head; n != NULL; n = n->next ) { D1011 * lapData = NULL; D1001 * lapData301 = NULL; if (n->data->type == data_D1011) { // Edge 305 uses this lapData = (D1011*)n->data->data; } else if (n->data->type == data_D1015) { // Forerunner 205 uses this lapData = (D1011*)n->data->data; // cast to wrong type - is safe because D1015 is identical, just a little bit longer } else if (n->data->type == data_D1001) { // Forerunner 301 uses this lapData301 = (D1001*)n->data->data; } else { stringstream ss; ss << "Unknown lap type is: " << n->data->type; Log::dbg(ss.str()); } if ((lapData != NULL) || (lapData301 != NULL)) { uint32 current_lap_index = 0; time_type current_start_time = 0; if (lapData != NULL) { current_lap_index = lapData->index; current_start_time = lapData->start_time; } if (lapData301 != NULL) { current_lap_index = lapData301->index; current_start_time = lapData301->start_time; } if ((current_lap_index >= first_lap_index) && (current_lap_index <= last_lap_index)) { uint32 startTimeNextLap = getNextLapStartTime(n); TcxLap * singleLap = NULL; if (lapData != NULL) { singleLap = getLapHeader(lapData); } else { singleLap = getLapHeader(lapData301); } int pointCount = 0; if (Log::enabledDbg()) { stringstream ss; ss << "Creating new lap: " << current_lap_index ; Log::dbg(ss.str()); } *singleActivity<< singleLap; if (firstLap) { singleActivity->setId(GpsFunctions::print_dtime(current_start_time)); firstLap = false; } uint32 currentTrackIndex = 0; TcxTrack * singleTrack = NULL; for ( garmin_list_node * t = track->head; t != NULL; t = t->next ) { if (t->data->type == data_D311) { D311 * d311 = (D311 *)t->data->data; currentTrackIndex = d311->index; if (d311->index == track_index) { singleTrack = new TcxTrack(); *singleLap << singleTrack; } } else if (t->data->type == data_D304) { D304 * trackpointData = (D304 *)t->data->data; if (currentTrackIndex == track_index) { if (singleTrack != NULL) { if (trackpointData->time >= current_start_time) { if (startTimeNextLap > 0) { if (trackpointData->time < startTimeNextLap) { (*singleTrack) << getTrackPoint(trackpointData); pointCount++; } } else { (*singleTrack) << getTrackPoint(trackpointData); pointCount++; } } } else { Log::err("Current track is null - but track index matches !?"); } } } else if (t->data->type == data_D303) { // Used by forerunner301 D303 * trackpointData = (D303 *)t->data->data; if (currentTrackIndex == track_index) { if (singleTrack != NULL) { if (trackpointData->time >= current_start_time) { if (startTimeNextLap > 0) { if (trackpointData->time < startTimeNextLap) { (*singleTrack) << getTrackPoint(trackpointData); pointCount++; } } else { (*singleTrack) << getTrackPoint(trackpointData); pointCount++; } } } else { Log::err("Current track is null - but track index matches !?"); } } } else { stringstream ss; ss << "Unknown track point: " << t->data->type; Log::dbg(ss.str()); } } if (Log::enabledDbg()) { stringstream ss; ss << "Point count for this lap: " << pointCount; Log::dbg(ss.str()); } } } else { Log::dbg("Unknown Lap Type found in data"); } } if (Log::enabledDbg()) { Log::dbg("Added Lap: " + singleActivity->getOverview()); } } } else { Log::dbg("Not a run :-("); } runNode = runNode->next; } return activities; } TcxCreator * Edge305Device::getCreator(const garmin_unit garmin) { TcxCreator *thisCreator = new TcxCreator(); thisCreator->setName(this->displayName); stringstream ss; ss << garmin.id; thisCreator->setUnitId(ss.str()); ss.str(""); ss << garmin.product.product_id; thisCreator->setProductId(ss.str()); int major = garmin.product.software_version / 100; int minor = garmin.product.software_version % 100; ss.str(""); ss << major; stringstream ss2; ss2 << minor; thisCreator->setVersion(ss.str(),ss2.str()); thisCreator->setBuild("0","0"); return thisCreator; } TcxLap * Edge305Device::getLapHeader(D1011 * lapData) { TcxLap * singleLap = new TcxLap(); //TODO: Think about letting TcxLap calculate that itself uint32 dur = lapData->total_time; stringstream ss; int hun = dur % 100; dur -= hun; dur /= 100; ss << dur << "." << hun ; singleLap->setTotalTimeSeconds(ss.str()); ss.str(""); ss << lapData->total_dist; singleLap->setDistanceMeters(ss.str()); ss.str(""); ss << lapData->max_speed; singleLap->setMaximumSpeed(ss.str()); ss.str(""); ss << lapData->calories; singleLap->setCalories(ss.str()); if ( lapData->avg_heart_rate != 0 ) { ss.str(""); ss << (unsigned int)(lapData->avg_heart_rate); singleLap->setAverageHeartRateBpm(ss.str()); } if ( lapData->max_heart_rate != 0 ) { ss.str(""); ss << (unsigned int)(lapData->max_heart_rate); singleLap->setMaximumHeartRateBpm(ss.str()); } if (lapData->intensity == D1001_active) { singleLap->setIntensity(TrainingCenterDatabase::Active); } else { singleLap->setIntensity(TrainingCenterDatabase::Resting); } if (this->runType == 1) { singleLap->setCadenceSensorType(TrainingCenterDatabase::Footpod); } else { singleLap->setCadenceSensorType(TrainingCenterDatabase::Bike); } if ( lapData->avg_cadence != 0xff ) { ss.str(""); ss << (unsigned int)(lapData->avg_cadence); singleLap->setCadence(ss.str()); } switch (lapData->intensity) { case D1011_manual: singleLap->setTriggerMethod(TrainingCenterDatabase::Manual); break; case D1011_distance: singleLap->setTriggerMethod(TrainingCenterDatabase::Distance); break; case D1011_location: singleLap->setTriggerMethod(TrainingCenterDatabase::Location); break; case D1011_time: singleLap->setTriggerMethod(TrainingCenterDatabase::Time); break; case D1011_heart_rate: singleLap->setTriggerMethod(TrainingCenterDatabase::HeartRate); break; } return singleLap; } TcxLap * Edge305Device::getLapHeader(D1001 * lapData) { TcxLap * singleLap = new TcxLap(); //TODO: Think about letting TcxLap calculate that itself uint32 dur = lapData->total_time; stringstream ss; int hun = dur % 100; dur -= hun; dur /= 100; ss << dur << "." << hun ; singleLap->setTotalTimeSeconds(ss.str()); ss.str(""); ss << lapData->total_dist; singleLap->setDistanceMeters(ss.str()); ss.str(""); ss << lapData->max_speed; singleLap->setMaximumSpeed(ss.str()); ss.str(""); ss << lapData->calories; singleLap->setCalories(ss.str()); if ( lapData->avg_heart_rate != 0 ) { ss.str(""); ss << (unsigned int)(lapData->avg_heart_rate); singleLap->setAverageHeartRateBpm(ss.str()); } if ( lapData->max_heart_rate != 0 ) { ss.str(""); ss << (unsigned int)(lapData->max_heart_rate); singleLap->setMaximumHeartRateBpm(ss.str()); } if (lapData->intensity == D1001_active) { singleLap->setIntensity(TrainingCenterDatabase::Active); } else { singleLap->setIntensity(TrainingCenterDatabase::Resting); } if (this->runType == 1) { singleLap->setCadenceSensorType(TrainingCenterDatabase::Footpod); } else { singleLap->setCadenceSensorType(TrainingCenterDatabase::Bike); } return singleLap; } TcxTrackpoint * Edge305Device::getTrackPoint ( D304 * p) { TcxTrackpoint * singlePoint = new TcxTrackpoint(GpsFunctions::print_dtime(p->time)); if (( p->posn.lat != 0x7fffffff ) && ( p->posn.lon != 0x7fffffff )) { stringstream lat; lat.precision(10); // default 4 decimal chars which is not enough stringstream lon; lon.precision(10); // default 4 decimal chars which is not enough lat << SEMI2DEG(p->posn.lat); lon << SEMI2DEG(p->posn.lon); singlePoint->setPosition(lat.str(), lon.str()); } stringstream ss; if (p->alt < 1.0e24 ) { ss << p->alt; singlePoint->setAltitudeMeters(ss.str()); } if (p->distance < 1.0e24 ) { ss.str(""); ss << p->distance; singlePoint->setDistanceMeters(ss.str()); } if ( p->heart_rate != 0 ) { ss.str(""); ss << (unsigned int)(p->heart_rate); singlePoint->setHeartRateBpm(ss.str()); } if (this->runType == 0) { singlePoint->setCadenceSensorType(TrainingCenterDatabase::Bike); } else { singlePoint->setCadenceSensorType(TrainingCenterDatabase::Footpod); } if ( p->cadence != 0xff ) { ss.str(""); ss << (unsigned int)(p->cadence); singlePoint->setCadence(ss.str()); } if ( p->sensor != 0 ) { singlePoint->setSensorState(TrainingCenterDatabase::Present); } else { singlePoint->setSensorState(TrainingCenterDatabase::Absent); } return singlePoint; } TcxTrackpoint * Edge305Device::getTrackPoint ( D303 * p) { TcxTrackpoint * singlePoint = new TcxTrackpoint(GpsFunctions::print_dtime(p->time)); if (( p->posn.lat != 0x7fffffff ) && ( p->posn.lon != 0x7fffffff )) { stringstream lat; lat.precision(10); // default 4 decimal chars which is not enough stringstream lon; lon.precision(10); // default 4 decimal chars which is not enough lat << SEMI2DEG(p->posn.lat); lon << SEMI2DEG(p->posn.lon); singlePoint->setPosition(lat.str(), lon.str()); } stringstream ss; if (p->alt < 1.0e24 ) { ss << p->alt; singlePoint->setAltitudeMeters(ss.str()); } if ( p->heart_rate != 0 ) { ss.str(""); ss << (unsigned int)(p->heart_rate); singlePoint->setHeartRateBpm(ss.str()); } return singlePoint; } /*static*/ string Edge305Device::getAttachedDeviceName() { garmin_unit garmin; string deviceName = ""; Log::dbg("Searching for garmin devices like Edge 305/Forerunner 305..."); if ( garmin_init(&garmin,0) != 0 ) { if (garmin.product.product_description != NULL) // Vista HCx also gets detected by this, but returns NULL values { deviceName = filterDeviceName((string)((char*)garmin.product.product_description)); Log::dbg("Found garmin device: "+deviceName); } garmin_close(&garmin); } return deviceName; } string Edge305Device::getDeviceDescription() const { if (Log::enabledDbg()) Log::dbg("GpsDevice::getDeviceDescription() "+this->displayName); /* 006-B0450-00 320 EDGE305 Software Version 3.20 3305091776 Your name GPSData http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd GPX InputOutput FitnessHistory http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2 http://www.garmin.com/xmlschemas/TrainingCenterDatabasev2.xsd TCX OutputFromUnit FitnessUserProfile http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2 http://www.garmin.com/xmlschemas/TrainingCenterDatabasev2.xsd UserProfile TCX InputOutput FitnessCourses http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2 http://www.garmin.com/xmlschemas/TrainingCenterDatabasev2.xsd TCX InputOutput FitnessWorkouts http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2 http://www.garmin.com/xmlschemas/TrainingCenterDatabasev2.xsd TCX InputOutput 006-B0450-00 0 0 Missing 006-B0478-00 0 0 Missing 918 5 0 0 Missing 006-B0450-00 006-B0450-00 true true 14 3 20 EDGE305 006-B0450-00 006-B0450-00 true 246 0 0 Missing 006-B0478-00 006-B0478-00 true true */ garmin_unit garmin; if ( garmin_init(&garmin,0) != 0 ) { garmin_close(&garmin); } else { Log::err("Opening of garmin device failed. No longer attached!?"); return ""; } TiXmlDocument doc; TiXmlDeclaration * decl = new TiXmlDeclaration( "1.0", "UTF-8", "no" ); doc.LinkEndChild( decl ); /**/ TiXmlElement * device = new TiXmlElement( "Device" ); device->SetAttribute("xmlns", "http://www.garmin.com/xmlschemas/GarminDevice/v2"); device->SetAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance"); device->SetAttribute("xsi:schemaLocation", "http://www.garmin.com/xmlschemas/GarminDevice/v2 http://www.garmin.com/xmlschemas/GarminDevicev2.xsd"); doc.LinkEndChild( device ); /* 006-B0450-00 320 EDGE305 Software Version 3.20 */ TiXmlElement * model = new TiXmlElement( "Model" ); TiXmlElement * partnumber = new TiXmlElement( "PartNumber" ); partnumber->LinkEndChild(new TiXmlText("006-B0450-00")); TiXmlElement * version = new TiXmlElement( "SoftwareVersion" ); std::stringstream ss; ss << garmin.product.software_version; version->LinkEndChild(new TiXmlText( ss.str() )); TiXmlElement * descr = new TiXmlElement( "Description" ); descr->LinkEndChild(new TiXmlText(this->displayName)); model->LinkEndChild(partnumber); model->LinkEndChild(version); model->LinkEndChild(descr); device->LinkEndChild( model ); /* 3333333333 */ TiXmlElement * id = new TiXmlElement( "Id" ); ss.str(""); // empty stringstream ss << garmin.id; id->LinkEndChild(new TiXmlText(ss.str())); device->LinkEndChild(id); /* Your name*/ TiXmlElement * dispName = new TiXmlElement( "DisplayName" ); dispName->LinkEndChild(new TiXmlText(this->displayName)); device->LinkEndChild(dispName); TiXmlElement * massStorage = new TiXmlElement( "MassStorageMode" ); device->LinkEndChild(massStorage); /* GPSData http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd GPX InputOutput */ TiXmlElement * dataTypes = new TiXmlElement( "DataType" ); massStorage->LinkEndChild(dataTypes); TiXmlElement * name = new TiXmlElement( "Name" ); name->LinkEndChild(new TiXmlText("GPSData")); dataTypes->LinkEndChild(name); TiXmlElement * file = new TiXmlElement( "File" ); dataTypes->LinkEndChild(file); TiXmlElement * spec = new TiXmlElement( "Specification" ); file->LinkEndChild(spec); TiXmlElement * identifier = new TiXmlElement( "Identifier" ); identifier->LinkEndChild(new TiXmlText("http://www.topografix.com/GPX/1/1")); spec->LinkEndChild(identifier); TiXmlElement * docu = new TiXmlElement( "Documentation" ); docu->LinkEndChild(new TiXmlText("http://www.topografix.com/GPX/1/1/gpx.xsd")); spec->LinkEndChild(docu); TiXmlElement * loc = new TiXmlElement( "Location" ); file->LinkEndChild(loc); TiXmlElement * fileEx = new TiXmlElement( "FileExtension" ); fileEx->LinkEndChild(new TiXmlText("GPX")); loc->LinkEndChild(fileEx); TiXmlElement * transferDir = new TiXmlElement( "TransferDirection" ); transferDir->LinkEndChild(new TiXmlText("InputOutput")); file->LinkEndChild(transferDir); /* FitnessHistory http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2 http://www.garmin.com/xmlschemas/TrainingCenterDatabasev2.xsd TCX OutputFromUnit */ dataTypes = new TiXmlElement( "DataType" ); massStorage->LinkEndChild(dataTypes); name = new TiXmlElement( "Name" ); name->LinkEndChild(new TiXmlText("FitnessHistory")); dataTypes->LinkEndChild(name); file = new TiXmlElement( "File" ); dataTypes->LinkEndChild(file); spec = new TiXmlElement( "Specification" ); file->LinkEndChild(spec); identifier = new TiXmlElement( "Identifier" ); identifier->LinkEndChild(new TiXmlText("http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2")); spec->LinkEndChild(identifier); docu = new TiXmlElement( "Documentation" ); docu->LinkEndChild(new TiXmlText("http://www.garmin.com/xmlschemas/TrainingCenterDatabasev2.xsd")); spec->LinkEndChild(docu); loc = new TiXmlElement( "Location" ); file->LinkEndChild(loc); fileEx = new TiXmlElement( "FileExtension" ); fileEx->LinkEndChild(new TiXmlText("TCX")); loc->LinkEndChild(fileEx); transferDir = new TiXmlElement( "TransferDirection" ); transferDir->LinkEndChild(new TiXmlText("InputOutput")); file->LinkEndChild(transferDir); TiXmlPrinter printer; printer.SetIndent( "\t" ); doc.Accept( &printer ); string str = printer.Str(); if (Log::enabledDbg()) Log::dbg("GpsDevice::getDeviceDescription() Done: "+this->displayName ); return str; } int Edge305Device::startWriteToGps(string filename, string xml) { Log::err("Write to Edge305 not yet implemented!"); this->transferSuccessful = false; return 0; } int Edge305Device::finishWriteToGps() { /* 0 = idle 1 = working 2 = waiting 3 = finished */ return 3; } void Edge305Device::cancelWriteToGps() { } int Edge305Device::getTransferSucceeded() { return this->transferSuccessful; } void Edge305Device::setStorageCommand(string cmd) { } MessageBox * Edge305Device::getMessage() { return NULL; } void Edge305Device::userAnswered(const int answer) { } bool Edge305Device::isDeviceAvailable() { garmin_unit garmin; if ( garmin_init(&garmin,0) != 0 ) { garmin_close(&garmin); return true; } return false; } // At least my garmin has unprintable characters at the end, sometimes even \0 // So cut all unprintable characters at the end /*static*/ string Edge305Device::filterDeviceName(string name) { unsigned int i = 0; // new length of string while (i=' ') && (name[i]<='~')) { // 32-126 printable ascii characters i++; } else { break; } } if (i==0) { return "Unknown device"; } // just in case return name.substr(0,i); } int Edge305Device::startReadFITDirectory() { Log::err("startReadFITDirectory is not implemented for this device "+this->displayName); return 0; } int Edge305Device::finishReadFITDirectory() { Log::err("finishReadFITDirectory is not implemented for this device "+this->displayName); return 3; // Finished } void Edge305Device::cancelReadFITDirectory() { Log::err("cancelReadFITDirectory is not implemented for this device "+this->displayName); } int Edge305Device::startReadFitnessDirectory(string dataTypeName) { if (Log::enabledDbg()) Log::dbg("Starting thread to read fitness dir from garmin device: "+this->displayName); this->workType = READFITNESSDIR; if (startThread()) { return 1; } return 0; } int Edge305Device::finishReadFitnessDirectory() { return getThreadState(); } void Edge305Device::cancelReadFitnessData() { cancelThread(); } int Edge305Device::startReadFitnessDetail(string id) { if (Log::enabledDbg()) Log::dbg("Starting thread to read fitness detail from garmin device: "+this->displayName+ " Searching for "+id); this->workType = READFITNESSDETAIL; this->readFitnessDetailId = id; if (startThread()) { return 1; } return 0; } int Edge305Device::finishReadFitnessDetail() { lockVariables(); int status = this->threadState; unlockVariables(); return status; } void Edge305Device::cancelReadFitnessDetail() { cancelThread(); } int Edge305Device::startReadFromGps() { if (Log::enabledDbg()) Log::dbg("Starting thread to read gpx from garmin device: "+this->displayName); this->workType = READFROMGPS; this->threadState = 1; if (startThread()) { return 1; } return 0; } int Edge305Device::finishReadFromGps() { return getThreadState(); } void Edge305Device::cancelReadFromGps() { if (Log::enabledDbg()) Log::dbg("Canceling thread to read gpx from garmin device: "+this->displayName); cancelThread(); } string Edge305Device::getGpxData() { return this->gpxDataGpsXml; } int Edge305Device::getThreadState() { /* 0 = idle 1 = working 2 = waiting 3 = finished */ lockVariables(); int status = this->threadState; unlockVariables(); return status; } bool Edge305Device::_get_run_track_lap_info ( garmin_data * run, uint32 * track_index, uint32 * first_lap_index, uint32 * last_lap_index, uint8 * sport_type ) { D1000 * d1000; D1009 * d1009; D1010 * d1010; bool ok = true; switch ( run->type ) { case data_D1000: d1000 = (D1000*)(run->data); *track_index = d1000->track_index; *first_lap_index = d1000->first_lap_index; *last_lap_index = d1000->last_lap_index; *sport_type = d1000->sport_type; break; case data_D1009: d1009 = (D1009*)run->data; *track_index = d1009->track_index; *first_lap_index = d1009->first_lap_index; *last_lap_index = d1009->last_lap_index; *sport_type = d1009->sport_type; break; case data_D1010: d1010 = (D1010*)run->data; *track_index = d1010->track_index; *first_lap_index = d1010->first_lap_index; *last_lap_index = d1010->last_lap_index; *sport_type = d1010->sport_type; break; default: stringstream ss; ss << "get_run_track_lap_info: run type " << run->type << " is invalid!"; Log::err(ss.str()); ok = false; break; } return ok; } uint32 Edge305Device::getNextLapStartTime(garmin_list_node * node) { if (node == NULL) { return 0; } garmin_list_node * nextNode = node->next; if (nextNode == NULL) { return 0; } D1011 * lapData = NULL; if (nextNode->data->type == data_D1011) { // Edge 305 uses this lapData = (D1011*)nextNode->data->data; } else if (nextNode->data->type == data_D1015) { // Forerunner 205 uses this lapData = (D1011*)nextNode->data->data; // cast to wrong type - is safe because D1015 is identical, just a little bit longer } else if (nextNode->data->type == data_D1001) { // Forerunner 205 uses this D1001 * lapData301 = (D1001*)nextNode->data->data; return lapData301->start_time; } else { return 0; } return lapData->start_time; } string Edge305Device::getBinaryFile(string relativeFilePath) { Log::err("getBinaryFile is not yet implemented for "+this->displayName); return ""; } int Edge305Device::startDownloadData(string gpsDataString) { Log::err("startDownloadData is not yet implemented for "+this->displayName); return 0; } int Edge305Device::writeDownloadData(char *, int length) { Log::err("writeDownloadData is not yet implemented for "+this->displayName); return -1; } void Edge305Device::saveDownloadData() { Log::err("saveDownloadData is not yet implemented for "+this->displayName); } void Edge305Device::cancelDownloadData() { Log::err("cancelDownloadData is not yet implemented for "+this->displayName); } int Edge305Device::finishDownloadData() { Log::err("finishDownloadData is not yet implemented for "+this->displayName); return 0; } string Edge305Device::getNextDownloadDataUrl() { Log::err("getNextDownloadDataUrl is not yet implemented for "+this->displayName); return ""; } /** * Starts a thread that writes the passed xml string to the given filename * @param filename - filename on disk * @param data - the filename to write to on the device. * @param dataTypeName - a Fitness DataType from the GarminDevice.xml retrieved with DeviceDescription * @return int returns 1 if successful otherwise 0 */ int Edge305Device::startWriteFitnessData(string filename, string data, string dataTypeName) { if (Log::enabledDbg()) { Log::dbg("startWriteFitnessData is not yet implemented for "+this->displayName); } return 0; } /** * This is used to indicate the status of the write fitness data process. * @return 0 = idle 1 = working 2 = waiting 3 = finished */ int Edge305Device::finishWriteFitnessData() { if (Log::enabledDbg()) { Log::dbg("finishWriteFitnessData is not yet implemented for "+this->displayName); } return 3; } /** * Cancels the current write of fitness data */ void Edge305Device::cancelWriteFitnessData() { if (Log::enabledDbg()) { Log::dbg("cancelWriteFitnessData is not yet implemented for "+this->displayName); } } /** * Returns the bytes available in the given path on the device * @return bytes available (-1 for non-mass storage mode devices.) */ int Edge305Device::bytesAvailable(string path) { if (Log::enabledDbg()) { Log::dbg("bytesAvailable is not yet implemented for "+this->displayName); } return -1; } GarminPlugin-0.3.23/src/edge305Device.h000066400000000000000000000213241232766717500174310ustar00rootroot00000000000000/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */ /* * GarminPlugin * Copyright (C) Andreas Diesner 2011 * * GarminPlugin is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GarminPlugin is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #ifndef EDGE305DEVICE_H_INCLUDED #define EDGE305DEVICE_H_INCLUDED #include #include "messageBox.h" #include "gpsDevice.h" #include "garmin.h" #include "gpsFunctions.h" #include "TcxBuilder/TcxBase.h" using namespace std; class MessageBox; class Edge305Device : public GpsDevice { public: Edge305Device(); Edge305Device(string name); virtual ~Edge305Device(); /** * Starts a thread that tries to read the fitness data from a garmin device * @param dataTypeName - which type of data should be read from the device * @return int returns 1 if successful otherwise 0 */ int startReadFitnessData(string dataTypeName); /** * Returns the status of reading fitness data from the device * @return int 0 = idle 1 = working 2 = waiting 3 = finished */ int finishReadFitnessData(); /** * Gets the fitness data xml * @return xml containing fitness data read from garmin device */ string getFitnessData(); /** * Checks if a device is attached and returns the device name. * If no device is present and empty string is returned * @return string with device name */ static string getAttachedDeviceName(); string getDeviceDescription() const; int startWriteToGps(string filename, string xml); int finishWriteToGps(); void cancelWriteToGps(); int getTransferSucceeded(); void setStorageCommand(string cmd); MessageBox * getMessage(); void userAnswered(const int answer); bool isDeviceAvailable(); /** * Starts reading the FIT data directory * @return int returns 1 if successful otherwise 0 */ virtual int startReadFITDirectory(); /** * Checks status reading FIT data directory * @return 0 = idle 1 = working 2 = waiting 3 = finished */ virtual int finishReadFITDirectory(); /** * Cancels reading the FIT data directory */ virtual void cancelReadFITDirectory(); /** * Starts reading the fitness data without points * @param dataTypeName - which type of data should be read from the device * @return int returns 1 if successful otherwise 0 */ virtual int startReadFitnessDirectory(string dataTypeName); /** * Checks if the read of the fitness directory finished * @return 0 = idle 1 = working 2 = waiting 3 = finished */ virtual int finishReadFitnessDirectory(); /** * Cancels the read of the fitness data */ virtual void cancelReadFitnessData(); virtual int startReadFitnessDetail(string id); virtual int finishReadFitnessDetail(); virtual void cancelReadFitnessDetail(); /** * Start the reading of a file in the GPX format (like current.gpx on Oregon) */ virtual int startReadFromGps(); /** * This is used to indicate the status of the read process. * @return 0 = idle 1 = working 2 = waiting 3 = finished */ virtual int finishReadFromGps(); /** * Cancels the current read from the device. */ virtual void cancelReadFromGps(); virtual string getGpxData(); /** * Returns a file from the device */ virtual string getBinaryFile(string relativeFilePath); /** * Starts a binary file write to the device * @return number of urls detected in gpsDataString */ virtual int startDownloadData(string gpsDataString); /** * Retrieves the next download url * @return url to download */ virtual string getNextDownloadDataUrl(); /** * This is used to indicate the status of the write download data process. * @return 0 = idle 1 = working 2 = waiting 3 = finished */ virtual int finishDownloadData(); /** * Writes some bytes into the file opened by startDownloadData * @return Bytes written to file */ virtual int writeDownloadData(char *, int length); /** * Saves/Closes the current file */ virtual void saveDownloadData(); /** * Cancels the current file download */ virtual void cancelDownloadData(); /** * Starts a thread that writes the passed xml string to the given filename * @param filename - filename on disk * @param data - the filename to write to on the device. * @param dataTypeName - a Fitness DataType from the GarminDevice.xml retrieved with DeviceDescription * @return int returns 1 if successful otherwise 0 */ virtual int startWriteFitnessData(string filename, string data, string dataTypeName); /** * This is used to indicate the status of the write fitness data process. * @return 0 = idle 1 = working 2 = waiting 3 = finished */ virtual int finishWriteFitnessData(); /** * Cancels the current write of fitness data */ virtual void cancelWriteFitnessData(); /** * Returns the bytes available in the given path on the device * @return bytes available (-1 for non-mass storage mode devices.) */ virtual int bytesAvailable(string path); protected: virtual void doWork(); void readFitnessDataFromDevice(bool readTrackData, string fitnessDetailId); /** * Directory where this device stores its fitness data */ string fitnessDirectory; string fitnessFileExtension; /** * Reads fitnessdata xml from a garmin device like Edge 305/Forerunner 305 * @return xml containing fitness data read from garmin device */ string readFitnessData(bool readTrackData, string fitnessDetailId); /** * Reads fitnessdata into fitnessData xml from a garmin device like Edge 305/Forerunner 305 * @return xml containing fitness data read from garmin device */ TcxBase * readFitnessDataFromGarmin(); /** * Starts reading from garmin device and stores gpx data in gpxDataGpsXml; */ void readGpxDataFromDevice(); /** * Reads the gpx data from the device and returns a string in gpx format */ string readGpxData(); private: /** * Prints an activity read from the garmin device * @param run Garmin list of points describing the runs * @param lap Garmin list of points describing the laps * @param track Garmin list of points describing the tracks * @param garmin device descriptor * @return xml string that describes all activities provided by the given lists */ TcxActivities * printActivities(garmin_list * runList, garmin_list * lap, garmin_list * track, const garmin_unit garmin); /** * Prints the header of a lap * @param D1011 internal lap format of garmintools * @param firstLap if set to true an Time header is added * @param printTrackData if should be outputted * @return xml string */ TcxLap * getLapHeader(D1011 * lapData); TcxLap * getLapHeader(D1001 * lapData); /** * Prints a track point * @param D304 internal track point format of garmintools * @return xml string */ TcxTrackpoint * getTrackPoint ( D304 * p); TcxTrackpoint * getTrackPoint ( D303 * p); /** * Prints information about the device * @param garmin device descriptor * @return xml string */ TcxCreator * getCreator(const garmin_unit garmin); /** * Returns the state of the thread idle/busy/waiting/finished */ int getThreadState(); /** * Stores the fitnessData which was read from the device */ string fitnessDataTcdXml; /** * Stores the gpxData which was read from the device */ string gpxDataGpsXml; bool transferSuccessful; static string filterDeviceName(string name); string readFitnessDetailId; /** * Stores type of current run (0=Biking, 1=Running, 2=Other) */ int runType; /** * Stores the fitness data read from current.gpx */ TcxBase *fitnessData; bool _get_run_track_lap_info ( garmin_data * run,uint32 * track_index,uint32 * first_lap_index,uint32 * last_lap_index, uint8 * sport_type ); uint32 getNextLapStartTime(garmin_list_node * node); }; #endif // EDGE305DEVICE_H_INCLUDED GarminPlugin-0.3.23/src/fit/000077500000000000000000000000001232766717500155645ustar00rootroot00000000000000GarminPlugin-0.3.23/src/fit/fitDefines.hpp000066400000000000000000000130111232766717500203510ustar00rootroot00000000000000/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */ /* * GarminPlugin * Copyright (C) Andreas Diesner 2013 * * GarminPlugin is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GarminPlugin is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #ifndef FITDEFINES_HPP_ #define FITDEFINES_HPP_ enum FIT_SPORT { SPORT_GENERIC=0, SPORT_RUNNING=1, SPORT_CYCLING=2, SPORT_TRANSITION=3, // Multisport SPORT_FITNESS_EQUIPMENT=4, SPORT_SWIMMING=5, SPORT_BASKETBALL=6, SPORT_SOCCER=7, SPORT_TENNIS=8, SPORT_AMERICAN_FOOTBALL=9, SPORT_TRAINING=10, SPORT_ALL=254, // All is for goals only to include all sports. SPORT_INVALID=0xFF, }; #define FIT_ENUM_INVALID (0xFF) #define FIT_POSITION_INVALID ((signed long)0x7FFFFFFF) enum FIT_LAP_INTENSITY { INTENSITY_ACTIVE=0, INTENSITY_REST=1, INTENSITY_WARMUP=2, INTENSITY_COOLDOWN=3, INTENSITY_INVALID=0xFF, }; enum FIT_LAP_TRIGGER { LAP_TRIGGER_MANUAL=0, LAP_TRIGGER_TIME=1, LAP_TRIGGER_DISTANCE=2, LAP_TRIGGER_POSITION_START=3, LAP_TRIGGER_POSITION_LAP=4, LAP_TRIGGER_POSITION_WAYPOINT=5, LAP_TRIGGER_POSITION_MARKED=6, LAP_TRIGGER_SESSION_END=7, LAP_TRIGGER_INVALID=0xFF, }; enum FIT_FILEID_TYPE { FIT_FILE_DEVICE=1, FIT_FILE_SETTINGS=2, FIT_FILE_SPORT=3, FIT_FILE_ACTIVITY=4, FIT_FILE_WORKOUT=5, FIT_FILE_COURSE=6, FIT_FILE_SCHEDULES=7, FIT_FILE_WEIGHT=9, FIT_FILE_TOTALS=10, FIT_FILE_GOALS=11, FIT_FILE_BLOOD_PRESSURE=14, FIT_FILE_MONITORING=15, FIT_FILE_ACTIVITY_SUMMARY=20, FIT_FILE_MONITORING_DAILY=28, FIT_FILE_INVALID=0xFF, }; enum FIT_FILEID_PRODUCT { FIT_GARMIN_PRODUCT_HRM1=1, FIT_GARMIN_PRODUCT_AXH01=2, // AXH01 HRM chipset FIT_GARMIN_PRODUCT_AXB01=3, FIT_GARMIN_PRODUCT_AXB02=4, FIT_GARMIN_PRODUCT_HRM2SS=5, FIT_GARMIN_PRODUCT_DSI_ALF02=6, FIT_GARMIN_PRODUCT_FR405=717, // Forerunner 405 FIT_GARMIN_PRODUCT_FR50=782, // Forerunner 50 FIT_GARMIN_PRODUCT_FR60=988, // Forerunner 60 FIT_GARMIN_PRODUCT_DSI_ALF01=1011, FIT_GARMIN_PRODUCT_FR310XT=1018, // Forerunner 310 FIT_GARMIN_PRODUCT_EDGE500=1036, FIT_GARMIN_PRODUCT_FR110=1124, // Forerunner 110 FIT_GARMIN_PRODUCT_EDGE800=1169, FIT_GARMIN_PRODUCT_CHIRP=1253, FIT_GARMIN_PRODUCT_EDGE200=1325, FIT_GARMIN_PRODUCT_FR910XT=1328, FIT_GARMIN_PRODUCT_ALF04=1341, FIT_GARMIN_PRODUCT_FR610=1345, FIT_GARMIN_PRODUCT_FR70=1436, FIT_GARMIN_PRODUCT_FR310XT_4T=1446, FIT_GARMIN_PRODUCT_AMX=1461, FIT_GARMIN_PRODUCT_SDM4=10007, // SDM4 footpod FIT_GARMIN_PRODUCT_TRAINING_CENTER=20119, FIT_GARMIN_PRODUCT_CONNECT=65534, // Garmin Connect website FIT_GARMIN_PRODUCT_INVALID=0xFFFF }; enum FIT_FILEID_MANUFACTURER { FIT_MANUFACTURER_GARMIN=1, FIT_MANUFACTURER_GARMIN_FR405_ANTFS=2, // Do not use. Used by FR405 for ANTFS man id. FIT_MANUFACTURER_ZEPHYR=3, FIT_MANUFACTURER_DAYTON=4, FIT_MANUFACTURER_IDT=5, FIT_MANUFACTURER_SRM=6, FIT_MANUFACTURER_QUARQ=7, FIT_MANUFACTURER_IBIKE=8, FIT_MANUFACTURER_SARIS=9, FIT_MANUFACTURER_SPARK_HK=10, FIT_MANUFACTURER_TANITA=11, FIT_MANUFACTURER_ECHOWELL=12, FIT_MANUFACTURER_DYNASTREAM_OEM=13, FIT_MANUFACTURER_NAUTILUS=14, FIT_MANUFACTURER_DYNASTREAM=15, FIT_MANUFACTURER_TIMEX=16, FIT_MANUFACTURER_METRIGEAR=17, FIT_MANUFACTURER_XELIC=18, FIT_MANUFACTURER_BEURER=19, FIT_MANUFACTURER_CARDIOSPORT=20, FIT_MANUFACTURER_A_AND_D=21, FIT_MANUFACTURER_HMM=22, FIT_MANUFACTURER_SUUNTO=23, FIT_MANUFACTURER_THITA_ELEKTRONIK=24, FIT_MANUFACTURER_GPULSE=25, FIT_MANUFACTURER_CLEAN_MOBILE=26, FIT_MANUFACTURER_PEDAL_BRAIN=27, FIT_MANUFACTURER_PEAKSWARE=28, FIT_MANUFACTURER_SAXONAR=29, FIT_MANUFACTURER_LEMOND_FITNESS=30, FIT_MANUFACTURER_DEXCOM=31, FIT_MANUFACTURER_WAHOO_FITNESS=32, FIT_MANUFACTURER_OCTANE_FITNESS=33, FIT_MANUFACTURER_ARCHINOETICS=34, FIT_MANUFACTURER_THE_HURT_BOX=35, FIT_MANUFACTURER_CITIZEN_SYSTEMS=36, FIT_MANUFACTURER_MAGELLAN=37, FIT_MANUFACTURER_OSYNCE=38, FIT_MANUFACTURER_HOLUX=39, FIT_MANUFACTURER_CONCEPT2=40, FIT_MANUFACTURER_ONE_GIANT_LEAP=42, FIT_MANUFACTURER_ACE_SENSOR=43, FIT_MANUFACTURER_BRIM_BROTHERS=44, FIT_MANUFACTURER_XPLOVA=45, FIT_MANUFACTURER_PERCEPTION_DIGITAL=46, FIT_MANUFACTURER_BF1SYSTEMS=47, FIT_MANUFACTURER_PIONEER=48, FIT_MANUFACTURER_SPANTEC=49, FIT_MANUFACTURER_METALOGICS=50, FIT_MANUFACTURER_4IIIIS=51, FIT_MANUFACTURER_SEIKO_EPSON=52, FIT_MANUFACTURER_SEIKO_EPSON_OEM=53, FIT_MANUFACTURER_IFOR_POWELL=54, FIT_MANUFACTURER_MAXWELL_GUIDER=55, FIT_MANUFACTURER_STAR_TRAC=56, FIT_MANUFACTURER_BREAKAWAY=57, FIT_MANUFACTURER_ALATECH_TECHNOLOGY_LTD=58, FIT_MANUFACTURER_MIO_TECHNOLOGY_EUROPE=59, FIT_MANUFACTURER_ROTOR=60, FIT_MANUFACTURER_GEONAUTE=61, FIT_MANUFACTURER_ID_BIKE=62, FIT_MANUFACTURER_SPECIALIZED=63, FIT_MANUFACTURER_WTEK=64, FIT_MANUFACTURER_PHYSICAL_ENTERPRISES=65, FIT_MANUFACTURER_NORTH_POLE_ENGINEERING=66, FIT_MANUFACTURER_BKOOL=67, FIT_MANUFACTURER_CATEYE=68, FIT_MANUFACTURER_STAGES_CYCLING=69, FIT_MANUFACTURER_SIGMASPORT=70, FIT_MANUFACTURER_DEVELOPMENT=255, FIT_MANUFACTURER_ACTIGRAPHCORP=5759, FIT_MANUFACTURER_INVALID=0xFFFF }; #endif /* FITDEFINES_HPP_ */ GarminPlugin-0.3.23/src/fit/fitFileException.hpp000066400000000000000000000024521232766717500215410ustar00rootroot00000000000000/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */ /* * GarminPlugin * Copyright (C) Andreas Diesner 2011 * * GarminPlugin is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GarminPlugin is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #ifndef FITFILEEXCEPTION_H #define FITFILEEXCEPTION_H #include using namespace std; class FitFileException { public: FitFileException(string msg) { this->errorMsg = msg; }; virtual ~FitFileException() {}; /** * Gets the exception message * @return string with message description */ string getError() { return this->errorMsg; }; protected: private: string errorMsg; }; #endif // FITFILEEXCEPTION_H GarminPlugin-0.3.23/src/fit/fitMsg.hpp000066400000000000000000000162241232766717500175330ustar00rootroot00000000000000/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */ /* * GarminPlugin * Copyright (C) Andreas Diesner 2013 * * GarminPlugin is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GarminPlugin is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ // The following profiles are not yet implemented! #define FIT_MESSAGE_CAPABILITIES ((unsigned char)1) #define FIT_MESSAGE_DEVICE_SETTINGS ((unsigned char)2) #define FIT_MESSAGE_USER_PROFILE ((unsigned char)3) #define FIT_MESSAGE_HRM_PROFILE ((unsigned char)4) #define FIT_MESSAGE_SDM_PROFILE ((unsigned char)5) #define FIT_MESSAGE_BIKE_PROFILE ((unsigned char)6) #define FIT_MESSAGE_ZONES_TARGET ((unsigned char)7) #define FIT_MESSAGE_HR_ZONE ((unsigned char)8) #define FIT_MESSAGE_POWER_ZONE ((unsigned char)9) #define FIT_MESSAGE_MET_ZONE ((unsigned char)10) #define FIT_MESSAGE_SPORT ((unsigned char)12) #define FIT_MESSAGE_TRAINING_GOALS ((unsigned char)15) #define FIT_MESSAGE_WORKOUT ((unsigned char)26) #define FIT_MESSAGE_WORKOUT_STEP ((unsigned char)27) #define FIT_MESSAGE_WEIGHT_SCALE ((unsigned char)30) #define FIT_MESSAGE_TOTALS ((unsigned char)33) #define FIT_MESSAGE_SOFTWARE ((unsigned char)35) #define FIT_MESSAGE_FILE_CAPABILITIES ((unsigned char)37) #define FIT_MESSAGE_MESG_CAPABILITIES ((unsigned char)38) #define FIT_MESSAGE_FIELD_CAPABILITIES ((unsigned char)39) #define FIT_MESSAGE_BLOOD_PRESSURE ((unsigned char)51) #ifndef FITMSG_H #define FITMSG_H #include class FitMsg { public: FitMsg(unsigned char type) { this->classType = type; }; virtual ~FitMsg() {}; /** * Sets the timestamp of the message */ virtual void SetTimestamp(unsigned int time) {}; /** * Get type of message */ unsigned char GetType() { return this->classType; }; /** * Add a field to this message. * @return bool true if field was added successfully */ virtual bool addField(unsigned char fieldDefNum, unsigned char size, unsigned char baseType, unsigned char arch, char * data) = 0; protected: /** * Reads 2 bytes unsigned short from buffer with the type 0x84 (endianes aware) */ static unsigned short read0x84(char * buf, unsigned char arch) { bool isLittleEndian = ((arch & 0x01) == 0) ? 1 : 0; unsigned short ret; if (isLittleEndian) { ret = ((unsigned char)buf[0]) + ((unsigned char)buf[1]<<8); } else { // God knows why, but the sdk never reads in big endian. ret = ((unsigned char)(buf[1]) + ((unsigned char)buf[0]<<8)); } return ret; }; /** * Reads 4 bytes unsigned long from buffer with the type 0x8C (endianes aware) */ static unsigned long read0x8C(char * buf, unsigned char arch) { bool isLittleEndian = ((arch & 0x01) == 0) ? 1 : 0; unsigned long ret; if (isLittleEndian) { ret = ((0xFF & buf[3]) << 24) | ((0xFF & buf[2]) << 16) | ((0xFF & buf[1]) << 8) | (0xFF & buf[0]); } else { // God knows why, but the sdk never reads in big endian. ret = ((unsigned char) buf[0] << 24) | ((unsigned char) buf[1] << 16) | ((unsigned char) buf[2] << 8) | (unsigned char)buf[3]; } ret = ret & 0xFFFFFFFF; return ret; }; /** * Reads 4 bytes unsigned long from buffer with the type 0x86 (endianes aware) */ static unsigned long read0x86(char * buf, unsigned char arch) { // only difference between 0x86 and 0x8C is the default value return read0x8C(buf, arch); }; /** * Reads 4 bytes signed long from buffer with the type 0x85 (endianes aware) */ static signed long read0x85(char * buf, unsigned char arch) { bool isLittleEndian = ((arch & 0x01) == 0) ? 1 : 0; signed long ret; if (isLittleEndian) { ret = ((0xFF & buf[3]) << 24) | ((0xFF & buf[2]) << 16) | ((0xFF & buf[1]) << 8) | (0xFF & buf[0]); } else { // God knows why, but the sdk never reads in big endian. ret = ((0xFF & buf[0]) << 24) | ((0xFF & buf[1]) << 16) | ((0xFF & buf[2]) << 8) | (0xFF & buf[3]); } return ret; }; /** * Reads 4 bytes float from buffer with the type 0x88 (endianes aware) */ static float read0x88(char * buf, unsigned char arch) { return read0x88(buf,arch, 0x88,1,0); }; /** * Reads 4 bytes float from buffer with the type 0x88 (endianes aware) * Supports scale and offset */ static float read0x88(char * buf, unsigned char arch, float scale, float offset, unsigned char baseType) { float float32Value=0; if (baseType == 0x84) { unsigned short sShortValue = read0x84(buf, arch); float32Value= sShortValue; } else if (baseType == 0x86) { unsigned long sLongValue = read0x86(buf, arch); float32Value= sLongValue; } else if (baseType == 0x85) { signed long sLongValue = read0x85(buf, arch); memcpy(&float32Value, &sLongValue, sizeof(float32Value)); } else if (baseType == 0x00) { unsigned char charVal= read0x00(buf,arch); float32Value= charVal; } float32Value = float32Value / scale - offset; return float32Value; }; /** * Reads 1 bytes unsigned char from buffer with the type 0x02 */ static unsigned char read0x02(char * buf, unsigned char arch) { unsigned char ret; ret = (0xFF & buf[0]); return ret; }; /** * Reads 1 bytes unsigned char from buffer with the type 0x00 */ static unsigned char read0x00(char * buf, unsigned char arch) { unsigned char ret; ret = (0xFF & buf[0]); return ret; }; /** * Reads 1 bytes signed char from buffer with the type 0x00 */ static signed char read0x01(char * buf, unsigned char arch) { signed char ret; ret = (signed char)buf[0]; return ret; }; /** * Stores the class type */ unsigned char classType; }; #endif // FITMSG_H GarminPlugin-0.3.23/src/fit/fitMsg_Activity.hpp000066400000000000000000000073671232766717500214170ustar00rootroot00000000000000/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */ /* * GarminPlugin * Copyright (C) Andreas Diesner 2011 * * GarminPlugin is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GarminPlugin is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #ifndef FITMSG_ACTIVITY_H #define FITMSG_ACTIVITY_H #define FIT_MESSAGE_ACTIVITY ((unsigned char)34) class FitMsg_Activity : public FitMsg { public: FitMsg_Activity() : FitMsg(FIT_MESSAGE_ACTIVITY) { }; virtual ~FitMsg_Activity() {}; /** * Adds a field to the message. Unknown fields are rejected * @return bool if field was known to the message */ bool addField(unsigned char fieldDefNum, unsigned char size, unsigned char baseType, unsigned char arch, char * data) { //TODO: Compare size with expected size //TODO: Compare baseType with expected baseType bool fieldWasAdded = true; switch (fieldDefNum) { case 253: setTimestamp(read0x86(data,arch)); break; case 0: setTotalTimerTime(read0x88(data,arch,1000,0,0x86)); break; case 1: setNumSessions(read0x84(data,arch)); break; case 2: setType(read0x00(data,arch)); break; case 3: setEvent(read0x00(data,arch)); break; case 4: setEventType(read0x00(data,arch)); break; case 5: setLocalTimestamp(read0x86(data,arch)); break; case 6: setEventGroup(read0x02(data,arch)); break; default: fieldWasAdded = false; break; } return fieldWasAdded; }; enum FIT_EVENT { }; private: /* timestamp - Unit: */ unsigned long timestamp; /* total_timer_time - Unit: s */ float totalTimerTime; /* num_sessions - Unit: */ unsigned short numSessions; /* type - Unit: */ unsigned char type; /* event - Unit: */ unsigned char event; /* event_type - Unit: */ unsigned char eventType; /* local_timestamp - Unit: */ unsigned long localTimestamp; /* event_group - Unit: */ unsigned char eventGroup; public: unsigned char getEvent() const { return event; } void setEvent(unsigned char event) { this->event = event; } unsigned char getEventGroup() const { return eventGroup; } void setEventGroup(unsigned char eventGroup) { this->eventGroup = eventGroup; } unsigned char getEventType() const { return eventType; } void setEventType(unsigned char eventType) { this->eventType = eventType; } unsigned long getLocalTimestamp() const { return localTimestamp; } void setLocalTimestamp(unsigned long localTimestamp) { this->localTimestamp = localTimestamp; } unsigned short getNumSessions() const { return numSessions; } void setNumSessions(unsigned short numSessions) { this->numSessions = numSessions; } unsigned long getTimestamp() const { return timestamp; } void setTimestamp(unsigned long timestamp) { this->timestamp = timestamp; } float getTotalTimerTime() const { return totalTimerTime; } void setTotalTimerTime(float totalTimerTime) { this->totalTimerTime = totalTimerTime; } unsigned char getType() const { return type; } void setType(unsigned char type) { this->type = type; } }; #endif // FITMSG_ACTIVITY_H GarminPlugin-0.3.23/src/fit/fitMsg_DeviceInfo.hpp000066400000000000000000000113701232766717500216230ustar00rootroot00000000000000/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */ /* * GarminPlugin * Copyright (C) Andreas Diesner 2013 * * GarminPlugin is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GarminPlugin is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #ifndef FITMSG_DEVICEINFO_H #define FITMSG_DEVICEINFO_H #define FIT_MESSAGE_DEVICE_INFO ((unsigned char)23) class FitMsg_DeviceInfo: public FitMsg { public: FitMsg_DeviceInfo() : FitMsg(FIT_MESSAGE_DEVICE_INFO) { }; virtual ~FitMsg_DeviceInfo() {}; /** * Adds a field to the message. Unknown fields are rejected * @return bool if field was known to the message */ bool addField(unsigned char fieldDefNum, unsigned char size, unsigned char baseType, unsigned char arch, char * data) { //TODO: Compare size with expected size //TODO: Compare baseType with expected baseType bool fieldWasAdded = true; switch (fieldDefNum) { case 253: setTimestamp(read0x86(data,arch)); break; case 0: setDeviceIndex(read0x02(data,arch)); break; case 1: setDeviceType(read0x02(data,arch)); break; case 2: setManufacturer(read0x84(data,arch)); break; case 3: setSerialNumber(read0x8C(data,arch)); break; case 4: setProduct(read0x84(data,arch)); break; case 5: setSoftwareVersion(read0x88(data,arch,100,0,0x84)); break; case 6: setHardwareVersion(read0x02(data,arch)); break; case 7: setCumOperatingTime(read0x86(data,arch)); break; case 10: setBatteryVoltage(read0x88(data,arch,256,0,0x84)); break; case 11: setBatteryStatus(read0x02(data,arch)); break; default: fieldWasAdded = false; break; } return fieldWasAdded; }; private: /* timestamp - Unit: s */ unsigned long timestamp; /* device_index - Unit: */ unsigned char deviceIndex; /* device_type - Unit: */ unsigned char deviceType; /* manufacturer - Unit: */ unsigned short manufacturer; /* serial_number - Unit: */ unsigned long serialNumber; /* product - Unit: */ unsigned short product; /* software_version - Unit: */ float softwareVersion; /* hardware_version - Unit: */ unsigned char hardwareVersion; /* cum_operating_time - Unit: s */ unsigned long cumOperatingTime; /* battery_voltage - Unit: V */ float batteryVoltage; /* battery_status - Unit: */ unsigned char batteryStatus; public: unsigned char getBatteryStatus() const { return batteryStatus; } void setBatteryStatus(unsigned char batteryStatus) { this->batteryStatus = batteryStatus; } float getBatteryVoltage() const { return batteryVoltage; } void setBatteryVoltage(float batteryVoltage) { this->batteryVoltage = batteryVoltage; } unsigned long getCumOperatingTime() const { return cumOperatingTime; } void setCumOperatingTime(unsigned long cumOperatingTime) { this->cumOperatingTime = cumOperatingTime; } unsigned char getDeviceIndex() const { return deviceIndex; } void setDeviceIndex(unsigned char deviceIndex) { this->deviceIndex = deviceIndex; } unsigned char getDeviceType() const { return deviceType; } void setDeviceType(unsigned char deviceType) { this->deviceType = deviceType; } unsigned char getHardwareVersion() const { return hardwareVersion; } void setHardwareVersion(unsigned char hardwareVersion) { this->hardwareVersion = hardwareVersion; } unsigned short getManufacturer() const { return manufacturer; } void setManufacturer(unsigned short manufacturer) { this->manufacturer = manufacturer; } unsigned short getProduct() const { return product; } void setProduct(unsigned short product) { this->product = product; } unsigned long getSerialNumber() const { return serialNumber; } void setSerialNumber(unsigned long serialNumber) { this->serialNumber = serialNumber; } float getSoftwareVersion() const { return softwareVersion; } void setSoftwareVersion(float softwareVersion) { this->softwareVersion = softwareVersion; } unsigned long getTimestamp() const { return timestamp; } void setTimestamp(unsigned long timestamp) { this->timestamp = timestamp; } }; #endif // FITMSG_DEVICEINFO_H GarminPlugin-0.3.23/src/fit/fitMsg_Event.hpp000066400000000000000000000164401232766717500206740ustar00rootroot00000000000000/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */ /* * GarminPlugin * Copyright (C) Andreas Diesner 2013 * * GarminPlugin is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GarminPlugin is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #ifndef FITMSG_EVENT_H #define FITMSG_EVENT_H #define FIT_MESSAGE_EVENT ((unsigned char)21) class FitMsg_Event : public FitMsg { public: FitMsg_Event() : FitMsg(FIT_MESSAGE_EVENT) { }; virtual ~FitMsg_Event() {}; /** * Adds a field to the message. Unknown fields are rejected * @return bool if field was known to the message */ bool addField(unsigned char fieldDefNum, unsigned char size, unsigned char baseType, unsigned char arch, char * data) { //TODO: Compare size with expected size //TODO: Compare baseType with expected baseType bool fieldWasAdded = true; switch (fieldDefNum) { case 253: setTimestamp(read0x86(data,arch)); break; case 0: setEvent(read0x00(data,arch)); break; case 1: setEventType(read0x00(data,arch)); break; case 2: setData16(read0x84(data,arch)); break; case 3: fieldWasAdded = consumeEvent(size, baseType, arch, data); break; case 4: setEventGroup(read0x02(data,arch)); break; default: fieldWasAdded = false; break; } return fieldWasAdded; }; private: unsigned long timestamp; unsigned char event; unsigned char eventType; unsigned short data16; unsigned long data; unsigned char timerTrigger; unsigned short coursePointIndex; float batteryLevel; float virtualPartnerSpeed; unsigned char hrHighAlert; unsigned char hrLowAlert; float speedHighAlert; float speedLowAlert; unsigned short cadHighAlert; unsigned short cadLowAlert; unsigned short powerHighAlert; unsigned short powerLowAlert; float timeDurationAlert; float distanceDurationAlert; unsigned long calorieDurationAlert; unsigned char fitnessEquipmentState; unsigned char eventGroup; bool consumeEvent(unsigned char size, unsigned char baseType, unsigned char arch, char * data) { /* case 3: setData(read0x86(data,arch)); break; case 3: setTimerTrigger(read0x00(data,arch)); break; case 3: setCoursePointIndex(read0x84(data,arch)); break; case 3: setBatteryLevel(read0x88(data,arch)); break; case 3: setVirtualPartnerSpeed(read0x88(data,arch)); break; case 3: setHrHighAlert(read0x02(data,arch)); break; case 3: setHrLowAlert(read0x02(data,arch)); break; case 3: setSpeedHighAlert(read0x88(data,arch)); break; case 3: setSpeedLowAlert(read0x88(data,arch)); break; case 3: setCadHighAlert(read0x84(data,arch)); break; case 3: setCadLowAlert(read0x84(data,arch)); break; case 3: setPowerHighAlert(read0x84(data,arch)); break; case 3: setPowerLowAlert(read0x84(data,arch)); break; case 3: setTimeDurationAlert(read0x88(data,arch)); break; case 3: setDistanceDurationAlert(read0x88(data,arch)); break; case 3: setCalorieDurationAlert(read0x86(data,arch)); break; case 3: setFitnessEquipmentState(read0x00(data,arch)); break; */ return false; } public: float getBatteryLevel() const { return batteryLevel; } void setBatteryLevel(float batteryLevel) { this->batteryLevel = batteryLevel; } unsigned short getCadHighAlert() const { return cadHighAlert; } void setCadHighAlert(unsigned short cadHighAlert) { this->cadHighAlert = cadHighAlert; } unsigned short getCadLowAlert() const { return cadLowAlert; } void setCadLowAlert(unsigned short cadLowAlert) { this->cadLowAlert = cadLowAlert; } unsigned long getCalorieDurationAlert() const { return calorieDurationAlert; } void setCalorieDurationAlert(unsigned long calorieDurationAlert) { this->calorieDurationAlert = calorieDurationAlert; } unsigned short getCoursePointIndex() const { return coursePointIndex; } void setCoursePointIndex(unsigned short coursePointIndex) { this->coursePointIndex = coursePointIndex; } unsigned long getData() const { return data; } void setData(unsigned long data) { this->data = data; } unsigned short getData16() const { return data16; } void setData16(unsigned short data16) { this->data16 = data16; } float getDistanceDurationAlert() const { return distanceDurationAlert; } void setDistanceDurationAlert(float distanceDurationAlert) { this->distanceDurationAlert = distanceDurationAlert; } unsigned char getEvent() const { return event; } void setEvent(unsigned char event) { this->event = event; } unsigned char getEventGroup() const { return eventGroup; } void setEventGroup(unsigned char eventGroup) { this->eventGroup = eventGroup; } unsigned char getEventType() const { return eventType; } void setEventType(unsigned char eventType) { this->eventType = eventType; } unsigned char getFitnessEquipmentState() const { return fitnessEquipmentState; } void setFitnessEquipmentState(unsigned char fitnessEquipmentState) { this->fitnessEquipmentState = fitnessEquipmentState; } unsigned char getHrHighAlert() const { return hrHighAlert; } void setHrHighAlert(unsigned char hrHighAlert) { this->hrHighAlert = hrHighAlert; } unsigned char getHrLowAlert() const { return hrLowAlert; } void setHrLowAlert(unsigned char hrLowAlert) { this->hrLowAlert = hrLowAlert; } unsigned short getPowerHighAlert() const { return powerHighAlert; } void setPowerHighAlert(unsigned short powerHighAlert) { this->powerHighAlert = powerHighAlert; } unsigned short getPowerLowAlert() const { return powerLowAlert; } void setPowerLowAlert(unsigned short powerLowAlert) { this->powerLowAlert = powerLowAlert; } float getSpeedHighAlert() const { return speedHighAlert; } void setSpeedHighAlert(float speedHighAlert) { this->speedHighAlert = speedHighAlert; } float getSpeedLowAlert() const { return speedLowAlert; } void setSpeedLowAlert(float speedLowAlert) { this->speedLowAlert = speedLowAlert; } float getTimeDurationAlert() const { return timeDurationAlert; } void setTimeDurationAlert(float timeDurationAlert) { this->timeDurationAlert = timeDurationAlert; } unsigned char getTimerTrigger() const { return timerTrigger; } void setTimerTrigger(unsigned char timerTrigger) { this->timerTrigger = timerTrigger; } unsigned long getTimestamp() const { return timestamp; } void setTimestamp(unsigned long timestamp) { this->timestamp = timestamp; } float getVirtualPartnerSpeed() const { return virtualPartnerSpeed; } void setVirtualPartnerSpeed(float virtualPartnerSpeed) { this->virtualPartnerSpeed = virtualPartnerSpeed; } }; #endif // FITMSG_EVENT_H GarminPlugin-0.3.23/src/fit/fitMsg_File_Creator.hpp000066400000000000000000000060311232766717500221440ustar00rootroot00000000000000/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */ /* * GarminPlugin * Copyright (C) Andreas Diesner 2011 * * GarminPlugin is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GarminPlugin is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #ifndef FITMSG_FILE_CREATOR_H #define FITMSG_FILE_CREATOR_H #define FIT_MESSAGE_FILE_CREATOR ((unsigned char)49) #define FIT_FILE_ID_SOFTWARE_VERSION_INVALID ((unsigned short)0xFFFF) #define FIT_FILE_ID_HARDWARE_VERSION_INVALID ((unsigned char)0xFF) class FitMsg_File_Creator : public FitMsg { public: FitMsg_File_Creator() : FitMsg(FIT_MESSAGE_FILE_CREATOR) { this->software_version = FIT_FILE_ID_SOFTWARE_VERSION_INVALID; // 16 bit this->hardware_version = FIT_FILE_ID_HARDWARE_VERSION_INVALID; // 8 bit }; virtual ~FitMsg_File_Creator() {}; /** * Returns the software version * @return unsigned short Software Version */ unsigned short getSoftwareVersion() { return this->software_version; }; /** * Returns the hardware version * @return unsigned char Hardware Version */ unsigned char getHardwareVersion() { return this->hardware_version; }; /** * Sets the software version */ void setSoftwareVersion(unsigned short ver) { this->software_version = ver; }; /** * Sets the hardware version */ void setHardwareVersion(unsigned char ver) { this->hardware_version = ver; }; /** * Adds a field to the message. Unknown fields are rejected * @return bool if field was known to the message */ bool addField(unsigned char fieldDefNum, unsigned char size, unsigned char baseType, unsigned char arch, char * data) { //TODO: Compare size with expected size //TODO: Compare baseType with expected baseType bool fieldWasAdded = true; switch (fieldDefNum) { case 0: setSoftwareVersion(read0x84(data,arch)); break; case 1: setHardwareVersion((unsigned char)data[0]); break; default: fieldWasAdded = false; break; } return fieldWasAdded; }; private: /** * Stores the software version */ unsigned short software_version; /** * Stores the hardware version */ unsigned char hardware_version; }; #endif // FITMSG_FILE_CREATOR_H GarminPlugin-0.3.23/src/fit/fitMsg_File_ID.hpp000066400000000000000000000215031232766717500210420ustar00rootroot00000000000000/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */ /* * GarminPlugin * Copyright (C) Andreas Diesner 2011 * * GarminPlugin is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GarminPlugin is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #define FIT_MESSAGE_FILE_ID ((unsigned char)0) #define FIT_FILE_ID_TYPE_INVALID ((unsigned char)0xFF) #define FIT_FILE_ID_TYPE_DEVICE ((unsigned char)1) #define FIT_FILE_ID_TYPE_SETTINGS ((unsigned char)2) #define FIT_FILE_ID_TYPE_SPORT ((unsigned char)3) #define FIT_FILE_ID_TYPE_ACTIVITY ((unsigned char)4) #define FIT_FILE_ID_TYPE_WORKOUT ((unsigned char)5) #define FIT_FILE_ID_TYPE_WEIGHT ((unsigned char)9) #define FIT_FILE_ID_TYPE_TOTALS ((unsigned char)10) #define FIT_FILE_ID_TYPE_GOALS ((unsigned char)11) #define FIT_FILE_ID_TYPE_BLOOD_PRESSURE ((unsigned char)14) #define FIT_FILE_ID_MANUFACTURER_INVALID ((unsigned short)0xFFFF) #define FIT_FILE_ID_MANUFACTURER_GARMIN ((unsigned short)1) #define FIT_FILE_ID_MANUFACTURER_GARMIN_FR405_ANTFS ((unsigned short)2) #define FIT_FILE_ID_MANUFACTURER_ZEPHYR ((unsigned short)3) #define FIT_FILE_ID_MANUFACTURER_DAYTON ((unsigned short)4) #define FIT_FILE_ID_MANUFACTURER_IDT ((unsigned short)5) #define FIT_FILE_ID_MANUFACTURER_SRM ((unsigned short)6) #define FIT_FILE_ID_MANUFACTURER_QUARQ ((unsigned short)7) #define FIT_FILE_ID_MANUFACTURER_IBIKE ((unsigned short)8) #define FIT_FILE_ID_MANUFACTURER_SARIS ((unsigned short)9) #define FIT_FILE_ID_MANUFACTURER_SPARK_HK ((unsigned short)10) #define FIT_FILE_ID_MANUFACTURER_TANITA ((unsigned short)11) #define FIT_FILE_ID_MANUFACTURER_ECHOWELL ((unsigned short)12) #define FIT_FILE_ID_MANUFACTURER_DYNASTREAM_OEM ((unsigned short)13) #define FIT_FILE_ID_MANUFACTURER_NAUTILUS ((unsigned short)14) #define FIT_FILE_ID_MANUFACTURER_DYNASTREAM ((unsigned short)15) #define FIT_FILE_ID_MANUFACTURER_TIMEX ((unsigned short)16) #define FIT_FILE_ID_MANUFACTURER_METRIGEAR ((unsigned short)17) #define FIT_FILE_ID_MANUFACTURER_XELIC ((unsigned short)18) #define FIT_FILE_ID_MANUFACTURER_BEURER ((unsigned short)19) #define FIT_FILE_ID_MANUFACTURER_CARDIOSPORT ((unsigned short)20) #define FIT_FILE_ID_MANUFACTURER_A_AND_D ((unsigned short)21) #define FIT_FILE_ID_MANUFACTURER_HMM ((unsigned short)22) #define FIT_FILE_ID_GARMIN_PRODUCT_INVALID ((unsigned short)0xFFFF) #define FIT_FILE_ID_GARMIN_PRODUCT_HRM1 ((unsigned short)1) #define FIT_FILE_ID_GARMIN_PRODUCT_AXH01 ((unsigned short)2) // AXH01 HRM chipset #define FIT_FILE_ID_GARMIN_PRODUCT_AXB01 ((unsigned short)3) #define FIT_FILE_ID_GARMIN_PRODUCT_AXB02 ((unsigned short)4) #define FIT_FILE_ID_GARMIN_PRODUCT_HRM2SS ((unsigned short)5) #define FIT_FILE_ID_GARMIN_PRODUCT_FR405 ((unsigned short)717) // Forerunner 405 #define FIT_FILE_ID_GARMIN_PRODUCT_FR50 ((unsigned short)782) // Forerunner 50 #define FIT_FILE_ID_GARMIN_PRODUCT_FR60 ((unsigned short)988) // Forerunner 60 #define FIT_FILE_ID_GARMIN_PRODUCT_FR310XT ((unsigned short)1018) // Forerunner 310 #define FIT_FILE_ID_GARMIN_PRODUCT_EDGE500 ((unsigned short)1036) #define FIT_FILE_ID_GARMIN_PRODUCT_FR110 ((unsigned short)1124) // Forerunner 110 #define FIT_FILE_ID_GARMIN_PRODUCT_TRAINING_CENTER ((unsigned short)20119) #define FIT_FILE_ID_GARMIN_PRODUCT_CONNECT ((unsigned short)65534) // Garmin Connect website #define FIT_FILE_ID_SERIAL_NUMBER_INVALID ((unsigned long)0x00000000) #define FIT_FILE_ID_TIME_CREATED_INVALID ((unsigned long)0xFFFFFFFF) #define FIT_FILE_ID_NUMBER_INVALID ((unsigned short)0xFFFF) #ifndef FITMSG_FILE_ID_H #define FITMSG_FILE_ID_H class FitMsg_File_ID : public FitMsg { public: FitMsg_File_ID() : FitMsg(FIT_MESSAGE_FILE_ID) { this->type = FIT_FILE_ID_TYPE_INVALID; // 8 bit this->manufacturer = FIT_FILE_ID_MANUFACTURER_INVALID; // 16 bit this->product = FIT_FILE_ID_GARMIN_PRODUCT_INVALID; // 16 bit this->serialNumber = FIT_FILE_ID_SERIAL_NUMBER_INVALID; // 32 bit this->timeCreated = FIT_FILE_ID_TIME_CREATED_INVALID; // 32 bit this->number = FIT_FILE_ID_NUMBER_INVALID; // 16 bit }; virtual ~FitMsg_File_ID() {}; /** * Gets the file type. See defines for valid values * @return unsigned char device type */ unsigned char getType() { return this->type; }; /** * Gets the manufacturer. See defines for valid values * @return unsigned short manufacturer */ unsigned short getManufacturer() { return this->manufacturer; }; /** * Gets the Product. See defines for valid values * @return unsigned long product */ unsigned short getProduct() { return this->product; }; /** * Gets the serial number. * @return unsigned long serial number */ unsigned long getSerialNumber() { return this->serialNumber; }; /** * Gets the creation time. * @return unsigned long creation time */ unsigned long getTimeCreated() { return this->timeCreated; }; /** * Gets the number (????). * @return unsigned short number */ unsigned short getNumber() { return this->number; }; void setType(unsigned char type) { this->type = type; }; void setManufacturer(unsigned short man) { this->manufacturer = man; }; void setProduct(unsigned short prod) { this->product = prod; }; void setSerialNumber(unsigned long serial) { this->serialNumber = serial; }; void setTimeCreated(unsigned long time) { this->timeCreated = time; }; void setNumber(unsigned short nbr) { this->number = nbr; }; bool addField(unsigned char fieldDefNum, unsigned char size, unsigned char baseType, unsigned char arch, char * data) { //TODO: Compare size with expected size //TODO: Compare baseType with expected baseType bool fieldWasAdded = true; switch (fieldDefNum) { case 0: setType(read0x00(data,arch)); break; case 1: setManufacturer(read0x84(data,arch)); break; case 2: setProduct(read0x84(data,arch)); break; case 3: setSerialNumber(read0x8C(data,arch)); break; case 4: setTimeCreated(read0x86(data,arch)); break; case 5: setNumber(read0x84(data,arch)); break; default: fieldWasAdded = false; break; } return fieldWasAdded; }; private: /* type - Unit: */ unsigned char type; /* manufacturer - Unit: */ unsigned short manufacturer; /* product - Unit: */ unsigned short product; /* serial_number - Unit: */ unsigned long serialNumber; /* time_created - Unit: */ unsigned long timeCreated; /* number - Unit: */ unsigned short number; }; #endif // FITMSG_FILE_ID_H GarminPlugin-0.3.23/src/fit/fitMsg_Lap.hpp000066400000000000000000000464001232766717500203260ustar00rootroot00000000000000/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */ /* * GarminPlugin * Copyright (C) Andreas Diesner 2013 * * GarminPlugin is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GarminPlugin is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #ifndef FITMSG_LAP_H #define FITMSG_LAP_H #define FIT_MESSAGE_LAP ((unsigned char)19) class FitMsg_Lap : public FitMsg { public: FitMsg_Lap() : FitMsg(FIT_MESSAGE_LAP) { }; virtual ~FitMsg_Lap() {}; /** * Adds a field to the message. Unknown fields are rejected * @return bool if field was known to the message */ bool addField(unsigned char fieldDefNum, unsigned char size, unsigned char baseType, unsigned char arch, char * data) { //TODO: Compare size with expected size //TODO: Compare baseType with expected baseType bool fieldWasAdded = true; switch (fieldDefNum) { case 254: setMessageIndex(read0x84(data,arch)); break; case 253: setTimestamp(read0x86(data,arch)); break; case 0: setEvent(read0x00(data,arch)); break; case 1: setEventType(read0x00(data,arch)); break; case 2: setStartTime(read0x86(data,arch)); break; case 3: setStartPositionLat(read0x85(data,arch)); break; case 4: setStartPositionLong(read0x85(data,arch)); break; case 5: setEndPositionLat(read0x85(data,arch)); break; case 6: setEndPositionLong(read0x85(data,arch)); break; case 7: setTotalElapsedTime(read0x88(data,arch,1000,0,0x86)); break; case 8: setTotalTimerTime(read0x88(data,arch,1000,0,0x86)); break; case 9: setTotalDistance(read0x88(data,arch,100,0,0x86)); break; case 10: setTotalCycles(read0x86(data,arch)); break; case 11: setTotalCalories(read0x84(data,arch)); break; case 12: setTotalFatCalories(read0x84(data,arch)); break; case 13: setAvgSpeed(read0x88(data,arch,1000,0,0x84)); break; case 14: setMaxSpeed(read0x88(data,arch,1000,0,0x84)); break; case 15: setAvgHeartRate(read0x02(data,arch)); break; case 16: setMaxHeartRate(read0x02(data,arch)); break; case 17: setAvgCadence(read0x02(data,arch)); break; case 18: setMaxCadence(read0x02(data,arch)); break; case 19: setAvgPower(read0x84(data,arch)); break; case 20: setMaxPower(read0x84(data,arch)); break; case 21: setTotalAscent(read0x84(data,arch)); break; case 22: setTotalDescent(read0x84(data,arch)); break; case 23: setIntensity(read0x00(data,arch)); break; case 24: setLapTrigger(read0x00(data,arch)); break; case 25: setSport(read0x00(data,arch)); break; case 26: setEventGroup(read0x02(data,arch)); break; case 32: setNumLengths(read0x84(data,arch)); break; case 33: setNormalizedPower(read0x84(data,arch)); break; case 34: setLeftRightBalance(read0x84(data,arch)); break; case 35: setFirstLengthIndex(read0x84(data,arch)); break; case 37: setAvgStrokeDistance(read0x88(data,arch,100,0,0x84)); break; case 38: setSwimStroke(read0x00(data,arch)); break; case 39: setSubSport(read0x00(data,arch)); break; case 40: setNumActiveLengths(read0x84(data,arch)); break; case 41: setTotalWork(read0x86(data,arch)); break; case 42: setAvgAltitude(read0x88(data,arch,5,500,0x84)); break; case 43: setMaxAltitude(read0x88(data,arch,5,500,0x84)); break; case 44: setGpsAccuracy(read0x02(data,arch)); break; case 45: setAvgGrade(read0x88(data,arch,100,0,0x83)); break; case 46: setAvgPosGrade(read0x88(data,arch,100,0,0x83)); break; case 47: setAvgNegGrade(read0x88(data,arch,100,0,0x83)); break; case 48: setMaxPosGrade(read0x88(data,arch,100,0,0x83)); break; case 49: setMaxNegGrade(read0x88(data,arch,100,0,0x83)); break; case 50: setAvgTemperature(read0x01(data,arch)); break; case 51: setMaxTemperature(read0x01(data,arch)); break; case 52: setTotalMovingTime(read0x88(data,arch,1000,0,0x86)); break; case 53: setAvgPosVerticalSpeed(read0x88(data,arch,1000,0,0x83)); break; case 54: setAvgNegVerticalSpeed(read0x88(data,arch,1000,0,0x83)); break; case 55: setMaxPosVerticalSpeed(read0x88(data,arch,1000,0,0x83)); break; case 56: setMaxNegVerticalSpeed(read0x88(data,arch,1000,0,0x83)); break; case 61: setRepetitionNum(read0x84(data,arch)); break; case 62: setMinAltitude(read0x88(data,arch,5,500,0x84)); break; case 63: setMinHeartRate(read0x02(data,arch)); break; case 71: setWktStepIndex(read0x84(data,arch)); break; default: fieldWasAdded = false; break; } return fieldWasAdded; }; enum FIT_EVENT { }; private: /* message_index - Unit: */ unsigned short messageIndex; /* timestamp - Unit: s */ unsigned long timestamp; /* event - Unit: */ unsigned char event; /* event_type - Unit: */ unsigned char eventType; /* start_time - Unit: */ unsigned long startTime; /* start_position_lat - Unit: semicircles */ signed long startPositionLat; /* start_position_long - Unit: semicircles */ signed long startPositionLong; /* end_position_lat - Unit: semicircles */ signed long endPositionLat; /* end_position_long - Unit: semicircles */ signed long endPositionLong; /* total_elapsed_time - Unit: s */ float totalElapsedTime; /* total_timer_time - Unit: s */ float totalTimerTime; /* total_distance - Unit: m */ float totalDistance; /* total_cycles - Unit: cycles */ unsigned long totalCycles; /* total_cycles - Unit: cycles */ unsigned long totalStrides; /* total_calories - Unit: kcal */ unsigned short totalCalories; /* total_fat_calories - Unit: kcal */ unsigned short totalFatCalories; /* avg_speed - Unit: m/s */ float avgSpeed; /* max_speed - Unit: m/s */ float maxSpeed; /* avg_heart_rate - Unit: bpm */ unsigned char avgHeartRate; /* max_heart_rate - Unit: bpm */ unsigned char maxHeartRate; /* avg_cadence - Unit: rpm */ unsigned char avgCadence; /* avg_cadence - Unit: rpm */ //unsigned char avgRunningCadence; == avgCadence /* max_cadence - Unit: rpm */ unsigned char maxCadence; /* max_cadence - Unit: rpm */ //unsigned char maxRunningCadence; == maxCadence /* avg_power - Unit: watts */ unsigned short avgPower; /* max_power - Unit: watts */ unsigned short maxPower; /* total_ascent - Unit: m */ unsigned short totalAscent; /* total_descent - Unit: m */ unsigned short totalDescent; /* intensity - Unit: */ unsigned char intensity; /* lap_trigger - Unit: */ unsigned char lapTrigger; /* sport - Unit: */ unsigned char sport; /* event_group - Unit: */ unsigned char eventGroup; /* num_lengths - Unit: lengths */ unsigned short numLengths; /* normalized_power - Unit: watts */ unsigned short normalizedPower; /* left_right_balance - Unit: */ unsigned short leftRightBalance; /* first_length_index - Unit: */ unsigned short firstLengthIndex; /* avg_stroke_distance - Unit: m */ float avgStrokeDistance; /* swim_stroke - Unit: */ unsigned char swimStroke; /* sub_sport - Unit: */ unsigned char subSport; /* num_active_lengths - Unit: lengths */ unsigned short numActiveLengths; /* total_work - Unit: J */ unsigned long totalWork; /* avg_altitude - Unit: m */ float avgAltitude; /* max_altitude - Unit: m */ float maxAltitude; /* gps_accuracy - Unit: m */ unsigned char gpsAccuracy; /* avg_grade - Unit: % */ float avgGrade; /* avg_pos_grade - Unit: % */ float avgPosGrade; /* avg_neg_grade - Unit: % */ float avgNegGrade; /* max_pos_grade - Unit: % */ float maxPosGrade; /* max_neg_grade - Unit: % */ float maxNegGrade; /* avg_temperature - Unit: C */ signed char avgTemperature; /* max_temperature - Unit: C */ signed char maxTemperature; /* total_moving_time - Unit: s */ float totalMovingTime; /* avg_pos_vertical_speed - Unit: m/s */ float avgPosVerticalSpeed; /* avg_neg_vertical_speed - Unit: m/s */ float avgNegVerticalSpeed; /* max_pos_vertical_speed - Unit: m/s */ float maxPosVerticalSpeed; /* max_neg_vertical_speed - Unit: m/s */ float maxNegVerticalSpeed; /* time_in_hr_zone - Unit: s */ unsigned char numTimeInHrZone; /* time_in_speed_zone - Unit: s */ unsigned char numTimeInSpeedZone; /* time_in_cadence_zone - Unit: s */ unsigned char numTimeInCadenceZone; /* time_in_power_zone - Unit: s */ unsigned char numTimeInPowerZone; /* repetition_num - Unit: */ unsigned short repetitionNum; /* min_altitude - Unit: m */ float minAltitude; /* min_heart_rate - Unit: bpm */ unsigned char minHeartRate; /* wkt_step_index - Unit: */ unsigned short wktStepIndex; public: float getAvgAltitude() const { return avgAltitude; } void setAvgAltitude(float avgAltitude) { this->avgAltitude = avgAltitude; } unsigned char getAvgCadence() const { return avgCadence; } void setAvgCadence(unsigned char avgCadence) { this->avgCadence = avgCadence; } float getAvgGrade() const { return avgGrade; } void setAvgGrade(float avgGrade) { this->avgGrade = avgGrade; } unsigned char getAvgHeartRate() const { return avgHeartRate; } void setAvgHeartRate(unsigned char avgHeartRate) { this->avgHeartRate = avgHeartRate; } float getAvgNegGrade() const { return avgNegGrade; } void setAvgNegGrade(float avgNegGrade) { this->avgNegGrade = avgNegGrade; } float getAvgNegVerticalSpeed() const { return avgNegVerticalSpeed; } void setAvgNegVerticalSpeed(float avgNegVerticalSpeed) { this->avgNegVerticalSpeed = avgNegVerticalSpeed; } float getAvgPosGrade() const { return avgPosGrade; } void setAvgPosGrade(float avgPosGrade) { this->avgPosGrade = avgPosGrade; } float getAvgPosVerticalSpeed() const { return avgPosVerticalSpeed; } void setAvgPosVerticalSpeed(float avgPosVerticalSpeed) { this->avgPosVerticalSpeed = avgPosVerticalSpeed; } unsigned short getAvgPower() const { return avgPower; } void setAvgPower(unsigned short avgPower) { this->avgPower = avgPower; } unsigned char getAvgRunningCadence() const { return avgCadence; } void setAvgRunningCadence(unsigned char avgRunningCadence) { this->avgCadence = avgRunningCadence; } float getAvgSpeed() const { return avgSpeed; } void setAvgSpeed(float avgSpeed) { this->avgSpeed = avgSpeed; } float getAvgStrokeDistance() const { return avgStrokeDistance; } void setAvgStrokeDistance(float avgStrokeDistance) { this->avgStrokeDistance = avgStrokeDistance; } signed char getAvgTemperature() const { return avgTemperature; } void setAvgTemperature(signed char avgTemperature) { this->avgTemperature = avgTemperature; } signed long getEndPositionLat() const { return endPositionLat; } void setEndPositionLat(signed long endPositionLat) { this->endPositionLat = endPositionLat; } signed long getEndPositionLong() const { return endPositionLong; } void setEndPositionLong(signed long endPositionLong) { this->endPositionLong = endPositionLong; } unsigned char getEvent() const { return event; } void setEvent(unsigned char event) { this->event = event; } unsigned char getEventGroup() const { return eventGroup; } void setEventGroup(unsigned char eventGroup) { this->eventGroup = eventGroup; } unsigned char getEventType() const { return eventType; } void setEventType(unsigned char eventType) { this->eventType = eventType; } unsigned short getFirstLengthIndex() const { return firstLengthIndex; } void setFirstLengthIndex(unsigned short firstLengthIndex) { this->firstLengthIndex = firstLengthIndex; } unsigned char getGpsAccuracy() const { return gpsAccuracy; } void setGpsAccuracy(unsigned char gpsAccuracy) { this->gpsAccuracy = gpsAccuracy; } unsigned char getIntensity() const { return intensity; } void setIntensity(unsigned char intensity) { this->intensity = intensity; } unsigned char getLapTrigger() const { return lapTrigger; } void setLapTrigger(unsigned char lapTrigger) { this->lapTrigger = lapTrigger; } unsigned short getLeftRightBalance() const { return leftRightBalance; } void setLeftRightBalance(unsigned short leftRightBalance) { this->leftRightBalance = leftRightBalance; } float getMaxAltitude() const { return maxAltitude; } void setMaxAltitude(float maxAltitude) { this->maxAltitude = maxAltitude; } unsigned char getMaxCadence() const { return maxCadence; } void setMaxCadence(unsigned char maxCadence) { this->maxCadence = maxCadence; } unsigned char getMaxHeartRate() const { return maxHeartRate; } void setMaxHeartRate(unsigned char maxHeartRate) { this->maxHeartRate = maxHeartRate; } float getMaxNegGrade() const { return maxNegGrade; } void setMaxNegGrade(float maxNegGrade) { this->maxNegGrade = maxNegGrade; } float getMaxNegVerticalSpeed() const { return maxNegVerticalSpeed; } void setMaxNegVerticalSpeed(float maxNegVerticalSpeed) { this->maxNegVerticalSpeed = maxNegVerticalSpeed; } float getMaxPosGrade() const { return maxPosGrade; } void setMaxPosGrade(float maxPosGrade) { this->maxPosGrade = maxPosGrade; } float getMaxPosVerticalSpeed() const { return maxPosVerticalSpeed; } void setMaxPosVerticalSpeed(float maxPosVerticalSpeed) { this->maxPosVerticalSpeed = maxPosVerticalSpeed; } unsigned short getMaxPower() const { return maxPower; } void setMaxPower(unsigned short maxPower) { this->maxPower = maxPower; } unsigned char getMaxRunningCadence() const { return maxCadence; } void setMaxRunningCadence(unsigned char maxRunningCadence) { this->maxCadence = maxRunningCadence; } float getMaxSpeed() const { return maxSpeed; } void setMaxSpeed(float maxSpeed) { this->maxSpeed = maxSpeed; } signed char getMaxTemperature() const { return maxTemperature; } void setMaxTemperature(signed char maxTemperature) { this->maxTemperature = maxTemperature; } unsigned short getMessageIndex() const { return messageIndex; } void setMessageIndex(unsigned short messageIndex) { this->messageIndex = messageIndex; } float getMinAltitude() const { return minAltitude; } void setMinAltitude(float minAltitude) { this->minAltitude = minAltitude; } unsigned char getMinHeartRate() const { return minHeartRate; } void setMinHeartRate(unsigned char minHeartRate) { this->minHeartRate = minHeartRate; } unsigned short getNormalizedPower() const { return normalizedPower; } void setNormalizedPower(unsigned short normalizedPower) { this->normalizedPower = normalizedPower; } unsigned short getNumActiveLengths() const { return numActiveLengths; } void setNumActiveLengths(unsigned short numActiveLengths) { this->numActiveLengths = numActiveLengths; } unsigned short getNumLengths() const { return numLengths; } void setNumLengths(unsigned short numLengths) { this->numLengths = numLengths; } unsigned char getNumTimeInCadenceZone() const { return numTimeInCadenceZone; } void setNumTimeInCadenceZone(unsigned char numTimeInCadenceZone) { this->numTimeInCadenceZone = numTimeInCadenceZone; } unsigned char getNumTimeInHrZone() const { return numTimeInHrZone; } void setNumTimeInHrZone(unsigned char numTimeInHrZone) { this->numTimeInHrZone = numTimeInHrZone; } unsigned char getNumTimeInPowerZone() const { return numTimeInPowerZone; } void setNumTimeInPowerZone(unsigned char numTimeInPowerZone) { this->numTimeInPowerZone = numTimeInPowerZone; } unsigned char getNumTimeInSpeedZone() const { return numTimeInSpeedZone; } void setNumTimeInSpeedZone(unsigned char numTimeInSpeedZone) { this->numTimeInSpeedZone = numTimeInSpeedZone; } unsigned short getRepetitionNum() const { return repetitionNum; } void setRepetitionNum(unsigned short repetitionNum) { this->repetitionNum = repetitionNum; } unsigned char getSport() const { return sport; } void setSport(unsigned char sport) { this->sport = sport; } signed long getStartPositionLat() const { return startPositionLat; } void setStartPositionLat(signed long startPositionLat) { this->startPositionLat = startPositionLat; } signed long getStartPositionLong() const { return startPositionLong; } void setStartPositionLong(signed long startPositionLong) { this->startPositionLong = startPositionLong; } unsigned long getStartTime() const { return startTime; } void setStartTime(unsigned long startTime) { this->startTime = startTime; } unsigned char getSubSport() const { return subSport; } void setSubSport(unsigned char subSport) { this->subSport = subSport; } unsigned char getSwimStroke() const { return swimStroke; } void setSwimStroke(unsigned char swimStroke) { this->swimStroke = swimStroke; } unsigned long getTimestamp() const { return timestamp; } void setTimestamp(unsigned long timestamp) { this->timestamp = timestamp; } unsigned short getTotalAscent() const { return totalAscent; } void setTotalAscent(unsigned short totalAscent) { this->totalAscent = totalAscent; } unsigned short getTotalCalories() const { return totalCalories; } void setTotalCalories(unsigned short totalCalories) { this->totalCalories = totalCalories; } unsigned long getTotalCycles() const { return totalCycles; } void setTotalCycles(unsigned long totalCycles) { this->totalCycles = totalCycles; } unsigned short getTotalDescent() const { return totalDescent; } void setTotalDescent(unsigned short totalDescent) { this->totalDescent = totalDescent; } float getTotalDistance() const { return totalDistance; } void setTotalDistance(float totalDistance) { this->totalDistance = totalDistance; } float getTotalElapsedTime() const { return totalElapsedTime; } void setTotalElapsedTime(float totalElapsedTime) { this->totalElapsedTime = totalElapsedTime; } unsigned short getTotalFatCalories() const { return totalFatCalories; } void setTotalFatCalories(unsigned short totalFatCalories) { this->totalFatCalories = totalFatCalories; } float getTotalMovingTime() const { return totalMovingTime; } void setTotalMovingTime(float totalMovingTime) { this->totalMovingTime = totalMovingTime; } unsigned long getTotalStrides() const { return totalStrides; } void setTotalStrides(unsigned long totalStrides) { this->totalStrides = totalStrides; } float getTotalTimerTime() const { return totalTimerTime; } void setTotalTimerTime(float totalTimerTime) { this->totalTimerTime = totalTimerTime; } unsigned long getTotalWork() const { return totalWork; } void setTotalWork(unsigned long totalWork) { this->totalWork = totalWork; } unsigned short getWktStepIndex() const { return wktStepIndex; } void setWktStepIndex(unsigned short wktStepIndex) { this->wktStepIndex = wktStepIndex; } }; #endif // FITMSG_LAP_H GarminPlugin-0.3.23/src/fit/fitMsg_Listener.hpp000066400000000000000000000024241232766717500213750ustar00rootroot00000000000000/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */ /* * GarminPlugin * Copyright (C) Andreas Diesner 2011 * * GarminPlugin is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GarminPlugin is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #ifndef FITMSG_LISTENER_H #define FITMSG_LISTENER_H #include #include "fitMsg.hpp" using namespace std; class FitMsg_Listener { public: FitMsg_Listener() {}; virtual ~FitMsg_Listener() {}; /** * Overwrite to receive fit messages */ virtual void fitMsgReceived(FitMsg *msg)=0; /** * Overwrite and enable debug to receive debug messages */ virtual void fitDebugMsg(string msg) {}; }; #endif // FITMSG_LISTENER_H GarminPlugin-0.3.23/src/fit/fitMsg_Record.hpp000066400000000000000000000250231232766717500210260ustar00rootroot00000000000000/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */ /* * GarminPlugin * Copyright (C) Andreas Diesner 2013 * * GarminPlugin is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GarminPlugin is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #ifndef FITMSG_RECORD_H #define FITMSG_RECORD_H #define FIT_MESSAGE_RECORD ((unsigned char)20) class FitMsg_Record : public FitMsg { public: FitMsg_Record() : FitMsg(FIT_MESSAGE_RECORD) { }; virtual ~FitMsg_Record() {}; /** * Adds a field to the message. Unknown fields are rejected * @return bool if field was known to the message */ bool addField(unsigned char fieldDefNum, unsigned char size, unsigned char baseType, unsigned char arch, char * data) { //TODO: Compare size with expected size //TODO: Compare baseType with expected baseType bool fieldWasAdded = true; switch (fieldDefNum) { case 253: setTimestamp(read0x86(data,arch)); break; case 0: setPositionLat(read0x85(data,arch)); break; case 1: setPositionLong(read0x85(data,arch)); break; case 2: setAltitude(read0x88(data,arch,5,500,0x84)); break; case 3: setHeartRate(read0x02(data,arch)); break; case 4: setCadence(read0x02(data,arch)); break; case 5: setDistance(read0x88(data,arch,100,0,0x86)); break; case 6: setSpeed(read0x88(data,arch,1000,0,0x84)); break; case 7: setPower(read0x84(data,arch)); break; case 9: setGrade(read0x88(data,arch,100,0,0x83)); break; case 10: setResistance(read0x02(data,arch)); break; case 11: setTimeFromCourse(read0x88(data,arch,1000,0,0x85)); break; case 12: setCycleLength(read0x88(data,arch,100,0,0x02)); break; case 13: setTemperature(read0x01(data,arch)); break; case 17: setNumSpeed1s(read0x02(data,arch)); break; case 18: setCycles(read0x02(data,arch)); break; case 19: setTotalCycles(read0x86(data,arch)); break; case 28: setCompressedAccumulatedPower(read0x84(data,arch)); break; case 29: setAccumulatedPower(read0x86(data,arch)); break; case 30: setLeftRightBalance(read0x02(data,arch)); break; case 31: setGpsAccuracy(read0x02(data,arch)); break; case 32: setVerticalSpeed(read0x88(data,arch,1000,0,0x83)); break; case 33: setCalories(read0x84(data,arch)); break; case 43: setLeftTorqueEffectiveness(read0x88(data,arch,2,0,0x02)); break; case 44: setRightTorqueEffectiveness(read0x88(data,arch,2,0,0x02)); break; case 45: setLeftPedalSmoothness(read0x88(data,arch,2,0,0x02)); break; case 46: setRightPedalSmoothness(read0x88(data,arch,2,0,0x02)); break; case 47: setCombinedPedalSmoothness(read0x88(data,arch,2,0,0x02)); break; case 52: setCadence256(read0x88(data,arch,256,0,0x84)); break; default: fieldWasAdded = false; break; } return fieldWasAdded; }; private: /* timestamp - Unit: s */ unsigned long timestamp; /* position_lat - Unit: semicircles */ signed long positionLat; /* position_long - Unit: semicircles */ signed long positionLong; /* altitude - Unit: m */ float altitude; /* heart_rate - Unit: bpm */ unsigned char heartRate; /* cadence - Unit: rpm */ unsigned char cadence; /* distance - Unit: m */ float distance; /* speed - Unit: m/s */ float speed; /* power - Unit: watts */ unsigned short power; /* compressed_speed_distance - Unit: */ unsigned char numCompressedSpeedDistance; /* grade - Unit: % */ float grade; /* resistance - Unit: */ unsigned char resistance; /* time_from_course - Unit: s */ float timeFromCourse; /* cycle_length - Unit: m */ float cycleLength; /* temperature - Unit: C */ signed char temperature; /* speed_1s - Unit: m/s */ unsigned char numSpeed1s; /* cycles - Unit: */ unsigned char cycles; /* total_cycles - Unit: cycles */ unsigned long totalCycles; /* compressed_accumulated_power - Unit: */ unsigned short compressedAccumulatedPower; /* accumulated_power - Unit: watts */ unsigned long accumulatedPower; /* left_right_balance - Unit: */ unsigned char leftRightBalance; /* gps_accuracy - Unit: m */ unsigned char gpsAccuracy; /* vertical_speed - Unit: m/s */ float verticalSpeed; /* calories - Unit: kcal */ unsigned short calories; /* left_torque_effectiveness - Unit: percent */ float leftTorqueEffectiveness; /* right_torque_effectiveness - Unit: percent */ float rightTorqueEffectiveness; /* left_pedal_smoothness - Unit: percent */ float leftPedalSmoothness; /* right_pedal_smoothness - Unit: percent */ float rightPedalSmoothness; /* combined_pedal_smoothness - Unit: percent */ float combinedPedalSmoothness; /* cadence256 - Unit: rpm */ float cadence256; public: unsigned long getAccumulatedPower() const { return accumulatedPower; } void setAccumulatedPower(unsigned long accumulatedPower) { this->accumulatedPower = accumulatedPower; } float getAltitude() const { return altitude; } void setAltitude(float altitude) { this->altitude = altitude; } unsigned char getCadence() const { return cadence; } void setCadence(unsigned char cadence) { this->cadence = cadence; } float getCadence256() const { return cadence256; } void setCadence256(float cadence256) { this->cadence256 = cadence256; } unsigned short getCalories() const { return calories; } void setCalories(unsigned short calories) { this->calories = calories; } float getCombinedPedalSmoothness() const { return combinedPedalSmoothness; } void setCombinedPedalSmoothness(float combinedPedalSmoothness) { this->combinedPedalSmoothness = combinedPedalSmoothness; } unsigned short getCompressedAccumulatedPower() const { return compressedAccumulatedPower; } void setCompressedAccumulatedPower( unsigned short compressedAccumulatedPower) { this->compressedAccumulatedPower = compressedAccumulatedPower; } float getCycleLength() const { return cycleLength; } void setCycleLength(float cycleLength) { this->cycleLength = cycleLength; } unsigned char getCycles() const { return cycles; } void setCycles(unsigned char cycles) { this->cycles = cycles; } float getDistance() const { return distance; } void setDistance(float distance) { this->distance = distance; } unsigned char getGpsAccuracy() const { return gpsAccuracy; } void setGpsAccuracy(unsigned char gpsAccuracy) { this->gpsAccuracy = gpsAccuracy; } float getGrade() const { return grade; } void setGrade(float grade) { this->grade = grade; } unsigned char getHeartRate() const { return heartRate; } void setHeartRate(unsigned char heartRate) { this->heartRate = heartRate; } float getLeftPedalSmoothness() const { return leftPedalSmoothness; } void setLeftPedalSmoothness(float leftPedalSmoothness) { this->leftPedalSmoothness = leftPedalSmoothness; } unsigned char getLeftRightBalance() const { return leftRightBalance; } void setLeftRightBalance(unsigned char leftRightBalance) { this->leftRightBalance = leftRightBalance; } float getLeftTorqueEffectiveness() const { return leftTorqueEffectiveness; } void setLeftTorqueEffectiveness(float leftTorqueEffectiveness) { this->leftTorqueEffectiveness = leftTorqueEffectiveness; } unsigned char getNumCompressedSpeedDistance() const { return numCompressedSpeedDistance; } void setNumCompressedSpeedDistance( unsigned char numCompressedSpeedDistance) { this->numCompressedSpeedDistance = numCompressedSpeedDistance; } unsigned char getNumSpeed1s() const { return numSpeed1s; } void setNumSpeed1s(unsigned char numSpeed1s) { this->numSpeed1s = numSpeed1s; } signed long getPositionLat() const { return positionLat; } void setPositionLat(signed long positionLat) { this->positionLat = positionLat; } signed long getPositionLong() const { return positionLong; } void setPositionLong(signed long positionLong) { this->positionLong = positionLong; } unsigned short getPower() const { return power; } void setPower(unsigned short power) { this->power = power; } unsigned char getResistance() const { return resistance; } void setResistance(unsigned char resistance) { this->resistance = resistance; } float getRightPedalSmoothness() const { return rightPedalSmoothness; } void setRightPedalSmoothness(float rightPedalSmoothness) { this->rightPedalSmoothness = rightPedalSmoothness; } float getRightTorqueEffectiveness() const { return rightTorqueEffectiveness; } void setRightTorqueEffectiveness(float rightTorqueEffectiveness) { this->rightTorqueEffectiveness = rightTorqueEffectiveness; } float getSpeed() const { return speed; } void setSpeed(float speed) { this->speed = speed; } signed char getTemperature() const { return temperature; } void setTemperature(signed char temperature) { this->temperature = temperature; } float getTimeFromCourse() const { return timeFromCourse; } void setTimeFromCourse(float timeFromCourse) { this->timeFromCourse = timeFromCourse; } unsigned long getTimestamp() const { return timestamp; } void setTimestamp(unsigned long timestamp) { this->timestamp = timestamp; } unsigned long getTotalCycles() const { return totalCycles; } void setTotalCycles(unsigned long totalCycles) { this->totalCycles = totalCycles; } float getVerticalSpeed() const { return verticalSpeed; } void setVerticalSpeed(float verticalSpeed) { this->verticalSpeed = verticalSpeed; } }; #endif // FITMSG_RECORD_H GarminPlugin-0.3.23/src/fit/fitMsg_Session.hpp000066400000000000000000000525151232766717500212410ustar00rootroot00000000000000/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */ /* * GarminPlugin * Copyright (C) Andreas Diesner 2013 * * GarminPlugin is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GarminPlugin is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #ifndef FITMSG_SESSION_H #define FITMSG_SESSION_H #define FIT_MESSAGE_SESSION ((unsigned char)18) #include "fitDefines.hpp" #include class FitMsg_Session: public FitMsg { public: FitMsg_Session() : FitMsg(FIT_MESSAGE_SESSION) { }; virtual ~FitMsg_Session() {}; /** * Adds a field to the message. Unknown fields are rejected * @return bool if field was known to the message */ bool addField(unsigned char fieldDefNum, unsigned char size, unsigned char baseType, unsigned char arch, char * data) { //TODO: Compare size with expected size //TODO: Compare baseType with expected baseType bool fieldWasAdded = true; switch (fieldDefNum) { case 254: setMessageIndex(read0x84(data,arch)); break; case 253: setTimestamp(read0x86(data,arch)); break; case 0: setEvent(read0x00(data,arch)); break; case 1: setEventType(read0x00(data,arch)); break; case 2: setStartTime(read0x86(data,arch)); break; case 3: setStartPositionLat(read0x85(data,arch)); break; case 4: setStartPositionLong(read0x85(data,arch)); break; case 5: setSport(read0x00(data,arch)); break; case 6: setSubSport(read0x00(data,arch)); break; case 7: setTotalElapsedTime(read0x88(data,arch,1000,0,0x86)); break; case 8: setTotalTimerTime(read0x88(data,arch,1000,0,0x86)); break; case 9: setTotalDistance(read0x88(data,arch,100,0,0x86)); break; case 10: setTotalCycles(read0x86(data,arch)); break; case 11: setTotalCalories(read0x84(data,arch)); break; case 13: setTotalFatCalories(read0x84(data,arch)); break; case 14: setAvgSpeed(read0x88(data,arch,1000,0,0x84)); break; case 15: setMaxSpeed(read0x88(data,arch,1000,0,0x84)); break; case 16: setAvgHeartRate(read0x02(data,arch)); break; case 17: setMaxHeartRate(read0x02(data,arch)); break; case 18: setAvgCadence(read0x02(data,arch)); break; case 19: setMaxCadence(read0x02(data,arch)); break; case 20: setAvgPower(read0x84(data,arch)); break; case 21: setMaxPower(read0x84(data,arch)); break; case 22: setTotalAscent(read0x84(data,arch)); break; case 23: setTotalDescent(read0x84(data,arch)); break; case 24: setTotalTrainingEffect(read0x88(data,arch,10,0,0x02)); break; case 25: setFirstLapIndex(read0x84(data,arch)); break; case 26: setNumLaps(read0x84(data,arch)); break; case 27: setEventGroup(read0x02(data,arch)); break; case 28: setTrigger(read0x00(data,arch)); break; case 29: setNecLat(read0x85(data,arch)); break; case 30: setNecLong(read0x85(data,arch)); break; case 31: setSwcLat(read0x85(data,arch)); break; case 32: setSwcLong(read0x85(data,arch)); break; case 34: setNormalizedPower(read0x84(data,arch)); break; case 35: setTrainingStressScore(read0x88(data,arch,10,0,0x84)); break; case 36: setIntensityFactor(read0x88(data,arch,1000,0,0x84)); break; case 37: setLeftRightBalance(read0x84(data,arch)); break; case 41: setAvgStrokeCount(read0x88(data,arch,10,0,0x86)); break; case 42: setAvgStrokeDistance(read0x88(data,arch,100,0,0x84)); break; case 43: setSwimStroke(read0x00(data,arch)); break; case 44: setPoolLength(read0x88(data,arch,100,0,0x84)); break; case 46: setPoolLengthUnit(read0x00(data,arch)); break; case 47: setNumActiveLengths(read0x84(data,arch)); break; case 48: setTotalWork(read0x86(data,arch)); break; case 49: setAvgAltitude(read0x88(data,arch,5,500,0x84)); break; case 50: setMaxAltitude(read0x88(data,arch,5,500,0x84)); break; case 51: setGpsAccuracy(read0x02(data,arch)); break; case 52: setAvgGrade(read0x88(data,arch,100,0,0x83)); break; case 53: setAvgPosGrade(read0x88(data,arch,100,0,0x83)); break; case 54: setAvgNegGrade(read0x88(data,arch,100,0,0x83)); break; case 55: setMaxPosGrade(read0x88(data,arch,100,0,0x83)); break; case 56: setMaxNegGrade(read0x88(data,arch,100,0,0x83)); break; case 57: setAvgTemperature(read0x01(data,arch)); break; case 58: setMaxTemperature(read0x01(data,arch)); break; case 59: setTotalMovingTime(read0x88(data,arch,1000,0,0x86)); break; case 60: setAvgPosVerticalSpeed(read0x88(data,arch,1000,0,0x83)); break; case 61: setAvgNegVerticalSpeed(read0x88(data,arch,1000,0,0x83)); break; case 62: setMaxPosVerticalSpeed(read0x88(data,arch,1000,0,0x83)); break; case 63: setMaxNegVerticalSpeed(read0x88(data,arch,1000,0,0x83)); break; case 64: setMinHeartRate(read0x02(data,arch)); break; case 65: setNumTimeInHrZone(read0x02(data,arch)); break; case 66: setNumTimeInSpeedZone(read0x02(data,arch)); break; case 67: setNumTimeInCadenceZone(read0x02(data,arch)); break; case 68: setNumTimeInPowerZone(read0x02(data,arch)); break; case 69: setAvgLapTime(read0x88(data,arch,1000,0,0x86)); break; case 70: setBestLapIndex(read0x84(data,arch)); break; case 71: setMinAltitude(read0x88(data,arch,5,500,0x84)); break; default: fieldWasAdded = false; break; } return fieldWasAdded; }; private: /* message_index - Unit: */ unsigned short messageIndex; /* timestamp - Unit: s */ unsigned long timestamp; /* event - Unit: */ unsigned char event; /* event_type - Unit: */ unsigned char eventType; /* start_time - Unit: */ unsigned long startTime; /* start_position_lat - Unit: semicircles */ signed long startPositionLat; /* start_position_long - Unit: semicircles */ signed long startPositionLong; /* sport - Unit: */ unsigned char sport; /* sub_sport - Unit: */ unsigned char subSport; /* total_elapsed_time - Unit: s */ float totalElapsedTime; /* total_timer_time - Unit: s */ float totalTimerTime; /* total_distance - Unit: m */ float totalDistance; /* total_cycles - Unit: cycles */ unsigned long totalCycles; /* total_cycles - Unit: cycles */ //unsigned long totalStrides; == totalCycles /* total_calories - Unit: kcal */ unsigned short totalCalories; /* total_fat_calories - Unit: kcal */ unsigned short totalFatCalories; /* avg_speed - Unit: m/s */ float avgSpeed; /* max_speed - Unit: m/s */ float maxSpeed; /* avg_heart_rate - Unit: bpm */ unsigned char avgHeartRate; /* max_heart_rate - Unit: bpm */ unsigned char maxHeartRate; /* avg_cadence - Unit: rpm */ unsigned char avgCadence; /* avg_cadence - Unit: rpm */ //unsigned char avgRunningCadence; == avgCadence /* max_cadence - Unit: rpm */ unsigned char maxCadence; /* max_cadence - Unit: rpm */ //unsigned char maxRunningCadence; == maxCadence /* avg_power - Unit: watts */ unsigned short avgPower; /* max_power - Unit: watts */ unsigned short maxPower; /* total_ascent - Unit: m */ unsigned short totalAscent; /* total_descent - Unit: m */ unsigned short totalDescent; /* total_training_effect - Unit: */ float totalTrainingEffect; /* first_lap_index - Unit: */ unsigned short firstLapIndex; /* num_laps - Unit: */ unsigned short numLaps; /* event_group - Unit: */ unsigned char eventGroup; /* trigger - Unit: */ unsigned char trigger; /* nec_lat - Unit: semicircles */ signed long necLat; /* nec_long - Unit: semicircles */ signed long necLong; /* swc_lat - Unit: semicircles */ signed long swcLat; /* swc_long - Unit: semicircles */ signed long swcLong; /* normalized_power - Unit: watts */ unsigned short normalizedPower; /* training_stress_score - Unit: tss */ float trainingStressScore; /* intensity_factor - Unit: if */ float intensityFactor; /* left_right_balance - Unit: */ unsigned short leftRightBalance; /* avg_stroke_count - Unit: strokes/lap */ float avgStrokeCount; /* avg_stroke_distance - Unit: m */ float avgStrokeDistance; /* swim_stroke - Unit: swim_stroke */ unsigned char swimStroke; /* pool_length - Unit: m */ float poolLength; /* pool_length_unit - Unit: */ unsigned char poolLengthUnit; /* num_active_lengths - Unit: lengths */ unsigned short numActiveLengths; /* total_work - Unit: J */ unsigned long totalWork; /* avg_altitude - Unit: m */ float avgAltitude; /* max_altitude - Unit: m */ float maxAltitude; /* gps_accuracy - Unit: m */ unsigned char gpsAccuracy; /* avg_grade - Unit: % */ float avgGrade; /* avg_pos_grade - Unit: % */ float avgPosGrade; /* avg_neg_grade - Unit: % */ float avgNegGrade; /* max_pos_grade - Unit: % */ float maxPosGrade; /* max_neg_grade - Unit: % */ float maxNegGrade; /* avg_temperature - Unit: C */ signed char avgTemperature; /* max_temperature - Unit: C */ signed char maxTemperature; /* total_moving_time - Unit: s */ float totalMovingTime; /* avg_pos_vertical_speed - Unit: m/s */ float avgPosVerticalSpeed; /* avg_neg_vertical_speed - Unit: m/s */ float avgNegVerticalSpeed; /* max_pos_vertical_speed - Unit: m/s */ float maxPosVerticalSpeed; /* max_neg_vertical_speed - Unit: m/s */ float maxNegVerticalSpeed; /* min_heart_rate - Unit: bpm */ unsigned char minHeartRate; /* time_in_hr_zone - Unit: s */ unsigned char numTimeInHrZone; /* time_in_speed_zone - Unit: s */ unsigned char numTimeInSpeedZone; /* time_in_cadence_zone - Unit: s */ unsigned char numTimeInCadenceZone; /* time_in_power_zone - Unit: s */ unsigned char numTimeInPowerZone; /* avg_lap_time - Unit: s */ float avgLapTime; /* best_lap_index - Unit: */ unsigned short bestLapIndex; /* min_altitude - Unit: m */ float minAltitude; public: float getAvgAltitude() const { return avgAltitude; } void setAvgAltitude(float avgAltitude) { this->avgAltitude = avgAltitude; } unsigned char getAvgCadence() const { return avgCadence; } void setAvgCadence(unsigned char avgCadence) { this->avgCadence = avgCadence; } float getAvgGrade() const { return avgGrade; } void setAvgGrade(float avgGrade) { this->avgGrade = avgGrade; } unsigned char getAvgHeartRate() const { return avgHeartRate; } void setAvgHeartRate(unsigned char avgHeartRate) { this->avgHeartRate = avgHeartRate; } float getAvgLapTime() const { return avgLapTime; } void setAvgLapTime(float avgLapTime) { this->avgLapTime = avgLapTime; } float getAvgNegGrade() const { return avgNegGrade; } void setAvgNegGrade(float avgNegGrade) { this->avgNegGrade = avgNegGrade; } float getAvgNegVerticalSpeed() const { return avgNegVerticalSpeed; } void setAvgNegVerticalSpeed(float avgNegVerticalSpeed) { this->avgNegVerticalSpeed = avgNegVerticalSpeed; } float getAvgPosGrade() const { return avgPosGrade; } void setAvgPosGrade(float avgPosGrade) { this->avgPosGrade = avgPosGrade; } float getAvgPosVerticalSpeed() const { return avgPosVerticalSpeed; } void setAvgPosVerticalSpeed(float avgPosVerticalSpeed) { this->avgPosVerticalSpeed = avgPosVerticalSpeed; } unsigned short getAvgPower() const { return avgPower; } void setAvgPower(unsigned short avgPower) { this->avgPower = avgPower; } unsigned char getAvgRunningCadence() const { return avgCadence; } void setAvgRunningCadence(unsigned char avgRunningCadence) { this->avgCadence = avgRunningCadence; } float getAvgSpeed() const { return avgSpeed; } void setAvgSpeed(float avgSpeed) { this->avgSpeed = avgSpeed; } float getAvgStrokeCount() const { return avgStrokeCount; } void setAvgStrokeCount(float avgStrokeCount) { this->avgStrokeCount = avgStrokeCount; } float getAvgStrokeDistance() const { return avgStrokeDistance; } void setAvgStrokeDistance(float avgStrokeDistance) { this->avgStrokeDistance = avgStrokeDistance; } signed char getAvgTemperature() const { return avgTemperature; } void setAvgTemperature(signed char avgTemperature) { this->avgTemperature = avgTemperature; } unsigned short getBestLapIndex() const { return bestLapIndex; } void setBestLapIndex(unsigned short bestLapIndex) { this->bestLapIndex = bestLapIndex; } unsigned char getEvent() const { return event; } void setEvent(unsigned char event) { this->event = event; } unsigned char getEventGroup() const { return eventGroup; } void setEventGroup(unsigned char eventGroup) { this->eventGroup = eventGroup; } unsigned char getEventType() const { return eventType; } void setEventType(unsigned char eventType) { this->eventType = eventType; } unsigned short getFirstLapIndex() const { return firstLapIndex; } void setFirstLapIndex(unsigned short firstLapIndex) { this->firstLapIndex = firstLapIndex; } unsigned char getGpsAccuracy() const { return gpsAccuracy; } void setGpsAccuracy(unsigned char gpsAccuracy) { this->gpsAccuracy = gpsAccuracy; } float getIntensityFactor() const { return intensityFactor; } void setIntensityFactor(float intensityFactor) { this->intensityFactor = intensityFactor; } unsigned short getLeftRightBalance() const { return leftRightBalance; } void setLeftRightBalance(unsigned short leftRightBalance) { this->leftRightBalance = leftRightBalance; } float getMaxAltitude() const { return maxAltitude; } void setMaxAltitude(float maxAltitude) { this->maxAltitude = maxAltitude; } unsigned char getMaxCadence() const { return maxCadence; } void setMaxCadence(unsigned char maxCadence) { this->maxCadence = maxCadence; } unsigned char getMaxHeartRate() const { return maxHeartRate; } void setMaxHeartRate(unsigned char maxHeartRate) { this->maxHeartRate = maxHeartRate; } float getMaxNegGrade() const { return maxNegGrade; } void setMaxNegGrade(float maxNegGrade) { this->maxNegGrade = maxNegGrade; } float getMaxNegVerticalSpeed() const { return maxNegVerticalSpeed; } void setMaxNegVerticalSpeed(float maxNegVerticalSpeed) { this->maxNegVerticalSpeed = maxNegVerticalSpeed; } float getMaxPosGrade() const { return maxPosGrade; } void setMaxPosGrade(float maxPosGrade) { this->maxPosGrade = maxPosGrade; } float getMaxPosVerticalSpeed() const { return maxPosVerticalSpeed; } void setMaxPosVerticalSpeed(float maxPosVerticalSpeed) { this->maxPosVerticalSpeed = maxPosVerticalSpeed; } unsigned short getMaxPower() const { return maxPower; } void setMaxPower(unsigned short maxPower) { this->maxPower = maxPower; } unsigned char getMaxRunningCadence() const { return maxCadence; } void setMaxRunningCadence(unsigned char maxRunningCadence) { this->maxCadence = maxRunningCadence; } float getMaxSpeed() const { return maxSpeed; } void setMaxSpeed(float maxSpeed) { this->maxSpeed = maxSpeed; } signed char getMaxTemperature() const { return maxTemperature; } void setMaxTemperature(signed char maxTemperature) { this->maxTemperature = maxTemperature; } unsigned short getMessageIndex() const { return messageIndex; } void setMessageIndex(unsigned short messageIndex) { this->messageIndex = messageIndex; } float getMinAltitude() const { return minAltitude; } void setMinAltitude(float minAltitude) { this->minAltitude = minAltitude; } unsigned char getMinHeartRate() const { return minHeartRate; } void setMinHeartRate(unsigned char minHeartRate) { this->minHeartRate = minHeartRate; } signed long getNecLat() const { return necLat; } void setNecLat(signed long necLat) { this->necLat = necLat; } signed long getNecLong() const { return necLong; } void setNecLong(signed long necLong) { this->necLong = necLong; } unsigned short getNormalizedPower() const { return normalizedPower; } void setNormalizedPower(unsigned short normalizedPower) { this->normalizedPower = normalizedPower; } unsigned short getNumActiveLengths() const { return numActiveLengths; } void setNumActiveLengths(unsigned short numActiveLengths) { this->numActiveLengths = numActiveLengths; } unsigned short getNumLaps() const { return numLaps; } void setNumLaps(unsigned short numLaps) { this->numLaps = numLaps; } unsigned char getNumTimeInCadenceZone() const { return numTimeInCadenceZone; } void setNumTimeInCadenceZone(unsigned char numTimeInCadenceZone) { this->numTimeInCadenceZone = numTimeInCadenceZone; } unsigned char getNumTimeInHrZone() const { return numTimeInHrZone; } void setNumTimeInHrZone(unsigned char numTimeInHrZone) { this->numTimeInHrZone = numTimeInHrZone; } unsigned char getNumTimeInPowerZone() const { return numTimeInPowerZone; } void setNumTimeInPowerZone(unsigned char numTimeInPowerZone) { this->numTimeInPowerZone = numTimeInPowerZone; } unsigned char getNumTimeInSpeedZone() const { return numTimeInSpeedZone; } void setNumTimeInSpeedZone(unsigned char numTimeInSpeedZone) { this->numTimeInSpeedZone = numTimeInSpeedZone; } float getPoolLength() const { return poolLength; } void setPoolLength(float poolLength) { this->poolLength = poolLength; } unsigned char getPoolLengthUnit() const { return poolLengthUnit; } void setPoolLengthUnit(unsigned char poolLengthUnit) { this->poolLengthUnit = poolLengthUnit; } FIT_SPORT getSport() const { return (FIT_SPORT)sport; } void setSport(unsigned char sport) { this->sport = sport; } signed long getStartPositionLat() const { return startPositionLat; } void setStartPositionLat(signed long startPositionLat) { this->startPositionLat = startPositionLat; } signed long getStartPositionLong() const { return startPositionLong; } void setStartPositionLong(signed long startPositionLong) { this->startPositionLong = startPositionLong; } unsigned long getStartTime() const { return startTime; } void setStartTime(unsigned long startTime) { this->startTime = startTime; } unsigned char getSubSport() const { return subSport; } void setSubSport(unsigned char subSport) { this->subSport = subSport; } signed long getSwcLat() const { return swcLat; } void setSwcLat(signed long swcLat) { this->swcLat = swcLat; } signed long getSwcLong() const { return swcLong; } void setSwcLong(signed long swcLong) { this->swcLong = swcLong; } unsigned char getSwimStroke() const { return swimStroke; } void setSwimStroke(unsigned char swimStroke) { this->swimStroke = swimStroke; } unsigned long getTimestamp() const { return timestamp; } void setTimestamp(unsigned long timestamp) { this->timestamp = timestamp; } unsigned short getTotalAscent() const { return totalAscent; } void setTotalAscent(unsigned short totalAscent) { this->totalAscent = totalAscent; } unsigned short getTotalCalories() const { return totalCalories; } void setTotalCalories(unsigned short totalCalories) { this->totalCalories = totalCalories; } unsigned long getTotalCycles() const { return totalCycles; } void setTotalCycles(unsigned long totalCycles) { this->totalCycles = totalCycles; } unsigned short getTotalDescent() const { return totalDescent; } void setTotalDescent(unsigned short totalDescent) { this->totalDescent = totalDescent; } float getTotalDistance() const { return totalDistance; } void setTotalDistance(float totalDistance) { this->totalDistance = totalDistance; } float getTotalElapsedTime() const { return totalElapsedTime; } void setTotalElapsedTime(float totalElapsedTime) { this->totalElapsedTime = totalElapsedTime; } unsigned short getTotalFatCalories() const { return totalFatCalories; } void setTotalFatCalories(unsigned short totalFatCalories) { this->totalFatCalories = totalFatCalories; } float getTotalMovingTime() const { return totalMovingTime; } void setTotalMovingTime(float totalMovingTime) { this->totalMovingTime = totalMovingTime; } unsigned long getTotalStrides() const { return totalCycles; } void setTotalStrides(unsigned long totalStrides) { this->totalCycles = totalStrides; } float getTotalTimerTime() const { return totalTimerTime; } void setTotalTimerTime(float totalTimerTime) { this->totalTimerTime = totalTimerTime; } float getTotalTrainingEffect() const { return totalTrainingEffect; } void setTotalTrainingEffect(float totalTrainingEffect) { this->totalTrainingEffect = totalTrainingEffect; } unsigned long getTotalWork() const { return totalWork; } void setTotalWork(unsigned long totalWork) { this->totalWork = totalWork; } float getTrainingStressScore() const { return trainingStressScore; } void setTrainingStressScore(float trainingStressScore) { this->trainingStressScore = trainingStressScore; } unsigned char getTrigger() const { return trigger; } void setTrigger(unsigned char trigger) { this->trigger = trigger; } }; #endif // FITMSG_SESSION_H GarminPlugin-0.3.23/src/fit/fitReader.cpp000066400000000000000000000360561232766717500202070ustar00rootroot00000000000000/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */ /* * GarminPlugin * Copyright (C) Andreas Diesner 2011 * * GarminPlugin is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GarminPlugin is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #include "fitReader.hpp" #include "fitFileException.hpp" #include "fitMsg_File_ID.hpp" #include "fitMsg_File_Creator.hpp" #include "fitMsg_Lap.hpp" #include "fitMsg_Activity.hpp" #include "fitMsg_Record.hpp" #include "fitMsg_Event.hpp" #include "fitMsg_Session.hpp" #include "fitMsg_DeviceInfo.hpp" #include FitReader::FitReader(string filename) : headerLength(0) , dataSize(0) , remainingDataBytes(0) , doFitDebug(false) , fitMsgListener(0) , lastTimeOffset(0) , timestamp(0) { // Initialize all message definition with undefined for (int i=0; ifile.open(filename.c_str(), ios::in | ios::binary); } FitReader::~FitReader() { } bool FitReader::readHeader() { if ((this->file.good()) && (this->file.is_open())) { // Header is stored at the beginning this->file.seekg(std::ios::beg); char buf[12]; this->file.read(buf,12); dbgHex("RAW Header Data: ", buf, 12); // Header length this->headerLength = (unsigned char) buf[0]; dbg("Header Length: ", this->headerLength); // Protocol Version and Profile Number if ((((unsigned char)buf[1] & 0xF0) >> 4) > FIT_MAJOR_VERSION) { dbg("Major Version too high: ", (((unsigned char)buf[1] & 0xF0) >> 4)); return false; } else { dbg("Major Version: ", (((unsigned char)buf[1] & 0xF0) >> 4)); } // Minor Version is also not checked by reference implementation //if (((unsigned char)buf[0] & 0x0F) > FIT_MINOR_VERSION) { // throw FitFileException("Unknown MINOR Version in FIT file. Unable to decode."); //} // Ignore FIT PROFILE Version //(((((FIT_PROFILE_MAJOR_VERSION * 100) + FIT_PROFILE_MINOR_VERSION) & 0x00FF) == buf[1]) && // ((((FIT_PROFILE_MAJOR_VERSION * 100) + FIT_PROFILE_MINOR_VERSION) & 0xFF00) == buf[2])) // Read DataSize of Records this->dataSize = ((unsigned char)buf[4]) + ((unsigned char)buf[5] << 8) + ((unsigned char)buf[6] << 16) + ((unsigned char)buf[7] << 24); dbg("Data size: ", this->dataSize); // Check constant string .FIT if ((buf[8]=='.')&&(buf[9]=='F')&&(buf[10]=='I')&&(buf[11]=='T')) { this->file.seekg(this->headerLength); // Seek to start of data this->remainingDataBytes = dataSize; // There is data to read return true; } else { dbg(".FIT Header not found in file!"); } } return false; } bool FitReader::isFitFile() { if ((this->file.good()) && (this->file.is_open())) { // check length of file this->file.seekg (0, ios::end); unsigned int length = this->file.tellg(); // File length must be at least 14 bytes (12 bytes header, 2 bytes crc) if (length < 14) { dbg("Not a FIT file: File length is smaller than 14 bytes"); return false; } if (readHeader()) { if (length != (this->dataSize + this->headerLength + 2)) { dbg("File size in header does not match actual file size"); throw FitFileException("FIT Decode Error. Filesize does not match header information!"); } if (!isCorrectCRC()) { dbg("CRC is incorrect"); throw FitFileException("FIT Decode Error. CRC incorrect!"); } return true; } } dbg("Fit file is not open or has i/o errors"); return false; } void FitReader::registerFitMsgFkt(FitMsg_Listener * listener) { this->fitMsgListener = listener; } void FitReader::setDebugOutput(bool enable) { this->doFitDebug = enable; } void FitReader::dbg(const string txt) { if ((doFitDebug) && (this->fitMsgListener != NULL)) { // output debug message to debug sink this->fitMsgListener->fitDebugMsg("FitReader: " + txt); } } void FitReader::dbg(const string txt, const int nbr) { if ((doFitDebug) && (this->fitMsgListener != NULL)) { stringstream ss; ss << txt << nbr; dbg(ss.str()); } } void FitReader::dbgHex(const string txt, const char* data, const unsigned int length) { if ((doFitDebug) && (this->fitMsgListener != NULL)) { // Build hex string for debug message stringstream ss; ss << txt; unsigned int i = 0; while (i < length) { if ((unsigned char)data[i] < 16) { ss << "0"; ss << hex << (unsigned int)(data[i++] & 0xFF); } else { ss << hex << (unsigned int)(data[i++] & 0xFF); } ss << " "; } dbg(ss.str()); } } bool FitReader::isCorrectCRC() { // Only calculate header on an open file without errors if ((this->file.is_open()) && (this->file.good())) { // CRC is calculated over the complete file this->file.seekg(std::ios::beg); char buf[1024]; const unsigned short crc_table[16] = { 0x0000, 0xCC01, 0xD801, 0x1400, 0xF001, 0x3C00, 0x2800, 0xE401, 0xA001, 0x6C00, 0x7800, 0xB401, 0x5000, 0x9C01, 0x8801, 0x4400 }; unsigned short crc = 0; while (!this->file.eof()) { this->file.read(buf, 1024); int bytesRead = this->file.gcount(); for (int i=0; i> 4) & 0x0FFF; crc = crc ^ tmp ^ crc_table[ (unsigned char)buf[i] & 0x0F]; // now compute checksum of upper four bits of byte tmp = crc_table[crc & 0x0F]; crc = (crc >> 4) & 0x0FFF; crc = crc ^ tmp ^ crc_table[( (unsigned char)buf[i] >> 4) & 0x0F]; } } this->file.clear(); // Clear eof bit this->file.seekg(this->headerLength); // Seek to start of data if (crc != 0) { dbg("CRC is incorrect: ", crc); return false; } dbg("CRC is correct: ", crc); return true; } dbg("Fit file is not open or has i/o errors"); return false; } bool FitReader::readNextRecord() { if ((!this->file.is_open()) || (this->file.bad()) || (this->remainingDataBytes <= 0)) { if (this->remainingDataBytes == 0) { // just for better debug message text dbg("End of fit file"); } else { dbg("File i/o error"); } return false; } FitMsg *fitMsg = readNextFitMsg(); if (fitMsg != NULL) { // Notify message listener if (this->fitMsgListener != NULL) { this->fitMsgListener->fitMsgReceived(fitMsg); } delete(fitMsg); } return true; } FitMsg * FitReader::readNextFitMsg() { if ((!this->file.is_open()) || (this->file.bad()) || (this->remainingDataBytes <= 0)) { if (this->remainingDataBytes == 0) { // just for better debug message text dbg("End of fit file"); } else { dbg("File i/o error"); } return NULL; } char buf[6]; this->file.read(buf,1); // read record header byte this->remainingDataBytes--; dbgHex("RAW Record Header: ", buf, 1); // Compressed header or normal header? bool isNormalHeader = ((buf[0] & 0x80) == 0) ? true : false; if (!isNormalHeader) { dbg("Compressed header"); unsigned int localMsgNr = (buf[0] & 0x60) >> 5; // compressed header can only use profile 0-3 unsigned char timeOffset = (buf[0] & 0x1F); // Time offset in seconds from last timestamp if (this->localMsgDef[localMsgNr].globalMsgNum == MESSAGE_TYPE_UNDEFIND) { dbg("FIT Decode Error, undefined local message: ", localMsgNr); throw FitFileException("FIT Decode Error. Local Message not yet defined!"); } //TODO: calculate correct timestamp! //TODO: timestamp is never set, but should be! this->timestamp += (timeOffset - this->lastTimeOffset) & 0x1F; this->lastTimeOffset = timeOffset; FitMsg *fitMsg = readDataPackage(this->localMsgDef[localMsgNr], this->timestamp); return fitMsg; } else { // if (!isNormalHeader) dbg("Is normal header"); // isNormalHeader bool isDefinitionMsg = ((buf[0] & 0x40) == 0) ? 0 : 1; // Definition or data message? unsigned int localMsgNr = (buf[0] & 0x0F); // Profile number if (isDefinitionMsg) { this->remainingDataBytes-=5; this->file.read(buf,5); // Read 5 bytes of definition field dbgHex("Definition Msg Header: ", buf, 5); //char reserved = buf[0]; // First byte is reserved bool isLittleEndian = ((buf[1] & 0x01) == 0) ? 1 : 0; // Little or big endian unsigned int globalMsgNum = 0; if (isLittleEndian) { globalMsgNum = ((buf[2]) + ((unsigned int)buf[3]<<8)); } else { globalMsgNum = (((unsigned int)buf[2]<<8) + (buf[3])); } this->localMsgDef[localMsgNr].globalMsgNum = globalMsgNum; // Profile number this->localMsgDef[localMsgNr].arch = buf[1]; // Architecture (little/big endian) this->localMsgDef[localMsgNr].numFields = buf[4]; // Number of fields following dbg("Definition Msg-Type: Number=", localMsgNr); dbg("Definition Msg-Type: Arch=", buf[1]); dbg("Definition Msg-Type: NumFields=", this->localMsgDef[localMsgNr].numFields); dbg("Definition Msg-Type: GlobalMsgNum=", this->localMsgDef[localMsgNr].globalMsgNum); this->localMsgDef[localMsgNr].fields.clear(); // Messages can be redefined! Clear fields // Read all following fields of this profile int curFieldNum = 0; while (curFieldNum < this->localMsgDef[localMsgNr].numFields) { this->remainingDataBytes-=3; this->file.read(buf,3); // read 3 bytes definition of a field FieldDef field; field.fieldDefNum = (unsigned char)buf[0]; field.size = (unsigned char)buf[1]; field.baseType = (unsigned char)buf[2]; dbg("Field Def: FieldDefNum=", (unsigned char)buf[0]); dbg("Field Def: Size=", (unsigned char)buf[1]); dbg("Field Def: BaseType=", (unsigned char)buf[2]); this->localMsgDef[localMsgNr].fields.push_back(field); curFieldNum++; } } // if (isDefinitionMsg) else { // if (!isDefinitionMsg) if (this->localMsgDef[localMsgNr].globalMsgNum == MESSAGE_TYPE_UNDEFIND) { dbg("FIT Decode Error, undefined local message: ", localMsgNr); throw FitFileException("FIT Decode Error. Local Message not yet defined!"); } FitMsg *fitMsg = readDataPackage(localMsgDef[localMsgNr], 0); return fitMsg; } } return NULL; } FitMsg * FitReader::readDataPackage(MsgDef msg, unsigned int timestamp) { FitMsg * fitMsg = NULL; switch (msg.globalMsgNum) { case FIT_MESSAGE_FILE_ID : fitMsg = new FitMsg_File_ID(); break; case FIT_MESSAGE_FILE_CREATOR : fitMsg = new FitMsg_File_Creator(); break; case FIT_MESSAGE_LAP : fitMsg = new FitMsg_Lap(); break; case FIT_MESSAGE_ACTIVITY : fitMsg = new FitMsg_Activity(); break; case FIT_MESSAGE_RECORD : fitMsg = new FitMsg_Record(); break; case FIT_MESSAGE_EVENT : fitMsg = new FitMsg_Event(); break; case FIT_MESSAGE_DEVICE_INFO: fitMsg = new FitMsg_DeviceInfo(); break; case FIT_MESSAGE_SESSION: fitMsg = new FitMsg_Session(); break; default: dbg("Profile not yet implemented: ", msg.globalMsgNum); break; } // If timestamp from compressed header was given and message is known if ((timestamp != 0) && (fitMsg != NULL)) { dbg("Setting timestamp from compressed header: ", timestamp); fitMsg->SetTimestamp(timestamp); } char buf[256]; // 256 is maximum message length std::vector::iterator fieldIter = msg.fields.begin(); while( fieldIter != msg.fields.end() ) { FieldDef f = (*fieldIter); this->remainingDataBytes-=f.size; this->file.read(buf,f.size); // read data from file if (fitMsg != NULL) { // Add field to profile. Returns false if unknown field for this profile if (!fitMsg->addField(f.fieldDefNum, f.baseType, f.size, msg.arch, buf)) { dbg("Field is unknown for this profile: ", f.fieldDefNum); dbg("Reading FieldDefNum: ", f.fieldDefNum); dbg("Reading BaseType: ", f.baseType); dbgHex("Raw Read: ", buf, f.size); } } // If this is a timestamp field, use it for compressed header if (f.fieldDefNum == FIT_TIMESTAMP_FIELD_NUM) { if ((msg.arch & 0x01) == 0) { this->timestamp = ((unsigned char) buf[3] << 24) | ((unsigned char) buf[2] << 16) | ((unsigned char) buf[1] << 8) | (unsigned char)buf[0]; } else { this->timestamp = ((unsigned char) buf[0] << 24) | ((unsigned char) buf[1] << 16) | ((unsigned char) buf[2] << 8) | (unsigned char)buf[3]; } this->lastTimeOffset = (unsigned char)(this->timestamp & 0x1F); } ++fieldIter; } return fitMsg; } void FitReader::closeFitFile() { // Close file if (this->file.is_open()) { this->file.close(); } } FitMsg * FitReader::getNextFitMsgFromType(int messageType) { if ((!this->file.good()) || (!this->file.is_open())) { dbg("File not open"); return NULL; } while (this->remainingDataBytes > 0) { FitMsg * msg = readNextFitMsg(); if (msg != NULL) { if (msg->GetType() == messageType) { return msg; } delete(msg); } } return NULL; } GarminPlugin-0.3.23/src/fit/fitReader.hpp000066400000000000000000000133761232766717500202140ustar00rootroot00000000000000/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */ /* * GarminPlugin * Copyright (C) Andreas Diesner 2011 * * GarminPlugin is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GarminPlugin is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #ifndef FITREADER_H #define FITREADER_H #include #include #include #include #include "fitMsg.hpp" #include "fitMsg_Listener.hpp" using namespace std; #define FIT_MAJOR_VERSION 1 #define FIT_MINOR_VERSION 0 #define FIT_PROFILE_MAJOR_VERSION 1 #define FIT_PROFILE_MINOR_VERSION 0 #define MAX_LOCAL_MSG 16 #define MESSAGE_TYPE_UNDEFIND -1 #define FIT_TIMESTAMP_FIELD_NUM ((unsigned char)253) class FitReader { public: FitReader(string filename); virtual ~FitReader(); /** * Checks if the size and header of the file is correct * Throws FitFileException on CRC error or incorrect file size information * @return bool true if fit file */ bool isFitFile(); /** * Registers a FitMsg-Receiver funktion. Gets called for every known and sucessfully * decoded message block in the fit file */ void registerFitMsgFkt(FitMsg_Listener * listener); /** * Reads the next record in the file. If a FitMsgFkt was registered this function * gets called when a data message was decoded and the message is known. * Calls fitMsgListener to consume the next fitMsg. * @throw FitFileException - on data format error * @return bool - true if more records exist */ bool readNextRecord(); /** * Reads the next fit msg in the file and returns it * Caller must delete FitMsg! * @throw FitFileException - on data format error * @return bool - true if more records exist */ FitMsg * readNextFitMsg(); /** * Closes the fit file. */ void closeFitFile(); /** * Enable/Disable debug output to FitMsg_Listener */ void setDebugOutput(bool enable); /** * Reads the next fit message matching messageType */ FitMsg * getNextFitMsgFromType(int messageType); private: /** * Reads the fit header and checks for correct version. Function expects 12 bytes * @return bool - returns true if correct header detected */ bool readHeader(); /** * Reads the complete file and calculates the CRC. * @return bool - returns true if CRC is correct */ bool isCorrectCRC(); /** * Used to output debug messages */ void dbg(const string txt); /** * Used to output debug messages with a number */ void dbg(const string txt, const int nbr); /** * Used to output debug messages with hex buffers */ void dbgHex(const string txt, const char* data, const unsigned int length); /** * Describes one field in a message definition */ typedef struct _FieldDef { unsigned char fieldDefNum; // Field number in given profile unsigned char size; // Size of field in bytes unsigned char baseType; // Base Type (Bit7 = 1 --> signed) } FieldDef; /** * Stores a message definition. Up to 16 different definitions can be read * from the fit file. */ typedef struct _MsgDef { int globalMsgNum; // Which profile to use for this data unsigned char arch; // Architecture used to store data (Bit0) int numFields; // Number of fields in data message vector fields; // Field description } MsgDef; /** * Stores all 16 profiles that have been read from fit file. */ MsgDef localMsgDef[MAX_LOCAL_MSG]; /** * Reads a data package from file and returns it * FitMsg needs to be deleted by caller! */ FitMsg * readDataPackage(MsgDef msg, unsigned int timestamp); /** * Stores the header length (first byte in file) */ unsigned char headerLength; /** * Stores the data size of the data section (file size - header size - 2 (crc)) */ unsigned int dataSize; /** * Remaining bytes in data section */ unsigned int remainingDataBytes; /** * Pointer to fit file on disk */ ifstream file; /** * Enables output of debug messages to fitMsgListener */ bool doFitDebug; /** * Pointer to function that receives the fit messages stored in the file */ FitMsg_Listener * fitMsgListener; /** * Last time offset in compressed header fields */ unsigned char lastTimeOffset; /** * Last timestamp, needed for compressed header fields */ unsigned int timestamp; }; #endif // FITREADER_H GarminPlugin-0.3.23/src/garminFilebasedDevice.cpp000066400000000000000000002470531232766717500217150ustar00rootroot00000000000000/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */ /* * GarminPlugin * Copyright (C) Andreas Diesner 2011 * * GarminPlugin is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GarminPlugin is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #include "garminFilebasedDevice.h" #include #include #include #include "sys/statfs.h" #include #include #include #include #include "Fit2TcxConverter.h" #include "gpsFunctions.h" #include #include // needed for sort #include // Searching for files with wildcards #include // glob(), globfree() GarminFilebasedDevice::GarminFilebasedDevice() : GpsDevice("") , deviceDescription(0) , fitFileElement(0) { } GarminFilebasedDevice::~GarminFilebasedDevice() { if (this->deviceDescription != NULL) { delete(deviceDescription); this->deviceDescription = NULL; } } void GarminFilebasedDevice::fitMsgReceived(FitMsg *msg) { if (this->fitFileElement == NULL) { return; } if (msg->GetType() == FIT_MESSAGE_FILE_ID) { FitMsg_File_ID *fileid = dynamic_cast (msg); if (fileid != NULL) { if (fileid->getTimeCreated() != FIT_FILE_ID_TIME_CREATED_INVALID) { TiXmlElement * timeElem = new TiXmlElement( "CreationTime" ); timeElem->LinkEndChild(new TiXmlText(GpsFunctions::print_dtime(fileid->getTimeCreated()))); this->fitFileElement->LinkEndChild(timeElem); } TiXmlElement * fitId = this->fitFileElement->FirstChildElement("FitId"); if (fitId == NULL) { fitId = new TiXmlElement( "FitId" ); this->fitFileElement->LinkEndChild( fitId ); } if (fileid->getTimeCreated() != FIT_FILE_ID_TIME_CREATED_INVALID) { TiXmlElement * typeElem = new TiXmlElement( "Id" ); stringstream ss; ss << (unsigned int)fileid->getTimeCreated(); typeElem->LinkEndChild(new TiXmlText(ss.str())); fitId->LinkEndChild(typeElem); } if (fileid->getType() != FIT_FILE_ID_TYPE_INVALID) { TiXmlElement * typeElem = new TiXmlElement( "FileType" ); stringstream ss; ss << (int)fileid->getType(); typeElem->LinkEndChild(new TiXmlText(ss.str())); fitId->LinkEndChild(typeElem); } if (fileid->getManufacturer() != FIT_FILE_ID_MANUFACTURER_INVALID) { TiXmlElement * manElem = new TiXmlElement( "Manufacturer" ); stringstream ss; ss << fileid->getManufacturer(); manElem->LinkEndChild(new TiXmlText(ss.str())); fitId->LinkEndChild(manElem); } if (fileid->getProduct() != FIT_FILE_ID_GARMIN_PRODUCT_INVALID) { TiXmlElement * prodElem = new TiXmlElement( "Product" ); stringstream ss; ss << fileid->getProduct(); prodElem->LinkEndChild(new TiXmlText(ss.str())); fitId->LinkEndChild(prodElem); } if (fileid->getSerialNumber() != FIT_FILE_ID_SERIAL_NUMBER_INVALID) { TiXmlElement * serElem = new TiXmlElement( "SerialNumber" ); stringstream ss; ss << (fileid->getSerialNumber() & 0xFFFFFFFF); serElem->LinkEndChild(new TiXmlText(ss.str())); fitId->LinkEndChild(serElem); } } else { // Should not happen... internal error msgtype does not fit to class type } } else { // received a message we are not interested in } } string GarminFilebasedDevice::getDeviceDescription() const { if (this->deviceDescription == NULL) { return ""; } TiXmlPrinter printer; printer.SetIndent( "\t" ); this->deviceDescription->Accept( &printer ); string str = printer.Str(); if (Log::enabledDbg()) Log::dbg("GarminFilebasedDevice::getDeviceDescription() Done: "+this->displayName ); return str; } void GarminFilebasedDevice::setDeviceDescription(TiXmlDocument * device) { this->deviceDescription = new TiXmlDocument(*device); if (this->deviceDescription != NULL) { setPathsFromConfiguration(); } } int GarminFilebasedDevice::startWriteToGps(const string filename, const string xml) { string::size_type loc = filename.find( "..", 0 ); if( loc != string::npos ) { Log::err("SECURITY WARNING: Filenames with .. are not allowed!"); return 0; } loc = filename.find( "/", 0 ); if( loc != string::npos ) { Log::err("SECURITY WARNING: Filenames with / are not allowed!"); return 0; } string newFilename = filename; // Get File extension of file to write: string::size_type idx; idx = filename.rfind('.'); string fileToWriteExtension = ""; if(idx != std::string::npos) { fileToWriteExtension = filename.substr(idx+1); } if (fileToWriteExtension.compare("") == 0) { // File has no file extension. size_t foundPos; foundPos=filename.find("gpxfile"); if (foundPos!=string::npos) { // site http://my.garmin.com/locate/savePOI.htm uses this filename "gpxfile11152893811" for gpx files fileToWriteExtension = "gpx"; newFilename.append(".gpx"); if (Log::enabledDbg()) { Log::dbg("Using file extension gpx [file contains string gpxfile]"); } } else { // search inside xml for keywords foundPos=xml.find("::iterator it = deviceDirectories.begin(); it != deviceDirectories.end(); ++it) { MassStorageDirectoryType const& currentDir = (*it); if (currentDir.writeable) { // Compare file extension if (strncasecmp(fileToWriteExtension.c_str(), currentDir.extension.c_str(), currentDir.extension.length()) == 0) { targetDirectory = this->baseDirectory + "/" + currentDir.path; break; } else if (Log::enabledDbg()) { Log::dbg("Wrong file extension for target directory: "+currentDir.name); } } } if (targetDirectory.length() == 0) { Log::err("Unable to find a valid target directory to write file "+filename); this->transferSuccessful = false; return 0; } // There shouldn't be a thread running... but who knows... lockVariables(); this->xmlToWrite = xml; this->filenameToWrite = targetDirectory + "/" + newFilename; this->overwriteFile = 2; // not yet asked this->workType = WRITEGPX; unlockVariables(); if (Log::enabledDbg()) Log::dbg("Saving to file: "+this->filenameToWrite); if (startThread()) { return 1; } return 0; } void GarminFilebasedDevice::writeGpxFile() { lockVariables(); string xml = this->xmlToWrite; string filename = this->filenameToWrite; string systemCmd = this->storageCmd; this->threadState = 1; // Working unlockVariables(); struct stat stFileInfo; int intStat; // Attempt to get the file attributes intStat = stat(filename.c_str(),&stFileInfo); if(intStat == 0) { // File exists - we need to ask the user to overwrite lockVariables(); this->waitingMessage = new MessageBox(Question, "File "+filename+" exists. Overwrite?", BUTTON_YES | BUTTON_NO , BUTTON_NO, this); this->threadState = 2; unlockVariables(); waitThread(); // Sleep until thread gets signal (user answered) bool doOverwrite = true; lockVariables(); if (this->overwriteFile != 1) { this->threadState = 3; this->transferSuccessful = false; doOverwrite = false; } unlockVariables(); if (!doOverwrite) { Log::dbg("Thread aborted"); return; } } ofstream file; file.open (filename.c_str()); file << xml; file.close(); // Execute extern command if wanted if (systemCmd.length() > 0) { string placeholder = "%1"; int pos=systemCmd.find( placeholder ); if (pos >=0) { systemCmd.replace(systemCmd.find(placeholder),placeholder.length(),filename); } pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, NULL); pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, NULL); Log::dbg("Thread before executing user command: "+systemCmd); int ret = system(systemCmd.c_str()); pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, NULL); if (ret != 0) { lockVariables(); this->waitingMessage = new MessageBox(Question, "Error executing command: "+systemCmd, BUTTON_OK , BUTTON_OK, NULL); this->threadState = 2; unlockVariables(); sleep(1); // give application time to fetch messagebox lockVariables(); this->threadState = 3; unlockVariables(); Log::err("Executing user command failed: "+systemCmd); return; } } lockVariables(); this->threadState = 3; // Finished this->transferSuccessful = true; // Successfull; unlockVariables(); } void GarminFilebasedDevice::doWork() { if ((this->workType == WRITEGPX) || (this->workType == WRITEFITNESSDATA)) { this->writeGpxFile(); } else if (this->workType == READFITNESS) { this->readFitnessDataFromDevice(true, ""); } else if (this->workType == READFITNESSDIR) { this->readFitnessDataFromDevice(false, ""); } else if (this->workType == READFITNESSDETAIL) { this->readFitnessDataFromDevice(true, this->readFitnessDetailId); } else if (this->workType == READFITDIRECTORY) { this->readFITDirectoryFromDevice(); } else if (this->workType == READABLEFILELISTING) { this->readFileListingFromDevice(); } else if (this->workType == READFITNESSUSERPROFILE) { this->readFitnessUserProfile(); } else if (this->workType == READFITNESSCOURSES) { this->readFitnessCourses(true); } else if (this->workType == READFITNESSCOURSESDIR) { this->readFitnessCourses(false); } else if (this->workType == READFITNESSWORKOUTS) { this->readFitnessWorkouts(); } else if (this->workType == DIRECTORYLISTING) { this->readDirectoryListing(); } else { Log::err("Work Type not implemented!"); } } void GarminFilebasedDevice::readFileListingFromDevice() { if (Log::enabledDbg()) { Log::dbg("Thread readFileListing started"); } string workDir=""; string extensionToRead=""; string pathOnDevice = ""; string basename = ""; lockVariables(); this->threadState = 1; // Working bool doCalculateMd5 = this->readableFileListingComputeMD5; for (list::iterator it = deviceDirectories.begin(); it != deviceDirectories.end(); ++it) { MassStorageDirectoryType const& currentDir = (*it); if ((currentDir.extension.compare(this->readableFileListingFileTypeName) == 0) && (currentDir.name.compare(this->readableFileListingDataTypeName) == 0) && (currentDir.readable)) { workDir = this->baseDirectory + "/" + currentDir.path; extensionToRead = currentDir.extension; pathOnDevice = currentDir.path; basename = currentDir.basename; } } unlockVariables(); TiXmlDocument * output = new TiXmlDocument(); TiXmlDeclaration * decl = new TiXmlDeclaration( "1.0", "UTF-8", "no"); output->LinkEndChild( decl ); TiXmlElement * dirList = new TiXmlElement( "DirectoryListing" ); dirList->SetAttribute("xmlns","http://www.garmin.com/xmlschemas/DirectoryListing/v1"); dirList->SetAttribute("RequestedPath",pathOnDevice); dirList->SetAttribute("UnitId",this->deviceId); dirList->SetAttribute("VolumePrefix",""); output->LinkEndChild( dirList ); if (workDir.length() > 0) { DIR *dp; struct dirent *dirp; if (Log::enabledDbg()) { Log::dbg("Found directory to read: "+workDir); } if((dp = opendir(workDir.c_str())) != NULL) { while ((dirp = readdir(dp)) != NULL) { string fileName = string(dirp->d_name); string fullFileName = workDir+'/'+fileName; bool isDirectory = (dirp->d_type == 4) ? true : false; if (Log::enabledDbg()) { Log::dbg("Found file: "+fileName); } if ((fileName == ".") || (fileName == "..")) { continue; } // Check file extension string lastFilePart = fileName.substr(fileName.length() - extensionToRead.length()); if (strncasecmp(lastFilePart.c_str(), extensionToRead.c_str(), extensionToRead.length()) != 0) { if (Log::enabledDbg()) { Log::dbg("Found file with incorrect extension: "+fileName);} continue; } // Check basename if set if (basename.length()>0) { string firstFilePart = fileName.substr(0, basename.length()); if (strncasecmp(firstFilePart.c_str(), basename.c_str(), basename.length()) != 0) { if (Log::enabledDbg()) { Log::dbg("Found file with incorrect basename: "+fileName);} continue; } } TiXmlElement * curFile = new TiXmlElement( "File" ); if (isDirectory) { curFile->SetAttribute("IsDirectory","true"); } else { curFile->SetAttribute("IsDirectory","false"); } curFile->SetAttribute("Path",pathOnDevice+'/'+fileName); // Get File Size struct stat filestatus; stat( fullFileName.c_str(), &filestatus ); stringstream ss; ss << filestatus.st_size; curFile->SetAttribute("Size",ss.str()); // Get the timestamp TiXmlElement * timeElem = new TiXmlElement( "CreationTime" ); timeElem->LinkEndChild(new TiXmlText(GpsFunctions::print_dtime(filestatus.st_mtime-TIME_OFFSET))); curFile->LinkEndChild(timeElem); if ((!isDirectory) && (doCalculateMd5)) { if (Log::enabledDbg()) { Log::dbg("Calculating MD5 sum of " + fullFileName);} string md5 = getMd5FromFile(fullFileName); curFile->SetAttribute("MD5Sum",md5); } dirList->LinkEndChild( curFile ); } closedir(dp); } else { Log::err("Error opening directory! "+ workDir); } } else { if (Log::enabledDbg()) { Log::dbg("No directory found to read"); } } TiXmlPrinter printer; printer.SetIndent( " " ); output->Accept( &printer ); string outputXml = printer.Str(); delete(output); lockVariables(); this->threadState = 3; // Finished this->directoryListingXml = outputXml; this->transferSuccessful = true; // Successfull; unlockVariables(); if (Log::enabledDbg()) { Log::dbg("Thread readFileListing finished"); } return; } /** * Sort two activities */ bool activitySorter (TiXmlNode * a,TiXmlNode * b) { string aId=""; string bId=""; TiXmlElement * idNode = a->FirstChildElement("Id"); if (idNode != NULL) { aId = idNode->GetText(); } idNode = b->FirstChildElement("Id"); if (idNode != NULL) { bId = idNode->GetText(); } return (aId.compare(bId) > 0); } /** * Sort two fit files */ bool fitFileSorter (TiXmlNode * a,TiXmlNode * b) { string aId=""; string bId=""; TiXmlElement * cTimeNode = a->FirstChildElement("CreationTime"); if (cTimeNode != NULL) { aId = cTimeNode->GetText(); } cTimeNode = b->FirstChildElement("CreationTime"); if (cTimeNode != NULL) { bId = cTimeNode->GetText(); } return (aId.compare(bId) > 0); } /** * Parses all attributes of a TiXmlElement and adds them to another TiXmlElement if it is missing */ void GarminFilebasedDevice::addMissingAttributes(TiXmlElement * in, TiXmlElement * out) { if ((in==NULL) || (out==NULL)) { return; } TiXmlAttribute* pAttrib=in->FirstAttribute(); while (pAttrib) { const char * a = out->Attribute(pAttrib->Name()); if (a==NULL) { // Attribute does not exist in out, need to create it out->SetAttribute(pAttrib->Name(),pAttrib->Value()); } pAttrib=pAttrib->Next(); } } /** * Reads TCX directories */ void GarminFilebasedDevice::readFitnessDataFromDevice(bool readTrackData, string fitnessDetailId) { Log::dbg("Thread readFitnessData started"); /* Thread-Status 0 = idle 1 = working 2 = waiting 3 = finished */ string workDir=""; string extension=""; lockVariables(); this->threadState = 1; // Working bool doReadTcx=true; for (list::iterator it = deviceDirectories.begin(); it != deviceDirectories.end(); ++it) { MassStorageDirectoryType const& currentDir = (*it); if ((currentDir.dirType == TCXDIR) && (currentDir.name.compare("FitnessHistory") == 0)) { workDir = this->baseDirectory + "/" + currentDir.path; extension = currentDir.extension; } } // alternative, search for FIT files if (workDir.length() == 0) { for (list::iterator it = deviceDirectories.begin(); it != deviceDirectories.end(); ++it) { MassStorageDirectoryType const& currentDir = (*it); if ((currentDir.dirType == FITDIR) && (currentDir.name.compare("FIT_TYPE_4") == 0)) { workDir = this->baseDirectory + "/" + currentDir.path; extension = currentDir.extension; doReadTcx = false; } } } unlockVariables(); vector files = vector(); // Check if the device supports reading tcx or fit files if (workDir.length() == 0) { Log::err("Device does not support reading TCX or FIT Files. Element FitnessHistory/FIT_TYPE_4 not found in xml!"); } else { Log::dbg("Opening directory: "+workDir); DIR *dp; struct dirent *dirp; if((dp = opendir(workDir.c_str())) != NULL) { while ((dirp = readdir(dp)) != NULL) { files.push_back(string(dirp->d_name)); } closedir(dp); } else { Log::err("Error opening fitness directory! "+ workDir); } } TiXmlDocument * output = new TiXmlDocument(); TiXmlDeclaration * decl = new TiXmlDeclaration( "1.0", "UTF-8", "no"); output->LinkEndChild( decl ); TiXmlElement * train = new TiXmlElement( "TrainingCenterDatabase" ); train->SetAttribute("xmlns","http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2"); train->SetAttribute("xmlns:xsi","http://www.w3.org/2001/XMLSchema-instance"); train->SetAttribute("xsi:schemaLocation","http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2 http://www.garmin.com/xmlschemas/TrainingCenterDatabasev2.xsd"); output->LinkEndChild( train ); TiXmlElement * activities = new TiXmlElement( "Activities" ); train->LinkEndChild( activities ); // We need to sort the activities, that's why they are first stored in a list vector activitiesList; // Loop over all files in Fitnessdirectory: for (unsigned int i = 0;i < files.size();i++) { if (files[i].length() > extension.length()) { string lastFilePart = files[i].substr(files[i].length() - extension.length()); if (strncasecmp(lastFilePart.c_str(), extension.c_str(), extension.length()) == 0) { if (Log::enabledDbg()) { Log::dbg("Opening file: "+ files[i]); } TiXmlDocument *doc = NULL; if (doReadTcx) { doc = new TiXmlDocument(workDir + "/" + files[i]); if (!doc->LoadFile()) { delete(doc); doc=NULL; Log::err("Unable to load file: "+ files[i]); } } else { Fit2TcxConverter *fitConv = new Fit2TcxConverter(); FitReader *fit = new FitReader(workDir + "/" + files[i]); fit->registerFitMsgFkt(fitConv); try { if (fit->isFitFile()) { while (fit->readNextRecord()) { } fit->closeFitFile(); doc = fitConv->getTiXmlDocument(readTrackData, fitnessDetailId); } else { Log::err("Not a fit file: " + workDir + "/" + files[i]); } } catch (FitFileException &e) { Log::err("Exception: " + e.getError()); } catch (...) { Log::err("Unknown exception happened while reading fit file!"); } delete (fit); } if (doc != NULL) { TiXmlElement * trainFile = doc->FirstChildElement("TrainingCenterDatabase"); if (trainFile != NULL) { addMissingAttributes(trainFile, train); TiXmlElement * inputActivities = trainFile->FirstChildElement("Activities"); while ( inputActivities != NULL) { TiXmlElement * inputActivity =inputActivities->FirstChildElement("Activity"); while ( inputActivity != NULL) { string currentLapId=""; TiXmlElement * idNode = inputActivity->FirstChildElement("Id"); if (idNode != NULL) { currentLapId = idNode->GetText(); } if ((fitnessDetailId.length() == 0) || (fitnessDetailId.compare(currentLapId) == 0)) { TiXmlNode * newAct = inputActivity->Clone(); if (!readTrackData) { // Track data must be deleted TiXmlNode * node = newAct->FirstChildElement("Lap"); while (node != NULL) { TiXmlNode * trackNode = node->FirstChildElement("Track"); while (trackNode != NULL) { node->RemoveChild( node->FirstChildElement("Track") ); trackNode = node->FirstChildElement("Track"); } //node = newAct->FirstChildElement("Lap"); node = node->NextSibling(); } } //activities->LinkEndChild( newAct ); activitiesList.push_back(newAct); if (Log::enabledDbg()) { Log::dbg("Adding activity "+currentLapId+" from file "+files[i]); } } inputActivity = inputActivity->NextSiblingElement( "Activity" ); } inputActivities = inputActivities->NextSiblingElement( "Activities" ); } } delete(doc); doc = NULL; } else { Log::err("Unable to load fitness file "+files[i]); } } else { if (Log::enabledDbg()) { Log::dbg("File "+files[i]+" has wrong extension!. Not ["+extension+"]"); } } } } // Sort list, newest activity must be on top sort(activitiesList.begin(), activitiesList.end(), activitySorter); vector::iterator it; for ( it=activitiesList.begin() ; it < activitiesList.end(); ++it ) { TiXmlNode * curAct = *it; activities->LinkEndChild( curAct ); } TiXmlPrinter printer; printer.SetIndent( " " ); output->Accept( &printer ); string fitnessXml = printer.Str(); // Write to backup directory if needed if ((readTrackData) && (fitnessDetailId.length()>0)) { time_t startTime = GpsFunctions::getStartTimestampFromXml(output); backupWorkout(fitnessXml, extension, startTime); } // Delete Xml structure delete(output); lockVariables(); this->fitnessDataTcdXml = fitnessXml; this->threadState = 3; // Finished this->transferSuccessful = true; // Successfull; unlockVariables(); if (Log::enabledDbg()) { Log::dbg("Thread readFitnessData finished"); } return; } void GarminFilebasedDevice::readFITDirectoryFromDevice() { if (Log::enabledDbg()) { Log::dbg("Thread readFITDirectory started");} lockVariables(); this->threadState = 1; // Working unlockVariables(); TiXmlDocument * output = new TiXmlDocument(); TiXmlDeclaration * decl = new TiXmlDeclaration( "1.0", "UTF-8", "no"); output->LinkEndChild( decl ); TiXmlElement * dirList = new TiXmlElement( "DirectoryListing" ); dirList->SetAttribute("xmlns","http://www.garmin.com/xmlschemas/DirectoryListing/v1"); dirList->SetAttribute("RequestedPath",""); dirList->SetAttribute("UnitId",deviceId); dirList->SetAttribute("VolumePrefix",""); output->LinkEndChild( dirList ); // We need to sort the fit files, that's why they are first stored in a list vector fitFileList; for (list::iterator it = deviceDirectories.begin(); it != deviceDirectories.end(); ++it) { MassStorageDirectoryType const& currentFitDir = (*it); if ((currentFitDir.dirType != FITDIR)) { continue; } DIR *dp; struct dirent *dirp; string fullPath = this->baseDirectory + "/" + currentFitDir.path; if((dp = opendir(fullPath.c_str())) != NULL) { if (Log::enabledDbg()) { Log::dbg("Searching for files in "+fullPath);} while ((dirp = readdir(dp)) != NULL) { string fileName = string(dirp->d_name); bool isDirectory = (dirp->d_type == 4) ? true : false; if (isDirectory) { continue; } // Ignore directories if (fileName.length() > currentFitDir.extension.length()) { string lastFilePart = fileName.substr(fileName.length() - currentFitDir.extension.length()); if (strncasecmp(lastFilePart.c_str(), currentFitDir.extension.c_str(), currentFitDir.extension.length()) == 0) { if (Log::enabledDbg()) { Log::dbg("Found file with correct extension: "+fileName);} this->fitFileElement = new TiXmlElement( "File" ); this->fitFileElement->SetAttribute("IsDirectory","false"); this->fitFileElement->SetAttribute("Path",currentFitDir.path+'/'+fileName); // Opening and parsing of fit file: string fullFileName = this->baseDirectory + "/" + currentFitDir.path+'/'+fileName; FitReader fit(fullFileName); fit.registerFitMsgFkt(this); try { if (Log::enabledInfo()) { Log::info("Reading fit file: "+fullFileName); } if (fit.isFitFile()) { while (fit.readNextRecord()) { // processing of records is done in fitMsgReceived() } fit.closeFitFile(); //dirList->LinkEndChild( this->fitFileElement ); fitFileList.push_back(this->fitFileElement); } else { Log::err("Invalid fit file: "+fullFileName); delete(this->fitFileElement); } } catch (FitFileException &e) { Log::err("Decoding error: "+e.getError()); delete(this->fitFileElement); } } else { if (Log::enabledDbg()) { Log::dbg("Wrong file extension of "+fileName);} } } } closedir(dp); } else { Log::err("Failed to open FitnessDirectory: "+currentFitDir.path); } } // Sort list, newest fit file must be on top sort(fitFileList.begin(), fitFileList.end(), fitFileSorter); vector::iterator it; for ( it=fitFileList.begin() ; it < fitFileList.end(); ++it ) { TiXmlNode * curFitFile = *it; dirList->LinkEndChild( curFitFile ); } TiXmlPrinter printer; printer.SetIndent( " " ); output->Accept( &printer ); string outputXml = printer.Str(); delete(output); lockVariables(); this->directoryListingXml = outputXml; this->threadState = 3; // Finished this->transferSuccessful = true; // Successfull; unlockVariables(); if (Log::enabledDbg()) { Log::dbg("Thread readFITDirectory finished"); } return; } MessageBox * GarminFilebasedDevice::getMessage() { MessageBox * msg = this->waitingMessage; this->waitingMessage = NULL; return msg; } void GarminFilebasedDevice::userAnswered(const int answer) { if (answer == 1) { if (Log::enabledDbg()) Log::dbg("User wants file overwritten"); lockVariables(); this->overwriteFile = 1; unlockVariables(); } else { if (Log::enabledDbg()) Log::dbg("User wants file to be untouched"); lockVariables(); this->overwriteFile = 0; unlockVariables(); } lockVariables(); this->threadState = 1; /* set back to working */ unlockVariables(); signalThread(); } int GarminFilebasedDevice::finishWriteToGps() { /* 0 = idle 1 = working 2 = waiting 3 = finished */ lockVariables(); int status = this->threadState; unlockVariables(); return status; } void GarminFilebasedDevice::cancelWriteToGps() { cancelThread(); } int GarminFilebasedDevice::getTransferSucceeded() { if (this->transferSuccessful) { return 1; } return 0; } void GarminFilebasedDevice::setBaseDirectory(string directory) { this->baseDirectory = directory; if (this->deviceDescription != NULL) { setPathsFromConfiguration(); } } void GarminFilebasedDevice::setStorageCommand(string cmd) { this->storageCmd = cmd; } bool GarminFilebasedDevice::isDeviceAvailable() { struct stat st; if(stat(this->baseDirectory.c_str(),&st) == 0) { // directory exists return true; } Log::dbg("Device is not available: "+this->displayName); return false; } void GarminFilebasedDevice::setUpdatePathsFromConfiguration() { if (this->deviceDescription != NULL) { TiXmlElement * node = this->deviceDescription->FirstChildElement("Device"); if (node!=NULL) { node = node->FirstChildElement("Id"); } if (node!=NULL) { deviceId = node->GetText(); } node = this->deviceDescription->FirstChildElement("Device"); if (node!=NULL) { node = node->FirstChildElement("MassStorageMode"); } if (node!=NULL) { node = node->FirstChildElement("UpdateFile"); } while ( node != NULL) { TiXmlElement *ti_path = node->FirstChildElement("Path"); TiXmlElement *ti_filename = node->FirstChildElement("FileName"); TiXmlElement *ti_partnum = node->FirstChildElement("PartNumber"); MassStorageDirectoryType devDir; if (ti_path != NULL) { devDir.path = ti_path->GetText(); } if (ti_filename != NULL) { devDir.basename = ti_filename->GetText(); } if (ti_partnum != NULL) { devDir.name = ti_partnum->GetText(); } devDir.writeable = true; devDir.readable = false; devDir.dirType = UNKNOWN; // Debug print if (Log::enabledDbg()) { stringstream ss; ss << "UpdateFile: "; ss << "Path: " << devDir.path; ss << " File: " << devDir.basename; ss << " Name: " << devDir.name; Log::dbg("Found Feature: "+ss.str()); } deviceDirectories.push_back(devDir); node = node->NextSiblingElement("UpdateFile"); } } } /** * On some devices the file GarminDevice.xml contains a wrong upper/lower writing of the directory names * This is corrected in this function, by searching for the proper directory name if it can not be found */ void GarminFilebasedDevice::checkPathsFromConfiguration() { for (list::iterator it = deviceDirectories.begin(); it != deviceDirectories.end(); ++it) { MassStorageDirectoryType const& currentDir = (*it); string fullDirectoryName = this->baseDirectory + "/" + currentDir.path; struct stat st; if(stat(fullDirectoryName.c_str(),&st) != 0) { // directory does not exist, check upper/lower case of subdirectories if (Log::enabledInfo()) { Log::info("Directory "+currentDir.path+" does not exist on device, searching alternative upper/lowercase writings");} bool foundNewPath = true; stringstream ss(currentDir.path); string existingSubPath = ""; string item; while(std::getline(ss, item, '/')) { string parentPath = this->baseDirectory; if (existingSubPath.length() > 0) { parentPath += "/" + existingSubPath; } string pathToTest = parentPath + "/" + item; // Test name from configuration if(stat(pathToTest.c_str(),&st) != 0) { // directory does not exist... DIR *dp; struct dirent *dirp; if((dp = opendir(parentPath.c_str())) != NULL) { bool foundEntry = false; while ((dirp = readdir(dp)) != NULL) { string fileName = string(dirp->d_name); if ((fileName.length() == item.length()) && (strncasecmp(fileName.c_str(), item.c_str(), item.length()) == 0)) { item = fileName; foundEntry = true; break; } } closedir(dp); if (!foundEntry) { foundNewPath = false; } } else { if (Log::enabledDbg()) { Log::dbg("Unable to open directory "+parentPath+" while searching for "+currentDir.path); } } } if (existingSubPath.length() > 0) { existingSubPath += "/"; } existingSubPath += item; } if (foundNewPath) { if (currentDir.path.length() > 0) { std::string::const_iterator it = currentDir.path.end() - 1; if (*it == '/') { existingSubPath += "/"; } } Log::info("Overwriting "+ currentDir.path + " from configuration with " + existingSubPath); } else { if (Log::enabledDbg()) { Log::dbg("No alternative found for "+currentDir.path);} } } } } void GarminFilebasedDevice::setPathsFromConfiguration() { if (!deviceDirectories.empty()) { deviceDirectories.clear(); } this->fitnessFile = this->baseDirectory+"/Garmin/gpx/current/Current.gpx"; // Fallback if (this->deviceDescription != NULL) { TiXmlElement * node = this->deviceDescription->FirstChildElement("Device"); if (node!=NULL) { node = node->FirstChildElement("Id"); } if (node!=NULL) { deviceId = node->GetText(); } node = this->deviceDescription->FirstChildElement("Device"); if (node!=NULL) { node = node->FirstChildElement("MassStorageMode"); } if (node!=NULL) { node = node->FirstChildElement("DataType"); } while ( node != NULL) { TiXmlElement * node2 = node->FirstChildElement("Name"); if (node2 != NULL) { string nameText = node2->GetText(); node2 = node->FirstChildElement("File"); while (node2 != NULL) { TiXmlElement * transferDirection = node2->FirstChildElement("TransferDirection"); string transDir = transferDirection->GetText(); MassStorageDirectoryType devDir; devDir.dirType = UNKNOWN; devDir.name = nameText; if (transDir.compare("InputToUnit") == 0) { devDir.writeable = true; devDir.readable = false; } else if (transDir.compare("InputOutput") == 0) { devDir.writeable = true; devDir.readable = true; } else if (transDir.compare("OutputFromUnit") == 0) { devDir.writeable = false; devDir.readable = true; } TiXmlElement * ti_loc = NULL; TiXmlElement * ti_path = NULL; TiXmlElement * ti_basename = NULL; TiXmlElement * ti_ext = NULL; if (node2!=NULL) { ti_loc = node2->FirstChildElement("Location"); } if (ti_loc!=NULL) { ti_path = ti_loc->FirstChildElement("Path"); } if (ti_loc!=NULL) { ti_basename = ti_loc->FirstChildElement("BaseName"); } if (ti_loc!=NULL) { ti_ext = ti_loc->FirstChildElement("FileExtension"); } if (ti_path != NULL) { devDir.path = ti_path->GetText(); } if (ti_basename != NULL) { devDir.basename = ti_basename->GetText(); } // Determine Type of directory string::size_type position = nameText.find( "FIT_TYPE_", 0 ); if ((position != string::npos) || (nameText.compare("FITBinary")==0)) { devDir.dirType = FITDIR; } else if ((nameText.compare("FitnessWorkouts")==0) || (nameText.compare("FitnessHistory")==0) || (nameText.compare("FitnessCourses")==0) || (nameText.compare("FitnessUserProfile")==0)) { devDir.dirType = TCXDIR; } else if (nameText.compare("GPSData")==0) { devDir.dirType = GPXDIR; } if (ti_ext != NULL) { string ext = ti_ext->GetText(); devDir.extension = ext; } // Debug print if (Log::enabledDbg()) { stringstream ss; if (devDir.dirType == FITDIR) { ss << "FIT: "; } else if (devDir.dirType == TCXDIR) { ss << "TCX: "; } else if (devDir.dirType == GPXDIR) { ss << "GPX: "; } else { ss << "???: "; } ss << "Path: " << devDir.path; ss << " Ext: " << devDir.extension; ss << " Name: " << devDir.name; Log::dbg("Found Feature: "+ss.str()); } deviceDirectories.push_back(devDir); node2 = node2->NextSiblingElement("File"); } } node = node->NextSiblingElement( "DataType" ); } } setUpdatePathsFromConfiguration(); checkPathsFromConfiguration(); } int GarminFilebasedDevice::startReadFITDirectory() { if (Log::enabledDbg()) Log::dbg("Starting thread to read from garmin device"); lockVariables(); this->threadState = 1; this->directoryListingXml = ""; unlockVariables(); this->workType = READFITDIRECTORY; if (startThread()) { return 1; } return 0; } int GarminFilebasedDevice::finishReadFITDirectory() { lockVariables(); int status = this->threadState; unlockVariables(); return status; } void GarminFilebasedDevice::cancelReadFITDirectory() { if (Log::enabledDbg()) { Log::dbg("cancelReadFITDirectory called for "+this->displayName); } cancelThread(); } int GarminFilebasedDevice::startReadFitnessDirectory(string dataTypeName) { if (Log::enabledDbg()) Log::dbg("Starting thread to read from garmin device"); if (dataTypeName.compare("FitnessCourses") == 0) { this->workType = READFITNESSCOURSESDIR; // FitnessCourses } else if (dataTypeName.compare("FitnessHistory") == 0) { this->workType = READFITNESSDIR; // FitnessHistory } else { Log::err("Unknown data to read: '"+dataTypeName+"' - Defaulting back to FitnessHistory"); this->workType = READFITNESSDIR; // FitnessHistory } if (startThread()) { return 1; } return 0; } int GarminFilebasedDevice::finishReadFitnessDirectory() { lockVariables(); int status = this->threadState; unlockVariables(); return status; } void GarminFilebasedDevice::cancelReadFitnessData() { cancelThread(); } int GarminFilebasedDevice::startReadFitnessDetail(string id) { if (Log::enabledDbg()) Log::dbg("Starting thread to read fitness detail from garmin device: "+this->displayName+ " Searching for "+id); this->workType = READFITNESSDETAIL; this->readFitnessDetailId = id; if (startThread()) { return 1; } return 0; } int GarminFilebasedDevice::finishReadFitnessDetail() { lockVariables(); int status = this->threadState; unlockVariables(); return status; } void GarminFilebasedDevice::cancelReadFitnessDetail() { cancelThread(); } int GarminFilebasedDevice::startReadFromGps() { struct stat stFileInfo; int intStat; // Search for GPSData in Configuration this->fitnessFile = ""; for (list::iterator it = deviceDirectories.begin(); it != deviceDirectories.end(); ++it) { MassStorageDirectoryType const& currentDir = (*it); if ((currentDir.dirType == GPXDIR) && (currentDir.name.compare("GPSData") == 0) && (currentDir.readable)) { this->fitnessFile = this->baseDirectory + "/" + currentDir.path; if (currentDir.basename.length() > 0) { this->fitnessFile += '/' + currentDir.basename + '.' + currentDir.extension; } } } if (this->fitnessFile.length() == 0) { Log::err("Unable to determine fitness file, does the device support GPSData?"); return 0; } // Attempt to get the file attributes intStat = stat(this->fitnessFile.c_str(),&stFileInfo); if(intStat != 0) { Log::err("The file "+this->fitnessFile+" could not be found. Unable to read Gpx data."); this->transferSuccessful = 0; return 0; } this->transferSuccessful = 1; if (Log::enabledDbg()) Log::dbg("No thread necessary to read from device, gpx file exists"); return 1; } int GarminFilebasedDevice::finishReadFromGps() { /* 0 = idle 1 = working 2 = waiting 3 = finished */ return 3; // No processing of data necessary, therefore finish instantly } string GarminFilebasedDevice::getGpxData() { stringstream filecontent; std::ifstream file; file.open (this->fitnessFile.c_str()); if (file) { string line; while (getline(file, line)) { filecontent << line << "\n"; } file.close(); } else { Log::err("GetGpxData(): Unable to open file "+this->fitnessFile); } return filecontent.str(); } void GarminFilebasedDevice::cancelReadFromGps() { this->transferSuccessful = 0; Log::dbg("Canceling ReadFromGps..."); // Nothing much to do here as no thread was started } string GarminFilebasedDevice::getBinaryFile(string relativeFilePath) { //TODO: Check for .. in file path. No website should be able to access files outside the garmin device! // Check if site is allowed to read from that directory if (Log::enabledDbg()) { Log::dbg("getBinaryFile called for "+this->displayName); } if (Log::enabledDbg()) { Log::dbg("Opening file "+relativeFilePath); } string fullFilePath = this->baseDirectory + '/' + relativeFilePath; std::ifstream in(fullFilePath.c_str()); if(!in) { Log::dbg("getBinaryFile unable to open file: "+fullFilePath); return ""; } std::stringstream buffer; buffer << in.rdbuf(); in.close(); // Write to backup directory if needed try { FitReader fit(fullFilePath); if (fit.isFitFile()) { fit.registerFitMsgFkt(this); FitMsg * fitMsg = fit.getNextFitMsgFromType(FIT_MESSAGE_FILE_ID); if (fitMsg != NULL) { if (fitMsg->GetType() == FIT_MESSAGE_FILE_ID) { FitMsg_File_ID *fileid = dynamic_cast (fitMsg); if (fileid != NULL) { if (fileid->getType() == FIT_FILE_ID_TYPE_ACTIVITY) { time_t startTime = fileid->getTimeCreated() + TIME_OFFSET; backupWorkout(buffer.str(), "fit", startTime); } else { Log::dbg("Not an activity - not creating a backup"); } } } delete(fitMsg); } } } catch (FitFileException &e) { Log::err("FitFileException on file "+fullFilePath+": "+e.getError()); } return buffer.str(); } int GarminFilebasedDevice::startDownloadData(string gpsDataString) { Log::err("startDownloadData was called for "+this->displayName); if (!deviceDownloadList.empty()) { Log::info("There are still files to download in the queue. Erasing these files..."); } deviceDownloadList.clear(); TiXmlDocument doc; doc.Parse(gpsDataString.c_str()); // It is possible that more than one file can be downloaded TiXmlElement * devDown = doc.FirstChildElement("DeviceDownload"); if (devDown != NULL) { TiXmlElement * file = devDown->FirstChildElement("File"); while (file != NULL) { const char * url = file->Attribute("Source"); const char * dest = file->Attribute("Destination"); const char * region = file->Attribute("RegionId"); if ((url != NULL) && (dest != NULL)) { string strRegion = ""; if (region != NULL) { strRegion = region; } string strUrl = url; string strDest = dest; if (Log::enabledDbg()) { Log::dbg("Download destination: "+strDest + " URL: "+strUrl); } if ((strUrl.length() > 0) && (strDest.length() > 0)) { // Replace \ with / string::size_type pos = strDest.find("\\", 0); while(string::npos != pos ) { strDest.replace(pos, 1, "/"); pos = strDest.find("\\", 0); } //If anyone knows a better way to detect directory traversal, please notify me pos = strDest.find("../", 0); if (string::npos == pos ) { //Test if target directory is a valid write directory bool directoryIsValid = false; string fileNameOnly = basename(strDest.c_str()); string directoryOnly = ""; if (fileNameOnly.length() < strDest.length()) { directoryOnly = strDest.substr(0,strDest.length()-fileNameOnly.length()-1); } Log::dbg("Comparing with "+directoryOnly); for (list::iterator it=deviceDirectories.begin(); it!=deviceDirectories.end(); ++it) { MassStorageDirectoryType const& dt = (*it); if ((directoryOnly.compare( dt.path ) == 0) && (dt.writeable)) { directoryIsValid = true; } } if (directoryIsValid) { DeviceDownloadData fileElement; fileElement.url = strUrl; fileElement.destination = strDest; fileElement.destinationtmp = strDest+".tmp"; fileElement.regionId = strRegion; deviceDownloadList.push_back(fileElement); } else { Log::err("Device does not allow to write to this path: "+strDest); } } else { Log::err("Invalid filename! Found '..' Directory traversal not allowed!"); } } } else { if (Log::enabledDbg()) { Log::dbg("Received an element with no Source/Destination Attribute"); } } file = file->NextSiblingElement("File"); } } else { if (Log::enabledDbg()) { Log::dbg("Unable to find xml element DeviceDownload in data"); } } if (Log::enabledDbg()) { stringstream ss; ss << "Received a list of " << deviceDownloadList.size() << " files to download!"; Log::dbg(ss.str()); } if (!deviceDownloadList.empty()) { downloadDataErrorCount = 0; } return deviceDownloadList.size(); } string GarminFilebasedDevice::getNextDownloadDataUrl() { if (!deviceDownloadList.empty()) { DeviceDownloadData downloadData = deviceDownloadList.front(); return downloadData.url; } return ""; } int GarminFilebasedDevice::writeDownloadData(char * buf, int length) { if (!deviceDownloadList.empty()) { DeviceDownloadData downloadData = deviceDownloadList.front(); string filename = baseDirectory + "/" + downloadData.destinationtmp; if (Log::enabledDbg()) { stringstream ss; ss << "Writing " << length << " bytes to file " << filename; Log::dbg(ss.str()); } if (!downloadDataOutputStream.is_open()) { downloadDataOutputStream.open(filename.c_str(), ios::out | ios::binary); } if (downloadDataOutputStream.is_open()) { downloadDataOutputStream.write (buf, length); } else { downloadDataErrorCount++; Log::err("Unable to open file "+filename); return -1; } } return length; } void GarminFilebasedDevice::saveDownloadData() { Log::dbg("saveDownloadData was called for "+this->displayName); if (downloadDataOutputStream.is_open()) { downloadDataOutputStream.close(); if (!deviceDownloadList.empty()) { Log::dbg("Removing file to download from list"); DeviceDownloadData fileElement = deviceDownloadList.front(); deviceDownloadList.pop_front(); postProcessDownloadData(fileElement); } } else { Log::dbg("Not closing anything, since nothing was open..."); } } void GarminFilebasedDevice::cancelDownloadData() { Log::dbg("cancelDownloadData was called for "+this->displayName); if (downloadDataOutputStream.is_open()) { downloadDataOutputStream.close(); } if (!deviceDownloadList.empty()) { deviceDownloadList.pop_front(); } downloadDataErrorCount++; this->transferSuccessful = false; } void GarminFilebasedDevice::postProcessDownloadData(DeviceDownloadData downloadData) { string filename = this->baseDirectory + "/" + downloadData.destination; string filenametmp = this->baseDirectory + "/" + downloadData.destinationtmp; if ((downloadData.destination.find("gmaptz.img") != string::npos) && (downloadData.url.find(".rgn") != string::npos)) { if (Log::enabledDbg()) { Log::dbg("Downloaded new rgn timezone file to gmaptz.img. Deletion of first 60 bytes needed."); } /** * The rgn file comes with an unknown header (to me), which needs to be deleted before the * device accepts it as an update file. * More information: http://www.noeman.org/gsm/garmin-maps/257457-garmin-timezone-map-v10-gmaptz-img.html */ std::ifstream fin(filenametmp.c_str(), ios::binary | ios::in ); std::ofstream fout(filename.c_str(), ios::binary | ios::out | ios::trunc); if (!fin.is_open()) { Log::err("Unable to open "+filenametmp+" for reading!"); return; } if (!fout.is_open()) { Log::err("Unable to open "+filename+" for writing!"); return; } fin.seekg(60,ios_base::beg); // Skip first 60 bytes fout << fin.rdbuf(); // Copy from temporary file name to real file name fin.close(); fout.close(); remove(filenametmp.c_str()); if (Log::enabledDbg()) { Log::dbg("Deleted first 60 bytes in "+downloadData.destination); } } else { if (Log::enabledDbg()) { Log::dbg("Renaming "+downloadData.destinationtmp+" -> "+downloadData.destination); } remove(filename.c_str()); rename(filenametmp.c_str(), filename.c_str()); } } /** * This is used to indicate the status of the write download data process. * @return 0 = idle 1 = working 2 = waiting 3 = finished */ int GarminFilebasedDevice::finishDownloadData() { if (downloadDataErrorCount > 0) { this->transferSuccessful = false; return 3; // Finished } if (!deviceDownloadList.empty()) { return 1; } else { this->transferSuccessful = true; return 3; } } /** * Starts a thread that writes the passed xml string to the given filename * @param filename - filename on disk * @param data - the filename to write to on the device. * @param dataTypeName - a Fitness DataType from the GarminDevice.xml retrieved with DeviceDescription * @return int returns 1 if successful otherwise 0 */ int GarminFilebasedDevice::startWriteFitnessData(string filename, string data, string dataTypeName) { string::size_type loc = filename.find( "../", 0 ); if( loc != string::npos ) { Log::err("SECURITY WARNING: Filenames with ../ are not allowed! "+filename); return 0; } string pathToWrite = ""; for (list::iterator it=deviceDirectories.begin(); it!=deviceDirectories.end(); ++it) { MassStorageDirectoryType const& dt = (*it); if ((dataTypeName.compare(dt.name) == 0) && (dt.writeable)) { pathToWrite = dt.path; } } if (pathToWrite.length() == 0) { Log::err("Path for " + dataTypeName + " not found. Not writing to device!"); return 0; } // There shouldn't be a thread running... but who knows... lockVariables(); this->xmlToWrite = data; this->filenameToWrite = this->baseDirectory + "/" + pathToWrite + "/" + filename; this->overwriteFile = 2; // not yet asked this->workType = WRITEFITNESSDATA; unlockVariables(); if (Log::enabledDbg()) Log::dbg("Saving to file: "+this->filenameToWrite); if (startThread()) { return 1; } return 0; return 0; } /** * This is used to indicate the status of the write fitness data process. * @return 0 = idle 1 = working 2 = waiting 3 = finished */ int GarminFilebasedDevice::finishWriteFitnessData() { lockVariables(); int status = this->threadState; unlockVariables(); return status; } /** * Cancels the current write of fitness data */ void GarminFilebasedDevice::cancelWriteFitnessData() { cancelThread(); } /** * Returns the bytes available in the given path on the device * @return bytes available (-1 for non-mass storage mode devices.) */ int GarminFilebasedDevice::bytesAvailable(string path) { if (Log::enabledDbg()) { Log::dbg("bytesAvailable called for path "+path); } string fullPath = baseDirectory + "/" + path; struct statfs st; unsigned long long freeBytes = 0; if (statfs(fullPath.c_str(), &st) == 0) { freeBytes = (unsigned long long)st.f_bfree * (unsigned long long) st.f_bsize; } else { Log::err("Error getting bytes available for path: "+fullPath); /* * Apparently Garmin Map Updater requests invalid pathes like this one: * BytesAvailable(0,"Garmin/http://downloadg.garmin.com/direct/D3288000A.IMG?garmindlm=12345_678") * In this case, return baseDirectory size */ fullPath = baseDirectory; if (statfs(fullPath.c_str(), &st) == 0) { freeBytes = (unsigned long long)st.f_bfree * (unsigned long long) st.f_bsize; } } if (Log::enabledDbg()) { stringstream ss; ss << "Bytes available for path " << fullPath << ": " << freeBytes; Log::dbg(ss.str()); } if (freeBytes > INT_MAX) { return INT_MAX; } else { return (int)freeBytes; } } int GarminFilebasedDevice::startReadFitnessData(string dataTypeName) { if (Log::enabledDbg()) Log::dbg("Starting thread to read from garmin device ("+dataTypeName+")"); if (dataTypeName.compare("FitnessUserProfile")==0) { this->workType = READFITNESSUSERPROFILE; } else if (dataTypeName.compare("FitnessWorkouts")==0) { this->workType = READFITNESSWORKOUTS; } else if (dataTypeName.compare("FitnessCourses")==0) { this->workType = READFITNESSCOURSES; } else if (dataTypeName.compare("FitnessHistory")==0) { this->workType = READFITNESS; } else { Log::err("Unknown data to read: '"+dataTypeName+"' - Defaulting back to FitnessHistory"); this->workType = READFITNESS; } if (startThread()) { return 1; } return 0; } int GarminFilebasedDevice::finishReadFitnessData() { /* 0 = idle 1 = working 2 = waiting 3 = finished */ lockVariables(); int status = this->threadState; unlockVariables(); return status; } string GarminFilebasedDevice::getFitnessData() { return this->fitnessDataTcdXml; } /** * Starts an asynchronous file listing operation for a Mass Storage mode device. * Only files that are output from the device are listed.
* The result can be retrieved with getDirectoryXml(). * Minimum plugin version 2.8.1.0
* * @param {String} dataTypeName a DataType from GarminDevice.xml retrieved with DeviceDescription * @param {String} fileTypeName a Specification Identifier for a File in dataTypeName from GarminDevice.xml * @param {Boolean} computeMD5 If true, the plug-in will generate an MD5 checksum for each readable file. */ int GarminFilebasedDevice::startReadableFileListing(string dataTypeName, string fileTypeName, bool computeMd5) { lockVariables(); this->threadState = 1; this->readableFileListingDataTypeName = dataTypeName; this->readableFileListingFileTypeName = fileTypeName; this->readableFileListingComputeMD5 = computeMd5; this->directoryListingXml = ""; unlockVariables(); if (Log::enabledDbg()) Log::dbg("Starting thread to read file listing from garmin device "+this->displayName); this->workType = READABLEFILELISTING; if (startThread()) { return 1; } return 0; } /** * Returns the status of the asynchronous file listing operation for the mass storage mode device * @return 0 = idle 1 = working 2 = waiting 3 = finished */ int GarminFilebasedDevice::finishReadableFileListing() { lockVariables(); int status = this->threadState; unlockVariables(); return status; } /** * Cancels the asynchronous file listing operation for the mass storage mode device */ void GarminFilebasedDevice::cancelReadableFileListing() { if (Log::enabledDbg()) { Log::dbg("cancelReadableFileListing for device "+this->displayName); } cancelThread(); } /** * Returns the status of the asynchronous file listing operation * @return string with directory listing */ string GarminFilebasedDevice::getDirectoryListingXml() { return this->directoryListingXml; } void GarminFilebasedDevice::readFitnessUserProfile() { Log::dbg("Thread readFitnessUserProfile started"); string workFile=""; lockVariables(); this->threadState = 1; // Working for (list::iterator it = deviceDirectories.begin(); it != deviceDirectories.end(); ++it) { MassStorageDirectoryType const& currentDir = (*it); if ((currentDir.readable) && (currentDir.name.compare("FitnessUserProfile") == 0)) { workFile = this->baseDirectory + "/" + currentDir.path +"/" + currentDir.basename + "." + currentDir.extension; } } unlockVariables(); // Check if the device supports reading tcx files if (workFile.length() == 0) { Log::err("Device does not support reading FitnessUserProfile. Element FitnessUserProfile not found in xml!"); lockVariables(); this->fitnessDataTcdXml = ""; this->threadState = 3; // Finished this->transferSuccessful = false; // Failed; unlockVariables(); return; } if (Log::enabledDbg()) { Log::dbg("Opening file "+workFile); } std::ifstream in(workFile.c_str()); if(!in) { Log::err("readFitnessUserProfile unable to open file: "+workFile); lockVariables(); this->fitnessDataTcdXml = ""; this->threadState = 3; // Finished this->transferSuccessful = false; // Failed; unlockVariables(); return; } std::stringstream buffer; buffer << in.rdbuf(); in.close(); lockVariables(); this->fitnessDataTcdXml = buffer.str(); this->threadState = 3; // Finished this->transferSuccessful = true; // Success; unlockVariables(); return; } void GarminFilebasedDevice::readFitnessCourses(bool readTrackData) { if (Log::enabledDbg()) { Log::dbg("Thread readFitnessCourses started"); } string workDir=""; string extension=""; lockVariables(); this->threadState = 1; // Working for (list::iterator it = deviceDirectories.begin(); it != deviceDirectories.end(); ++it) { MassStorageDirectoryType const& currentDir = (*it); if ((currentDir.readable) && (currentDir.name.compare("FitnessCourses") == 0)) { workDir = this->baseDirectory + "/" + currentDir.path; extension = currentDir.extension; break; } } unlockVariables(); // Check if the device supports reading crs files if (workDir.length() == 0) { Log::err("Device does not support reading CRS Files. Element FitnessCourses not found in xml!"); lockVariables(); this->fitnessDataTcdXml = ""; this->threadState = 3; // Finished this->transferSuccessful = false; // Failed; unlockVariables(); return; } DIR *dp; struct dirent *dirp; vector files = vector(); if((dp = opendir(workDir.c_str())) == NULL) { Log::err("Error opening course directory! "+ workDir); lockVariables(); this->fitnessDataTcdXml = ""; this->threadState = 3; // Finished this->transferSuccessful = false; // Failed; unlockVariables(); return; } while ((dirp = readdir(dp)) != NULL) { files.push_back(string(dirp->d_name)); } closedir(dp); TiXmlDocument * output = new TiXmlDocument(); TiXmlDeclaration * decl = new TiXmlDeclaration( "1.0", "UTF-8", "no"); output->LinkEndChild( decl ); TiXmlElement * train = new TiXmlElement( "TrainingCenterDatabase" ); train->SetAttribute("xmlns","http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2"); train->SetAttribute("xmlns:xsi","http://www.w3.org/2001/XMLSchema-instance"); train->SetAttribute("xsi:schemaLocation","http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2 http://www.garmin.com/xmlschemas/TrainingCenterDatabasev2.xsd"); output->LinkEndChild( train ); TiXmlElement * folders = new TiXmlElement( "Folders" ); train->LinkEndChild( folders ); TiXmlElement * courses = new TiXmlElement( "Courses" ); train->LinkEndChild( courses ); // Loop over all files in Courses directory: for (unsigned int i = 0;i < files.size();i++) { if (files[i].find("."+extension)!=string::npos) { if (Log::enabledDbg()) { Log::dbg("Opening file: "+ files[i]); } TiXmlDocument doc(workDir + "/" + files[i]); if (doc.LoadFile()) { TiXmlElement * train = doc.FirstChildElement("TrainingCenterDatabase"); if (train != NULL) { TiXmlElement * inputCourses = train->FirstChildElement("Courses"); while ( inputCourses != NULL) { TiXmlElement * inputCourse =inputCourses->FirstChildElement("Course"); while ( inputCourse != NULL) { TiXmlNode * newCourse = inputCourse->Clone(); if (!readTrackData) { // Track data must be deleted TiXmlNode * trackNode = newCourse->FirstChildElement("Track"); while (trackNode != NULL) { newCourse->RemoveChild( trackNode ); trackNode = newCourse->FirstChildElement("Track"); } TiXmlNode * coursePointNode = newCourse->FirstChildElement("CoursePoint"); while (coursePointNode != NULL) { newCourse->RemoveChild( coursePointNode ); coursePointNode = newCourse->FirstChildElement("CoursePoint"); } TiXmlNode * creatorNode = newCourse->FirstChildElement("Creator"); while (creatorNode != NULL) { newCourse->RemoveChild( creatorNode ); creatorNode = newCourse->FirstChildElement("Creator"); } } courses->LinkEndChild( newCourse ); inputCourse = inputCourse->NextSiblingElement( "Course" ); } inputCourses = inputCourses->NextSiblingElement( "Courses" ); } } } else { Log::err("Unable to load course file "+files[i]); } } } addAuthorXmlElement(train); TiXmlPrinter printer; printer.SetIndent( " " ); output->Accept( &printer ); string fitnessXml = printer.Str(); delete(output); lockVariables(); this->fitnessDataTcdXml = fitnessXml; this->threadState = 3; // Finished this->transferSuccessful = true; // Successfull; unlockVariables(); if (Log::enabledDbg()) { Log::dbg("Thread readFitnessCourses finished"); } return; } void GarminFilebasedDevice::addAuthorXmlElement(TiXmlElement * parentNode) { if (parentNode == NULL) { return; } TiXmlElement * authorNode = new TiXmlElement( "Author" ); authorNode->SetAttribute("xsi:type","Application_t"); parentNode->LinkEndChild( authorNode ); TiXmlElement * nameNode = new TiXmlElement( "Name" ); nameNode->LinkEndChild(new TiXmlText("Garmin Communicator Plug-In")); authorNode->LinkEndChild( nameNode ); TiXmlElement * buildNode = new TiXmlElement( "Build" ); authorNode->LinkEndChild( buildNode ); TiXmlElement * versionNode = new TiXmlElement( "Version" ); buildNode->LinkEndChild( versionNode ); TiXmlElement * versionMajNode = new TiXmlElement( "VersionMajor" ); versionMajNode->LinkEndChild(new TiXmlText("2")); versionNode->LinkEndChild( versionMajNode ); TiXmlElement * versionMinNode = new TiXmlElement( "VersionMinor" ); versionMinNode->LinkEndChild(new TiXmlText("9")); versionNode->LinkEndChild( versionMinNode ); TiXmlElement * versionBuildMajNode = new TiXmlElement( "BuildMajor" ); versionBuildMajNode->LinkEndChild(new TiXmlText("3")); versionNode->LinkEndChild( versionBuildMajNode ); TiXmlElement * versionBuildMinNode = new TiXmlElement( "BuildMinor" ); versionBuildMinNode->LinkEndChild(new TiXmlText("0")); versionNode->LinkEndChild( versionBuildMinNode ); TiXmlElement * buildTypeNode = new TiXmlElement( "Type" ); buildTypeNode->LinkEndChild(new TiXmlText("Release")); buildNode->LinkEndChild( buildTypeNode ); TiXmlElement * buildTimeNode = new TiXmlElement( "Time" ); buildTimeNode->LinkEndChild(new TiXmlText("Oct 28 2010, 10:21:55")); buildNode->LinkEndChild( buildTimeNode ); TiXmlElement * buildBuilderNode = new TiXmlElement( "Builder" ); buildBuilderNode->LinkEndChild(new TiXmlText("sqa")); buildNode->LinkEndChild( buildBuilderNode ); TiXmlElement * buildLangNode = new TiXmlElement( "LangID" ); buildLangNode->LinkEndChild(new TiXmlText("EN")); authorNode->LinkEndChild( buildLangNode ); TiXmlElement * buildPartNode = new TiXmlElement( "PartNumber" ); buildPartNode->LinkEndChild(new TiXmlText("006-A0160-00")); authorNode->LinkEndChild( buildPartNode ); } void GarminFilebasedDevice::readFitnessWorkouts() { if (Log::enabledDbg()) { Log::dbg("Thread readFitnessWorkouts started"); } string workDir=""; string extension=""; lockVariables(); this->threadState = 1; // Working for (list::iterator it = deviceDirectories.begin(); it != deviceDirectories.end(); ++it) { MassStorageDirectoryType const& currentDir = (*it); if ((currentDir.readable) && (currentDir.name.compare("FitnessWorkouts") == 0)) { workDir = this->baseDirectory + "/" + currentDir.path; extension = currentDir.extension; break; } } unlockVariables(); // Check if the device supports reading crs files if (workDir.length() == 0) { Log::err("Device does not support reading Workout Files. Element FitnessWorkouts not found in xml!"); lockVariables(); this->fitnessDataTcdXml = ""; this->threadState = 3; // Finished this->transferSuccessful = false; // Failed; unlockVariables(); return; } DIR *dp; struct dirent *dirp; vector files = vector(); if((dp = opendir(workDir.c_str())) == NULL) { Log::err("Error opening workout directory! "+ workDir); lockVariables(); this->fitnessDataTcdXml = ""; this->threadState = 3; // Finished this->transferSuccessful = false; // Failed; unlockVariables(); return; } while ((dirp = readdir(dp)) != NULL) { files.push_back(string(dirp->d_name)); } closedir(dp); TiXmlDocument * output = new TiXmlDocument(); TiXmlDeclaration * decl = new TiXmlDeclaration( "1.0", "UTF-8", "no"); output->LinkEndChild( decl ); TiXmlElement * train = new TiXmlElement( "TrainingCenterDatabase" ); train->SetAttribute("xmlns","http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2"); train->SetAttribute("xmlns:xsi","http://www.w3.org/2001/XMLSchema-instance"); train->SetAttribute("xsi:schemaLocation","http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2 http://www.garmin.com/xmlschemas/TrainingCenterDatabasev2.xsd"); output->LinkEndChild( train ); TiXmlElement * folders = new TiXmlElement( "Folders" ); train->LinkEndChild( folders ); TiXmlElement * folderWorkouts = new TiXmlElement( "Workouts" ); folders->LinkEndChild( folderWorkouts ); TiXmlElement * workoutsRunning = new TiXmlElement( "Running" ); workoutsRunning->SetAttribute("Name","Running"); folderWorkouts->LinkEndChild( workoutsRunning ); TiXmlElement * workoutsBiking = new TiXmlElement( "Biking" ); workoutsBiking->SetAttribute("Name","Biking"); folderWorkouts->LinkEndChild( workoutsBiking ); TiXmlElement * workoutsOther = new TiXmlElement( "Other" ); workoutsOther->SetAttribute("Name","Other"); folderWorkouts->LinkEndChild( workoutsOther ); TiXmlElement * workouts = new TiXmlElement( "Workouts" ); train->LinkEndChild( workouts ); // Loop over all files in workout directory: for (unsigned int i = 0;i < files.size();i++) { if (files[i].find("."+extension)!=string::npos) { if (Log::enabledDbg()) { Log::dbg("Opening file: "+ files[i]); } TiXmlDocument doc(workDir + "/" + files[i]); if (doc.LoadFile()) { TiXmlElement * inputTrain = doc.FirstChildElement("TrainingCenterDatabase"); if (inputTrain != NULL) { // Do folder part TiXmlElement * inputFolders = NULL; TiXmlElement * inputFoldersWorkouts = NULL; inputFolders = inputTrain->FirstChildElement("Folders"); if (inputFolders != NULL) { inputFoldersWorkouts = inputFolders->FirstChildElement("Workouts"); } if (inputFoldersWorkouts != NULL) { // Running TiXmlElement * inputFoldersWorkoutsType = inputFoldersWorkouts->FirstChildElement("Running"); TiXmlElement * inputWorkoutNameRef = NULL; if (inputFoldersWorkoutsType != NULL) { inputWorkoutNameRef = inputFoldersWorkoutsType->FirstChildElement("WorkoutNameRef");} while (inputWorkoutNameRef != NULL) { TiXmlNode * newNode = inputWorkoutNameRef->Clone(); workoutsRunning->LinkEndChild(newNode); inputWorkoutNameRef = inputWorkoutNameRef->NextSiblingElement("WorkoutNameRef"); } // Biking inputFoldersWorkoutsType = inputFoldersWorkouts->FirstChildElement("Biking"); if (inputFoldersWorkoutsType != NULL) { inputWorkoutNameRef = inputFoldersWorkoutsType->FirstChildElement("WorkoutNameRef");} while (inputWorkoutNameRef != NULL) { workoutsBiking->LinkEndChild(inputWorkoutNameRef->Clone()); inputWorkoutNameRef = inputWorkoutNameRef->NextSiblingElement("WorkoutNameRef"); } // Other inputFoldersWorkoutsType = inputFoldersWorkouts->FirstChildElement("Other"); if (inputFoldersWorkoutsType != NULL) { inputWorkoutNameRef = inputFoldersWorkoutsType->FirstChildElement("WorkoutNameRef");} while (inputWorkoutNameRef != NULL) { workoutsOther->LinkEndChild(inputWorkoutNameRef->Clone()); inputWorkoutNameRef = inputWorkoutNameRef->NextSiblingElement("WorkoutNameRef"); } } // Do workout part TiXmlElement * inputWorkouts = inputTrain->FirstChildElement("Workouts"); if (inputWorkouts != NULL) { TiXmlElement * inputWorkout = inputWorkouts->FirstChildElement("Workout"); while (inputWorkout != NULL) { workouts->LinkEndChild(inputWorkout->Clone()); inputWorkout = inputWorkout->NextSiblingElement("Workout"); } } } } else { Log::err("Unable to load course file "+files[i]); } } } addAuthorXmlElement(train); TiXmlPrinter printer; printer.SetIndent( " " ); output->Accept( &printer ); string fitnessXml = printer.Str(); delete(output); lockVariables(); this->fitnessDataTcdXml = fitnessXml; this->threadState = 3; // Finished this->transferSuccessful = true; // Successfull; unlockVariables(); if (Log::enabledDbg()) { Log::dbg("Thread readFitnessWorkouts finished"); } return; } int GarminFilebasedDevice::startDirectoryListing(string relativePath, bool computeMd5) { lockVariables(); this->threadState = 1; this->readableFileListingFileTypeName = relativePath; this->readableFileListingComputeMD5 = computeMd5; this->directoryListingXml = ""; unlockVariables(); if (Log::enabledDbg()) Log::dbg("Starting thread to read directory listing from garmin device "+this->displayName); this->workType = DIRECTORYLISTING; if (startThread()) { return 1; } return 0; } int GarminFilebasedDevice::finishDirectoryListing() { lockVariables(); int status = this->threadState; unlockVariables(); return status; } void GarminFilebasedDevice::cancelDirectoryListing() { if (Log::enabledDbg()) { Log::dbg("cancelDirectoryListing for device "+this->displayName); } cancelThread(); } void GarminFilebasedDevice::readDirectoryListing() { if (Log::enabledDbg()) { Log::dbg("Thread readDirectoryListing started"); } lockVariables(); string workDir=this->readableFileListingFileTypeName; // contains relative file path this->threadState = 1; // Working bool doCalculateMd5 = this->readableFileListingComputeMD5; unlockVariables(); TiXmlDocument * output = new TiXmlDocument(); TiXmlDeclaration * decl = new TiXmlDeclaration( "1.0", "UTF-8", "no"); output->LinkEndChild( decl ); string volumePrefix = this->baseDirectory; if (volumePrefix[volumePrefix.length()-1] != '/') { volumePrefix += '/'; } TiXmlElement * dirList = new TiXmlElement( "DirectoryListing" ); dirList->SetAttribute("xmlns","http://www.garmin.com/xmlschemas/DirectoryListing/v1"); dirList->SetAttribute("RequestedPath",workDir); dirList->SetAttribute("UnitId",this->deviceId); dirList->SetAttribute("VolumePrefix",volumePrefix); output->LinkEndChild( dirList ); stack directoryList; // Cut front slashes while ((workDir.length()>0) && (workDir[0]=='/')) { workDir = workDir.substr(1); } string::size_type loc = workDir.find( "..", 0 ); if( loc != string::npos ) { Log::err("SECURITY WARNING: work directories with .. are not allowed!"); } else { directoryList.push(workDir); } while (!directoryList.empty()) { string relativeWorkDir = directoryList.top(); directoryList.pop(); // get rid of the element string currentWorkDir = this->baseDirectory + "/" + relativeWorkDir; // Add / if directory exists if (relativeWorkDir[relativeWorkDir.length()-1] != '/') { struct stat dirstat; if(0 == stat(currentWorkDir.c_str(), &dirstat)) { if (S_ISDIR(dirstat.st_mode)) { currentWorkDir += '/'; relativeWorkDir += '/'; } } } string pattern = "*"; string::size_type lastSlash= relativeWorkDir.rfind("/"); if ((lastSlash != string::npos) && (lastSlash != (relativeWorkDir.length()-1))) { pattern = relativeWorkDir.substr(lastSlash+1); relativeWorkDir = relativeWorkDir.substr(0,lastSlash+1); currentWorkDir = this->baseDirectory + "/" + relativeWorkDir; } if (Log::enabledDbg()) { stringstream ss; ss << "Searching for pattern [" << pattern <<"] in [" << currentWorkDir <<"]"; Log::dbg(ss.str()); } glob_t gl; if (0 == glob(string(currentWorkDir+pattern).c_str(), 0, NULL, &gl)) { for(unsigned int i=0;iSetAttribute("IsDirectory","true"); directoryList.push(relativeFileName); } else { curFile->SetAttribute("IsDirectory","false"); } curFile->SetAttribute("Path",relativeFileName); if (!isDirectory) { stringstream ss; ss << filestatus.st_size; curFile->SetAttribute("Size",ss.str()); } // Get the timestamp TiXmlElement * timeElem = new TiXmlElement( "CreationTime" ); timeElem->LinkEndChild(new TiXmlText(GpsFunctions::print_dtime(filestatus.st_mtime-TIME_OFFSET))); curFile->LinkEndChild(timeElem); if ((!isDirectory) && (doCalculateMd5)) { if (Log::enabledDbg()) { Log::dbg("Calculating MD5 sum of " + fullFileName);} string md5 = getMd5FromFile(fullFileName); curFile->SetAttribute("MD5Sum",md5); } dirList->LinkEndChild( curFile ); } globfree(&gl); } else { Log::err("Error opening directory! "+ currentWorkDir); } } TiXmlPrinter printer; printer.SetIndent( " " ); output->Accept( &printer ); string outputXml = printer.Str(); delete(output); lockVariables(); this->threadState = 3; // Finished this->directoryListingXml = outputXml; this->transferSuccessful = true; // Successfull; unlockVariables(); if (Log::enabledDbg()) { Log::dbg("Thread readDirectoryListing finished"); } return; } #define MD5READBUFFERSIZE 1024*16 string GarminFilebasedDevice::getMd5FromFile(string filename) { if (!gcry_check_version (GCRYPT_VERSION)) { Log::err("Unable to use GNU Crypt library to calculate MD5 - wrong version!"); return ""; } if (!gcry_control (GCRYCTL_INITIALIZATION_FINISHED_P)) { gcry_control (GCRYCTL_DISABLE_SECMEM, 0); /* Disable secure memory. */ gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); /* Tell Libgcrypt that initialization has completed. */ } gcry_md_hd_t c; unsigned char buf[MD5READBUFFERSIZE]; gcry_md_open(&c, GCRY_MD_MD5, 0); gcry_md_enable(c, GCRY_MD_MD5); if (!c) { Log::err("Unable to use GNU Crypt library to calculate MD5"); return ""; } FILE *f = fopen(filename.c_str(),"r"); if (f==NULL) { Log::err("Unable open file to calculate MD5"); gcry_md_close(c); return ""; } int fd=fileno(f); for (;;) { unsigned int i=read(fd,buf,MD5READBUFFERSIZE); if (i <= 0) break; gcry_md_write(c, buf, i); } fclose(f); string md5=""; unsigned char * md = gcry_md_read(c, 0); int md5len = gcry_md_get_algo_dlen(GCRY_MD_MD5); for (int i=0; i * * GarminPlugin is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GarminPlugin is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #ifndef GARMINFILEBASEDDEVICE_H_INCLUDED #define GARMINFILEBASEDDEVICE_H_INCLUDED #include #include #include #include #include "messageBox.h" #include "gpsDevice.h" #include "log.h" #include "fit/fitReader.hpp" #include "fit/fitMsg.hpp" #include "fit/fitMsg_File_ID.hpp" #include "fit/fitFileException.hpp" using namespace std; class MessageBox; class GarminFilebasedDevice : public GpsDevice, FitMsg_Listener { public: GarminFilebasedDevice(); virtual ~GarminFilebasedDevice(); void setDeviceDescription(TiXmlDocument * device); /** * Returns the device description in XML format to be passed to the Garmin Javascript Libs * @return xml string with device description */ string getDeviceDescription() const; /** * Starts a thread that writes the passed xml string to the given filename * @param filename - filename on disk * @param xml - content for the file on disk * @return int returns 1 if successful otherwise 0 */ int startWriteToGps(string filename, string xml); /** * Sets the path on disk where the device is mounted * @param directory full path to a directory on disk */ virtual void setBaseDirectory(string directory); /** * Sets a command that gets executed after the file was stored on disk * @param cmd command to execute after the file was stored on disk */ virtual void setStorageCommand(string cmd); /** * Returns true if the device is available - current implementation checks if directory exists * @return true if devices should be shown to user */ virtual bool isDeviceAvailable(); /** * Starts reading the FIT data directory */ virtual int startReadFITDirectory(); /** * Checks if the read of the FIT data directory finished * @return 0 = idle 1 = working 2 = waiting 3 = finished */ virtual int finishReadFITDirectory(); /** * Cancels reading the FIT data directory */ virtual void cancelReadFITDirectory(); /** * Starts reading the fitness data without points * @param dataTypeName - which type of data should be read from the device * @return int returns 1 if successful otherwise 0 */ virtual int startReadFitnessDirectory(string dataTypeName); /** * Checks if the read of the fitness directory finished * @return 0 = idle 1 = working 2 = waiting 3 = finished */ virtual int finishReadFitnessDirectory(); /** * Cancels the read of the fitness data */ virtual void cancelReadFitnessData(); virtual int startReadFitnessDetail(string id); virtual int finishReadFitnessDetail(); virtual void cancelReadFitnessDetail(); virtual string getGpxData(); /** * Start the reading of a file in the GPX format (like current.gpx on Oregon) */ virtual int startReadFromGps(); /** * This is used to indicate the status of the read process. * @return 0 = idle 1 = working 2 = waiting 3 = finished */ virtual int finishReadFromGps(); /** * Cancels the current read from the device. */ virtual void cancelReadFromGps(); /** * Returns a file from the device */ virtual string getBinaryFile(string relativeFilePath); /** * Starts a binary file write to the device * @return number of downloads found in data */ virtual int startDownloadData(string gpsDataString); /** * Retrieves the next download url * @return url to download */ virtual string getNextDownloadDataUrl(); /** * Writes some bytes into the file opened by startDownloadData * @return Bytes written to file */ virtual int writeDownloadData(char *, int length); /** * This is used to indicate the status of the write download data process. * @return 0 = idle 1 = working 2 = waiting 3 = finished */ virtual int finishDownloadData(); /** * Saves/Closes the current file */ virtual void saveDownloadData(); /** * Cancels the current file download */ virtual void cancelDownloadData(); /** * Starts a thread that writes the passed xml string to the given filename * @param filename - filename on disk * @param data - the filename to write to on the device. * @param dataTypeName - a Fitness DataType from the GarminDevice.xml retrieved with DeviceDescription * @return int returns 1 if successful otherwise 0 */ virtual int startWriteFitnessData(string filename, string data, string dataTypeName); /** * This is used to indicate the status of the write fitness data process. * @return 0 = idle 1 = working 2 = waiting 3 = finished */ virtual int finishWriteFitnessData(); /** * Cancels the current write of fitness data */ virtual void cancelWriteFitnessData(); /** * Returns the bytes available in the given path on the device * @return bytes available (-1 for non-mass storage mode devices.) */ virtual int bytesAvailable(string path); /** * Starts a thread that tries to read the fitness data from a garmin device * @param dataTypeName - which type of data should be read from the device * @return int returns 1 if successful otherwise 0 */ virtual int startReadFitnessData(string dataTypeName); /** * Returns the status of reading fitness data from the device * @return int 0 = idle 1 = working 2 = waiting 3 = finished */ virtual int finishReadFitnessData(); /** * Gets the fitness data xml * @return xml containing fitness data read from garmin device */ virtual string getFitnessData(); /** * Receives all decoded messages stored in the fit file */ virtual void fitMsgReceived(FitMsg *msg); /** * Starts an asynchronous file listing operation for a Mass Storage mode device. * Only files that are output from the device are listed.
* The result can be retrieved with getDirectoryXml(). * Minimum plugin version 2.8.1.0
* * @param {String} dataTypeName a DataType from GarminDevice.xml retrieved with DeviceDescription * @param {String} fileTypeName a Specification Identifier for a File in dataTypeName from GarminDevice.xml * @param {Boolean} computeMD5 If true, the plug-in will generate an MD5 checksum for each readable file. * @return int returns 1 if successful otherwise 0 */ virtual int startReadableFileListing(string dataTypeName, string fileTypeName, bool computeMd5); /** * Returns the status of the asynchronous file listing operation for the mass storage mode device * @return 0 = idle 1 = working 2 = waiting 3 = finished */ virtual int finishReadableFileListing(); /** * Cancels the asynchronous file listing operation for the mass storage mode device */ virtual void cancelReadableFileListing(); /** * Returns the status of the asynchronous file listing operation * @return string with directory listing */ virtual string getDirectoryListingXml(); /** * Starts an asynchronous file listing operation for a Mass Storage mode device. * This function lists all files that are available on the device.
* The result can be retrieved with getDirectoryListingXml(). * Minimum plugin version 2.8.1.0
* * @param {String} relativePath specifies the relative path on the device * @param {Boolean} computeMD5 If true, the plug-in will generate an MD5 checksum for each readable file. * @return int returns 1 if successful otherwise 0 */ virtual int startDirectoryListing(string relativePath, bool computeMd5); /** * Returns the status of the asynchronous file listing operation for the mass storage mode device * @return 0 = idle 1 = working 2 = waiting 3 = finished */ virtual int finishDirectoryListing(); /** * Cancels the asynchronous file listing operation for the mass storage mode device */ virtual void cancelDirectoryListing(); protected: /** * Reads tcx files in the fit directory. (called by thread) */ void readFitnessDataFromDevice(bool readTrackData, string fitnessDetailId); /** * Reads the fitness profile from the device (called by thread) */ void readFitnessUserProfile(); /** * Reads the fitness courses from the device (called by thread) */ void readFitnessCourses(bool readTrackData); /** * Reads the fitness workout from the device (called by thread) */ void readFitnessWorkouts(); /** * Reads the a directory listing from the device (called by thread) */ void readDirectoryListing(); /** * Reads file structure of fit directories for ReadFITDirectory */ void readFITDirectoryFromDevice(); /** * Reads the file listening from the device */ void readFileListingFromDevice(); /** * Returns a message for the user. Should be called if finishWriteToGps returns 2 (waiting) * The function that fetches the message must delete the message! * @return MessageBox for the user to display */ virtual MessageBox * getMessage(); /** * A message can be answered by the user. This function must be called if the message was answered * @param answer contains the button the user pressed */ virtual void userAnswered(const int answer); /** * Cancels the write thread */ virtual void cancelWriteToGps(); /** * Returns if the transfer to the device was successful * @return int 0 = failed 1 = success */ virtual int getTransferSucceeded(); TiXmlDocument * deviceDescription; /** * Returns the status if writing to device is finished * @return int 0 = idle 1 = working 2 = waiting 3 = finished */ virtual int finishWriteToGps(); /** * Adds the author element to a given node */ void addAuthorXmlElement(TiXmlElement * parentNode); virtual void doWork(); void writeGpxFile(); /** * Directory where this device is mounted in the file system */ string baseDirectory; /** * Command that should be executed after file was written. Leave empty if no command should be executed */ string storageCmd; /** * File content to write to disk */ string xmlToWrite; /** * File name for file on disk */ string filenameToWrite; /** * The thread can create a message for the user - this message is stored here */ MessageBox * waitingMessage; /** * If an overwrite yes/no message is posted to the user, this variable is set to 1 if the user wishes to overwrite the file. Otherwise set to 0 */ int overwriteFile; /** * The thread stores the success state in this variable */ bool transferSuccessful; /** * Searches the configuration for the update directory and adds it. */ void setUpdatePathsFromConfiguration(); /** * Searches for FIT, TCX and GPX directories in the configuration */ virtual void setPathsFromConfiguration(); /** * Check upper/lower case of paths, if they match the file system and correct if needed */ void checkPathsFromConfiguration(); /** * Parses all attributes of a TiXmlElement and adds them to another TiXmlElement if it is missing */ void addMissingAttributes(TiXmlElement * in, TiXmlElement * out); /** * File where this device stores its fitness/gpx data */ string fitnessFile; /** * Contains the device id */ string deviceId; /** * Is used to store the data given by startDownloadData() */ typedef struct _DeviceDownloadData { string url; /**< URL to download */ string destination; /**< Local path to store url */ string destinationtmp;/**< Local path to store url while downloading */ string regionId; /**< RegionId - unknown purpose */ } DeviceDownloadData; /** * Renames temporary file to real file name * TimeZone data file needs post processing after download. */ void postProcessDownloadData(DeviceDownloadData fileElement); /** * stores a list of files to download and store on the device (provided by startDownloadData()) */ list deviceDownloadList; /** * File hande for downloadData */ ofstream downloadDataOutputStream; /** * Counts errors during file download to the device */ int downloadDataErrorCount; enum DirDataType { FITDIR, TCXDIR, GPXDIR, CRSDIR, UNKNOWN }; typedef struct _MassStorageDirectoryType { DirDataType dirType; string path; string name; string extension; string basename; bool writeable; bool readable; } MassStorageDirectoryType; /** * Contains a list of directories available on device (read from garmindevice.xml) */ list deviceDirectories; /** * Stores the fitnessData which was read from the device */ string fitnessDataTcdXml; /** * Stores the id of the track that should be read */ string readFitnessDetailId; /** * Stores the current xml element where the Fit Message Listener (fitMsgReceived()) * should write the file information data to * Needed for the Fit-File Reader */ TiXmlElement * fitFileElement; /** * Variable containing the dataTypeName to be read by the asynchronous task READABLEFILELISTING */ string readableFileListingDataTypeName; /** * Variable containing the FileTypeName to be read by the asynchronous task READABLEFILELISTING */ string readableFileListingFileTypeName; /** * Variable containing boolean computeMD5 to be read by the asynchronous task READABLEFILELISTING */ bool readableFileListingComputeMD5; /** * Stores the file listing Data which was read from the device */ string directoryListingXml; /** * Read a file and calculate the md5 checksum */ string getMd5FromFile(string filename); }; #endif // GARMINFILEBASEDDEVICE_H_INCLUDED GarminPlugin-0.3.23/src/gpsDevice.cpp000066400000000000000000000171671232766717500174330ustar00rootroot00000000000000/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */ /* * GarminPlugin * Copyright (C) Andreas Diesner 2010 * * GarminPlugin is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GarminPlugin is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #include "gpsDevice.h" #include "log.h" #include "gpsFunctions.h" #include #include #include pthread_mutex_t shareVariables_mtx= PTHREAD_MUTEX_INITIALIZER; pthread_cond_t waitThreadCond = PTHREAD_COND_INITIALIZER; pthread_mutex_t waitThreadMutex = PTHREAD_MUTEX_INITIALIZER; GpsDevice::GpsDevice(string dispName) : displayName(dispName) , threadId (0) , progressState(0) , backupPath("") { } GpsDevice::~GpsDevice() { Log::dbg("Destructor of GpsDevice "+ this->displayName + " called"); cancelThread(); } bool GpsDevice::startThread() { progressState = 0; int code = pthread_create(&(this->threadId), NULL, GpsDevice::workerThread, (void*)this); if (code != 0) { Log::err("Creation of thread failed!"); return false; // Error happened } return true; } void GpsDevice::lockVariables() { pthread_mutex_lock( &shareVariables_mtx ); // LOCK Shared variables } void GpsDevice::unlockVariables() { pthread_mutex_unlock( &shareVariables_mtx); // UNLOCK Shared variables } void GpsDevice::waitThread() { Log::dbg("Thread is going to sleep!"); pthread_mutex_lock(&waitThreadMutex); while (2 == this->threadState) { pthread_cond_wait(&waitThreadCond, &waitThreadMutex); } pthread_mutex_unlock(&waitThreadMutex); Log::dbg("Thread was woken up!"); } void GpsDevice::signalThread() { Log::dbg("Thread wake up signal sending..."); // wake up thread pthread_mutex_lock(&waitThreadMutex); pthread_cond_signal(&waitThreadCond); pthread_mutex_unlock(&waitThreadMutex); Log::dbg("Thread wake up signal was sent!"); } void GpsDevice::cancelThread() { Log::dbg("Cancel Thread in GPSDevice für "+this->displayName); if (this->threadId > 0) { pthread_cancel(this->threadId); } } /*static*/ void * GpsDevice::workerThread(void * pthis) { Log::dbg("Thread started"); GpsDevice * obj = (GpsDevice*)pthis; obj->doWork(); Log::dbg("Thread finished"); obj->threadId = 0; return NULL; } /** * Default implementation simply increments the counter * with each call to simulate a progress bar */ int GpsDevice::getProgress() { if (progressState < 100) { progressState++; } else { progressState=0; } return progressState; } /** * Starts an asynchronous file listing operation for a Mass Storage mode device. * Only files that are output from the device are listed.
* The result can be retrieved with getDirectoryXml(). * Minimum plugin version 2.8.1.0
* * @param {String} dataTypeName a DataType from GarminDevice.xml retrieved with DeviceDescription * @param {String} fileTypeName a Specification Identifier for a File in dataTypeName from GarminDevice.xml * @param {Boolean} computeMD5 If true, the plug-in will generate an MD5 checksum for each readable file. */ int GpsDevice::startReadableFileListing(string dataTypeName, string fileTypeName, bool computeMd5) { Log::err("startReadableFileListing is not implemented for device "+this->displayName); return 0; } /** * Returns the status of the asynchronous file listing operation for the mass storage mode device * @return 0 = idle 1 = working 2 = waiting 3 = finished */ int GpsDevice::finishReadableFileListing() { Log::err("finishReadableFileListing is not implemented for device "+this->displayName); return 3; } /** * Cancels the asynchronous file listing operation for the mass storage mode device */ void GpsDevice::cancelReadableFileListing() { Log::err("cancelReadableFileListing is not implemented for device "+this->displayName); } /** * Returns the status of the asynchronous file listing operation * @return string with directory listing */ string GpsDevice::getDirectoryListingXml() { Log::err("getDirectoryListingXml is not implemented for device "+this->displayName); // Since this is the default implementation, return empty result return "\n\ "; } /** * Starts an asynchronous file listing operation for a Mass Storage mode device. * This function lists all files that are available on the device.
* The result can be retrieved with getDirectoryListingXml(). * Minimum plugin version 2.8.1.0
* The file search is recursive! * * @param {String} relativePath specifies the relative path on the device. May contain wildcards like (*.gpx) * @param {Boolean} computeMD5 If true, the plug-in will generate an MD5 checksum for each readable file. * @return int returns 1 if successful otherwise 0 */ int GpsDevice::startDirectoryListing(string relativePath, bool computeMd5) { Log::err("startDirectoryListing is not implemented for device "+this->displayName); return 0; } /** * Returns the status of the asynchronous file listing operation for the mass storage mode device * @return 0 = idle 1 = working 2 = waiting 3 = finished */ int GpsDevice::finishDirectoryListing() { Log::err("finishDirectoryListing is not implemented for device "+this->displayName); return 3; } /** * Cancels the asynchronous file listing operation for the mass storage mode device */ void GpsDevice::cancelDirectoryListing() { Log::err("cancelDirectoryListing is not implemented for device "+this->displayName); } void GpsDevice::backupWorkout(string workout, string type, time_t timestamp) { if (backupPath.empty()) { Log::info("Workout backup is disabled"); return; } string path = backupPath; if (*path.begin() == '~') { string homeDir = getenv ("HOME"); path = homeDir + path.substr(1); } path = GpsFunctions::str_replace("[TYPE]", type, path); path = GpsFunctions::str_replace("[YEAR]", "%Y", path); path = GpsFunctions::str_replace("[MONTH]", "%m", path); path = GpsFunctions::str_replace("[DAY]", "%d", path); if (*path.rbegin() != '/') { path += '/'; } path += "%Y-%m-%d_%H-%M-%S."+type; char buffer[400]; struct tm * timeinfo = localtime ( ×tamp ); strftime(buffer,400,path.c_str(),timeinfo); path = buffer; // Check if the output file exists (by opening it) ifstream ifile(path.c_str()); if (ifile) { Log::info("Backup file exists, not creating workout backup: "+path); return; } int pos=path.find_last_of('/'); string pathOnly = path.substr(0,pos); Log::info("Creating backup of workout in: "+pathOnly); if (GpsFunctions::mkpath(pathOnly, 0755) == EEXIST) { Log::info("Successfully created path: "+pathOnly); Log::info("Writing workout: "+path); std::ofstream workoutFile; workoutFile.open(path.c_str()); if (workoutFile.is_open()) { workoutFile << workout; workoutFile.close(); } } else { Log::err("Not saving workout! Unable to create path: "+pathOnly); } } void GpsDevice::setBackupPath(string path) { this->backupPath = path; } GarminPlugin-0.3.23/src/gpsDevice.h000066400000000000000000000274071232766717500170760ustar00rootroot00000000000000/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */ /* * GarminPlugin * Copyright (C) Andreas Diesner 2010 * * GarminPlugin is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GarminPlugin is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #ifndef GPSDEVICE_H_INCLUDED #define GPSDEVICE_H_INCLUDED #include #include "messageBox.h" using namespace std; class MessageBox; class GpsDevice { public: GpsDevice(string deviceName); virtual ~GpsDevice(); /** * Returns the device description in XML format to be passed to the Garmin Javascript Libs * @return xml string with device description */ virtual string getDeviceDescription() const = 0; /** * Starts a thread that writes the passed xml string to the given filename * @param filename - filename on disk * @param xml - content for the file on disk * @return int returns 1 if successful otherwise 0 */ virtual int startWriteToGps(string filename, string xml) = 0; /** * Starts a thread that tries to read the fitness data from a garmin device * @param dataTypeName - which type of data should be read from the device * @return int returns 1 if successful otherwise 0 */ virtual int startReadFitnessData(string dataTypeName) = 0; /** * Returns the status if writing to device is finished * @return int 0 = idle 1 = working 2 = waiting 3 = finished */ virtual int finishWriteToGps() = 0; /** * Returns the status of reading fitness data from the device * @return int 0 = idle 1 = working 2 = waiting 3 = finished */ virtual int finishReadFitnessData() = 0; /** * Cancels the write thread */ virtual void cancelWriteToGps() = 0; /** * Returns if the transfer to the device was successful * @return int 0 = failed 1 = success */ virtual int getTransferSucceeded() = 0; /** * Returns the name of the device * @return string with name of device */ virtual string getDisplayName() { return this->displayName; }; /** * Set the name of the device * @param name set the name of the devices */ virtual void setDisplayName(string name) { this->displayName = name; }; /** * Sets a command that gets executed after the file was stored on disk * @param cmd command to execute after the file was stored on disk */ virtual void setStorageCommand(string cmd) = 0; /** * Returns a message for the user. Should be called if finishWriteToGps returns 2 (waiting) * The function that fetches the message must delete the message! * @return MessageBox for the user to display */ virtual MessageBox * getMessage() = 0; /** * A message can be answered by the user. This function must be called if the message was answered * @param answer contains the button the user pressed */ virtual void userAnswered(const int answer) = 0; /** * Returns true if the device is available - current implementation checks if directory exists * @return true if devices should be shown to user */ virtual bool isDeviceAvailable() = 0; /** * Gets the fitness data xml * @return xml containing fitness data read from garmin device */ virtual string getFitnessData() = 0; /** * Starts reading the FIT binary data directory * @return int returns 1 if successful otherwise 0 */ virtual int startReadFITDirectory() = 0; /** * Checks if the read of the FIT binary data directory finished * @return 0 = idle 1 = working 2 = waiting 3 = finished */ virtual int finishReadFITDirectory() = 0; /** * Cancels the read of the FIT binary data directory */ virtual void cancelReadFITDirectory() = 0; /** * Starts reading the fitness data without points * @param dataTypeName - which type of data should be read from the device * @return int returns 1 if successful otherwise 0 */ virtual int startReadFitnessDirectory(string dataTypeName) = 0; /** * Checks if the read of the fitness directory finished * @return 0 = idle 1 = working 2 = waiting 3 = finished */ virtual int finishReadFitnessDirectory() = 0; /** * Cancels the read of the fitness data */ virtual void cancelReadFitnessData() = 0; /** * Starts reading of fitness history. Returns only tracks that match the given id */ virtual int startReadFitnessDetail(string id) = 0; virtual int finishReadFitnessDetail() = 0; virtual void cancelReadFitnessDetail() = 0; /** * Start the reading of a file in the GPX format (like current.gpx on Oregon) */ virtual int startReadFromGps() = 0; /** * This is used to indicate the status of the read process. * @return 0 = idle 1 = working 2 = waiting 3 = finished */ virtual int finishReadFromGps() = 0; /** * Cancels the current read from the device. */ virtual void cancelReadFromGps() = 0; /** * Gets the gpx data xml * @return xml containing gpx data read from garmin device */ virtual string getGpxData() = 0; /** * Returns a file from the device */ virtual string getBinaryFile(string relativeFilePath) = 0; /** * Starts a binary file write to the device * @return number of downloads found in data */ virtual int startDownloadData(string gpsDataString) = 0; /** * Retrieves the next download url * @return url to download */ virtual string getNextDownloadDataUrl() = 0; /** * This is used to indicate the status of the write download data process. * @return 0 = idle 1 = working 2 = waiting 3 = finished */ virtual int finishDownloadData() = 0; /** * Writes some bytes into the file opened by startDownloadData * @return Bytes written to file */ virtual int writeDownloadData(char *, int length) = 0; /** * Saves/Closes the current file */ virtual void saveDownloadData() = 0; /** * Cancels the current file download */ virtual void cancelDownloadData() = 0; /** * Starts a thread that writes the passed xml string to the given filename * @param filename - filename on disk * @param data - the filename to write to on the device. * @param dataTypeName - a Fitness DataType from the GarminDevice.xml retrieved with DeviceDescription * @return int returns 1 if successful otherwise 0 */ virtual int startWriteFitnessData(string filename, string data, string dataTypeName) = 0; /** * This is used to indicate the status of the write fitness data process. * @return 0 = idle 1 = working 2 = waiting 3 = finished */ virtual int finishWriteFitnessData() = 0; /** * Cancels the current write of fitness data */ virtual void cancelWriteFitnessData() = 0; /** * Returns the bytes available in the given path on the device * @return bytes available (-1 for non-mass storage mode devices.) */ virtual int bytesAvailable(string path) = 0; /** * Returns the progress of the current read/write state in percentage * Default implementation simply increments the counter with each call * Overwrite to get a real progress bar * @return int with the progress */ virtual int getProgress(); /** * Starts an asynchronous file listing operation for a Mass Storage mode device. * Only files that are output from the device are listed.
* The result can be retrieved with getDirectoryXml(). * Minimum plugin version 2.8.1.0
* * @param {String} dataTypeName a DataType from GarminDevice.xml retrieved with DeviceDescription * @param {String} fileTypeName a Specification Identifier for a File in dataTypeName from GarminDevice.xml * @param {Boolean} computeMD5 If true, the plug-in will generate an MD5 checksum for each readable file. * @return int returns 1 if successful otherwise 0 */ virtual int startReadableFileListing(string dataTypeName, string fileTypeName, bool computeMd5); /** * Returns the status of the asynchronous file listing operation for the mass storage mode device * @return 0 = idle 1 = working 2 = waiting 3 = finished */ virtual int finishReadableFileListing(); /** * Cancels the asynchronous file listing operation for the mass storage mode device */ virtual void cancelReadableFileListing(); /** * Returns the status of the asynchronous file listing operation * @return string with directory listing */ virtual string getDirectoryListingXml(); /** * Starts an asynchronous file listing operation for a Mass Storage mode device. * This function lists all files that are available on the device.
* The result can be retrieved with getDirectoryListingXml(). * Minimum plugin version 2.8.1.0
* * @param {String} relativePath specifies the relative path on the device * @param {Boolean} computeMD5 If true, the plug-in will generate an MD5 checksum for each readable file. * @return int returns 1 if successful otherwise 0 */ virtual int startDirectoryListing(string relativePath, bool computeMd5); /** * Returns the status of the asynchronous file listing operation for the mass storage mode device * @return 0 = idle 1 = working 2 = waiting 3 = finished */ virtual int finishDirectoryListing(); /** * Cancels the asynchronous file listing operation for the mass storage mode device */ virtual void cancelDirectoryListing(); /** * Sets a path to store all workouts that are uploaded */ virtual void setBackupPath(string path); protected: enum WorkType { WRITEGPX, READFITNESS, READFITNESSUSERPROFILE, READFITNESSWORKOUTS, READFITNESSCOURSES, READFITNESSCOURSESDIR, READFITNESSDIR, READFITNESSDETAIL, READFROMGPS, READFITDIRECTORY, WRITEFITNESSDATA, READABLEFILELISTING, DIRECTORYLISTING }; WorkType workType; /** * Stores the status of the thread * 0 = idle 1 = working 2 = waiting 3 = finished * This value is used by finishWriteToGps to signal the current status * @see finishWriteToGps */ int threadState; void waitThread(); /** * Name of the GpsDevice which gets displayed to the user */ string displayName; /** * Stores the thread id */ pthread_t threadId; void cancelThread(); void lockVariables(); void unlockVariables(); void signalThread(); bool startThread(); virtual void doWork() = 0; /** * Stores a local copy of the workout on your disk (if configured) * Timestamp is needed to replace variables like [YEAR] in path */ void backupWorkout(string workout, string filename, time_t timestamp); /** * Is used for the progress bar and should be a value between 0 and 100% */ int progressState; /** * Save a backup copy into this directory each time a workout is uploaded */ string backupPath; private: /** * Thread that gets called when the device performs a longer operation * like writing data to the device or reading fitness data * @param instance of the GpsDevice that should be written to disk */ static void * workerThread(void * pthis); }; #endif // GPSDEVICE_H_INCLUDED GarminPlugin-0.3.23/src/gpsFunctions.h000066400000000000000000000141671232766717500176460ustar00rootroot00000000000000/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */ /* * GarminPlugin * Copyright (C) Andreas Diesner 2011 * * GarminPlugin is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GarminPlugin is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #ifndef GPSFUNCTIONS_H_INCLUDED #define GPSFUNCTIONS_H_INCLUDED #include #include #include #include #include #include #define d2r (M_PI / 180.0) class GpsFunctions { public: //calculate haversine distance for linear distance static double haversine_km(double lat1, double long1, double lat2, double long2) { double dlong = (long2 - long1) * d2r; double dlat = (lat2 - lat1) * d2r; double a = pow(sin(dlat/2.0), 2) + cos(lat1*d2r) * cos(lat2*d2r) * pow(sin(dlong/2.0), 2); double c = 2 * atan2(sqrt(a), sqrt(1-a)); double d = 6367 * c; return d; } static double haversine_mi(double lat1, double long1, double lat2, double long2) { double dlong = (long2 - long1) * d2r; double dlat = (lat2 - lat1) * d2r; double a = pow(sin(dlat/2.0), 2) + cos(lat1*d2r) * cos(lat2*d2r) * pow(sin(dlong/2.0), 2); double c = 2 * atan2(sqrt(a), sqrt(1-a)); double d = 3956 * c; return d; } static double haversine_m_str(string lat1, string long1, string lat2, string long2) { double dCoords[4]; std::istringstream ss( lat1 + " " + long1 + " " +lat2 + " " + long2, istringstream::in); for (int n=0; n<4; n++) { ss >> dCoords[n]; } return haversine_km(dCoords[0],dCoords[1],dCoords[2],dCoords[3]) * 1000; } /** * Prints a time in the format 2007-04-20T23:55:01Z * @param t timestamp * @return string */ #define TIME_OFFSET 631065600 static string print_dtime( unsigned int t ) { time_t tval; struct tm tmval; char buf[128]; int len; /* 012345678901234567890123 This will make, for example, 2007-04-20T23:55:01-0700, but that date isn't quite ISO 8601 compliant. We need to stick a ':' in the time zone between the hours and the minutes. */ tval = t + TIME_OFFSET; //localtime_r(&tval,&tmval); gmtime_r(&tval,&tmval); strftime(buf,sizeof(buf)-1,"%FT%TZ",&tmval); /* If the last character is a 'Z', don't do anything. Otherwise, we need to move the last two characters out one and stick a colon in the vacated spot. Let's not forget the trailing '\0' that needs to be moved as well. */ len = strlen(buf); if ( len > 0 && buf[len-1] != 'Z' ) { memmove(buf+len-1,buf+len-2,3); buf[len-2] = ':'; } return (string)buf; } static int mkpath(std::string path, mode_t mode) { size_t pre=0,pos; std::string dir; int mdret; if(path[path.size()-1]!='/') { path+='/'; } while((pos=path.find_first_of('/',pre))!=std::string::npos){ dir=path.substr(0,pos++); pre=pos; if(dir.size()==0) continue; // if leading / first time is 0 length if((mdret=mkdir(dir.c_str(),mode)) && errno!=EEXIST){ return mdret; } } struct stat status; stat( path.c_str(), &status ); if ( status.st_mode & S_IFDIR ) { return EEXIST; } return mdret; } /** * Parses a tcx file, and returns the unix timestamp for the start timestamp */ static time_t getStartTimestampFromXml(string xml) { if (xml.length() == 0) { return 0; } TiXmlDocument * xmldoc = new TiXmlDocument(); xmldoc->Parse(xml.c_str()); time_t res = getStartTimestampFromXml(xmldoc); delete(xmldoc); return res; } /** * Parses a tcx file, and returns the unix timestamp for the start timestamp */ static time_t getStartTimestampFromXml(TiXmlDocument * xmldoc) { if (xmldoc == NULL) { return 0; } // TrainingCenterDatabase -> Activities -> Activity -> Lap . StartTime; TiXmlElement * pElem = xmldoc->FirstChildElement( "TrainingCenterDatabase" ); if (pElem != NULL) { pElem = pElem->FirstChildElement( "Activities" ); if (pElem != NULL) { pElem = pElem->FirstChildElement( "Activity" ); if (pElem != NULL) { pElem = pElem->FirstChildElement( "Lap" ); if (pElem != NULL) { const char * startTimeStr = pElem->Attribute("StartTime"); if (startTimeStr!=NULL) { struct tm start; if (strptime(startTimeStr, "%FT%TZ",&start) != NULL) { return mktime(&start); } if (strptime(startTimeStr, "%FT%T.000Z",&start) != NULL) { return mktime(&start); } } } } } } return 0; } static string str_replace (string rep, string wit, string in) { int pos; while (true) { pos = in.find(rep); if (pos == -1) { break; } else { in.erase(pos, rep.length()); in.insert(pos, wit); } } return in; } static bool iequals(const string& a, const string& b) { unsigned int sz = a.size(); if (b.size() != sz) return false; for (unsigned int i = 0; i < sz; ++i) if (tolower(a[i]) != tolower(b[i])) return false; return true; } }; #endif // GPSFUNCTIONS_H_INCLUDED GarminPlugin-0.3.23/src/log.cpp000066400000000000000000000060101232766717500162640ustar00rootroot00000000000000/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */ /* * GarminPlugin * Copyright (C) Andreas Diesner 2010 * * GarminPlugin is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GarminPlugin is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #include "log.h" #include #include # include Log * Log::instance; LogLevel Log::level = Error; Log::Log() { this->logfile = ""; } Log::~Log() { } void Log::print(const string text) { string outtext = getTimestamp() + text; if (this->logfile == "") { cerr << outtext<< endl; } else { ofstream logf; logf.open (this->logfile.c_str(), ios::out | ios::app ); logf << outtext << endl; logf.close(); } } Log * Log::getInstance() { if (Log::instance == NULL) { Log::instance = new Log(); } return Log::instance; } void Log::dbg(const string text) { if (Log::level <= Debug) { Log::getInstance()->print(text); } } void Log::info(const string text) { if (Log::level <= Info) { Log::getInstance()->print(text); } } void Log::err(const string text) { if (Log::level <= Error) { Log::getInstance()->print(text); } } bool Log::enabledDbg() { if (Log::level <= Debug) { return true; } return false; } bool Log::enabledInfo() { if (Log::level <= Info) { return true; } return false; } bool Log::enabledErr() { if (Log::level <= Error) { return true; } return false; } void Log::setConfiguration(TiXmlDocument * config) { /* */ TiXmlElement * plugin = config->FirstChildElement( "GarminPlugin" ); const char * logfileAttr = plugin->Attribute("logfile"); const char * levelAttr = plugin->Attribute("level"); if (levelAttr != NULL) { string levelStr = levelAttr; if (levelStr == "DEBUG") { this->level = Debug; } else if (levelStr == "INFO") { this->level = Info; } else if (levelStr == "ERROR") { this->level = Error; } else { this->level = None; } } if (logfileAttr != NULL) { this->logfile = logfileAttr; } else { this->logfile = ""; } } string Log::getTimestamp() { time_t now = time ( NULL ); const struct tm* tm = localtime ( &now ); char s[40]; strftime ( s, 40, "%d.%m.%y %H:%M:%S ", tm ); string str = s; return str; } GarminPlugin-0.3.23/src/log.h000066400000000000000000000057031232766717500157410ustar00rootroot00000000000000/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */ /* * GarminPlugin * Copyright (C) Andreas Diesner 2010 * * GarminPlugin is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GarminPlugin is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #ifndef LOG_H_INCLUDED #define LOG_H_INCLUDED #include #include #include "tinyxml.h" using namespace std; /** * Specifies all possible loglevel modes. * The ones below the current mode are always included. */ enum LogLevel { Debug, /**< enum value Debug. Developer Information Output */ Info, /**< enum value Debug. Output additional informations */ Error, /**< enum value Debug. Output only errors like file i/o */ None /**< enum value None. No output at all */ }; class Log { public: /** * Prints a string to the log output * @param text Text to print. */ void print(const string text); /** * Returns the instance of this class * @return Instance to this class */ static Log * getInstance(); /** * Prints text if level is at least Debug * @param text to print */ static void dbg(const string text); /** * Prints text if level is at least Info * @param text to print */ static void info(const string text); /** * Prints text if level is at least Error * @param text to print */ static void err(const string text); /** * Check debug level setting * @return true if debug is enabled */ static bool enabledDbg(); /** * Check info level setting * @return true if info is enabled */ static bool enabledInfo(); /** * Check error level setting * @return true if error is enabled */ static bool enabledErr(); /** * Initializes the Logger with current configuration settings * @param config Current configuration */ void setConfiguration(TiXmlDocument * config); private: /** * Private constructor. * Use Log::getInstance() to get an instance of this class * @see getInstance() */ Log(); /** * Private destructor. */ ~Log(); /** * Stores the only instance of this class. */ static Log * instance; /** * Logfile to write to. If empty stderr is used. */ string logfile; /** * Loglevel to use */ static LogLevel level; /** * Returns the current time "DD.MM.YY HH:MM:SS " */ string getTimestamp(); }; #endif // LOG_H_INCLUDED GarminPlugin-0.3.23/src/main.cpp000066400000000000000000002447731232766717500164530ustar00rootroot00000000000000/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */ /* * GarminPlugin * Copyright (C) Andreas Diesner 2010 * * GarminPlugin is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GarminPlugin is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #include "config.h" #include #include "npapi/npapi.h" #include "npapi/npfunctions.h" #include "npapi/npruntime.h" #if HAVE_PRTYPES_H #include #elif HAVE_ZIPSTUB_H #include #endif #include #include #include "deviceManager.h" #include "configManager.h" #include "log.h" #include #include "zlib.h" #include #include #include #define GETSTRING(_v) ((_v).UTF8Characters) #define GETSTRINGLENGTH(_v) ((_v).UTF8Length) using namespace std; /** * A variable that stores the plugin name */ const char * pluginName = "Garmin Communicator"; /** * A variable that stores the plugin description (may contain HTML) */ const char * pluginDescription = "Garmin Communicator - Fake plugin. Version 0.3.23"; /** * A variable that stores the mime description of the plugin. */ const char * pluginMimeDescription = "application/vnd-garmin.mygarmin:garmin:Garmin Device Web Control"; /** * Manages all attached GPS Devices */ DeviceManager *devManager = NULL; /** * Manages the plugin configuration */ ConfigManager * confManager = NULL; /** * plugin_scriptable_object */ static NPObject *so = NULL; /** * NP_Initialize gets called with a pointer to the browser functions * Use these functions to allocate/delete memory */ static NPNetscapeFuncs *npnfuncs = NULL; /** * Unknown */ static NPP inst = NULL; /** * Counts the number of new's that have been executed on the plugin */ static int instanceCount = 0; /** * Stores the information about plugin properties * All these properties can be accessed from the outside. They are stored * in the vector propertyList. * @see propertyList */ typedef struct _Property { NPVariantType type; /**< Stores the type of the property */ bool boolValue; /**< If boolean value, this contains the value */ int32_t intValue; /**< If int value, this contains the value */ string stringValue; /**< If string value, this contains the value */ bool writeable; /**< True if property can be written from the outside */ } Property; /** * Function prototype for functions that can be called from the outside */ typedef bool(*pt2Func)(NPObject*, const NPVariant[] , uint32_t, NPVariant *); /** * Map that stores all properties and their names */ std::map propertyList; /** * Map that stores all available functions and their names */ std::map methodList; /** * Vector that stores all waiting messageboxes that should be displayed to the user */ std::vector messageList; /** * Stores the last device a write was started to */ GpsDevice * currentWorkingDevice = NULL; /** * Stores if the browser supports XEmbed - need to report true to Chrome to get the plugin detected */ bool supportsXEmbed = false; string getParameterTypeStr(const NPVariant& arg) { switch (arg.type) { case NPVariantType_Void: return "VOID"; case NPVariantType_Bool: return "BOOL"; case NPVariantType_Int32: return "INT32"; case NPVariantType_String: return "STRING"; case NPVariantType_Double: return "DOUBLE"; case NPVariantType_Object: return "OBJECT"; case NPVariantType_Null: return "NULL"; default: return "UNKNOWN"; } } string getStringFromNPString(const NPString& inputStr) { // Any NPString object returned when communicating with the browser cannot be // assumed to be null-terminated at the appropriate place // That is why I use memcpy here and null-terminate the string char * sTmp = new char[GETSTRINGLENGTH(inputStr)+1]; memcpy(sTmp, GETSTRING(inputStr), GETSTRINGLENGTH(inputStr)); sTmp[GETSTRINGLENGTH(inputStr)] = 0x00; // Null-terminate the string; string strValue = sTmp; delete[] sTmp; return strValue; } /** * If debug level, it outputs the content of string property variables into files in /tmp */ void debugOutputPropertyToFile(string property) { if (Log::enabledDbg()) { stringstream filename; time_t rawtime; time ( &rawtime ); filename << "/tmp/" << rawtime << "." << property; Log::dbg("Writing "+property+" content to file: "+filename.str()); ofstream output(filename.str().c_str()); if(output.is_open()) { output << propertyList[property].stringValue; output.close(); } else { Log::err("Error writing "+property+" content to file: "+filename.str()); } } } int getIntParameter(const NPVariant args[], int pos, int defaultVal) { int intValue = defaultVal; if (args[pos].type == NPVariantType_Int32) { intValue = args[pos].value.intValue; } else if (args[pos].type == NPVariantType_String) { std::string intValueStr = getStringFromNPString(args[pos].value.stringValue); Log::dbg("getIntParameter String: "+intValueStr); std::istringstream ss( intValueStr ); ss >> intValue; /* Does not work if (! ss.good()) { [...] } */ } else if (args[pos].type == NPVariantType_Double) { double doubleValue = args[pos].value.doubleValue; if (Log::enabledDbg()) { std::stringstream ss; ss << "getIntParameter Double: " << doubleValue; Log::dbg(ss.str()); } if ((isnan(doubleValue)) || (isinf(doubleValue))) { // Not A Number detection intValue = defaultVal; } else { intValue = (int)doubleValue; } } else { std::ostringstream errTxt; errTxt << "Expected INT parameter at position " << pos << ". Found: " << getParameterTypeStr(args[pos]); if (Log::enabledErr()) Log::err(errTxt.str()); } return intValue; } string getStringParameter(const NPVariant args[], int pos, string defaultVal) { string strValue = defaultVal; if (args[pos].type == NPVariantType_Int32) { stringstream ss; ss << args[pos].value.intValue; strValue = ss.str(); } else if (args[pos].type == NPVariantType_String) { strValue = getStringFromNPString(args[pos].value.stringValue); } else { std::ostringstream errTxt; errTxt << "Expected STRING parameter at position " << pos << ". Found: " << getParameterTypeStr(args[pos]); if (Log::enabledErr()) Log::err(errTxt.str()); } return strValue; } bool getBoolParameter(const NPVariant args[], int pos, bool defaultVal) { bool boolValue = defaultVal; if (args[pos].type == NPVariantType_Int32) { boolValue = (args[pos].value.intValue == 1) ? true : false; } else if (args[pos].type == NPVariantType_String) { string strValue = getStringFromNPString(args[pos].value.stringValue); boolValue = (strValue.compare("1") == 0) ? true : false; } else if (args[pos].type == NPVariantType_Bool) { boolValue = args[pos].value.boolValue; } else { std::ostringstream errTxt; errTxt << "Expected BOOL parameter at position " << pos << ". Found: " << getParameterTypeStr(args[pos]); if (Log::enabledErr()) Log::err(errTxt.str()); } return boolValue; } /* ** encodeBase64 ** ** base64 encode a stream adding padding and line breaks as per spec. ** Thanks to Bob Trower 08/04/01 ** http://base64.sourceforge.net/b64.c */ static const char cb64[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; void encodeBase64( stringstream * input, stringstream *output , int linesize ) { unsigned char in[3], out[4]; int i, len, blocksout = 0; while( !input->eof() ) { len = 0; for( i = 0; i < 3; i++ ) { input->get((char&)in[i]); if( !input->eof() ) { len++; } else { in[i] = 0; } } if( len ) { out[0] = cb64[ in[0] >> 2 ]; out[1] = cb64[ ((in[0] & 0x03) << 4) | ((in[1] & 0xf0) >> 4) ]; out[2] = (unsigned char) (len > 1 ? cb64[ ((in[1] & 0x0f) << 2) | ((in[2] & 0xc0) >> 6) ] : '='); out[3] = (unsigned char) (len > 2 ? cb64[ in[2] & 0x3f ] : '='); for( i = 0; i < 4; i++ ) { output->put(out[i]); } blocksout++; } if( blocksout >= (linesize/4)) { input->peek(); // Read but do not remove one character, so that eof really returns eof if at the end of the file if (( blocksout ) && (!input->eof())) { (*output) << endl; } blocksout = 0; } } } /** * Compresses a string using gzip and encodes it using base64 * Use uudecode to unpack and then gunzip */ #define CHUNK 16384 string compressStringData(const string text, const string filename) { if (Log::enabledDbg()) { stringstream ss; ss << text.size(); Log::dbg("Compressing content of string with length: " + ss.str()); } std::stringstream compressed (""); int ret; unsigned have; z_stream strm; char out[CHUNK]; /* allocate deflate state */ strm.zalloc = Z_NULL; strm.zfree = Z_NULL; strm.opaque = Z_NULL; ret = deflateInit2(&strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED, 31, 8, Z_DEFAULT_STRATEGY); if (ret != Z_OK) { Log::err("zLib Initialization failed at deflateInit2()"); return ""; } strm.avail_in = text.length(); strm.next_in = (Bytef*) text.c_str(); /* run deflate() on input until output buffer not full, finish compression if all of source has been read in */ do { strm.avail_out = CHUNK; strm.next_out = (Bytef*) out; ret = deflate(&strm, Z_FINISH); /* no bad return value */ have = CHUNK - strm.avail_out; compressed.write(out, have); if (compressed.bad()) { (void)deflateEnd(&strm); Log::err("compressStringData error during compression and writing to output buffer"); return ""; } } while (strm.avail_out == 0); /* clean up */ (void)deflateEnd(&strm); std::stringstream outstream; outstream << "begin-base64 644 " << filename << endl; encodeBase64(&compressed,&outstream, 76); outstream << endl << "====" << endl; return outstream.str(); } void printFinishState(string text, int state) { if (Log::enabledDbg()) { std::stringstream ss; ss << "Finish State of function " << text << ": "; // 0 = idle 1 = working 2 = waiting for user input 3 = finished switch (state) { case 0: ss << "Idle"; break; case 1: ss << "Working"; break; case 2: ss << "Waiting for user input"; break; case 3: ss << "Finished"; break; default: ss << "Unknown ("<\n\n"; ss << title; ss << "\n\n\n"; ss << state; ss << "% complete\n"; propertyList["ProgressXml"].stringValue = ss.str(); } /** * Method to unlock the plugin. * This method gets called from the outside. * Example Parameter: "http://wwwdev.garmin.com","3e2bab85cbc4e17d3ce5b55c8f2aa652" * Return int(1) to signal that unlock was successful * @param obj * @param args[] contains all passed parameters * @param argCount number of passed parameters * @param result store return value here * @return boolean. Return true if successful */ bool methodUnlock(NPObject *obj, const NPVariant args[], uint32_t argCount, NPVariant * result) { propertyList["Locked"].intValue = 0; result->type = NPVariantType_Int32; result->value.intValue = 1; return true; } /** * Method returns xml with attached devices. * This method gets called from the outside. * This method takes no parameter * Return string(xml) to signal which devices were found * @param obj * @param args[] contains all passed parameters * @param argCount number of passed parameters * @param result store return value here * @return boolean. Return true if successful */ bool methodDevicesXmlString(NPObject *obj, const NPVariant args[], uint32_t argCount, NPVariant * result) { string deviceXml = devManager->getDevicesXML(); char *outStr = (char*)npnfuncs->memalloc(deviceXml.size() + 1); memcpy(outStr, deviceXml.c_str(), deviceXml.size() + 1); result->type = NPVariantType_String; GETSTRING(result->value.stringValue) = outStr; GETSTRINGLENGTH(result->value.stringValue) = deviceXml.size(); return true; } /** * Search for attached devices. * This method gets called from the outside. * This method takes no parameter * Return nothing * @param obj * @param args[] contains all passed parameters * @param argCount number of passed parameters * @param result store return value here * @return boolean. Return true if successful */ bool methodStartFindDevices(NPObject *obj, const NPVariant args[], uint32_t argCount, NPVariant * result) { currentWorkingDevice = NULL; //Reread current configuration in case it has changed on disk confManager->readConfiguration(); devManager->setConfiguration(confManager->getConfiguration()); devManager->startFindDevices(); return true; } /** * Cancel the search for devices. * This method gets called from the outside. * This method takes no parameter * Return nothing * @param obj * @param args[] contains all passed parameters * @param argCount number of passed parameters * @param result store return value here * @return boolean. Return true if successful */ bool methodCancelFindDevices(NPObject *obj, const NPVariant args[], uint32_t argCount, NPVariant * result) { devManager->cancelFindDevices(); return true; } /** * Returns the status of the device search (Finished or still searching) * This method gets called from the outside. * This method takes no parameter * Return int(1) when finished * @param obj * @param args[] contains all passed parameters * @param argCount number of passed parameters * @param result store return value here * @return boolean. Return true if successful */ bool methodFinishFindDevices(NPObject *obj, const NPVariant args[], uint32_t argCount, NPVariant * result) { /* * Unlike most other routines, this function knows only "0" or "1" as return value * (not "0"=idle, "1"=working, "2"=waiting, "3"=finished) * * The deviceManager uses internally the state (0=idle, 1=working and 3=finished) * which results in this confusing code: if state!=1 return 1 */ result->type = NPVariantType_Int32; int searchState = devManager->finishedFindDevices(); printFinishState("FinishFindDevices", searchState); if (searchState != 1 /* = WORKING */ ) { result->value.intValue = 1; /* FINISHED SEARCHING */ } else { result->value.intValue = 0; /* STILL SEARCHING */ } return true; } /** * Starts writing data to the gps device. The data and the filename * is stored in the property FileName and GpsXml. * This method gets called from the outside. * This method takes one parameter - the device number as int * Return int(1) when write started * @param obj * @param args[] contains all passed parameters * @param argCount number of passed parameters * @param result store return value here * @return boolean. Return true if successful */ bool methodStartWriteToGps(NPObject *obj, const NPVariant args[], uint32_t argCount, NPVariant * result) { updateProgressBar("Write to GPS", 0); if (argCount == 1) { int deviceId = getIntParameter(args, 0, -1); if (deviceId != -1) { currentWorkingDevice = devManager->getGpsDevice(deviceId); if (currentWorkingDevice != NULL) { result->type = NPVariantType_Int32; result->value.intValue = currentWorkingDevice->startWriteToGps(propertyList["FileName"].stringValue, propertyList["GpsXml"].stringValue); return true; } else { if (Log::enabledInfo()) Log::info("StartWriteToGps: Device not found"); } } else { if (Log::enabledErr()) Log::err("StartWriteToGps: Unable to determine device id"); } } else { if (Log::enabledErr()) Log::err("StartWriteToGps: Wrong parameter count"); } return false; } /** * Checks if device has finished writing. * * Valid return values are: * 0 = idle 1 = working 2 = waiting for user input 3 = finished * * If user input is required the function fills the property MessageBoxXml with the message * On success the method updates the property GpsTransferSucceeded * This method gets called from the outside. * This method takes one parameter - the device number as int * @param obj * @param args[] contains all passed parameters * @param argCount number of passed parameters * @param result store return value here * @return boolean. Return true if successful */ bool methodFinishWriteToGps(NPObject *obj, const NPVariant args[], uint32_t argCount, NPVariant * result) { /* Return Values are 0 = idle 1 = working 2 = waiting for user input 3 = finished */ if (!messageList.empty()) { // Push messages first MessageBox * msg = messageList.front(); if (msg != NULL) { propertyList["MessageBoxXml"].stringValue = msg->getXml(); result->type = NPVariantType_Int32; result->value.intValue = 2; /* waiting for user input */ return true; } else { if (Log::enabledErr()) Log::err("A null MessageBox is blocking the messages - fix the code!"); } } else { if (currentWorkingDevice != NULL) { result->type = NPVariantType_Int32; result->value.intValue = currentWorkingDevice->finishWriteToGps(); printFinishState("FinishWriteToGps", result->value.intValue); if (result->value.intValue == 2) { // waiting for user input messageList.push_back(currentWorkingDevice->getMessage()); MessageBox * msg = messageList.front(); if (msg != NULL) { propertyList["MessageBoxXml"].stringValue = msg->getXml(); } } else if (result->value.intValue == 3) { // transfer finished propertyList["GpsTransferSucceeded"].intValue = currentWorkingDevice->getTransferSucceeded(); updateProgressBar("Write to GPS", 100); } else { updateProgressBar("Write to GPS", currentWorkingDevice->getProgress()); } return true; } else { if (Log::enabledInfo()) Log::info("FinishWriteToGps: No working device specified"); } } return false; } /** * Stops writing to the device * @param obj * @param args[] contains all passed parameters * @param argCount number of passed parameters * @param result store return value here * @return boolean. Return true if successful */ bool methodCancelWriteToGps(NPObject *obj, const NPVariant args[], uint32_t argCount, NPVariant * result) { if (currentWorkingDevice != NULL) { currentWorkingDevice->cancelWriteToGps(); return true; } return true; } /** * Fetches a detailed device description * The return value is a string(xml) with lots of details about the device functionality * This method gets called from the outside. * This method takes one parameter - the device number as int * @param obj * @param args[] contains all passed parameters * @param argCount number of passed parameters * @param result store return value here * @return boolean. Return true if successful */ bool methodDeviceDescription(NPObject *obj, const NPVariant args[], uint32_t argCount, NPVariant * result) { if (argCount == 1) { int deviceId = getIntParameter(args, 0, -1); if (deviceId != -1) { GpsDevice * device = devManager->getGpsDevice(deviceId); if (device != NULL) { string deviceDescr = device->getDeviceDescription(); char *outStr = (char*)npnfuncs->memalloc(deviceDescr.size() + 1); memcpy(outStr, deviceDescr.c_str(), deviceDescr.size() + 1); result->type = NPVariantType_String; GETSTRING(result->value.stringValue) = outStr; GETSTRINGLENGTH(result->value.stringValue) = deviceDescr.size(); return true; } else { if (Log::enabledInfo()) Log::info("DeviceDescription: Device not found"); } } } else { if (Log::enabledErr()) Log::err("DeviceDescription: Argument count is wrong"); } return false; } /** * Receives the response to a messagebox answered by the user * This method gets called from the outside. * This method takes one parameter - the number of the button pressed by the user as int * @param obj * @param args[] contains all passed parameters * @param argCount number of passed parameters * @param result store return value here * @return boolean. Return true if successful */ bool methodRespondToMessageBox(NPObject *obj, const NPVariant args[], uint32_t argCount, NPVariant * result) { if (!messageList.empty()) { MessageBox * msg = messageList.front(); if (msg != NULL) { if (argCount >= 1) { int response = getIntParameter(args, 0, -1); if (response == -1) { // Fallback to boolean response = (getBoolParameter(args, 0, false)) ? 1 : 0; } msg->responseReceived(response); } else { if (Log::enabledErr()) Log::err("methodRespondToMessageBox: Wrong parameter count"); } } else { if (Log::enabledErr()) Log::err("A null MessageBox is blocking the messages - fix the code!"); } messageList.erase(messageList.begin()); propertyList["MessageBoxXml"].stringValue = ""; return true; } else { if (Log::enabledErr()) Log::err("Received a response to a messagebox that no longer exists !?"); } return false; } bool methodStartReadFitnessData(NPObject *obj, const NPVariant args[], uint32_t argCount, NPVariant * result) { updateProgressBar("Read from GPS", 0); if (argCount >= 2) { int deviceId = getIntParameter(args, 0, -1); string dataToRead = getStringParameter(args, 1, ""); if (deviceId != -1) { currentWorkingDevice = devManager->getGpsDevice(deviceId); if (currentWorkingDevice != NULL) { result->type = NPVariantType_Int32; result->value.intValue = currentWorkingDevice->startReadFitnessData(dataToRead); return true; } else { if (Log::enabledInfo()) Log::info("StartReadFitnessData: Device not found"); } } else { if (Log::enabledErr()) Log::err("StartReadFitnessData: Unable to determine device id"); } } else { if (Log::enabledErr()) Log::err("StartReadFitnessData: Wrong parameter count"); } return false; } bool methodFinishReadFitnessData(NPObject *obj, const NPVariant args[], uint32_t argCount, NPVariant * result) { /* Return Values are 0 = idle 1 = working 2 = waiting for user input 3 = finished */ if (!messageList.empty()) { // Push messages first MessageBox * msg = messageList.front(); if (msg != NULL) { propertyList["MessageBoxXml"].stringValue = msg->getXml(); result->type = NPVariantType_Int32; result->value.intValue = 2; /* waiting for user input */ return true; } else { if (Log::enabledErr()) Log::err("A null MessageBox is blocking the messages - fix the code!"); } } else { if (currentWorkingDevice != NULL) { result->type = NPVariantType_Int32; result->value.intValue = currentWorkingDevice->finishReadFitnessData(); printFinishState("FinishReadFitnessData", result->value.intValue); if (result->value.intValue == 2) { // waiting for user input messageList.push_back(currentWorkingDevice->getMessage()); MessageBox * msg = messageList.front(); if (msg != NULL) { propertyList["MessageBoxXml"].stringValue = msg->getXml(); } } else if (result->value.intValue == 3) { // transfer finished propertyList["FitnessTransferSucceeded"].intValue = currentWorkingDevice->getTransferSucceeded(); string tcdData = currentWorkingDevice->getFitnessData(); propertyList["TcdXml"].stringValue = tcdData; propertyList["TcdXmlz"].stringValue = compressStringData(tcdData, "data.xml.gz"); debugOutputPropertyToFile("TcdXml"); updateProgressBar("Read from GPS", 100); } else { updateProgressBar("Read from GPS", currentWorkingDevice->getProgress()); } return true; } else { if (Log::enabledInfo()) Log::info("FinishReadFitnessData: No working device specified"); } } return false; } bool methodStartReadFitnessDirectory(NPObject *obj, const NPVariant args[], uint32_t argCount, NPVariant * result) { updateProgressBar("Read FITDIR from GPS", 0); if (argCount >= 2) { // What is the second parameter for ? "FitnessHistory" int deviceId = getIntParameter(args, 0, -1); string dataTypeName = getStringParameter(args, 1, ""); if (deviceId != -1) { currentWorkingDevice = devManager->getGpsDevice(deviceId); if (currentWorkingDevice != NULL) { result->type = NPVariantType_Int32; result->value.intValue = currentWorkingDevice->startReadFitnessDirectory(dataTypeName); return true; } else { if (Log::enabledInfo()) Log::info("StartReadFitnessDirectory: Device not found"); } } else { if (Log::enabledErr()) Log::err("StartReadFitnessDirectory: Unable to determine device id"); } } else { if (Log::enabledErr()) Log::err("StartReadFitnessDirectory: Wrong parameter count"); } return false; } bool methodStartReadFITDirectory(NPObject *obj, const NPVariant args[], uint32_t argCount, NPVariant * result) { if (argCount >= 1) { int deviceId = getIntParameter(args, 0, -1); if (deviceId != -1) { currentWorkingDevice = devManager->getGpsDevice(deviceId); if (currentWorkingDevice != NULL) { result->type = NPVariantType_Int32; result->value.intValue = currentWorkingDevice->startReadFITDirectory(); return true; } else { if (Log::enabledInfo()) Log::info("StartReadFITDirectory: Device not found"); } } else { if (Log::enabledErr()) Log::err("StartReadFITDirectory: Unable to determine device id"); } } else { if (Log::enabledErr()) Log::err("StartReadFITDirectory: Wrong parameter count"); } return false; } bool methodFinishReadFITDirectory(NPObject *obj, const NPVariant args[], uint32_t argCount, NPVariant * result) { /* Return Values are 0 = idle 1 = working 2 = waiting for user input 3 = finished */ if (!messageList.empty()) { // Push messages first MessageBox * msg = messageList.front(); if (msg != NULL) { propertyList["MessageBoxXml"].stringValue = msg->getXml(); result->type = NPVariantType_Int32; result->value.intValue = 2; /* waiting for user input */ return true; } else { if (Log::enabledErr()) Log::err("A null MessageBox is blocking the messages - fix the code!"); } } else { if (currentWorkingDevice != NULL) { result->type = NPVariantType_Int32; result->value.intValue = currentWorkingDevice->finishReadFITDirectory(); printFinishState("FinishReadFITDirectory", result->value.intValue); if (result->value.intValue == 2) { // waiting for user input messageList.push_back(currentWorkingDevice->getMessage()); MessageBox * msg = messageList.front(); if (msg != NULL) { propertyList["MessageBoxXml"].stringValue = msg->getXml(); } } else if (result->value.intValue == 3) { // transfer finished propertyList["FitnessTransferSucceeded"].intValue = currentWorkingDevice->getTransferSucceeded(); propertyList["DirectoryListingXml"].stringValue = currentWorkingDevice->getDirectoryListingXml(); debugOutputPropertyToFile("DirectoryListingXml"); updateProgressBar("Read FITDIR from GPS", 100); } else { updateProgressBar("Read FITDIR from GPS", currentWorkingDevice->getProgress()); } return true; } else { if (Log::enabledInfo()) Log::info("FinishReadFITDirectory: No working device specified"); } } return false; } bool methodCancelReadFITDirectory(NPObject *obj, const NPVariant args[], uint32_t argCount, NPVariant * result) { if (currentWorkingDevice != NULL) { currentWorkingDevice -> cancelReadFITDirectory(); } return true; } bool methodStartReadFitnessDetail(NPObject *obj, const NPVariant args[], uint32_t argCount, NPVariant * result) { // StartReadFitnessDetail(0,"FitnessHistory","2010-02-27T14:23:46Z") updateProgressBar("Read fitness detail from GPS", 0); if (argCount >= 2) { // What is the second parameter for ? "FitnessHistory" int deviceId = getIntParameter(args, 0, -1); string id = ""; id = getStringParameter(args, 2, ""); if (deviceId != -1) { currentWorkingDevice = devManager->getGpsDevice(deviceId); if (currentWorkingDevice != NULL) { result->type = NPVariantType_Int32; result->value.intValue = currentWorkingDevice->startReadFitnessDetail(id); return true; } else { if (Log::enabledInfo()) Log::info("StartReadFitnessDirectory: Device not found"); } } else { if (Log::enabledErr()) Log::err("StartReadFitnessDirectory: Unable to determine device id"); } } else { if (Log::enabledErr()) Log::err("StartReadFitnessDirectory: Wrong parameter count"); } return false; } bool methodFinishReadFitnessDetail(NPObject *obj, const NPVariant args[], uint32_t argCount, NPVariant * result) { /* Return Values are 0 = idle 1 = working 2 = waiting for user input 3 = finished */ if (!messageList.empty()) { // Push messages first MessageBox * msg = messageList.front(); if (msg != NULL) { propertyList["MessageBoxXml"].stringValue = msg->getXml(); result->type = NPVariantType_Int32; result->value.intValue = 2; /* waiting for user input */ return true; } else { if (Log::enabledErr()) Log::err("A null MessageBox is blocking the messages - fix the code!"); } } else { if (currentWorkingDevice != NULL) { result->type = NPVariantType_Int32; result->value.intValue = currentWorkingDevice->finishReadFitnessDetail(); printFinishState("FinishReadFitnessDetail", result->value.intValue); if (result->value.intValue == 2) { // waiting for user input messageList.push_back(currentWorkingDevice->getMessage()); MessageBox * msg = messageList.front(); if (msg != NULL) { propertyList["MessageBoxXml"].stringValue = msg->getXml(); } } else if (result->value.intValue == 3) { // transfer finished propertyList["FitnessTransferSucceeded"].intValue = currentWorkingDevice->getTransferSucceeded(); string tcdData = currentWorkingDevice->getFitnessData(); propertyList["TcdXml"].stringValue = tcdData; propertyList["TcdXmlz"].stringValue = compressStringData(tcdData, "data.xml.gz"); debugOutputPropertyToFile("TcdXml"); updateProgressBar("Read fitness detail from GPS", 100); } else { updateProgressBar("Read fitness detail from GPS", currentWorkingDevice->getProgress()); } return true; } else { if (Log::enabledInfo()) Log::info("FinishReadFitnessDetail: No working device specified"); } } return false; } bool methodStartReadFromGps(NPObject *obj, const NPVariant args[], uint32_t argCount, NPVariant * result) { updateProgressBar("Read from GPS", 0); if (argCount >= 1) { int deviceId = getIntParameter(args, 0, -1); if (deviceId != -1) { currentWorkingDevice = devManager->getGpsDevice(deviceId); if (currentWorkingDevice != NULL) { result->type = NPVariantType_Int32; result->value.intValue = currentWorkingDevice->startReadFromGps(); return true; } else { if (Log::enabledInfo()) Log::info("StartReadFromGps: Device not found"); } } else { if (Log::enabledErr()) Log::err("StartReadFromGps: Unable to determine device id"); } } else { if (Log::enabledErr()) Log::err("StartReadFromGps: Wrong parameter count"); } return false; } bool methodFinishReadFromGps(NPObject *obj, const NPVariant args[], uint32_t argCount, NPVariant * result) { /* Return Values are 0 = idle 1 = working 2 = waiting for user input 3 = finished */ if (!messageList.empty()) { // Push messages first MessageBox * msg = messageList.front(); if (msg != NULL) { propertyList["MessageBoxXml"].stringValue = msg->getXml(); result->type = NPVariantType_Int32; result->value.intValue = 2; /* waiting for user input */ return true; } else { if (Log::enabledErr()) Log::err("A null MessageBox is blocking the messages - fix the code!"); } } else { if (currentWorkingDevice != NULL) { result->type = NPVariantType_Int32; result->value.intValue = currentWorkingDevice->finishReadFromGps(); printFinishState("FinishReadFromGps", result->value.intValue); if (result->value.intValue == 2) { // waiting for user input messageList.push_back(currentWorkingDevice->getMessage()); MessageBox * msg = messageList.front(); if (msg != NULL) { propertyList["MessageBoxXml"].stringValue = msg->getXml(); } } else if (result->value.intValue == 3) { // transfer finished propertyList["GpsTransferSucceeded"].intValue = currentWorkingDevice->getTransferSucceeded(); string gpxdata = currentWorkingDevice->getGpxData(); propertyList["GpsXml"].stringValue = gpxdata; debugOutputPropertyToFile("GpsXml"); updateProgressBar("Read from GPS", 100); } else { updateProgressBar("Read from GPS", currentWorkingDevice->getProgress()); } return true; } else { if (Log::enabledInfo()) Log::info("FinishReadFitnessDetail: No working device specified"); } } return false; } bool methodCancelReadFromGps(NPObject *obj, const NPVariant args[], uint32_t argCount, NPVariant * result) { if (currentWorkingDevice != NULL) { Log::dbg("Calling cancel read from gps"); currentWorkingDevice->cancelReadFromGps(); } return true; } bool methodCancelReadFitnessDetail(NPObject *obj, const NPVariant args[], uint32_t argCount, NPVariant * result) { if (currentWorkingDevice != NULL) { currentWorkingDevice -> cancelReadFitnessDetail(); } return true; } bool methodGetBinaryFile(NPObject *obj, const NPVariant args[], uint32_t argCount, NPVariant * result) { if ((argCount < 2) || (argCount > 3)) { Log::err("GetBinaryFile: Wrong parameter count. Three parameter required! (DeviceID, Filename, [Compress])"); return false; } int deviceId = getIntParameter(args, 0, -1); if (deviceId != -1) { GpsDevice * device = devManager->getGpsDevice(deviceId); if (device != NULL) { string fileName = getStringParameter(args,1,""); bool doCompress = false; if (argCount == 3) { doCompress = getBoolParameter(args,2,false); } string binaryData = device->getBinaryFile(fileName); string fileNameOnly = basename(fileName.c_str()); if (doCompress) { binaryData = compressStringData(binaryData, fileNameOnly + ".gz"); } else { std::stringstream outstream; std::stringstream binaryDataStream; binaryDataStream << binaryData; outstream << "begin-base64 644 " << fileNameOnly << endl; encodeBase64(&binaryDataStream,&outstream, 76); outstream << endl << "====" << endl; binaryData = outstream.str(); } char *outStr = (char*)npnfuncs->memalloc(binaryData.size() + 1); memcpy(outStr, binaryData.c_str(), binaryData.size() + 1); result->type = NPVariantType_String; GETSTRING(result->value.stringValue) = outStr; GETSTRINGLENGTH(result->value.stringValue) = binaryData.size(); return true; } else { Log::err("GetBinaryFile: No device with this ID!"); } } else { Log::err("GetBinaryFile: Device ID is invalid"); } return false; } bool methodStartDownloadData(NPObject *obj, const NPVariant args[], uint32_t argCount, NPVariant * result) { if (argCount != 2) { Log::err("StartDownloadData: Wrong parameter count. Two parameter required! (gpsDataString, DeviceId)"); return false; } updateProgressBar("Download to GPS", 0); int deviceId = getIntParameter(args, 1, -1); if (deviceId != -1) { currentWorkingDevice = devManager->getGpsDevice(deviceId); if (currentWorkingDevice != NULL) { string gpsDataString = getStringParameter(args,0,""); int urlsFound = currentWorkingDevice->startDownloadData(gpsDataString); if (urlsFound > 0) { string urlToDownload = currentWorkingDevice->getNextDownloadDataUrl(); if (urlToDownload.length() > 0) { if (Log::enabledDbg()) { Log::dbg("Requesting download for URL: "+urlToDownload); } if (NPERR_NO_ERROR != npnfuncs->geturlnotify(inst, urlToDownload.c_str(), NULL, NULL)) { Log::err("Unable to get url: "+urlToDownload); return false; } return true; } } else { Log::err("StartDownloadData: No URLs found to download"); } } else { Log::err("StartDownloadData: Unknown Device ID"); } } else { Log::err("StartDownloadData: Device ID is invalid"); } return false; } bool methodFinishDownloadData(NPObject *obj, const NPVariant args[], uint32_t argCount, NPVariant * result) { /* Return Values are 0 = idle 1 = working 2 = waiting for user input 3 = finished */ if (!messageList.empty()) { // Push messages first MessageBox * msg = messageList.front(); if (msg != NULL) { propertyList["MessageBoxXml"].stringValue = msg->getXml(); result->type = NPVariantType_Int32; result->value.intValue = 2; /* waiting for user input */ return true; } else { if (Log::enabledErr()) Log::err("A null MessageBox is blocking the messages - fix the code!"); } } else { if (currentWorkingDevice != NULL) { result->type = NPVariantType_Int32; result->value.intValue = currentWorkingDevice->finishDownloadData(); printFinishState("FinishDownloadData", result->value.intValue); if (result->value.intValue == 2) { // waiting for user input messageList.push_back(currentWorkingDevice->getMessage()); MessageBox * msg = messageList.front(); if (msg != NULL) { propertyList["MessageBoxXml"].stringValue = msg->getXml(); } } else if (result->value.intValue == 3) { // transfer finished propertyList["DownloadDataSucceeded"].intValue = currentWorkingDevice->getTransferSucceeded(); updateProgressBar("Download to GPS", 100); } else { updateProgressBar("Download to GPS", currentWorkingDevice->getProgress()); } return true; } else { if (Log::enabledInfo()) Log::info("FinishDownloadData: No working device specified"); } } return false; } bool methodFinishReadFitnessDirectory(NPObject *obj, const NPVariant args[], uint32_t argCount, NPVariant * result) { /* Return Values are 0 = idle 1 = working 2 = waiting for user input 3 = finished */ if (!messageList.empty()) { // Push messages first MessageBox * msg = messageList.front(); if (msg != NULL) { propertyList["MessageBoxXml"].stringValue = msg->getXml(); result->type = NPVariantType_Int32; result->value.intValue = 2; /* waiting for user input */ return true; } else { if (Log::enabledErr()) Log::err("A null MessageBox is blocking the messages - fix the code!"); } } else { if (currentWorkingDevice != NULL) { result->type = NPVariantType_Int32; result->value.intValue = currentWorkingDevice->finishReadFitnessDirectory(); printFinishState("FinishReadFitnessDirectory", result->value.intValue); if (result->value.intValue == 2) { // waiting for user input messageList.push_back(currentWorkingDevice->getMessage()); MessageBox * msg = messageList.front(); if (msg != NULL) { propertyList["MessageBoxXml"].stringValue = msg->getXml(); } } else if (result->value.intValue == 3) { // transfer finished propertyList["FitnessTransferSucceeded"].intValue = currentWorkingDevice->getTransferSucceeded(); string tcdData = currentWorkingDevice->getFitnessData(); propertyList["TcdXml"].stringValue = tcdData; propertyList["TcdXmlz"].stringValue = compressStringData(tcdData, "data.xml.gz"); debugOutputPropertyToFile("TcdXml"); updateProgressBar("Read Fitness Directory from GPS", 100); } else { updateProgressBar("Read Fitness Directory from GPS", currentWorkingDevice->getProgress()); } return true; } else { if (Log::enabledInfo()) Log::info("FinishReadFitnessData: No working device specified"); } } return false; } bool methodCancelReadFitnessData(NPObject *obj, const NPVariant args[], uint32_t argCount, NPVariant * result) { if (currentWorkingDevice != NULL) { Log::dbg("Calling cancel read fitness data"); currentWorkingDevice->cancelReadFitnessData(); } return true; } bool methodStartWriteFitnessData(NPObject *obj, const NPVariant args[], uint32_t argCount, NPVariant * result) { if (argCount != 2) { Log::err("StartWriteFitnessData: Wrong parameter count. Two parameter required! (deviceNumber, dataTypeName)"); return false; } updateProgressBar("Write fitness data to GPS", 0); int deviceId = getIntParameter(args, 0, -1); if (deviceId != -1) { currentWorkingDevice = devManager->getGpsDevice(deviceId); if (currentWorkingDevice != NULL) { string dataTypeName = getStringParameter(args,1,""); result->type = NPVariantType_Int32; result->value.intValue = currentWorkingDevice->startWriteFitnessData(propertyList["FileName"].stringValue, propertyList["TcdXml"].stringValue, dataTypeName); return true; } else { Log::err("StartWriteFitnessData: Unknown Device ID"); } } else { Log::err("StartWriteFitnessData: Device ID is invalid"); } return false; } bool methodFinishWriteFitnessData(NPObject *obj, const NPVariant args[], uint32_t argCount, NPVariant * result) { /* Return Values are 0 = idle 1 = working 2 = waiting for user input 3 = finished */ if (!messageList.empty()) { // Push messages first MessageBox * msg = messageList.front(); if (msg != NULL) { propertyList["MessageBoxXml"].stringValue = msg->getXml(); result->type = NPVariantType_Int32; result->value.intValue = 2; /* waiting for user input */ return true; } else { if (Log::enabledErr()) Log::err("A null MessageBox is blocking the messages - fix the code!"); } } else { if (currentWorkingDevice != NULL) { result->type = NPVariantType_Int32; result->value.intValue = currentWorkingDevice->finishWriteFitnessData(); printFinishState("FinishWriteFitnessData", result->value.intValue); if (result->value.intValue == 2) { // waiting for user input messageList.push_back(currentWorkingDevice->getMessage()); MessageBox * msg = messageList.front(); if (msg != NULL) { propertyList["MessageBoxXml"].stringValue = msg->getXml(); } } else if (result->value.intValue == 3) { // transfer finished //TODO: Is this the correct property? propertyList["FitnessTransferSucceeded"].intValue = currentWorkingDevice->getTransferSucceeded(); updateProgressBar("Write fitness data to GPS", 100); } else { updateProgressBar("Write fitness data to GPS", currentWorkingDevice->getProgress()); } return true; } else { if (Log::enabledInfo()) Log::info("FinishWriteFitnessData: No working device specified"); } } return false; } bool methodCancelWriteFitnessData(NPObject *obj, const NPVariant args[], uint32_t argCount, NPVariant * result) { if (currentWorkingDevice != NULL) { Log::dbg("Calling CancelWriteFitnessData"); currentWorkingDevice->cancelWriteFitnessData(); } return true; } bool methodBytesAvailable(NPObject *obj, const NPVariant args[], uint32_t argCount, NPVariant * result) { if (argCount != 2) { Log::err("BytesAvailable: Wrong parameter count. Two parameter required! (deviceNumber, relativeFilePath)"); return false; } int deviceId = getIntParameter(args, 0, -1); if (deviceId != -1) { currentWorkingDevice = devManager->getGpsDevice(deviceId); if (currentWorkingDevice != NULL) { string relativeFilePath = getStringParameter(args, 1, ""); result->type = NPVariantType_Int32; result->value.intValue = currentWorkingDevice->bytesAvailable(relativeFilePath); return true; } else { Log::err("BytesAvailable: Unknown Device ID"); } } else { Log::err("BytesAvailable: Device ID is invalid"); } return false; } bool methodStartReadableFileListing(NPObject *obj, const NPVariant args[], uint32_t argCount, NPVariant * result) { if (argCount >= 4) { int deviceId = getIntParameter(args, 0, -1); string dataTypeName = getStringParameter(args, 1, ""); string fileTypeName = getStringParameter(args, 2, ""); bool computeMD5 = getBoolParameter(args, 3, false); if (deviceId != -1) { currentWorkingDevice = devManager->getGpsDevice(deviceId); if (currentWorkingDevice != NULL) { result->type = NPVariantType_Int32; if (currentWorkingDevice->startReadableFileListing(dataTypeName,fileTypeName,computeMD5) == 1) { return true; } else { // Not a file based device! return false; } } else { if (Log::enabledInfo()) Log::info("StartReadableFileListing: Device not found"); } } else { if (Log::enabledErr()) Log::err("StartReadableFileListing: Unable to determine device id"); } } else { if (Log::enabledErr()) Log::err("StartReadableFileListing: Wrong parameter count"); } return false; } bool methodFinishReadableFileListing(NPObject *obj, const NPVariant args[], uint32_t argCount, NPVariant * result) { /* Return Values are 0 = idle 1 = working 2 = waiting for user input 3 = finished */ if (!messageList.empty()) { // Push messages first MessageBox * msg = messageList.front(); if (msg != NULL) { propertyList["MessageBoxXml"].stringValue = msg->getXml(); result->type = NPVariantType_Int32; result->value.intValue = 2; /* waiting for user input */ return true; } else { if (Log::enabledErr()) Log::err("A null MessageBox is blocking the messages - fix the code!"); } } else { if (currentWorkingDevice != NULL) { result->type = NPVariantType_Int32; result->value.intValue = currentWorkingDevice->finishReadableFileListing(); printFinishState("FinishReadableFileListing", result->value.intValue); if (result->value.intValue == 2) { // waiting for user input messageList.push_back(currentWorkingDevice->getMessage()); MessageBox * msg = messageList.front(); if (msg != NULL) { propertyList["MessageBoxXml"].stringValue = msg->getXml(); } } else if (result->value.intValue == 3) { // transfer finished propertyList["FitnessTransferSucceeded"].intValue = currentWorkingDevice->getTransferSucceeded(); propertyList["DirectoryListingXml"].stringValue = currentWorkingDevice->getDirectoryListingXml(); debugOutputPropertyToFile("DirectoryListingXml"); updateProgressBar("ReadableFileListing from GPS", 100); } else { updateProgressBar("ReadableFileListing from GPS", currentWorkingDevice->getProgress()); } return true; } else { if (Log::enabledInfo()) Log::info("FinishReadableFileListing: No working device specified"); } } return false; } bool methodCancelReadableFileListing(NPObject *obj, const NPVariant args[], uint32_t argCount, NPVariant * result) { if (currentWorkingDevice != NULL) { currentWorkingDevice -> cancelReadableFileListing(); } return true; } /** * Reads a directory from the device. * The search is always recursive. * @param deviceId - integer, identifying the device * @param devicePath - string, relative path (eg: Garmin/GPX) on device, may contain wildcards (eg: Garmin/GPX/ *.gpx) * @param computeMD5 - set to true if you need md5 checksums for all files */ bool methodStartDirectoryListing(NPObject *obj, const NPVariant args[], uint32_t argCount, NPVariant * result) { if (argCount >= 3) { int deviceId = getIntParameter(args, 0, -1); string devicePath = getStringParameter(args, 1, ""); bool computeMD5 = getBoolParameter(args, 2, false); if (deviceId != -1) { currentWorkingDevice = devManager->getGpsDevice(deviceId); if (currentWorkingDevice != NULL) { result->type = NPVariantType_Int32; if (currentWorkingDevice->startDirectoryListing(devicePath,computeMD5) == 1) { return true; } else { // Not a file based device! return false; } } else { if (Log::enabledInfo()) Log::info("StartDirectoryListing: Device not found"); } } else { if (Log::enabledErr()) Log::err("StartDirectoryListing: Unable to determine device id"); } } else { if (Log::enabledErr()) Log::err("StartDirectoryListing: Wrong parameter count"); } return false; } bool methodFinishDirectoryListing(NPObject *obj, const NPVariant args[], uint32_t argCount, NPVariant * result) { /* Return Values are 0 = idle 1 = working 2 = waiting for user input 3 = finished */ if (!messageList.empty()) { // Push messages first MessageBox * msg = messageList.front(); if (msg != NULL) { propertyList["MessageBoxXml"].stringValue = msg->getXml(); result->type = NPVariantType_Int32; result->value.intValue = 2; /* waiting for user input */ return true; } else { if (Log::enabledErr()) Log::err("A null MessageBox is blocking the messages - fix the code!"); } } else { if (currentWorkingDevice != NULL) { result->type = NPVariantType_Int32; result->value.intValue = currentWorkingDevice->finishDirectoryListing(); printFinishState("FinishDirectoryListing", result->value.intValue); if (result->value.intValue == 2) { // waiting for user input messageList.push_back(currentWorkingDevice->getMessage()); MessageBox * msg = messageList.front(); if (msg != NULL) { propertyList["MessageBoxXml"].stringValue = msg->getXml(); } } else if (result->value.intValue == 3) { // transfer finished propertyList["FitnessTransferSucceeded"].intValue = currentWorkingDevice->getTransferSucceeded(); propertyList["DirectoryListingXml"].stringValue = currentWorkingDevice->getDirectoryListingXml(); debugOutputPropertyToFile("DirectoryListingXml"); updateProgressBar("DirectoryListing from GPS", 100); } else { updateProgressBar("DirectoryListing from GPS", currentWorkingDevice->getProgress()); } return true; } else { if (Log::enabledInfo()) Log::info("FinishDirectoryListing: No working device specified"); } } return false; } bool methodCancelDirectoryListing(NPObject *obj, const NPVariant args[], uint32_t argCount, NPVariant * result) { if (currentWorkingDevice != NULL) { currentWorkingDevice -> cancelDirectoryListing(); } return true; } bool methodParentDevice(NPObject *obj, const NPVariant args[], uint32_t argCount, NPVariant * result) { if (argCount >= 1) { int deviceId = getIntParameter(args, 0, -1); if (deviceId != -1) { // TODO: Since version 3.0.1.0 it is possible to have parent devices // Currently the plugin does not return any child devices, which is why // this function always returns -1 (no child device) result->type = NPVariantType_Int32; result->value.intValue = -1; if (Log::enabledDbg()) { stringstream ss; ss << "ParentDevice for device " << deviceId << " - returning 'device has no parent device'"; Log::dbg(ss.str()); } return true; } else { if (Log::enabledErr()) Log::err("ParentDevice: Unable to determine device id (first parameter)"); } } else { if (Log::enabledDbg()) { Log::dbg("Wrong argument count for ParentDevice"); } } return false; } /** * Initializes the Property List and Function List that are accessible from the outside */ void initializePropertyList() { // Properties propertyList.clear(); Property value; value.writeable = false; value.type = NPVariantType_String; value.stringValue = "\n\n\n\n006-A0160-00\n\n4\n1\n0\n0\nRelease\n\n0\n\n\n\n"; propertyList["VersionXml"] = value; value.stringValue = "\n\nGarminPlugin Status not yet implemented\n\n\n0% complete\n"; propertyList["ProgressXml"] = value; value.stringValue = ""; propertyList["MessageBoxXml"] = value; value.stringValue = ""; propertyList["TcdXmlz"] = value; // Compressed value.stringValue = ""; propertyList["DirectoryListingXml"] = value; // can be written from the outside value.writeable = true; value.stringValue = ""; propertyList["GpsXml"] = value; value.stringValue = ""; propertyList["FileName"] = value; value.stringValue = ""; propertyList["TcdXml"] = value; value.writeable = false; value.type = NPVariantType_Int32; value.intValue = 0; propertyList["GpsTransferSucceeded"] = value; propertyList["Locked"] = value; // unlock value.intValue = 1; propertyList["FitnessTransferSucceeded"] = value; value.intValue = 1; propertyList["DownloadDataSucceeded"] = value; // Functions pt2Func fooPointer = &methodDevicesXmlString; methodList["DevicesXmlString"] = fooPointer; fooPointer = &methodUnlock; methodList["Unlock"] = fooPointer; fooPointer = &methodStartFindDevices; methodList["StartFindDevices"] = fooPointer; fooPointer = &methodCancelFindDevices; methodList["CancelFindDevices"] = fooPointer; fooPointer = &methodFinishFindDevices; methodList["FinishFindDevices"] = fooPointer; fooPointer = &methodDeviceDescription; methodList["DeviceDescription"] = fooPointer; fooPointer = &methodStartWriteToGps; methodList["StartWriteToGps"] = fooPointer; fooPointer = &methodFinishWriteToGps; methodList["FinishWriteToGps"] = fooPointer; fooPointer = &methodCancelWriteToGps; methodList["CancelWriteToGps"] = fooPointer; fooPointer = &methodRespondToMessageBox; methodList["RespondToMessageBox"] = fooPointer; fooPointer = &methodStartReadFitnessData; methodList["StartReadFitnessData"] = fooPointer; fooPointer = &methodFinishReadFitnessData; methodList["FinishReadFitnessData"] = fooPointer; fooPointer = &methodStartReadFITDirectory; methodList["StartReadFITDirectory"] = fooPointer; fooPointer = &methodFinishReadFITDirectory; methodList["FinishReadFITDirectory"] = fooPointer; fooPointer = &methodCancelReadFITDirectory; methodList["CancelReadFITDirectory"] = fooPointer; fooPointer = &methodStartReadFitnessDirectory; methodList["StartReadFitnessDirectory"] = fooPointer; fooPointer = &methodFinishReadFitnessDirectory; methodList["FinishReadFitnessDirectory"] = fooPointer; fooPointer = &methodCancelReadFitnessData; methodList["CancelReadFitnessData"] = fooPointer; fooPointer = &methodStartReadFitnessDetail; methodList["StartReadFitnessDetail"] = fooPointer; fooPointer = &methodFinishReadFitnessDetail; methodList["FinishReadFitnessDetail"] = fooPointer; fooPointer = &methodCancelReadFitnessDetail; methodList["CancelReadFitnessDetail"] = fooPointer; fooPointer = &methodStartReadFromGps; methodList["StartReadFromGps"] = fooPointer; fooPointer = &methodFinishReadFromGps; methodList["FinishReadFromGps"] = fooPointer; fooPointer = &methodCancelReadFromGps; methodList["CancelReadFromGps"] = fooPointer; fooPointer = &methodGetBinaryFile; methodList["GetBinaryFile"] = fooPointer; fooPointer = &methodStartDownloadData; methodList["StartDownloadData"] = fooPointer; fooPointer = &methodFinishDownloadData; methodList["FinishDownloadData"] = fooPointer; fooPointer = &methodStartWriteFitnessData; methodList["StartWriteFitnessData"] = fooPointer; fooPointer = &methodFinishWriteFitnessData; methodList["FinishWriteFitnessData"] = fooPointer; fooPointer = &methodCancelWriteFitnessData; methodList["CancelWriteFitnessData"] = fooPointer; fooPointer = &methodBytesAvailable; methodList["BytesAvailable"] = fooPointer; // Directory File listing of file based devices fooPointer = &methodStartReadableFileListing; methodList["StartReadableFileListing"] = fooPointer; fooPointer = &methodFinishReadableFileListing; methodList["FinishReadableFileListing"] = fooPointer; fooPointer = &methodCancelReadableFileListing; methodList["CancelReadableFileListing"] = fooPointer; // Directory File listing of file based devices (is marked as experimental but still used in myGarmin portal fooPointer = &methodStartDirectoryListing; methodList["StartDirectoryListing"] = fooPointer; fooPointer = &methodFinishDirectoryListing; methodList["FinishDirectoryListing"] = fooPointer; fooPointer = &methodCancelDirectoryListing; methodList["CancelDirectoryListing"] = fooPointer; // Get Parent Device (new in 3.0.1.0) fooPointer = &methodParentDevice; methodList["ParentDevice"] = fooPointer; } /** * The browser checks if the function actually exists by calling this function. * This function returns true if the methodList was initialized with a function by that name. * @param obj unknown * @param methodname name of the method * @return boolean. Return true if method exists */ static bool hasMethod(NPObject* obj, NPIdentifier methodName) { string name = npnfuncs->utf8fromidentifier(methodName); //if (Log::enabledDbg()) Log::dbg("hasMethod: "+name); map::iterator it; it = methodList.find(name); if (it != methodList.end()) { return true; } else { if (Log::enabledInfo()) Log::info("hasMethod: "+name+" not found"); } return false; } /** * Prints the parameter that are used while calling a function * Just good for debugging. * @param name function name * @param args an array with the passed arguments * @param argCount number of arguments passed in args */ void printParameter(string name, const NPVariant args[], uint32_t argCount) { std::stringstream ss; ss << name << "("; for (uint32_t i = 0; i < argCount; i++) { if (args[i].type == NPVariantType_Int32) { ss << "" << args[i].value.intValue; } else if (args[i].type == NPVariantType_String) { ss << "\"" << getStringParameter(args, i, "") << "\""; } else if (args[i].type == NPVariantType_Bool) { if (args[i].value.boolValue) { ss << "true"; } else { ss << "false"; } } else if (args[i].type == NPVariantType_Double) { ss << "" << args[i].value.doubleValue; } else if (args[i].type == NPVariantType_Null) { ss << "null"; } else { ss << " ? "; } if (i < argCount-1) { ss << ","; } } ss << ")"; string functionCall; ss >> functionCall; Log::dbg(functionCall); } /** * Gets called by the browser when javascript calls a method. * Just good for debugging. * @param obj * @param methodName name of the function that shall be called * @param args array with the parameters * @param argCount number of passed parameters * @param result store return value here * @return boolean. Return true if successful */ static bool invoke(NPObject* obj, NPIdentifier methodName, const NPVariant *args, uint32_t argCount, NPVariant *result) { string name = npnfuncs->utf8fromidentifier(methodName); if (Log::enabledDbg()) printParameter(name, args, argCount); map::iterator it; it = methodList.find(name); if (it != methodList.end()) { pt2Func functionPointer = it->second; return (*functionPointer)(obj, args, argCount, result); } else { std::stringstream ss; ss << "Method " << name << " not found"; Log::err(ss.str()); } // aim exception handling npnfuncs->setexception(obj, "exception during invocation"); return false; } /** * Gets called by the browser to check if a property exists * @param obj * @param propertyName name of the property * @return boolean. Return true if property exists */ static bool hasProperty(NPObject *obj, NPIdentifier propertyName) { string name = npnfuncs->utf8fromidentifier(propertyName); //if (Log::enabledDbg()) Log::dbg("hasProperty: "+name); map::iterator it; it = propertyList.find(name); if (it != propertyList.end()) { return true; } else { if (Log::enabledInfo()) Log::info("hasProperty: "+name+" not found"); } return false; } /** * Gets called during getProperty, fixes some broken Website behavior (opencaching.com) * Some websites check the content of a variable with getProperty to determine if the function * succeeded instead of using the Finishxxx functions. This results in an endless getProperty * call, since the property is only updated during the Finishxxx call. * * Writes result to variable in propertyList * @param name */ static void instantVariableUpdate(string name) { if (currentWorkingDevice == NULL) { return; } if (name.compare("DirectoryListingXml") == 0) { Log::dbg("instantVariableUpdate updating DirectoryListingXml -- Remove me"); propertyList["DirectoryListingXml"].stringValue = currentWorkingDevice->getDirectoryListingXml(); } } /** * Gets called by the browser to get the content of a property * @param obj * @param propertyName name of the property * @param result must be filled with the content of the property * @return boolean. Return true if successful */ static bool getProperty(NPObject *obj, NPIdentifier propertyName, NPVariant *result) { string name = npnfuncs->utf8fromidentifier(propertyName); // Fix for websites like opencaching.com which do not call Finishxxxx before querying the value instantVariableUpdate(name); map::iterator it; it = propertyList.find(name); if (it != propertyList.end()) { stringstream dbgOut; Property storedProperty = it->second; result->type = storedProperty.type; if (NPVARIANT_IS_INT32(storedProperty)) { INT32_TO_NPVARIANT(storedProperty.intValue, *result); dbgOut << storedProperty.intValue; } else if (NPVARIANT_IS_STRING(storedProperty)) { // We have: // std::string str as the string to store // NPVariant *dst as the destination NPVariant char *outStr = (char*)npnfuncs->memalloc(storedProperty.stringValue.size() + 1); memcpy(outStr, storedProperty.stringValue.c_str(), storedProperty.stringValue.size() + 1); result->type = NPVariantType_String; GETSTRING(result->value.stringValue) = outStr; GETSTRINGLENGTH(result->value.stringValue) = storedProperty.stringValue.size(); if (storedProperty.stringValue.size() > 50) { dbgOut << storedProperty.stringValue.substr(0,47) << "..."; } else { dbgOut << storedProperty.stringValue; } } else { if (Log::enabledErr()) Log::err("getProperty "+name+": Type not yet implemented"); return false; } if (Log::enabledDbg()) Log::dbg("getProperty: "+name +" = ["+dbgOut.str()+"]"); return true; } else { if (Log::enabledInfo()) Log::info("getProperty: Property "+name+" not found"); } return false; } /** * Gets called by the browser to set the content of a property * @param obj * @param propertyName name of the property * @param value the new content for the property * @return boolean. Return true if successful */ static bool setProperty(NPObject *obj, NPIdentifier propertyName, const NPVariant *value) { string name = npnfuncs->utf8fromidentifier(propertyName); if (Log::enabledDbg()) Log::dbg("setProperty "+name); map::iterator it; it = propertyList.find(name); if (it != propertyList.end()) { Property storedProperty = it->second; if (storedProperty.writeable) { storedProperty.type = value->type; if (value->type == NPVariantType_String) { storedProperty.stringValue = getStringFromNPString(value->value.stringValue); propertyList[name] = storedProperty; // store return true; } else if (value->type == NPVariantType_Int32) { storedProperty.intValue = value->value.intValue; propertyList[name] = storedProperty; // store return true; } else { if (Log::enabledErr()) Log::err("setProperty: Unsupported type - must be implemented"); } } else { if (Log::enabledInfo()) Log::info("setProperty: Property ist read-only"); } } else { if (Log::enabledInfo()) Log::info("setProperty: Property "+name+" not found"); } return false; } /** * Functions that are accessible from the outside by the browser */ static NPClass npcRefObject = { NP_CLASS_STRUCT_VERSION, NULL, /*allocate*/ NULL, /*deallocate*/ NULL, /*invalidate */ hasMethod, invoke, NULL, /*invokeDefault*/ hasProperty, getProperty, setProperty, NULL, /*removeProperty*/ }; /** * Gets called by the browser to create a new instance * @param pluginType ? * @param instance ? * @param mode ? * @param argc ? * @param argn ? * @param argv ? * @param saved ? */ static NPError nevv(NPMIMEType pluginType, NPP instance, uint16_t mode, int16_t argc, char *argn[], char *argv[], NPSavedData *saved) { instanceCount++; inst = instance; if (Log::enabledDbg()) { stringstream ss; ss << "NPP_New(instance=" << instance << ",mode=" << mode << ",argc=" << argc << ",args=["; for (int i = 0; i < argc; ++i) { ss << (i ? "," : "") << argn[i] << "=" << argv[i]; } Log::dbg(ss.str()); } if(!so) { so = npnfuncs->createobject(instance, &npcRefObject); } if (Log::enabledDbg()) Log::dbg("Overwriting Garmin Javascript Browser detection!"); NPString str; NPObject* windowObject = NULL; NPError err = npnfuncs->getvalue(inst, NPNVWindowNPObject, &windowObject); if (err != NPERR_NO_ERROR) { Log::err("Error fetching NPNVWindowNPObject"); return NPERR_NO_ERROR; } NPVariant ret; // This is needed for google chrome and firefox to get rid of the browser check string javascriptCode = "var garminOverwriteBrowserDetectRunCount = 0;\ var garminOverwriteBrowserDetect = function() {\ if(typeof(BrowserDetect.init) != \"undefined\"){\ BrowserDetect.init = function() { };\ }\ if(typeof(BrowserDetect.OS) != \"undefined\"){\ BrowserDetect.OS='Windows';\ BrowserDetect.browser='Firefox';\ }\ garminOverwriteBrowserDetectRunCount++;\ if (garminOverwriteBrowserDetectRunCount < 80) {\ setTimeout ( \"garminOverwriteBrowserDetect()\", 25 );\ }\ };\ garminOverwriteBrowserDetect();"; char *buf = (char*)npnfuncs->memalloc(javascriptCode.size() + 1); memcpy(buf, javascriptCode.c_str(), javascriptCode.size()); GETSTRING(str) = buf; GETSTRINGLENGTH(str) = javascriptCode.size(); if (!npnfuncs->evaluate(inst, windowObject, &str, &ret)) { Log::err("Unable to execute javascript: "+javascriptCode); } if (Log::enabledDbg()) Log::dbg("End Overwriting Garmin Javascript Browser detection!"); if (Log::enabledDbg()) { string userAgentStr = npnfuncs->uagent(inst); Log::dbg("User Agent: "+userAgentStr); NPIdentifier identifier = npnfuncs->getstringidentifier("location"); NPVariant variantValue; bool b1 = npnfuncs->getproperty( inst, windowObject, identifier, &variantValue ); if (b1) { NPObject *locationObj = variantValue.value.objectValue; identifier = npnfuncs->getstringidentifier( "href" ); bool b2 = npnfuncs->getproperty( inst, locationObj, identifier, &variantValue ); if (b2) { if (variantValue.type == NPVariantType_String) { string href = getStringFromNPString(variantValue.value.stringValue); Log::dbg("URL: "+href); } } npnfuncs->releaseobject(locationObj); } } npnfuncs->releaseobject(windowObject); setlocale(LC_ALL, "POSIX"); return NPERR_NO_ERROR; } /** * Gets called by the browser to destroy an instance * @param instance ? * @param save ? * @return NPERR_NO_ERROR */ static NPError destroy(NPP instance, NPSavedData **save) { if (Log::enabledDbg()) Log::dbg("destroy"); instanceCount--; if (instanceCount == 0) { if (Log::enabledDbg()) Log::dbg("destroy - last instance"); if ((so) && (npnfuncs != NULL)) { npnfuncs->releaseobject(so); so = NULL; } } return NPERR_NO_ERROR; } /** * Gets called by the browser to get values like pluginname and mime type * @param instance ? * @param variable What value to get * @param value ? * @return NPERR_NO_ERROR */ static NPError getValue(NPP instance, NPPVariable variable, void *value) { inst = instance; switch(variable) { default: if (Log::enabledDbg()) Log::dbg("getValue - default"); return NPERR_GENERIC_ERROR; case NPPVpluginNameString: if (Log::enabledDbg()) Log::dbg("getvalue - name string"); *((const char **)value) = pluginName; break; case NPPVpluginDescriptionString: if (Log::enabledDbg()) Log::dbg("getvalue - description string"); *((const char **)value) = pluginDescription; break; case NPPVpluginScriptableNPObject: if (Log::enabledDbg()) Log::dbg("getvalue - scriptable object"); if(!so) { so = npnfuncs->createobject(instance, &npcRefObject); } npnfuncs->retainobject(so); *(NPObject **)value = so; break; case NPPVpluginNeedsXEmbed: if (Log::enabledDbg()) Log::dbg("getvalue - xembed"); *((bool *)value) = supportsXEmbed; // Support XEmbed (without Chrome does not work) break; } return NPERR_NO_ERROR; } /** * Expected by Safari on Darwin * @param instance ? * @param ev ? * @return NPERR_NO_ERROR */ static NPError /* */ handleEvent(NPP instance, void *ev) { inst = instance; if (Log::enabledDbg()) Log::dbg("handleEvent"); return NPERR_NO_ERROR; } /** * Expected by Opera * @param instance ? * @param pNPWindow ? * @return NPERR_NO_ERROR */ static NPError /* expected by Opera */ setWindow(NPP instance, NPWindow* pNPWindow) { inst = instance; if (Log::enabledDbg()) Log::dbg("setWindow"); return NPERR_NO_ERROR; } static void nppUrlNotify(NPP instance, const char* url, NPReason reason, void* notifyData) { if (reason == NPRES_DONE) { if (Log::enabledDbg()) Log::dbg("nppUrlNotify: Request was finished."); if (currentWorkingDevice != NULL) { string urlToDownload = currentWorkingDevice->getNextDownloadDataUrl(); if (urlToDownload.length() > 0) { if (Log::enabledDbg()) { Log::dbg("Requesting download for URL: "+urlToDownload); } if (NPERR_NO_ERROR != npnfuncs->geturlnotify(inst, urlToDownload.c_str(), NULL, NULL)) { Log::err("Unable to get url: "+urlToDownload); } } } } else if (reason == NPRES_USER_BREAK) { Log::err("nppUrlNotify: User canceled request"); if (currentWorkingDevice != NULL) { currentWorkingDevice->cancelDownloadData(); } } else if (reason == NPRES_NETWORK_ERR) { Log::err("nppUrlNotify: Canceled because of Network Error"); if (currentWorkingDevice != NULL) { currentWorkingDevice->cancelDownloadData(); } } else { if (Log::enabledDbg()) Log::dbg("nppUrlNotify: Unknown notify reason!"); } } static NPError nppNewStream(NPP instance, NPMIMEType type, NPStream* stream, NPBool seekable, uint16_t* stype) { if (*stype == NP_NORMAL) { if (Log::enabledDbg()) { string url = stream->url; Log::dbg("nppNewStream Type: NP_NORMAL URL: "+url); } return NPERR_NO_ERROR; } else { Log::err("nppNewStream: Unknown stream type!"); } return NPERR_GENERIC_ERROR; } #define NPP_STREAM_BUFFER_SIZE 5120 static int32_t nppWriteReady(NPP instance, NPStream* stream) { if (Log::enabledDbg()) Log::dbg("nppWriteReady"); return NPP_STREAM_BUFFER_SIZE; } static int32_t nppWrite(NPP instance, NPStream* stream, int32_t offset, int32_t len, void* buf) { if (Log::enabledDbg()) { stringstream ss; ss << "nppWrite Parameter: Offset: " << offset << " Length: " << len; Log::dbg(ss.str()); } if (currentWorkingDevice != NULL) { return currentWorkingDevice->writeDownloadData((char*)buf, len); } else { if (Log::enabledDbg()) Log::dbg("nppWrite: No working device!?"); } return -1; } static NPError nppDestroyStream(NPP instance, NPStream* stream, NPReason reason) { if (currentWorkingDevice != NULL) { if (reason == NPRES_DONE) { if (Log::enabledDbg()) Log::dbg("nppDestroyStream: Stream done"); currentWorkingDevice->saveDownloadData(); // Are there more downloads?? string urlToDownload = currentWorkingDevice->getNextDownloadDataUrl(); if (urlToDownload.length() > 0) { if (Log::enabledDbg()) { Log::dbg("Requesting download for URL: "+urlToDownload); } if (NPERR_NO_ERROR != npnfuncs->geturlnotify(inst, urlToDownload.c_str(), NULL, NULL)) { Log::err("Unable to get url: "+urlToDownload); } } } else { currentWorkingDevice->cancelDownloadData(); Log::err("nppDestroyStream: Download to device was canceled because of errors"); } } else { if (Log::enabledDbg()) Log::dbg("nppDestroyStream: No working device!?"); } return NPERR_NO_ERROR; } #ifdef __cplusplus extern "C" { #endif /** * Sets the entry points for the browser * @param nppfuncs ? * @return NPERR_NO_ERROR */ NPError OSCALL NP_GetEntryPoints(NPPluginFuncs *nppfuncs) { if (Log::enabledDbg()) Log::dbg("NP_GetEntryPoints"); nppfuncs->version = (NP_VERSION_MAJOR << 8) | NP_VERSION_MINOR; nppfuncs->newp = nevv; nppfuncs->destroy = destroy; nppfuncs->getvalue = getValue; nppfuncs->event = handleEvent; nppfuncs->setwindow = setWindow; nppfuncs->urlnotify = nppUrlNotify; nppfuncs->newstream = nppNewStream; nppfuncs->writeready = nppWriteReady; nppfuncs->write = nppWrite; nppfuncs->destroystream = nppDestroyStream; return NPERR_NO_ERROR; } #ifndef HIBYTE #define HIBYTE(x) ((((uint32_t)(x)) & 0xff00) >> 8) #endif /** * The browser initializes the plugin by calling this function * @param npnf ? * @param nppfuncs ? * @return NPERR_NO_ERROR */ NPError OSCALL NP_Initialize(NPNetscapeFuncs *npnf , NPPluginFuncs *nppfuncs ) { if(npnf == NULL) return NPERR_INVALID_FUNCTABLE_ERROR; if(HIBYTE(npnf->version) > NP_VERSION_MAJOR) return NPERR_INCOMPATIBLE_VERSION_ERROR; npnfuncs = npnf; NP_GetEntryPoints(nppfuncs); // Setup Configuration (which also initializes logging) if (confManager != NULL) { delete confManager; } confManager = new ConfigManager(); confManager->readConfiguration(); Log::getInstance()->setConfiguration(confManager->getConfiguration()); // Check for browser support of XEmbed NPError err = NPERR_NO_ERROR; err = npnfuncs->getvalue(NULL, NPNVSupportsXEmbedBool,(void *)&supportsXEmbed); if (err != NPERR_NO_ERROR) { supportsXEmbed = false; Log::err("Error while asking for XEmbed support"); } if (Log::enabledDbg()) { if (supportsXEmbed == false) { Log::dbg("Browser does not support XEmbed"); } else { Log::dbg("Browser supports XEmbed"); } } initializePropertyList(); if (devManager != NULL) { delete devManager; } devManager = new DeviceManager(); devManager->setConfiguration(confManager->getConfiguration()); MessageBox * msg = confManager->getMessage(); if (msg != NULL) { messageList.push_back(msg); } if (Log::enabledDbg()) Log::dbg("NP_Initialize successfull"); return NPERR_NO_ERROR; } /** * The browser shuts down the plugin by calling this function * @return NPERR_NO_ERROR */ NPError OSCALL NP_Shutdown() { if (Log::enabledDbg()) Log::dbg("NP_Shutdown"); delete devManager; delete confManager; devManager = NULL; return NPERR_NO_ERROR; } /** * The browser requests the mime description of the plugin with this function * @return Mime description */ const char * NP_GetMIMEDescription(void) { if (Log::enabledDbg()) Log::dbg("NP_GetMIMEDescription"); return pluginMimeDescription; } /** * Needs to be present for WebKit based browsers * @return NPERR_NO_ERROR */ NPError OSCALL NP_GetValue(void *npp, NPPVariable variable, void *value) { inst = (NPP)npp; return getValue((NPP)npp, variable, value); } #ifdef __cplusplus } #endif GarminPlugin-0.3.23/src/messageBox.cpp000066400000000000000000000070241232766717500176060ustar00rootroot00000000000000/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */ /* * GarminPlugin * Copyright (C) Andreas Diesner 2010 * * GarminPlugin is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GarminPlugin is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #include "messageBox.h" #include "log.h" using namespace std; MessageBox::MessageBox(MessageType type, string text, int buttons, int defaultBtn, GpsDevice *device) { this->device = device; this->text = text; this->buttons = buttons; this->defaultButton = defaultBtn; this->type = type; } string MessageBox::getXml() { /* Question The file F:/Garmin/gpx/GC22K31.gpx already exists on your GPS Device. OK to overwrite the file?

DeviceInfo
ReadFromDev.
OnFinishRead
WriteToDev.

Empty



Empty