Subversion Repositories public

Compare Revisions

Ignore whitespace Rev 229 → Rev 230

/sportwatcher/trunk/libgant/gant.h
0,0 → 1,192
/***************************************************************************
* Copyright (C) 2007 to 2009 by Andreas Theofilu *
* andreas@theosys.at *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation version 3 of the License. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
 
#ifndef _GANT_H
#define _GANT_H
 
#include <qstring.h>
#include <qfile.h>
 
#define MAXMSG 12 // SYNC,LEN,MSG,data[8],CHKSUM
#define hexval(c) ((c >= '0' && c <= '9') ? (c-'0') : ((c&0xdf)-'A'+10))
 
#define EVENT_RX_ACKNOWLEDGED 0x9b
#define EVENT_RX_BROADCAST 0x9a
#define EVENT_RX_BURST_PACKET 0x9c
#define EVENT_RX_EXT_ACKNOWLEDGED 0x9e
#define EVENT_RX_EXT_BROADCAST 0x9d
#define EVENT_RX_EXT_BURST_PACKET 0x9f
#define EVENT_TRANSFER_TX_COMPLETED 0x05
#define INVALID_MESSAGE 0x28
#define MESG_ACKNOWLEDGED_DATA_ID 0x4f
#define MESG_ASSIGN_CHANNEL_ID 0x42
#define MESG_BROADCAST_DATA_ID 0x4e
#define MESG_BURST_DATA_ID 0x50
#define MESG_CAPABILITIES_ID 0x54
#define MESG_CHANNEL_ID_ID 0x51
#define MESG_CHANNEL_MESG_PERIOD_ID 0x43
#define MESG_CHANNEL_RADIO_FREQ_ID 0x45
#define MESG_CHANNEL_SEARCH_TIMEOUT_ID 0x44
#define MESG_CHANNEL_STATUS_ID 0x52
#define MESG_CLOSE_CHANNEL_ID 0x4c
#define MESG_DATA_SIZE 13 // due to dodgy msg from suunto
#define MESG_EXT_ACKNOWLEDGED_DATA_ID 0x5e
#define MESG_EXT_BROADCAST_DATA_ID 0x5d
#define MESG_EXT_BURST_DATA_ID 0x5f
#define MESG_NETWORK_KEY_ID 0x46
#define MESG_OPEN_CHANNEL_ID 0x4b
#define MESG_OPEN_RX_SCAN_ID 0x5b
#define MESG_REQUEST_ID 0x4d
#define MESG_RESPONSE_EVENT_ID 0x40
#define MESG_RESPONSE_EVENT_SIZE 3
#define MESG_SEARCH_WAVEFORM_ID 0x49
#define MESG_SYSTEM_RESET_ID 0x4a
#define MESG_TX_SYNC 0xa4
#define MESG_UNASSIGN_CHANNEL_ID 0x41
#define RESPONSE_NO_ERROR 0x00
 
#define ACKSIZE 8 // above structure must be this size
#define AUTHSIZE 24 // ditto
#define PAIRSIZE 16
 
struct msg_queue
{
uchar msgid;
uchar len;
};
 
struct ack_msg
{
uchar code;
uchar atype;
uchar c1;
uchar c2;
uint id;
};
 
struct auth_msg
{
uchar code;
uchar atype;
uchar phase;
uchar u1;
uint id;
ulong auth1;
ulong auth2;
ulong fill1;
ulong fill2;
};
 
struct pair_msg
{
uchar code;
uchar atype;
uchar phase;
uchar u1;
uint id;
char devname[8];
};
 
class ant
{
public:
ant ();
~ant ();
 
bool setDevice (const QFile &fl);
bool setDevice (const QString &fl);
bool commfn (); // Start reading data from device
 
// Basic functions to manage the device
bool ANT_ResetSystem ();
bool ANT_Cmd55 (uchar chan);
bool ANT_OpenRxScanMode (uchar chan);
bool ANT_Init ();
bool ANT_RequestMessage (uchar chan, uchar mesg);
bool ANT_SetNetworkKeya (uchar net, uchar *key);
bool ANT_SetNetworkKey (uchar net, uchar *key);
bool ANT_AssignChannel (uchar chan, uchar chtype, uchar net);
bool ANT_UnAssignChannel (uchar chan);
bool ANT_SetChannelId (uchar chan, ushort dev, uchar devtype, uchar manid);
bool ANT_SetChannelRFFreq (uchar chan, uchar freq);
bool ANT_SetChannelPeriod (uchar chan, ushort period);
bool ANT_SetChannelSearchTimeout (uchar chan, uchar timeout);
bool ANT_SetSearchWaveform (uchar chan, ushort waveform);
bool ANT_SendAcknowledgedDataA (uchar chan, uchar *data);
bool ANT_SendAcknowledgedData (uchar chan, uchar *data);
unsigned short ANT_SendBurstTransferA(uchar chan, uchar *data, unsigned short numpkts);
unsigned short ANT_SendBurstTransfer (uchar chan, uchar *data, unsigned short numpkts);
bool ANT_OpenChannel (uchar chan);
bool ANT_CloseChannel (uchar chan);
int ANT_fd();
 
public:
typedef bool (ant::*RESPONSE_FUNC)(uchar chan, uchar msgid);
typedef bool (ant::*CHANNEL_EVENT_FUNC)(uchar chan, uchar event);
void ANT_AssignResponseFunction (RESPONSE_FUNC rf, uchar* rbuf);
void ANT_AssignChannelEventFunction (uchar chan, CHANNEL_EVENT_FUNC rf, uchar* rbuf);
 
protected:
bool msg_send(uchar mesg, uchar *inbuf, uchar len);
bool msg_send(uchar mesg, uchar data1, uchar data2);
bool msg_send(uchar mesg, uchar data1, uchar data2, uchar data3);
bool get_data(int fd);
 
private:
QFile device;
bool qFile;
int commenabled;
RESPONSE_FUNC rfn;
CHANNEL_EVENT_FUNC cfn;
uchar *rbufp;
uchar *cbufp;
};
 
class gant : public ant
{
public:
gant (const QString &af);
~gant ();
 
uint randno ();
bool chevent (uchar chan, uchar event);
bool revent (uchar chan, uchar event);
bool read_device ();
private:
uchar cbuf[MESG_DATA_SIZE]; // channel event data gets stored here
uchar ebuf[MESG_DATA_SIZE]; // response event data gets stored here
 
bool authfd;
QString authfile;
QFile faf;
 
uint mydev;
uint peerdev;
uint myid;
unsigned long myauth1;
unsigned long myauth2;
char authdata[33];
 
uchar clientid[3][8];
 
int state; // state machine state
};
 
#endif
/sportwatcher/trunk/libgant/Makefile.in
0,0 → 1,714
# Makefile.in generated by automake 1.9.6 from Makefile.am.
# KDE tags expanded automatically by am_edit - $Revision: 483858 $
# @configure_input@
 
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
 
@SET_MAKE@
 
 
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ..
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
target_triplet = @target@
subdir = libgant
DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \
$(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
$(top_srcdir)/configure.in
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(SHELL) $(top_srcdir)/admin/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
*) f=$$p;; \
esac;
am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
am__installdirs = "$(DESTDIR)$(libdir)"
libLIBRARIES_INSTALL = $(INSTALL_DATA)
LIBRARIES = $(lib_LIBRARIES)
ARFLAGS = cru
libgant_a_AR = $(AR) $(ARFLAGS)
libgant_a_LIBADD =
am_libgant_a_OBJECTS = gant.$(OBJEXT)
#>- libgant_a_OBJECTS = $(am_libgant_a_OBJECTS)
#>+ 1
libgant_a_OBJECTS = gant.$(OBJEXT)
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/admin/depcomp
am__depfiles_maybe = depfiles
#>- CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
#>- $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
#>+ 2
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) $(KDE_CXXFLAGS)
#>- LTCXXCOMPILE = $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) \
#>- $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
#>- $(AM_CXXFLAGS) $(CXXFLAGS)
#>+ 3
LTCXXCOMPILE = $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) \
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
$(AM_CXXFLAGS) $(CXXFLAGS) $(KDE_CXXFLAGS)
CXXLD = $(CXX)
#>- CXXLINK = $(LIBTOOL) --tag=CXX --mode=link $(CXXLD) $(AM_CXXFLAGS) \
#>- $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
#>+ 2
CXXLINK = $(LIBTOOL) --tag=CXX --mode=link $(CXXLD) $(AM_CXXFLAGS) \
$(CXXFLAGS) $(KDE_CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
SOURCES = $(libgant_a_SOURCES)
DIST_SOURCES = $(libgant_a_SOURCES)
HEADERS = $(noinst_HEADERS)
ETAGS = etags
CTAGS = ctags
#>- DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
#>+ 1
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) $(KDE_DIST)
ACLOCAL = @ACLOCAL@
AMDEP_FALSE = @AMDEP_FALSE@
AMDEP_TRUE = @AMDEP_TRUE@
AMTAR = @AMTAR@
AR = @AR@
ARTSCCONFIG = @ARTSCCONFIG@
AUTOCONF = @AUTOCONF@
AUTODIRS = @AUTODIRS@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CONF_FILES = @CONF_FILES@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DCOPIDL = @DCOPIDL@
DCOPIDL2CPP = @DCOPIDL2CPP@
DCOPIDLNG = @DCOPIDLNG@
DCOP_DEPENDENCIES = @DCOP_DEPENDENCIES@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
ECHO = @ECHO@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
ENABLE_PERMISSIVE_FLAG = @ENABLE_PERMISSIVE_FLAG@
EXEEXT = @EXEEXT@
F77 = @F77@
FFLAGS = @FFLAGS@
FRAMEWORK_COREAUDIO = @FRAMEWORK_COREAUDIO@
GMSGFMT = @GMSGFMT@
GREP = @GREP@
HAVE_GCC_VISIBILITY = @HAVE_GCC_VISIBILITY@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
KCFG_DEPENDENCIES = @KCFG_DEPENDENCIES@
KCONFIG_COMPILER = @KCONFIG_COMPILER@
KDECONFIG = @KDECONFIG@
KDE_CHECK_PLUGIN = @KDE_CHECK_PLUGIN@
KDE_EXTRA_RPATH = @KDE_EXTRA_RPATH@
KDE_INCLUDES = @KDE_INCLUDES@
KDE_LDFLAGS = @KDE_LDFLAGS@
KDE_MT_LDFLAGS = @KDE_MT_LDFLAGS@
KDE_MT_LIBS = @KDE_MT_LIBS@
KDE_NO_UNDEFINED = @KDE_NO_UNDEFINED@
KDE_PLUGIN = @KDE_PLUGIN@
KDE_RPATH = @KDE_RPATH@
KDE_USE_CLOSURE_FALSE = @KDE_USE_CLOSURE_FALSE@
KDE_USE_CLOSURE_TRUE = @KDE_USE_CLOSURE_TRUE@
KDE_USE_FINAL_FALSE = @KDE_USE_FINAL_FALSE@
KDE_USE_FINAL_TRUE = @KDE_USE_FINAL_TRUE@
KDE_USE_FPIE = @KDE_USE_FPIE@
KDE_USE_NMCHECK_FALSE = @KDE_USE_NMCHECK_FALSE@
KDE_USE_NMCHECK_TRUE = @KDE_USE_NMCHECK_TRUE@
KDE_USE_PIE = @KDE_USE_PIE@
KDE_XSL_STYLESHEET = @KDE_XSL_STYLESHEET@
LDFLAGS = @LDFLAGS@
LDFLAGS_AS_NEEDED = @LDFLAGS_AS_NEEDED@
LDFLAGS_NEW_DTAGS = @LDFLAGS_NEW_DTAGS@
LIBCOMPAT = @LIBCOMPAT@
LIBCRYPT = @LIBCRYPT@
LIBDL = @LIBDL@
LIBJPEG = @LIBJPEG@
LIBOBJS = @LIBOBJS@
LIBPNG = @LIBPNG@
LIBPTHREAD = @LIBPTHREAD@
LIBRESOLV = @LIBRESOLV@
LIBS = @LIBS@
LIBSM = @LIBSM@
LIBSOCKET = @LIBSOCKET@
LIBTOOL = @LIBTOOL@
LIBUCB = @LIBUCB@
LIBUTIL = @LIBUTIL@
LIBZ = @LIBZ@
LIB_KAB = @LIB_KAB@
LIB_KABC = @LIB_KABC@
LIB_KDECORE = @LIB_KDECORE@
LIB_KDED = @LIB_KDED@
LIB_KDEPIM = @LIB_KDEPIM@
LIB_KDEPRINT = @LIB_KDEPRINT@
LIB_KDEUI = @LIB_KDEUI@
LIB_KDNSSD = @LIB_KDNSSD@
LIB_KFILE = @LIB_KFILE@
LIB_KFM = @LIB_KFM@
LIB_KHTML = @LIB_KHTML@
LIB_KIMPROXY = @LIB_KIMPROXY@
LIB_KIO = @LIB_KIO@
LIB_KJS = @LIB_KJS@
LIB_KNEWSTUFF = @LIB_KNEWSTUFF@
LIB_KPARTS = @LIB_KPARTS@
LIB_KSPELL = @LIB_KSPELL@
LIB_KSYCOCA = @LIB_KSYCOCA@
LIB_KUNITTEST = @LIB_KUNITTEST@
LIB_KUTILS = @LIB_KUTILS@
LIB_POLL = @LIB_POLL@
LIB_QPE = @LIB_QPE@
LIB_QT = @LIB_QT@
LIB_SMB = @LIB_SMB@
LIB_X11 = @LIB_X11@
LIB_XEXT = @LIB_XEXT@
LIB_XRENDER = @LIB_XRENDER@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MAKEKDEWIDGETS = @MAKEKDEWIDGETS@
MCOPIDL = @MCOPIDL@
MEINPROC = @MEINPROC@
MOC = @MOC@
MSGFMT = @MSGFMT@
NOOPT_CFLAGS = @NOOPT_CFLAGS@
NOOPT_CXXFLAGS = @NOOPT_CXXFLAGS@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
QTE_NORTTI = @QTE_NORTTI@
QT_INCLUDES = @QT_INCLUDES@
QT_LDFLAGS = @QT_LDFLAGS@
RANLIB = @RANLIB@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
TOPSUBDIRS = @TOPSUBDIRS@
UIC = @UIC@
UIC_TR = @UIC_TR@
USER_INCLUDES = @USER_INCLUDES@
USER_LDFLAGS = @USER_LDFLAGS@
USE_EXCEPTIONS = @USE_EXCEPTIONS@
USE_RTTI = @USE_RTTI@
USE_THREADS = @USE_THREADS@
VERSION = @VERSION@
WOVERLOADED_VIRTUAL = @WOVERLOADED_VIRTUAL@
XGETTEXT = @XGETTEXT@
XMKMF = @XMKMF@
XMLLINT = @XMLLINT@
X_EXTRA_LIBS = @X_EXTRA_LIBS@
X_INCLUDES = @X_INCLUDES@
X_LDFLAGS = @X_LDFLAGS@
X_PRE_LIBS = @X_PRE_LIBS@
X_RPATH = @X_RPATH@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_F77 = @ac_ct_F77@
all_includes = @all_includes@
all_libraries = @all_libraries@
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
include_ARTS_FALSE = @include_ARTS_FALSE@
include_ARTS_TRUE = @include_ARTS_TRUE@
include_x11_FALSE = @include_x11_FALSE@
include_x11_TRUE = @include_x11_TRUE@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
kde_appsdir = @kde_appsdir@
kde_bindir = @kde_bindir@
kde_confdir = @kde_confdir@
kde_datadir = @kde_datadir@
kde_htmldir = @kde_htmldir@
kde_icondir = @kde_icondir@
kde_includes = @kde_includes@
kde_kcfgdir = @kde_kcfgdir@
kde_libraries = @kde_libraries@
kde_libs_htmldir = @kde_libs_htmldir@
kde_libs_prefix = @kde_libs_prefix@
kde_locale = @kde_locale@
kde_mimedir = @kde_mimedir@
kde_moduledir = @kde_moduledir@
kde_qtver = @kde_qtver@
kde_servicesdir = @kde_servicesdir@
kde_servicetypesdir = @kde_servicetypesdir@
kde_sounddir = @kde_sounddir@
kde_styledir = @kde_styledir@
kde_templatesdir = @kde_templatesdir@
kde_wallpaperdir = @kde_wallpaperdir@
kde_widgetdir = @kde_widgetdir@
kdeinitdir = @kdeinitdir@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
qt_includes = @qt_includes@
qt_libraries = @qt_libraries@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
target = @target@
target_alias = @target_alias@
target_cpu = @target_cpu@
target_os = @target_os@
target_vendor = @target_vendor@
unsermake_enable_pch_FALSE = @unsermake_enable_pch_FALSE@
unsermake_enable_pch_TRUE = @unsermake_enable_pch_TRUE@
x_includes = @x_includes@
x_libraries = @x_libraries@
xdg_appsdir = @xdg_appsdir@
xdg_directorydir = @xdg_directorydir@
xdg_menudir = @xdg_menudir@
#>- METASOURCES = AUTO
lib_LIBRARIES = libgant.a
libgant_a_SOURCES = gant.cpp
noinst_HEADERS = gant.h
libgant_a_LDFLAGS = $(KDE_RPATH) $(all_libraries)
AM_CXXFLAGS = $(all_includes)
#>- all: all-am
#>+ 1
all: docs-am all-am
 
.SUFFIXES:
.SUFFIXES: .cpp .lo .o .obj
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
#>- @for dep in $?; do \
#>- case '$(am__configure_deps)' in \
#>- *$$dep*) \
#>- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
#>- && exit 0; \
#>- exit 1;; \
#>- esac; \
#>- done; \
#>- echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu libgant/Makefile'; \
#>- cd $(top_srcdir) && \
#>- $(AUTOMAKE) --gnu libgant/Makefile
#>+ 12
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
&& exit 0; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu libgant/Makefile'; \
cd $(top_srcdir) && \
$(AUTOMAKE) --gnu libgant/Makefile
cd $(top_srcdir) && perl admin/am_edit libgant/Makefile.in
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
 
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
 
$(top_srcdir)/configure: $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
install-libLIBRARIES: $(lib_LIBRARIES)
@$(NORMAL_INSTALL)
test -z "$(libdir)" || $(mkdir_p) "$(DESTDIR)$(libdir)"
@list='$(lib_LIBRARIES)'; for p in $$list; do \
if test -f $$p; then \
f=$(am__strip_dir) \
echo " $(libLIBRARIES_INSTALL) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \
$(libLIBRARIES_INSTALL) "$$p" "$(DESTDIR)$(libdir)/$$f"; \
else :; fi; \
done
@$(POST_INSTALL)
@list='$(lib_LIBRARIES)'; for p in $$list; do \
if test -f $$p; then \
p=$(am__strip_dir) \
echo " $(RANLIB) '$(DESTDIR)$(libdir)/$$p'"; \
$(RANLIB) "$(DESTDIR)$(libdir)/$$p"; \
else :; fi; \
done
 
uninstall-libLIBRARIES:
@$(NORMAL_UNINSTALL)
@list='$(lib_LIBRARIES)'; for p in $$list; do \
p=$(am__strip_dir) \
echo " rm -f '$(DESTDIR)$(libdir)/$$p'"; \
rm -f "$(DESTDIR)$(libdir)/$$p"; \
done
 
clean-libLIBRARIES:
-test -z "$(lib_LIBRARIES)" || rm -f $(lib_LIBRARIES)
libgant.a: $(libgant_a_OBJECTS) $(libgant_a_DEPENDENCIES)
-rm -f libgant.a
$(libgant_a_AR) libgant.a $(libgant_a_OBJECTS) $(libgant_a_LIBADD)
$(RANLIB) libgant.a
 
mostlyclean-compile:
-rm -f *.$(OBJEXT)
 
distclean-compile:
-rm -f *.tab.c
 
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gant.Po@am__quote@
 
.cpp.o:
@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $<
 
.cpp.obj:
@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
 
.cpp.lo:
@am__fastdepCXX_TRUE@ if $(LTCXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $<
 
mostlyclean-libtool:
-rm -f *.lo
 
clean-libtool:
-rm -rf .libs _libs
 
distclean-libtool:
-rm -f libtool
uninstall-info-am:
 
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
mkid -fID $$unique
tags: TAGS
 
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$tags $$unique; \
fi
ctags: CTAGS
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(CTAGS_ARGS)$$tags$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$tags $$unique
 
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& cd $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) $$here
 
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
 
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
list='$(DISTFILES)'; for file in $$list; do \
case $$file in \
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
esac; \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkdir_p) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
else \
test -f $(distdir)/$$file \
|| cp -p $$d/$$file $(distdir)/$$file \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(LIBRARIES) $(HEADERS)
installdirs:
for dir in "$(DESTDIR)$(libdir)"; do \
test -z "$$dir" || $(mkdir_p) "$$dir"; \
done
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
 
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
 
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
 
clean-generic:
 
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
 
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
#>- clean: clean-am
#>+ 1
clean: kde-rpo-clean clean-am
 
#>- clean-am: clean-generic clean-libLIBRARIES clean-libtool \
#>- mostlyclean-am
#>+ 2
clean-am: clean-bcheck clean-generic clean-libLIBRARIES clean-libtool \
mostlyclean-am
 
distclean: distclean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-libtool distclean-tags
 
dvi: dvi-am
 
dvi-am:
 
html: html-am
 
info: info-am
 
info-am:
 
install-data-am:
 
install-exec-am: install-libLIBRARIES
 
install-info: install-info-am
 
install-man:
 
installcheck-am:
 
maintainer-clean: maintainer-clean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
 
mostlyclean: mostlyclean-am
 
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
mostlyclean-libtool
 
pdf: pdf-am
 
pdf-am:
 
ps: ps-am
 
ps-am:
 
uninstall-am: uninstall-info-am uninstall-libLIBRARIES
 
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
clean-libLIBRARIES clean-libtool ctags distclean \
distclean-compile distclean-generic distclean-libtool \
distclean-tags distdir dvi dvi-am html html-am info info-am \
install install-am install-data install-data-am install-exec \
install-exec-am install-info install-info-am \
install-libLIBRARIES install-man install-strip installcheck \
installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-compile \
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
tags uninstall uninstall-am uninstall-info-am \
uninstall-libLIBRARIES
 
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
 
#>+ 2
KDE_DIST=Makefile.in Makefile.am
 
#>+ 2
docs-am:
 
#>+ 15
force-reedit:
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
&& exit 0; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu libgant/Makefile'; \
cd $(top_srcdir) && \
$(AUTOMAKE) --gnu libgant/Makefile
cd $(top_srcdir) && perl admin/am_edit libgant/Makefile.in
 
 
#>+ 21
clean-bcheck:
rm -f *.bchecktest.cc *.bchecktest.cc.class a.out
 
bcheck: bcheck-am
 
bcheck-am:
@for i in ; do \
if test $(srcdir)/$$i -nt $$i.bchecktest.cc; then \
echo "int main() {return 0;}" > $$i.bchecktest.cc ; \
echo "#include \"$$i\"" >> $$i.bchecktest.cc ; \
echo "$$i"; \
if ! $(CXXCOMPILE) --dump-class-hierarchy -c $$i.bchecktest.cc; then \
rm -f $$i.bchecktest.cc; exit 1; \
fi ; \
echo "" >> $$i.bchecktest.cc.class; \
perl $(top_srcdir)/admin/bcheck.pl $$i.bchecktest.cc.class || { rm -f $$i.bchecktest.cc; exit 1; }; \
rm -f a.out; \
fi ; \
done
 
 
#>+ 3
final:
$(MAKE) all-am
 
#>+ 3
final-install:
$(MAKE) install-am
 
#>+ 3
no-final:
$(MAKE) all-am
 
#>+ 3
no-final-install:
$(MAKE) install-am
 
#>+ 3
kde-rpo-clean:
-rm -f *.rpo
 
#>+ 3
nmcheck:
nmcheck-am: nmcheck
/sportwatcher/trunk/libgant/Makefile.am
0,0 → 1,6
METASOURCES = AUTO
lib_LIBRARIES = libgant.a
libgant_a_SOURCES = gant.cpp
noinst_HEADERS = gant.h
libgant_a_LDFLAGS = $(KDE_RPATH) $(all_libraries)
AM_CXXFLAGS = $(all_includes)
/sportwatcher/trunk/libgant/gant.cpp
0,0 → 1,1110
/***************************************************************************
* Copyright (C) 2007 to 2009 by Andreas Theofilu *
* andreas@theosys.at *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation version 3 of the License. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
 
#include "gant.h"
#include <sys/select.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <termios.h>
#include <stdlib.h>
#include <assert.h>
#include <kmessagebox.h>
#include <klocale.h>
 
static char G50_KEY[] = "A8A423B9F55E63C1"; // garmin network key
 
static char sendack1[] = "4402320499990000";
// 44 message from pc?
// ..02 message type
// ....32 don't know
// ......04 don't know
// ........9999 my id
// ............0000 maybe id is 4 bytes
static char sendack2[] = "4404010099990000";
// ..04 message type
// ....01 don't know
// ......00 don't know
static char sendack3[] = "4406010000000000";
// ..06 message type
// ....01 don't know
static char sendack4[] = "4403000000000000";
// ..03 message type, go to idle
// ....01 don't know
 
ant::ant ()
{
qFile = false;
commenabled = 1;
rfn = cfn = 0;
}
 
ant::~ant ()
{
if (qFile)
device.close ();
 
qFile = false;
rfn = cfn = 0;
}
 
/*
* Set the device and store it inside the class
*/
bool ant::setDevice (const QFile &fl)
{
if (qFile)
{
device.close();
qFile = false;
}
 
device.setName (fl.name ());
 
if (!device.exists ())
{
KMessageBox::error (0, i18n("Device %1 does not exist!").arg(fl.name()));
return false;
}
 
if (!device.open (IO_Raw | IO_ReadWrite))
{
KMessageBox::error (0, i18n("Error opening device %1.").arg(fl.name()),
device.errorString());
return false;
}
 
qFile = true;
return true;
}
 
bool ant::setDevice (const QString &fl)
{
QFile f;
 
if (qFile)
{
device.close ();
qFile = false;
}
 
f.setName (fl);
return setDevice (f);
}
 
/*
* Send a message to the opened device.
*/
bool ant::msg_send(uchar mesg, uchar *inbuf, uchar len)
{
uchar buf[MAXMSG];
ssize_t nw;
int i;
uchar chk = MESG_TX_SYNC;
 
buf[0] = MESG_TX_SYNC;
buf[1] = len;
chk ^= len;
buf[2] = mesg;
chk ^= mesg;
for (i = 0; i < len; i++)
{
buf[3+i] = inbuf[i];
chk ^= inbuf[i];
}
buf[3+i] = chk;
usleep (10 * 1000);
 
if ((4 + i) != (nw = write(device.handle(), buf, 4 + i)))
{
KMessageBox::error (0, i18n("Error writing to device %1").arg(device.name()));
return false;
}
 
return true;
}
 
// two argument send
bool ant::msg_send(uchar mesg, uchar data1, uchar data2)
{
uchar buf[2];
 
buf[0] = data1;
buf[1] = data2;
return msg_send(mesg, buf, 2);
}
 
// three argument send
bool ant::msg_send(uchar mesg, uchar data1, uchar data2, uchar data3)
{
uchar buf[3];
 
buf[0] = data1;
buf[1] = data2;
buf[2] = data3;
return msg_send(mesg, buf, 3);
}
 
bool ant::commfn ()
{
fd_set readfds, writefds, exceptfds;
int ready, fd;
struct timeval to;
 
fd = device.handle ();
 
for(;;)
{
FD_ZERO(&readfds);
FD_ZERO(&writefds);
FD_ZERO(&exceptfds);
FD_SET(fd, &readfds);
to.tv_sec = 1;
to.tv_usec = 0;
ready = select(fd+1, &readfds, &writefds, &exceptfds, &to);
 
if (ready)
{
if (!get_data(fd))
return false;
}
}
 
return true;
}
 
bool ant::get_data(int fd)
{
static uchar buf[500];
static int bufc = 0;
int nr;
int dlen;
int i;
int j;
unsigned char chk = 0;
uchar event;
int found;
int srch;
int next;
 
nr = read(fd, buf+bufc, 20);
if (nr > 0)
bufc += nr;
else
return true;
 
if (bufc > 300)
{
KMessageBox::error (0, i18n(">>buf<< too long!"));
return false;
}
 
// some data in buf
// search for possible valid messages
srch = 0;
while (srch < bufc)
{
found = 0;
 
for (i = srch; i < bufc; i++)
{
if (buf[i] == MESG_TX_SYNC)
{
if (i+1 < bufc && buf[i+1] >= 1 && buf[i+1] <= 13)
{
dlen = buf[i+1];
 
if ((i + 3 + dlen) < bufc)
{
chk = 0;
 
for (j = i; j <= i+3+dlen; j++)
chk ^= buf[j];
 
if (0 == chk)
{
found = 1; // got a valid message
break;
}
else
fprintf (stderr, "bad chk %02x\n", chk);
}
}
}
}
 
if (found)
{
next = j;
// got a valid message, see if any data needs to be discarded
event = 0;
 
switch (buf[i+2])
{
case MESG_RESPONSE_EVENT_ID:
if (rfn)
{
memcpy(rbufp, buf+i+3, dlen);
 
if (!(this->*rfn)(buf[i+3], buf[i+5]))
return false;
}
break;
 
case MESG_BROADCAST_DATA_ID:
event = EVENT_RX_BROADCAST;
break;
 
case MESG_ACKNOWLEDGED_DATA_ID:
event = EVENT_RX_ACKNOWLEDGED;
break;
 
case MESG_BURST_DATA_ID:
event = EVENT_RX_BURST_PACKET;
break;
 
case MESG_EXT_BROADCAST_DATA_ID:
event = EVENT_RX_EXT_BROADCAST;
break;
 
case MESG_EXT_ACKNOWLEDGED_DATA_ID:
event = EVENT_RX_EXT_ACKNOWLEDGED;
break;
 
case MESG_EXT_BURST_DATA_ID:
event = EVENT_RX_EXT_BURST_PACKET;
break;
 
default:
if (rfn)
{
// should be this according to the docs, but doesn't fit
if (dlen > MESG_DATA_SIZE)
{
KMessageBox::error(0, i18n("rresponse buffer too small!"));
return false;
}
 
memcpy(rbufp, buf+i+3, dlen);
 
if (!(this->*rfn)(buf[i+3], buf[i+2]))
return false;
}
}
 
if (event)
{
if (cfn)
{
if (dlen > MESG_DATA_SIZE)
{
KMessageBox::error(0, i18n("cresponse buffer too small!"));
return false;
}
 
memcpy(cbufp, buf+i+4, dlen);
 
if (!(this->*cfn)(buf[i+3], event))
return false;
}
}
 
srch = next;
}
else
break;
}
 
if (next < bufc)
{
memmove(buf, buf+next, bufc-next);
bufc -= next;
}
else
bufc = 0;
}
 
bool ant::ANT_ResetSystem()
{
uchar filler = 0;
 
return msg_send(MESG_SYSTEM_RESET_ID, &filler, 1);
}
 
bool ant::ANT_Cmd55(uchar chan)
{
return msg_send(0x55, &chan, 1);
}
 
bool ant::ANT_OpenRxScanMode (uchar chan)
{
return msg_send(MESG_OPEN_RX_SCAN_ID, &chan, 1);
}
 
bool ant::ANT_Init ()
{
//char dev[40];
struct termios tp;
 
if (!qFile)
return false;
 
if (tcgetattr(device.handle(), &tp) < 0)
{
KMessageBox::error(0, i18n("Error getting terminal attributes!"));
return false;
}
 
tp.c_iflag &=
~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON|IXOFF|IXANY|INPCK|IUCLC);
tp.c_oflag &= ~OPOST;
tp.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN|ECHOE);
tp.c_cflag &= ~(CSIZE|PARENB);
tp.c_cflag |= CS8 | CLOCAL | CREAD | CRTSCTS;
 
if (cfsetispeed(&tp, B115200) < 0)
{
KMessageBox::error(0, i18n("Error setting input speed of line terminal!"));
return false;
}
 
if (cfsetospeed(&tp, B115200) < 0)
{
KMessageBox::error(0, i18n("Error setting output speed of line terminal!"));
return false;
}
 
tp.c_cc[VMIN] = 1;
tp.c_cc[VTIME] = 0;
 
if (tcsetattr(device.handle (), TCSANOW, &tp) < 0)
{
KMessageBox::error(0, i18n("Error setting terminal attributes!"));
return false;
}
 
// return commfn ();
return true;
}
 
bool ant::ANT_RequestMessage (uchar chan, uchar mesg)
{
return msg_send(MESG_REQUEST_ID, chan, mesg);
}
 
bool ant::ANT_SetNetworkKeya (uchar net, uchar *key)
{
uchar buf[9];
int i;
 
if (strlen((char *)key) != 16)
{
fprintf(stderr, "Bad key length %s\n", key);
return 0;
}
 
buf[0] = net;
 
for (i = 0; i < 8; i++)
buf[1+i] = hexval(key[i*2])*16+hexval(key[i*2+1]);
 
return msg_send(MESG_NETWORK_KEY_ID, buf, 9);
}
 
bool ant::ANT_SetNetworkKey (uchar net, uchar *key)
{
uchar buf[9];
//int i;
 
buf[0] = net;
memcpy(buf+1, key, 8);
return msg_send(MESG_NETWORK_KEY_ID, buf, 9);
}
 
bool ant::ANT_AssignChannel (uchar chan, uchar chtype, uchar net)
{
return msg_send(MESG_ASSIGN_CHANNEL_ID, chan, chtype, net);
}
 
bool ant::ANT_UnAssignChannel (uchar chan)
{
return msg_send(MESG_UNASSIGN_CHANNEL_ID, &chan, 1);
}
 
bool ant::ANT_SetChannelId (uchar chan, ushort dev, uchar devtype, uchar manid)
{
uchar buf[5];
 
buf[0] = chan;
buf[1] = dev%256;
buf[2] = dev/256;
buf[3] = devtype;
buf[4] = manid;
return msg_send(MESG_CHANNEL_ID_ID, buf, 5);
}
 
bool ant::ANT_SetChannelRFFreq (uchar chan, uchar freq)
{
return msg_send(MESG_CHANNEL_RADIO_FREQ_ID, chan, freq);
}
 
bool ant::ANT_SetChannelPeriod (uchar chan, ushort period)
{
uchar buf[3];
 
buf[0] = chan;
buf[1] = period%256;
buf[2] = period/256;
return msg_send(MESG_CHANNEL_MESG_PERIOD_ID, buf, 3);
}
 
bool ant::ANT_SetChannelSearchTimeout (uchar chan, uchar timeout)
{
return msg_send(MESG_CHANNEL_SEARCH_TIMEOUT_ID, chan, timeout);
}
 
bool ant::ANT_SetSearchWaveform (uchar chan, ushort waveform)
{
uchar buf[3];
 
buf[0] = chan;
buf[1] = waveform % 256;
buf[2] = waveform / 256;
return msg_send(MESG_SEARCH_WAVEFORM_ID, buf, 3);
}
 
bool ant::ANT_SendAcknowledgedDataA (uchar chan, uchar *data) // ascii version
{
uchar buf[9];
int i;
 
if (strlen((char *)data) != 16)
{
fprintf(stderr, "Bad data length %s\n", data);
return false;
}
 
buf[0] = chan;
 
for (i = 0; i < 8; i++)
buf[1+i] = hexval (data[i*2]) * 16 + hexval(data[i*2+1]);
 
return msg_send(MESG_ACKNOWLEDGED_DATA_ID, buf, 9);
}
 
bool ant::ANT_SendAcknowledgedData (uchar chan, uchar *data)
{
uchar buf[9];
//int i;
 
buf[0] = chan;
memcpy(buf+1, data, 8);
return msg_send(MESG_ACKNOWLEDGED_DATA_ID, buf, 9);
}
 
unsigned short ant::ANT_SendBurstTransferA(uchar chan, uchar *data, unsigned short numpkts)
{
uchar buf[9];
int i;
int j;
int seq = 0;
 
fprintf(stderr, "numpkts %d data %s\n", numpkts, data);
 
if (strlen((char *)data) != (16 * numpkts))
{
fprintf(stderr, "Bad data length %s numpkts %d\n", data, numpkts);
return 0;
}
 
for (j = 0; j < numpkts; j++)
{
buf[0] = chan | (seq << 5) | ((j == (numpkts - 1)) ? 0x80 : 0);
 
for (i = 0; i < 8; i++)
buf[1+i] = hexval (data[j*16+i*2]) * 16 + hexval (data[j*16+i*2+1]);
usleep(20 * 1000);
msg_send(MESG_BURST_DATA_ID, buf, 9);
seq++;
 
if (seq > 3)
seq = 1;
}
 
return numpkts;
}
 
unsigned short ant::ANT_SendBurstTransfer (uchar chan, uchar *data, unsigned short numpkts)
{
uchar buf[9];
//int i;
int j;
int seq = 0;
 
for (j = 0; j < numpkts; j++)
{
buf[0] = chan | (seq << 5) | ((j == (numpkts - 1)) ? 0x80 : 0);
memcpy (buf+1, data+j*8, 8);
usleep (20*1000);
msg_send (MESG_BURST_DATA_ID, buf, 9);
seq++;
 
if (seq > 3)
seq = 1;
}
 
return numpkts;
}
 
bool ant::ANT_OpenChannel (uchar chan)
{
return msg_send(MESG_OPEN_CHANNEL_ID, &chan, 1);
}
 
bool ant::ANT_CloseChannel (uchar chan)
{
return msg_send(MESG_CLOSE_CHANNEL_ID, &chan, 1);
}
 
void ant::ANT_AssignResponseFunction (RESPONSE_FUNC rf, uchar* rbuf)
{
rfn = rf;
rbufp = rbuf;
}
 
void ant::ANT_AssignChannelEventFunction (uchar, CHANNEL_EVENT_FUNC rf, uchar* rbuf)
{
cfn = rf;
cbufp = rbuf;
}
 
int ant::ANT_fd()
{
return device.handle();
}
 
/*
* Following functions control the device and uses the class "ant".
* This is class "gant".
*/
 
gant::gant (const QString &af)
{
mydev = 0;
peerdev = 0;
myid = 0;
state = 0;
authfd = false;
 
faf.setName (af);
 
if (!faf.open (IO_Raw | IO_ReadWrite))
{
KMessageBox::error (0, i18n("Error opening device %1.").arg(af),
faf.errorString());
}
 
authfile = af;
authfd = true;
}
 
gant::~gant ()
{
if (authfd)
faf.close();
}
 
uint gant::randno ()
{
return (uint)random ();
}
 
bool gant::chevent (uchar chan, uchar event)
{
uchar seq;
uchar last;
uchar status = cbuf[1];
uchar phase = cbuf[2];
struct ack_msg ack;
struct auth_msg auth;
struct pair_msg pair;
uint id;
//int i;
 
//fprintf(stderr, "state %d\n", state);
/* if (dbg && event != EVENT_RX_BURST_PACKET) {
fprintf(stderr, "chan %d event %02x channel open: ", chan, event);
for (i = 0; i < 8; i++)
fprintf(stderr, "%02x", cbuf[i]);
fprintf(stderr, "\n");
}
*/
// transition between garmin phases handled via state machine
switch (event)
{
case EVENT_RX_BROADCAST:
memcpy((void *)&id, cbuf+4, 4);
 
if (state == 1 && (phase & 7) == 0)
{
// received broadcast from watch in phase 0
state++;
 
if ((status & 8) == 8)
{
// pairing
myid = randno();
fprintf(stderr, "pairing, generated id %08x\n", myid);
}
else
{
// garmin moved to phase 1 in response to sendack1
int nr;
// printf("reading auth data from %s\n", authfile);
authfd = open(authfile, O_RDONLY);
 
if (!authfd || faf.size () < 32)
{
KMessageBox::error(0, i18n("There is no authfile available or it has wrong size!"));
return false;
}
 
nr = read(faf.handle(), authdata, 32);
 
if (nr != 32)
{
KMessageBox::error(0, i18n ("Error reading auth file %1!").arg(authfile));
return false;
}
 
memcpy((void *)&myauth1, authdata+16, 4);
memcpy((void *)&myauth2, authdata+20, 4);
memcpy((void *)&mydev, authdata+12, 4);
memcpy((void *)&myid, authdata+4, 4);
}
 
if (status & 0x20)
fprintf(stderr, "watch contains NEW data\n");
 
ANT_RequestMessage(chan, MESG_CHANNEL_ID_ID); /* request sender id */
}
else if (state == 3 && phase == 1)
{
state++;
ack.code = 0x44;
ack.atype = 4;
ack.c1 = 0x01;
ack.c2 = 0x00;
ack.id = myid;
ANT_SendAcknowledgedData(chan, (uchar *)&ack); // tell garmin to send id data
}
else if (state == 5 && phase == 1)
{
if ((status & 0x0f) == 4)
{
// received id/version or whatever
state++;
assert(sizeof auth == AUTHSIZE);
auth.code = 0x44;
auth.atype = 4;
auth.phase = 3;
auth.u1 = 8;
auth.id = myid;
auth.auth1 = myauth1;
auth.auth2 = myauth2;
auth.fill1 = auth.fill2 = 0;
ANT_SendBurstTransfer(chan, (uchar *)&auth, (sizeof auth)/8); // send our auth data
}
else if ((status & 0x0f) == 0x0c)
{
// pairing
assert(sizeof pair == PAIRSIZE);
state = 10;
pair.code = 0x44;
pair.atype = 4;
pair.phase = 2;
pair.u1 = 7;
pair.id = myid;
bzero(pair.devname, sizeof pair.devname);
 
if (peerdev <= 99999999) // only allow 8 digits
sprintf(pair.devname, "%d", peerdev);
else
fprintf(stderr, "pair dev name too large %08x \"%d\"\n", peerdev, peerdev);
 
// printf("sending pair data for dev %s\n", pair.devname);
ANT_SendBurstTransfer(chan, (uchar *)&pair, (sizeof pair)/8) ; // send pair data
}
else
{
fprintf(stderr, "error in gant.cpp on line %d\n", __LINE__);
return false;
}
}
else if (state == 6 && (status & 0x0f) == 4 && phase == 2)
{
// if our auth is ok, garmin has gone to phase 2
state++;
ack.code = 0x44;
ack.atype = 6;
ack.c1 = 0x01;
ack.c2 = 0x00;
ack.id = 0;
ANT_SendAcknowledgedData(chan, (uchar *)&ack); // tell garmin to start upload
}
else if (state == 8 && phase == 2)
{
// upload finished. received broadcast that still in phase 2
state++;
ack.code = 0x44;
ack.atype = 3;
ack.c1 = 0x00;
ack.c2 = 0x00;
ack.id = 0;
ANT_SendAcknowledgedData(chan, (uchar *)&ack); // tell garmin we're finished
}
else if (state == 9 && phase == 0)
{
// garmin replies it's back in phase 0
fprintf(stderr, "finished\n");
return true;
}
else if (state == 1 && phase != 0)
{
// don't know what phase we're in. let's try and reset
fprintf(stderr, "resetting\n");
ack.code = 0x44;
ack.atype = 3;
ack.c1 = 0x00;
ack.c2 = 0x00;
ack.id = 0;
ANT_SendAcknowledgedData(chan, (uchar *)&ack); // tell garmin we're finished
sleep(1);
return false;
}
else if (state == 20 && phase == 2)
{
// upload finished. tell garmin to delete logs
state++;
ack.code = 0x44;
ack.atype = 0x0b;
ack.c1 = 0x01;
ack.c2 = 0x00;
ack.id = 0;
ANT_SendAcknowledgedData(chan, (uchar *)&ack); // delete logs
}
else if (state == 21 && phase == 2)
{
state = 8;
}
break;
 
case EVENT_RX_BURST_PACKET:
seq = (chan & 0x60) >> 5;
last = (chan & 0x80) >> 7;
chan &= 0x1f;
 
if (state == 4)
{
static int once = 0;
// garmin sending authentication/identification data
 
if (!once)
once = 1;
 
memcpy(clientid[seq], cbuf, 8);
 
if (last)
{
state++;
 
memcpy(&peerdev, clientid[1]+4, 4);
 
if (mydev != 0 && peerdev != mydev)
{
fprintf(stderr, "Don't know this device %08x != %08x\n", peerdev, mydev);
return false;
}
}
}
else if (state == 7)
{
static int once = 0;
int nw;
 
// garmin uploading in response to sendack3
// in this state we're receiving the workout data
if (!once)
{
fprintf(stderr, "receiving\n");
once = 1;
}
 
nw = write(faf.handle(), cbuf, 8);
 
if (nw != 8)
{
KMessageBox::error(0, i18n ("Write to auth file %1 failed!").arg(authfile));
return false;
}
 
if (last)
{
state++; // just to exit
//state = 20; // to delete logs
}
}
else if (state == 10)
{
// receiving auth data
static int once = 0;
int nw;
 
if (!once)
{
// printf("storing auth data in %s\n", authfile);
once = 1;
// authfd = open(authfile, O_WRONLY|O_CREAT, 0644);
 
/* if (authfd < 0)
{
perror(authfile);
exit(1);
} */
}
 
nw = write(faf.handle(), cbuf, 8);
 
if (nw != 8)
{
KMessageBox::error(0, i18n ("Write to auth file %1 failed!").arg(authfile));
return false;
}
 
if (last)
{
//state = 6; // to download during pairing
state = 8; // to finish at end of pairing
}
}
else if (state == 6)
{
// response to authentication
static int once = 0;
// int i;
 
if (!once)
{
once = 1;
}
 
if (last)
{
if (cbuf[2] == 2)
{
fprintf(stderr, "authentication failed\n");
return false;
}
}
}
else
{
int i;
 
fprintf(stderr, "data in state %d: ", state);
 
for (i = 0; i < 8; i++)
fprintf(stderr, "%02x", cbuf[i]);
 
fprintf(stderr, "\n");
}
break;
}
 
return 1;
}
 
bool gant::revent (uchar chan, uchar event)
{
unsigned short devid;
struct ack_msg ack;
int i;
 
switch (event)
{
case EVENT_TRANSFER_TX_COMPLETED:
// ignore
// printf("Transfer complete %02x\n", ebuf[1]);
break;
 
case INVALID_MESSAGE:
fprintf(stderr, "Invalid message %02x\n", ebuf[1]);
break;
 
case RESPONSE_NO_ERROR:
switch (ebuf[1])
{
case MESG_ASSIGN_CHANNEL_ID:
ANT_AssignChannelEventFunction((uchar)chan, (CHANNEL_EVENT_FUNC)&gant::chevent, (uchar *)&cbuf);
break;
 
case MESG_OPEN_CHANNEL_ID:
state++;
fprintf(stderr, "channel open, waiting for broadcast\n", state);
break;
 
default:
// ignore
// printf("Message %02x NO_ERROR\n", ebuf[1]);
break;
}
break;
 
case MESG_CHANNEL_ID_ID:
devid = ebuf[1]+ebuf[2]*256;
 
if (mydev == 0 || devid == mydev%65536)
{
state++;
ack.code = 0x44; ack.atype = 2; ack.c1 = 0x32; ack.c2 = 0x04;
ack.id = myid;
ANT_SendAcknowledgedData(chan, (uchar *)&ack); // tell watch go to phase 1
}
else
{
fprintf(stderr, "Ignoring unknown device %08x, mydev %08x\n", devid, mydev);
}
break;
 
case MESG_NETWORK_KEY_ID:
case MESG_SEARCH_WAVEFORM_ID:
case MESG_OPEN_CHANNEL_ID:
fprintf(stderr, "response event %02x code %02x\n", event, ebuf[2]);
 
for (i = 0; i < 8; i++)
fprintf(stderr, "%02x", ebuf[i]);
 
fprintf(stderr, "\n");
break;
 
case MESG_CAPABILITIES_ID:
break;
 
case MESG_CHANNEL_STATUS_ID:
break;
 
default:
fprintf(stderr, "Unhandled response event %02x\n", event);
break;
}
 
return true;
}
 
bool gant::read_device ()
{
//int devnum = 0;
int chan = 0;
int net = 0;
int chtype = 0; // wildcard
int devno = 0; // wildcard
int devtype = 0; // wildcard
int manid = 0; // wildcard
int freq = 0x32; // garmin specific radio frequency
int period = 0x1000; // garmin specific broadcast period
int srchto = 255; // max timeout
int waveform = 0x0053; // aids search somehow
 
// Check if we already have a device set.
// if (!qFile)
// return false;
 
// TODO: Do this properly...
/* if (ac > 1) {
authfile = av[1];
}
else {
fprintf(stderr, "need auth file\n");
exit(1);
}
if (ac > 2)
fn = av[2]; // store the output filename for event function
if (ac > 3)
devnum = atoi(av[3]);
if (ac > 4)
myid = atoi(av[4]);
if (ac > 5)
mydev = atoi(av[5]);
*/
if (!ANT_Init())
return false;
 
if (!ANT_ResetSystem())
return false;
 
ANT_AssignResponseFunction((RESPONSE_FUNC)&gant::revent, (uchar *)&ebuf);
 
if (!ANT_RequestMessage(chan, MESG_CHANNEL_STATUS_ID)) //informative
return false;
 
if (!ANT_SetNetworkKeya(net, (uchar *)G50_KEY))
return false;
 
if (!ANT_AssignChannel(chan, chtype, net))
return false;
 
if (!ANT_SetChannelId(chan, devno, devtype, manid))
return false;
 
if (!ANT_RequestMessage(chan, MESG_CAPABILITIES_ID)) //informative
return false;
 
if (!ANT_SetChannelRFFreq(chan, freq))
return false;
 
if (!ANT_SetChannelPeriod(chan, period))
return false;
 
if (!ANT_SetChannelSearchTimeout(chan, srchto))
return false;
 
if (!ANT_SetSearchWaveform(chan, waveform))
return false;
 
if (!ANT_OpenChannel(chan)) // success for this bumps us to state 1
return false;
 
if (!ANT_RequestMessage(chan, MESG_CHANNEL_STATUS_ID)) //informative
return false;
 
// everything handled in event functions
// for(;;)
// sleep(10);
 
return commfn ();
}