[Pkg-running-devel] [antpm] 16/48: gant: untabify, reindent
Kristof Ralovich
ralovich-guest at moszumanska.debian.org
Mon Aug 11 10:10:32 UTC 2014
This is an automated email from the git hooks/post-receive script.
ralovich-guest pushed a commit to branch upstream
in repository antpm.
commit df82e37fb8e82c1df371b1e76ce66530aa515dd2
Author: RALOVICH, Kristof <tade60 at freemail.hu>
Date: Wed Mar 26 12:28:38 2014 +0100
gant: untabify, reindent
---
src/gant/antdefs.h | 78 +-
src/gant/antlib.c | 866 +++++++++---------
src/gant/gant.c | 2458 ++++++++++++++++++++++++++--------------------------
3 files changed, 1701 insertions(+), 1701 deletions(-)
diff --git a/src/gant/antdefs.h b/src/gant/antdefs.h
index 23cb824..f204b10 100644
--- a/src/gant/antdefs.h
+++ b/src/gant/antdefs.h
@@ -10,45 +10,45 @@ typedef unsigned long ulong;
typedef uchar (*RESPONSE_FUNC)(uchar chan, uchar msgid);
typedef uchar (*CHANNEL_EVENT_FUNC)(uchar chan, uchar event);
-#define RESPONSE_NO_ERROR 0x00
-#define EVENT_RX_SEARCH_TIMEOUT 0x01
-#define EVENT_RX_FAIL 0x02
-#define EVENT_TRANSFER_RX_FAILED 0x04
-#define EVENT_TRANSFER_TX_COMPLETED 0x05
-#define EVENT_TRANSFER_TX_FAILED 0x06
-#define INVALID_MESSAGE 0x28
-#define MESG_RESPONSE_EVENT_ID 0x40
-#define MESG_UNASSIGN_CHANNEL_ID 0x41
-#define MESG_ASSIGN_CHANNEL_ID 0x42
-#define MESG_CHANNEL_MESG_PERIOD_ID 0x43
-#define MESG_CHANNEL_SEARCH_TIMEOUT_ID 0x44
-#define MESG_CHANNEL_RADIO_FREQ_ID 0x45
-#define MESG_NETWORK_KEY_ID 0x46
-#define MESG_SEARCH_WAVEFORM_ID 0x49
-#define MESG_SYSTEM_RESET_ID 0x4a
-#define MESG_OPEN_CHANNEL_ID 0x4b
-#define MESG_CLOSE_CHANNEL_ID 0x4c
-#define MESG_REQUEST_ID 0x4d
-#define MESG_BROADCAST_DATA_ID 0x4e
-#define MESG_ACKNOWLEDGED_DATA_ID 0x4f
-#define MESG_BURST_DATA_ID 0x50
-#define MESG_CHANNEL_ID_ID 0x51
-#define MESG_CHANNEL_STATUS_ID 0x52
-#define MESG_CAPABILITIES_ID 0x54
-#define MESG_OPEN_RX_SCAN_ID 0x5b
-#define MESG_EXT_BROADCAST_DATA_ID 0x5d
-#define MESG_EXT_ACKNOWLEDGED_DATA_ID 0x5e
-#define MESG_EXT_BURST_DATA_ID 0x5f
-#define EVENT_RX_BROADCAST 0x9a
-#define EVENT_RX_ACKNOWLEDGED 0x9b
-#define EVENT_RX_BURST_PACKET 0x9c
-#define EVENT_RX_EXT_BROADCAST 0x9d
-#define EVENT_RX_EXT_ACKNOWLEDGED 0x9e
-#define EVENT_RX_EXT_BURST_PACKET 0x9f
-#define MESG_TX_SYNC 0xa4
-#define EVENT_RX_FAKE_BURST 0xdd
-#define MESG_RESPONSE_EVENT_SIZE 3
-#define MESG_DATA_SIZE 30
+#define RESPONSE_NO_ERROR 0x00
+#define EVENT_RX_SEARCH_TIMEOUT 0x01
+#define EVENT_RX_FAIL 0x02
+#define EVENT_TRANSFER_RX_FAILED 0x04
+#define EVENT_TRANSFER_TX_COMPLETED 0x05
+#define EVENT_TRANSFER_TX_FAILED 0x06
+#define INVALID_MESSAGE 0x28
+#define MESG_RESPONSE_EVENT_ID 0x40
+#define MESG_UNASSIGN_CHANNEL_ID 0x41
+#define MESG_ASSIGN_CHANNEL_ID 0x42
+#define MESG_CHANNEL_MESG_PERIOD_ID 0x43
+#define MESG_CHANNEL_SEARCH_TIMEOUT_ID 0x44
+#define MESG_CHANNEL_RADIO_FREQ_ID 0x45
+#define MESG_NETWORK_KEY_ID 0x46
+#define MESG_SEARCH_WAVEFORM_ID 0x49
+#define MESG_SYSTEM_RESET_ID 0x4a
+#define MESG_OPEN_CHANNEL_ID 0x4b
+#define MESG_CLOSE_CHANNEL_ID 0x4c
+#define MESG_REQUEST_ID 0x4d
+#define MESG_BROADCAST_DATA_ID 0x4e
+#define MESG_ACKNOWLEDGED_DATA_ID 0x4f
+#define MESG_BURST_DATA_ID 0x50
+#define MESG_CHANNEL_ID_ID 0x51
+#define MESG_CHANNEL_STATUS_ID 0x52
+#define MESG_CAPABILITIES_ID 0x54
+#define MESG_OPEN_RX_SCAN_ID 0x5b
+#define MESG_EXT_BROADCAST_DATA_ID 0x5d
+#define MESG_EXT_ACKNOWLEDGED_DATA_ID 0x5e
+#define MESG_EXT_BURST_DATA_ID 0x5f
+#define EVENT_RX_BROADCAST 0x9a
+#define EVENT_RX_ACKNOWLEDGED 0x9b
+#define EVENT_RX_BURST_PACKET 0x9c
+#define EVENT_RX_EXT_BROADCAST 0x9d
+#define EVENT_RX_EXT_ACKNOWLEDGED 0x9e
+#define EVENT_RX_EXT_BURST_PACKET 0x9f
+#define MESG_TX_SYNC 0xa4
+#define EVENT_RX_FAKE_BURST 0xdd
+#define MESG_RESPONSE_EVENT_SIZE 3
+#define MESG_DATA_SIZE 30
#endif
/* vim: se sw=8 ts=8: */
diff --git a/src/gant/antlib.c b/src/gant/antlib.c
index 2671093..8fdcd8f 100644
--- a/src/gant/antlib.c
+++ b/src/gant/antlib.c
@@ -42,591 +42,591 @@ static uchar *blast;
static int blsize;
struct msg_queue {
- uchar msgid;
- uchar len;
+ uchar msgid;
+ uchar len;
};
/* send message over serial port */
uchar
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(fd, buf, 4+i))) {
- if (dbg) {
- perror("failed write");
- }
- } else if (dbg == 2) {
- /* Wali: additional raw data output */
- printf(">>>\n 00000000:");
- for (i = 0; i < (len + 4); i++) {
- printf(" %02x", buf[i]);
- }
- putchar('\n');
- }
- return 1;
+ 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(fd, buf, 4+i))) {
+ if (dbg) {
+ perror("failed write");
+ }
+ } else if (dbg == 2) {
+ /* Wali: additional raw data output */
+ printf(">>>\n 00000000:");
+ for (i = 0; i < (len + 4); i++) {
+ printf(" %02x", buf[i]);
+ }
+ putchar('\n');
+ }
+ return 1;
}
/* two argument send */
uchar
msg_send2(uchar mesg, uchar data1, uchar data2)
{
- uchar buf[2];
- buf[0] = data1;
- buf[1] = data2;
- return msg_send(mesg, buf, 2);
+ uchar buf[2];
+ buf[0] = data1;
+ buf[1] = data2;
+ return msg_send(mesg, buf, 2);
}
/* three argument send */
uchar
msg_send3(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);
+ uchar buf[3];
+ buf[0] = data1;
+ buf[1] = data2;
+ buf[2] = data3;
+ return msg_send(mesg, buf, 3);
}
void 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;
- if (bufc > 30) {
- if (dbg)
- fprintf(stderr, "bufc %d\n", bufc);
- }
- if (bufc > 300) {
- fprintf(stderr, "buf too long %d\n", bufc);
- for (j = 0; j < bufc; j++)
- fprintf(stderr, "%02x", buf[j]);
- fprintf(stderr, "\n");
- exit(1);
- } else if (dbg == 2) {
- /* Wali: additional raw data output */
- printf("<<<\n 00000000:");
- for (i = 0; i < bufc; i++) {
- printf(" %02x", buf[i]);
- }
- putchar('\n');
- }
- /* some data in buf */
- /* search for possible valid messages */
+ 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;
+ if (bufc > 30) {
+ if (dbg)
+ fprintf(stderr, "bufc %d\n", bufc);
+ }
+ if (bufc > 300) {
+ fprintf(stderr, "buf too long %d\n", bufc);
+ for (j = 0; j < bufc; j++)
+ fprintf(stderr, "%02x", buf[j]);
+ fprintf(stderr, "\n");
+ exit(1);
+ } else if (dbg == 2) {
+ /* Wali: additional raw data output */
+ printf("<<<\n 00000000:");
+ for (i = 0; i < bufc; i++) {
+ printf(" %02x", buf[i]);
+ }
+ putchar('\n');
+ }
+ /* some data in buf */
+ /* search for possible valid messages */
srch = 0;
- while (srch < bufc) {
- found = 0;
- /* printf("srch %d bufc %d\n", srch, bufc); */
- for (i = srch; i < bufc; i++) {
- if (buf[i] == MESG_TX_SYNC) {
- /* fprintf(stderr, "bufc %d sync %d\n", bufc, i); */
- 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);
- for (j = i; j <= i+3+dlen; j++)
- fprintf(stderr, "%02x", buf[j]);
- fprintf(stderr, "\n");
- }
- }
- }
- }
- }
- if (found) {
- next = j;
- /* printf("next %d %02x\n", next, buf[j-1]); */
- /* got a valid message, see if any data needs to be discarded */
- if (i > srch) {
- fprintf(stderr, "\nDiscarding: ");
- for (j = 0; j < i; j++)
- fprintf(stderr, "%02x", buf[j]);
- fprintf(stderr, "\n");
- }
-
- if (dbg) {
- fprintf(stderr, "data: ");
- for(j = i; j < i+dlen+4; j++) {
- fprintf(stderr, "%02x", buf[j]);
- }
- fprintf(stderr, "\n");
- }
- event = 0;
- switch (buf[i+2]) {
- case MESG_RESPONSE_EVENT_ID:
- /* if (cfn) { */
- /* memcpy(cbufp, buf+i+4, dlen); */
- /* (*cfn)(buf[i+3], buf[i+5]); */
- /* else */
- if (rfn) {
- memcpy(rbufp, buf+i+3, dlen);
- (*rfn)(buf[i+3], buf[i+5]);
- } else {
- if (dbg)
- fprintf(stderr, "no rfn or cfn\n");
- }
- 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;
- /* coalesce these and generate a fake event on last packet */
- /* in case client wishes to ignore these events and capture the fake one */
- {
- static uchar *burstbuf[MAXCHAN];
- static int bused[MAXCHAN];
- static int lseq[MAXCHAN];
- int k;
-
- uchar seq;
- uchar last;
- uchar chan = *(buf+i+3);
- if (dbg) {
- fprintf(stderr, "burst %02x ", chan);
- for (k = 0; k < 12; k++)
- fprintf(stderr, "%02x", buf[i+k]);
- fprintf(stderr, "\n");
- }
- seq = (chan & 0x60) >> 5;
- last = (chan & 0x80) >> 7;
- chan &= 0x1f;
- if (dbg) fprintf(stderr, "ch %x seq %d last %d\n", chan, seq, last);
- if (!burstbuf[chan]) {
- if (seq != 0)
- fprintf(stderr, "out of sequence ch# %d %d\n", chan, seq);
- else {
+ while (srch < bufc) {
+ found = 0;
+ /* printf("srch %d bufc %d\n", srch, bufc); */
+ for (i = srch; i < bufc; i++) {
+ if (buf[i] == MESG_TX_SYNC) {
+ /* fprintf(stderr, "bufc %d sync %d\n", bufc, i); */
+ 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);
+ for (j = i; j <= i+3+dlen; j++)
+ fprintf(stderr, "%02x", buf[j]);
+ fprintf(stderr, "\n");
+ }
+ }
+ }
+ }
+ }
+ if (found) {
+ next = j;
+ /* printf("next %d %02x\n", next, buf[j-1]); */
+ /* got a valid message, see if any data needs to be discarded */
+ if (i > srch) {
+ fprintf(stderr, "\nDiscarding: ");
+ for (j = 0; j < i; j++)
+ fprintf(stderr, "%02x", buf[j]);
+ fprintf(stderr, "\n");
+ }
+
+ if (dbg) {
+ fprintf(stderr, "data: ");
+ for(j = i; j < i+dlen+4; j++) {
+ fprintf(stderr, "%02x", buf[j]);
+ }
+ fprintf(stderr, "\n");
+ }
+ event = 0;
+ switch (buf[i+2]) {
+ case MESG_RESPONSE_EVENT_ID:
+ /* if (cfn) { */
+ /* memcpy(cbufp, buf+i+4, dlen); */
+ /* (*cfn)(buf[i+3], buf[i+5]); */
+ /* else */
+ if (rfn) {
+ memcpy(rbufp, buf+i+3, dlen);
+ (*rfn)(buf[i+3], buf[i+5]);
+ } else {
+ if (dbg)
+ fprintf(stderr, "no rfn or cfn\n");
+ }
+ 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;
+ /* coalesce these and generate a fake event on last packet */
+ /* in case client wishes to ignore these events and capture the fake one */
+ {
+ static uchar *burstbuf[MAXCHAN];
+ static int bused[MAXCHAN];
+ static int lseq[MAXCHAN];
+ int k;
+
+ uchar seq;
+ uchar last;
+ uchar chan = *(buf+i+3);
+ if (dbg) {
+ fprintf(stderr, "burst %02x ", chan);
+ for (k = 0; k < 12; k++)
+ fprintf(stderr, "%02x", buf[i+k]);
+ fprintf(stderr, "\n");
+ }
+ seq = (chan & 0x60) >> 5;
+ last = (chan & 0x80) >> 7;
+ chan &= 0x1f;
+ if (dbg) fprintf(stderr, "ch %x seq %d last %d\n", chan, seq, last);
+ if (!burstbuf[chan]) {
+ if (seq != 0)
+ fprintf(stderr, "out of sequence ch# %d %d\n", chan, seq);
+ else {
+ burstbuf[chan] = (unsigned char*)malloc(BSIZE);
+ bzero(burstbuf[chan], BSIZE);
+ memcpy(burstbuf[chan], buf+i+4, 8);
+ bused[chan] = 8;
+ lseq[chan] = seq;
+ if (dbg)
+ fprintf(stderr, "init ch# %d %d\n", chan, lseq[chan]);
+ }
+ } else {
+ if (lseq[chan]+1 != seq) {
+ fprintf(stderr, "out of sequence ch# %d %d l %d\n", chan, seq, lseq[chan]);
+ free(burstbuf[chan]);
+ burstbuf[chan] = 0;
+ if (seq == 0) {
burstbuf[chan] = (unsigned char*)malloc(BSIZE);
- bzero(burstbuf[chan], BSIZE);
- memcpy(burstbuf[chan], buf+i+4, 8);
- bused[chan] = 8;
- lseq[chan] = seq;
- if (dbg)
- fprintf(stderr, "init ch# %d %d\n", chan, lseq[chan]);
- }
- } else {
- if (lseq[chan]+1 != seq) {
- fprintf(stderr, "out of sequence ch# %d %d l %d\n", chan, seq, lseq[chan]);
- free(burstbuf[chan]);
- burstbuf[chan] = 0;
- if (seq == 0) {
- burstbuf[chan] = (unsigned char*)malloc(BSIZE);
- bzero(burstbuf[chan], BSIZE);
- memcpy(burstbuf[chan], buf+i+4, 8);
- bused[chan] = 8;
- lseq[chan] = seq;
- fprintf(stderr, "reinit ch# %d %d\n", chan, lseq[chan]);
- }
- } else {
- if ((bused[chan] % BSIZE) == 0) {
- burstbuf[chan] = (unsigned char*)realloc(burstbuf[chan], bused[chan]+BSIZE);
- bzero(burstbuf[chan]+bused[chan], BSIZE);
- }
- memcpy(burstbuf[chan]+bused[chan], buf+i+4, 8);
- bused[chan] += 8;
- if (dbg) fprintf(stderr, "seq0 %d lseq %d\n", seq, lseq[chan]);
- if (seq == 3)
- lseq[chan] = 0;
- else
- lseq[chan] = seq;
- if (dbg) fprintf(stderr, "seq1 %d lseq %d\n", seq, lseq[chan]);
- }
- }
- if (burstbuf[chan] && last) {
- blast = burstbuf[chan];
- blsize = bused[chan];
- if (dbg) fprintf(stderr, "BU %d %lx\n", blsize, (long)blast);
- if (dbg) {
- fprintf(stderr, "bused ch# %d %d\n", chan, bused[chan]);
- for (k = 0; k < bused[chan]; k++)
- fprintf(stderr, "%02x", burstbuf[chan][k]);
- fprintf(stderr, "\n");
- }
- bused[chan] = 0;
- burstbuf[chan] = 0;
- }
- }
- 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_RESPONSE_EVENT_SIZE) { */
- if (dlen > MESG_DATA_SIZE) {
- fprintf(stderr, "cresponse buffer too small %d > %d\n", dlen, MESG_DATA_SIZE);
- for (j = 0; j < dlen; j++)
- fprintf(stderr, "%02x", *(buf+i+3+j));
- fprintf(stderr, "\n");
- exit(1);
- }
- memcpy(rbufp, buf+i+3, dlen);
- (*rfn)(buf[i+3], buf[i+2]);
- } else {
- if (dbg)
- fprintf(stderr, "no rfn\n");
- }
- }
- if (event) {
- uchar chan = *(buf+3) & 0x1f;
- if (cfn) {
- if (dlen > MESG_DATA_SIZE) {
- fprintf(stderr, "rresponse buffer too small %d > %d\n",
- dlen, MESG_DATA_SIZE);
- for (j = 0; j < dlen+1; j++)
- fprintf(stderr, "%02x", *(buf+i+4+j));
- fprintf(stderr, "\n");
- exit(1);
- }
- memcpy(cbufp, buf+i+4, dlen);
- if (dbg) {
- fprintf(stderr, "xch0#%d %d %lx\n", chan, blsize, (long)blast);
- for (j = 0; j < blsize; j++)
- fprintf(stderr, "%02x", *(blast+j));
- fprintf(stderr, "\n");
- }
- (*cfn)(chan, event);
- if (dbg) {
- fprintf(stderr, "xch1#%d %d %lx\n", chan, blsize, (long)blast);
- for (j = 0; j < blsize; j++)
- fprintf(stderr, "%02x", *(blast+j));
- fprintf(stderr, "\n");
- }
- /* FAKE BURST message */
- if (event == EVENT_RX_BURST_PACKET && blast && blsize) {
- if (dbg) {
- fprintf(stderr, "Fake burst ch#%d %d %lx\n", chan, blsize, (long)blast);
- for (j = 0; j < blsize; j++)
- fprintf(stderr, "%02x", *(blast+j));
- fprintf(stderr, "\n");
- }
- *(int *)(cbufp+4) = blsize;
- memcpy(cbufp+8, &blast, 4);
- (*cfn)(chan, EVENT_RX_FAKE_BURST);
- free(blast);
- blast = 0;
- blsize = 0;
- }
- } else
- if (dbg)
- fprintf(stderr, "no cfn\n");
- }
- srch = next;
- } else
- break;
- }
- if (next < bufc) {
- memmove(buf, buf+next, bufc-next);
- bufc -= next;
- } else
- bufc = 0;
+ bzero(burstbuf[chan], BSIZE);
+ memcpy(burstbuf[chan], buf+i+4, 8);
+ bused[chan] = 8;
+ lseq[chan] = seq;
+ fprintf(stderr, "reinit ch# %d %d\n", chan, lseq[chan]);
+ }
+ } else {
+ if ((bused[chan] % BSIZE) == 0) {
+ burstbuf[chan] = (unsigned char*)realloc(burstbuf[chan], bused[chan]+BSIZE);
+ bzero(burstbuf[chan]+bused[chan], BSIZE);
+ }
+ memcpy(burstbuf[chan]+bused[chan], buf+i+4, 8);
+ bused[chan] += 8;
+ if (dbg) fprintf(stderr, "seq0 %d lseq %d\n", seq, lseq[chan]);
+ if (seq == 3)
+ lseq[chan] = 0;
+ else
+ lseq[chan] = seq;
+ if (dbg) fprintf(stderr, "seq1 %d lseq %d\n", seq, lseq[chan]);
+ }
+ }
+ if (burstbuf[chan] && last) {
+ blast = burstbuf[chan];
+ blsize = bused[chan];
+ if (dbg) fprintf(stderr, "BU %d %lx\n", blsize, (long)blast);
+ if (dbg) {
+ fprintf(stderr, "bused ch# %d %d\n", chan, bused[chan]);
+ for (k = 0; k < bused[chan]; k++)
+ fprintf(stderr, "%02x", burstbuf[chan][k]);
+ fprintf(stderr, "\n");
+ }
+ bused[chan] = 0;
+ burstbuf[chan] = 0;
+ }
+ }
+ 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_RESPONSE_EVENT_SIZE) { */
+ if (dlen > MESG_DATA_SIZE) {
+ fprintf(stderr, "cresponse buffer too small %d > %d\n", dlen, MESG_DATA_SIZE);
+ for (j = 0; j < dlen; j++)
+ fprintf(stderr, "%02x", *(buf+i+3+j));
+ fprintf(stderr, "\n");
+ exit(1);
+ }
+ memcpy(rbufp, buf+i+3, dlen);
+ (*rfn)(buf[i+3], buf[i+2]);
+ } else {
+ if (dbg)
+ fprintf(stderr, "no rfn\n");
+ }
+ }
+ if (event) {
+ uchar chan = *(buf+3) & 0x1f;
+ if (cfn) {
+ if (dlen > MESG_DATA_SIZE) {
+ fprintf(stderr, "rresponse buffer too small %d > %d\n",
+ dlen, MESG_DATA_SIZE);
+ for (j = 0; j < dlen+1; j++)
+ fprintf(stderr, "%02x", *(buf+i+4+j));
+ fprintf(stderr, "\n");
+ exit(1);
+ }
+ memcpy(cbufp, buf+i+4, dlen);
+ if (dbg) {
+ fprintf(stderr, "xch0#%d %d %lx\n", chan, blsize, (long)blast);
+ for (j = 0; j < blsize; j++)
+ fprintf(stderr, "%02x", *(blast+j));
+ fprintf(stderr, "\n");
+ }
+ (*cfn)(chan, event);
+ if (dbg) {
+ fprintf(stderr, "xch1#%d %d %lx\n", chan, blsize, (long)blast);
+ for (j = 0; j < blsize; j++)
+ fprintf(stderr, "%02x", *(blast+j));
+ fprintf(stderr, "\n");
+ }
+ /* FAKE BURST message */
+ if (event == EVENT_RX_BURST_PACKET && blast && blsize) {
+ if (dbg) {
+ fprintf(stderr, "Fake burst ch#%d %d %lx\n", chan, blsize, (long)blast);
+ for (j = 0; j < blsize; j++)
+ fprintf(stderr, "%02x", *(blast+j));
+ fprintf(stderr, "\n");
+ }
+ *(int *)(cbufp+4) = blsize;
+ memcpy(cbufp+8, &blast, 4);
+ (*cfn)(chan, EVENT_RX_FAKE_BURST);
+ free(blast);
+ blast = 0;
+ blsize = 0;
+ }
+ } else
+ if (dbg)
+ fprintf(stderr, "no cfn\n");
+ }
+ srch = next;
+ } else
+ break;
+ }
+ if (next < bufc) {
+ memmove(buf, buf+next, bufc-next);
+ bufc -= next;
+ } else
+ bufc = 0;
}
void *commfn(void* arg)
{
- fd_set readfds, writefds, exceptfds;
- int ready;
- struct timeval to;
+ fd_set readfds, writefds, exceptfds;
+ int ready;
+ struct timeval to;
(void)arg;
- 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) {
- get_data(fd);
- }
- }
+ 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) {
+ get_data(fd);
+ }
+ }
}
uchar
ANT_ResetSystem(void)
{
- uchar filler = 0;
- return msg_send(MESG_SYSTEM_RESET_ID, &filler, 1);
+ uchar filler = 0;
+ return msg_send(MESG_SYSTEM_RESET_ID, &filler, 1);
}
uchar
ANT_Cmd55(uchar chan)
{
- return msg_send(0x55, &chan, 1);
+ return msg_send(0x55, &chan, 1);
}
uchar
ANT_OpenRxScanMode(uchar chan)
{
- return msg_send(MESG_OPEN_RX_SCAN_ID, &chan, 1);
+ return msg_send(MESG_OPEN_RX_SCAN_ID, &chan, 1);
}
uchar
ANT_Initf(const char *devname)
{
- struct termios tp;
-
- fd = open(devname, O_RDWR);
- if (fd < 0) {
- perror(devname);
- return 0;
- }
-
- S(tcgetattr(fd, &tp));
- 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;
-
- S(cfsetispeed(&tp, B115200));
- S(cfsetospeed(&tp, B115200));
- tp.c_cc[VMIN] = 1;
- tp.c_cc[VTIME] = 0;
- S(tcsetattr(fd, TCSANOW, &tp));
-
- S(pthread_create(&commthread, 0, commfn, 0));
- return 1;
+ struct termios tp;
+
+ fd = open(devname, O_RDWR);
+ if (fd < 0) {
+ perror(devname);
+ return 0;
+ }
+
+ S(tcgetattr(fd, &tp));
+ 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;
+
+ S(cfsetispeed(&tp, B115200));
+ S(cfsetospeed(&tp, B115200));
+ tp.c_cc[VMIN] = 1;
+ tp.c_cc[VTIME] = 0;
+ S(tcsetattr(fd, TCSANOW, &tp));
+
+ S(pthread_create(&commthread, 0, commfn, 0));
+ return 1;
}
uchar
ANT_Init(uchar devno)
{
- char dev[40];
+ char dev[40];
- sprintf(dev, "/dev/ttyUSB%d", devno);
- return ANT_Initf(dev);
+ sprintf(dev, "/dev/ttyUSB%d", devno);
+ return ANT_Initf(dev);
}
uchar
ANT_RequestMessage(uchar chan, uchar mesg)
{
- return msg_send2(MESG_REQUEST_ID, chan, mesg);
+ return msg_send2(MESG_REQUEST_ID, chan, mesg);
}
uchar
ANT_SetNetworkKeya(uchar net, const 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);
+ 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);
}
uchar
ANT_SetNetworkKey(uchar net, const uchar *key)
{
- uchar buf[9];
+ uchar buf[9];
- buf[0] = net;
- memcpy(buf+1, key, 8);
- return msg_send(MESG_NETWORK_KEY_ID, buf, 9);
+ buf[0] = net;
+ memcpy(buf+1, key, 8);
+ return msg_send(MESG_NETWORK_KEY_ID, buf, 9);
}
uchar
ANT_AssignChannel(uchar chan, uchar chtype, uchar net)
{
- return msg_send3(MESG_ASSIGN_CHANNEL_ID, chan, chtype, net);
+ return msg_send3(MESG_ASSIGN_CHANNEL_ID, chan, chtype, net);
}
uchar
ANT_UnAssignChannel(uchar chan)
{
- return msg_send(MESG_UNASSIGN_CHANNEL_ID, &chan, 1);
+ return msg_send(MESG_UNASSIGN_CHANNEL_ID, &chan, 1);
}
uchar
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);
+ 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);
}
uchar
ANT_SetChannelRFFreq(uchar chan, uchar freq)
{
- return msg_send2(MESG_CHANNEL_RADIO_FREQ_ID, chan, freq);
+ return msg_send2(MESG_CHANNEL_RADIO_FREQ_ID, chan, freq);
}
uchar
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);
+ uchar buf[3];
+ buf[0] = chan;
+ buf[1] = period%256;
+ buf[2] = period/256;
+ return msg_send(MESG_CHANNEL_MESG_PERIOD_ID, buf, 3);
}
uchar
ANT_SetChannelSearchTimeout(uchar chan, uchar timeout)
{
- return msg_send2(MESG_CHANNEL_SEARCH_TIMEOUT_ID, chan, timeout);
+ return msg_send2(MESG_CHANNEL_SEARCH_TIMEOUT_ID, chan, timeout);
}
uchar
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);
+ uchar buf[3];
+ buf[0] = chan;
+ buf[1] = waveform%256;
+ buf[2] = waveform/256;
+ return msg_send(MESG_SEARCH_WAVEFORM_ID, buf, 3);
}
uchar
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 0;
- }
- 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);
+ uchar buf[9];
+ int i;
+
+ if (strlen((char*)data) != 16) {
+ fprintf(stderr, "Bad data length %s\n", data);
+ return 0;
+ }
+ 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);
}
uchar
ANT_SendAcknowledgedData(uchar chan, uchar *data)
{
- uchar buf[9];
+ uchar buf[9];
- buf[0] = chan;
- memcpy(buf+1, data, 8);
- return msg_send(MESG_ACKNOWLEDGED_DATA_ID, buf, 9);
+ buf[0] = chan;
+ memcpy(buf+1, data, 8);
+ return msg_send(MESG_ACKNOWLEDGED_DATA_ID, buf, 9);
}
ushort
ANT_SendBurstTransferA(uchar chan, uchar *data, ushort numpkts)
{
- uchar buf[9];
- int i;
- int j;
- int seq = 0;
-
- if (dbg) 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;
+ uchar buf[9];
+ int i;
+ int j;
+ int seq = 0;
+
+ if (dbg) 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;
}
ushort
ANT_SendBurstTransfer(uchar chan, uchar *data, ushort numpkts)
{
- uchar buf[9];
- 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;
+ uchar buf[9];
+ 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;
}
uchar
ANT_OpenChannel(uchar chan)
{
- return msg_send(MESG_OPEN_CHANNEL_ID, &chan, 1);
+ return msg_send(MESG_OPEN_CHANNEL_ID, &chan, 1);
}
uchar
ANT_CloseChannel(uchar chan)
{
- return msg_send(MESG_CLOSE_CHANNEL_ID, &chan, 1);
+ return msg_send(MESG_CLOSE_CHANNEL_ID, &chan, 1);
}
void
ANT_AssignResponseFunction(RESPONSE_FUNC rf, uchar* rbuf)
{
- rfn = rf;
- rbufp = rbuf;
+ rfn = rf;
+ rbufp = rbuf;
}
void
ANT_AssignChannelEventFunction(uchar chan, CHANNEL_EVENT_FUNC rf, uchar* rbuf)
{
- (void)chan;
- cfn = rf;
- cbufp = rbuf;
+ (void)chan;
+ cfn = rf;
+ cbufp = rbuf;
}
int ANT_fd()
{
- return fd;
+ return fd;
}
/* vim: se ts=2 sw=2: */
diff --git a/src/gant/gant.c b/src/gant/gant.c
index dd0ef99..044f80c 100644
--- a/src/gant/gant.c
+++ b/src/gant/gant.c
@@ -29,34 +29,34 @@
#define XML_ERROR_CHECK {if (rc < 0){ERROR_OUT("Error in XML creation"); exit(-1);}}
typedef enum {
- XML_OUTSIDE,
- XML_IN_TrainingCenterDatabase,
- XML_IN_Activities,
- XML_IN_Activity,
- XML_IN_Lap,
- XML_IN_Track,
- XML_IN_Trackpoint
+ XML_OUTSIDE,
+ XML_IN_TrainingCenterDatabase,
+ XML_IN_Activities,
+ XML_IN_Activity,
+ XML_IN_Lap,
+ XML_IN_Track,
+ XML_IN_Trackpoint
} xml_pos;
struct _activity {
- unsigned short valid;
- unsigned short first_lap;
- unsigned short last_lap;
- unsigned short sport;
+ unsigned short valid;
+ unsigned short first_lap;
+ unsigned short last_lap;
+ unsigned short sport;
};
struct _lap {
- unsigned short valid;
- time_t timestamp;
- unsigned long duration;
- float distance;
- float max_speed;
- unsigned short calories;
- int hr_avg;
- int hr_max;
- int intensity;
- int cadence;
- int trigger;
+ unsigned short valid;
+ time_t timestamp;
+ unsigned long duration;
+ float distance;
+ float max_speed;
+ unsigned short calories;
+ int hr_avg;
+ int hr_max;
+ int intensity;
+ int cadence;
+ int trigger;
};
/* all version numbering according ant agent for windows 2.2.1 */
@@ -79,16 +79,16 @@ int seenphase0 = 0;
int lastphase;
int sentack2;
int newfreq = 0;
-int period = 0x1000; /* garmin specific broadcast period */
+int period = 0x1000; /* garmin specific broadcast period */
int donebind = 0;
int sentgetv;
char *fname = "garmin";
time_t garmin_epoch = 631065600;
-static const uchar ANTSPT_KEY[] = "A8A423B9F55E63C1"; /* ANT+Sport key */
+static const uchar ANTSPT_KEY[] = "A8A423B9F55E63C1"; /* ANT+Sport key */
-static uchar ebuf[MESG_DATA_SIZE]; /* response event data gets stored here */
-static uchar cbuf[MESG_DATA_SIZE]; /* channel event data gets stored here */
+static uchar ebuf[MESG_DATA_SIZE]; /* response event data gets stored here */
+static uchar cbuf[MESG_DATA_SIZE]; /* channel event data gets stored here */
int passive = 0;
int verbose = 0;
@@ -118,21 +118,21 @@ uint unitid = 0;
/*char *getversion = "440dffff00000000fe00000000000000";*/
/*char *getgpsver = "440dffff0000000006000200ff000000";*/
const char *acks[] = {
- "fe00000000000000", /* get version - 255, 248, 253 */
- "0e02000000000000", /* device short name (fr405a) - 525 */
+ "fe00000000000000", /* get version - 255, 248, 253 */
+ "0e02000000000000", /* device short name (fr405a) - 525 */
/* "1c00020000000000", // no data */
- "0a0002000e000000", /* unit id - 38 */
- "0a00020002000000", /* send position */
- "0a00020005000000", /* send time */
- "0a000200ad020000", /* 4 byte something? 0x10270000 = 10000 dec - 1523 */
- "0a000200c6010000", /* 3 x 4 ints? - 994 */
- "0a00020035020000", /* guessing this is # trackpoints per run - 1066 */
- "0a00020097000000", /* load of software versions - 247 */
- "0a000200c2010000", /* download runs - 27 (#runs), 990?, 12? */
- "0a00020075000000", /* download laps - 27 (#laps), 149 laps, 12? */
- "0a00020006000000", /* download trackpoints - 1510/99(run marker), ..1510,12 */
- "0a000200ac020000",
- ""
+ "0a0002000e000000", /* unit id - 38 */
+ "0a00020002000000", /* send position */
+ "0a00020005000000", /* send time */
+ "0a000200ad020000", /* 4 byte something? 0x10270000 = 10000 dec - 1523 */
+ "0a000200c6010000", /* 3 x 4 ints? - 994 */
+ "0a00020035020000", /* guessing this is # trackpoints per run - 1066 */
+ "0a00020097000000", /* load of software versions - 247 */
+ "0a000200c2010000", /* download runs - 27 (#runs), 990?, 12? */
+ "0a00020075000000", /* download laps - 27 (#laps), 149 laps, 12? */
+ "0a00020006000000", /* download trackpoints - 1510/99(run marker), ..1510,12 */
+ "0a000200ac020000",
+ ""
};
int sentcmd;
@@ -145,7 +145,7 @@ char *progname;
#define BSIZE 8*10000
/* uchar blast[BSIZE]; // should be like that, but not working */
-uchar *blast = 0; /* first time reading not initialized, but why it is working reading from adr 0? */
+uchar *blast = 0; /* first time reading not initialized, but why it is working reading from adr 0? */
int blsize = 0;
int bused = 0;
@@ -155,1255 +155,1255 @@ int lseq = -1;
/* shoot me for writing this! */
char *ground(double d)
{
- int neg = 0;
- static char res[30];
- ulong ival;
- ulong l; /* hope it doesn't overflow */
-
- if (d < 0)
- {
- neg = 1;
- d = -d;
- }
- ival = floor(d);
- d -= ival;
- l = floor(d * 100000000);
- if (l % 10 >= 5)
- l = l / 10 + 1;
- else
- l = l / 10;
- snprintf(res, 30, "%s%ld.%07ld", neg ? "-" : "", ival, l);
- return res;
+ int neg = 0;
+ static char res[30];
+ ulong ival;
+ ulong l; /* hope it doesn't overflow */
+
+ if (d < 0)
+ {
+ neg = 1;
+ d = -d;
+ }
+ ival = floor(d);
+ d -= ival;
+ l = floor(d * 100000000);
+ if (l % 10 >= 5)
+ l = l / 10 + 1;
+ else
+ l = l / 10;
+ snprintf(res, 30, "%s%ld.%07ld", neg ? "-" : "", ival, l);
+ return res;
}
char *timestamp(void)
{
- struct timeval tv;
- static char time[50];
- struct tm *tmp;
+ struct timeval tv;
+ static char time[50];
+ struct tm *tmp;
- gettimeofday(&tv, 0);
- tmp = gmtime(&tv.tv_sec);
+ gettimeofday(&tv, 0);
+ tmp = gmtime(&tv.tv_sec);
- snprintf(time, 50, "%02d:%02d:%02d.%02d", tmp->tm_hour, tmp->tm_min, tmp->tm_sec, (int)tv.tv_usec / 10000);
- return time;
+ snprintf(time, 50, "%02d:%02d:%02d.%02d", tmp->tm_hour, tmp->tm_min, tmp->tm_sec, (int)tv.tv_usec / 10000);
+ return time;
}
uint randno(void)
{
- uint r;
- int fd = open("/dev/urandom", O_RDONLY);
-
- if (fd > 0)
- {
- read(fd, &r, sizeof r);
- close(fd);
- }
- return r;
+ uint r;
+ int fd = open("/dev/urandom", O_RDONLY);
+
+ if (fd > 0)
+ {
+ read(fd, &r, sizeof r);
+ close(fd);
+ }
+ return r;
}
void print_tcx_header(xmlTextWriterPtr tcxfile)
{
- int rc;
+ int rc;
- /* Start the Document */
- rc = xmlTextWriterStartDocument(tcxfile, "1.0", "UTF-8", "no"); XML_ERROR_CHECK;
+ /* Start the Document */
+ rc = xmlTextWriterStartDocument(tcxfile, "1.0", "UTF-8", "no"); XML_ERROR_CHECK;
- /* Start the TrainingCenterDatabase */
- rc = xmlTextWriterStartElementNS(tcxfile, NULL, BAD_CAST "TrainingCenterDatabase", BAD_CAST "http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2"); XML_ERROR_CHECK;
- rc = xmlTextWriterWriteAttributeNS(tcxfile, BAD_CAST "xsi", BAD_CAST "schemaLocation", BAD_CAST "http://www.w3.org/2001/XMLSchema-instance", BAD_CAST "http://www.garmin.com/xmlschemas/ActivityExtension/v2 http://www.garmin.com/xmlschemas/ActivityExtensionv2.xsd http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2 http://www.garmin.com/xmlschemas/TrainingCenterDatabasev2.xsd"); XML_ERROR_CHECK;
+ /* Start the TrainingCenterDatabase */
+ rc = xmlTextWriterStartElementNS(tcxfile, NULL, BAD_CAST "TrainingCenterDatabase", BAD_CAST "http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2"); XML_ERROR_CHECK;
+ rc = xmlTextWriterWriteAttributeNS(tcxfile, BAD_CAST "xsi", BAD_CAST "schemaLocation", BAD_CAST "http://www.w3.org/2001/XMLSchema-instance", BAD_CAST "http://www.garmin.com/xmlschemas/ActivityExtension/v2 http://www.garmin.com/xmlschemas/ActivityExtensionv2.xsd http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2 http://www.garmin.com/xmlschemas/TrainingCenterDatabasev2.xsd"); XML_ERROR_CHECK;
- /* Finally start the Activities element */
- rc = xmlTextWriterStartElement(tcxfile, BAD_CAST "Activities"); XML_ERROR_CHECK;
+ /* Finally start the Activities element */
+ rc = xmlTextWriterStartElement(tcxfile, BAD_CAST "Activities"); XML_ERROR_CHECK;
- return;
+ return;
}
void print_tcx_footer(xmlTextWriterPtr tcxfile)
{
- int rc;
-
- /* *INDENT-OFF* */
- rc = xmlTextWriterEndElement(tcxfile); XML_ERROR_CHECK; /* Track (Is it a good idea to do it here?) */
- rc = xmlTextWriterEndElement(tcxfile); XML_ERROR_CHECK; /* Lap (Is it a good idea to do it here?) */
- rc = xmlTextWriterStartElement(tcxfile, BAD_CAST "Creator"); XML_ERROR_CHECK;
- rc = xmlTextWriterWriteAttribute(tcxfile, BAD_CAST "xsi:type", BAD_CAST "Device_t"); XML_ERROR_CHECK;
- rc = xmlTextWriterWriteFormatElement(tcxfile, BAD_CAST "Name", "%s", devname); XML_ERROR_CHECK;
- rc = xmlTextWriterWriteFormatElement(tcxfile, BAD_CAST "UnitId", "%u", unitid); XML_ERROR_CHECK;
- rc = xmlTextWriterWriteFormatElement(tcxfile, BAD_CAST "ProductID", "%u", part); XML_ERROR_CHECK;
- rc = xmlTextWriterStartElement(tcxfile, BAD_CAST "Version"); XML_ERROR_CHECK;
- rc = xmlTextWriterWriteFormatElement(tcxfile, BAD_CAST "VersionMajor", "%u", ver / 100); XML_ERROR_CHECK;
- rc = xmlTextWriterWriteFormatElement(tcxfile, BAD_CAST "VersionMinor", "%u", ver % 100); XML_ERROR_CHECK;
- rc = xmlTextWriterWriteElement(tcxfile, BAD_CAST "BuildMajor", BAD_CAST "0"); XML_ERROR_CHECK;
- rc = xmlTextWriterWriteElement(tcxfile, BAD_CAST "BuildMinor", BAD_CAST "0"); XML_ERROR_CHECK;
- rc = xmlTextWriterEndElement(tcxfile); XML_ERROR_CHECK; /* Version */
- rc = xmlTextWriterEndElement(tcxfile); XML_ERROR_CHECK; /* Creator */
- rc = xmlTextWriterEndElement(tcxfile); XML_ERROR_CHECK; /* Activity */
- rc = xmlTextWriterEndElement(tcxfile); XML_ERROR_CHECK; /* Activities */
- rc = xmlTextWriterStartElement(tcxfile, BAD_CAST "Author"); XML_ERROR_CHECK;
- rc = xmlTextWriterWriteAttribute(tcxfile, BAD_CAST "xsi:type", BAD_CAST "Application_t"); XML_ERROR_CHECK;
- rc = xmlTextWriterWriteElement(tcxfile, BAD_CAST "Name", BAD_CAST "Garmin ANT Agent(tm)"); XML_ERROR_CHECK;
- rc = xmlTextWriterStartElement(tcxfile, BAD_CAST "Build"); XML_ERROR_CHECK;
- rc = xmlTextWriterStartElement(tcxfile, BAD_CAST "Version"); XML_ERROR_CHECK;
- rc = xmlTextWriterWriteFormatElement(tcxfile, BAD_CAST "VersionMajor", "%u", majorrelease); XML_ERROR_CHECK;
- rc = xmlTextWriterWriteFormatElement(tcxfile, BAD_CAST "VersionMinor", "%u", minorrelease); XML_ERROR_CHECK;
- rc = xmlTextWriterWriteFormatElement(tcxfile, BAD_CAST "BuildMajor", "%u", majorbuild); XML_ERROR_CHECK;
- rc = xmlTextWriterWriteFormatElement(tcxfile, BAD_CAST "BuildMinor", "%u", minorbuild); XML_ERROR_CHECK;
- rc = xmlTextWriterEndElement(tcxfile); XML_ERROR_CHECK; /* Version */
- rc = xmlTextWriterWriteElement(tcxfile, BAD_CAST "Type", BAD_CAST "Release"); XML_ERROR_CHECK;
- rc = xmlTextWriterWriteFormatElement(tcxfile, BAD_CAST "Time", "%s", releasetime); XML_ERROR_CHECK;
- rc = xmlTextWriterWriteElement(tcxfile, BAD_CAST "Builder", BAD_CAST "sqa"); XML_ERROR_CHECK;
- rc = xmlTextWriterEndElement(tcxfile); XML_ERROR_CHECK; /* Build */
- rc = xmlTextWriterWriteElement(tcxfile, BAD_CAST "LangID", BAD_CAST "EN"); XML_ERROR_CHECK;
- rc = xmlTextWriterWriteElement(tcxfile, BAD_CAST "PartNumber", BAD_CAST "006-A0214-00"); XML_ERROR_CHECK;
- /* *INDENT-ON* */
- return;
+ int rc;
+
+ /* *INDENT-OFF* */
+ rc = xmlTextWriterEndElement(tcxfile); XML_ERROR_CHECK; /* Track (Is it a good idea to do it here?) */
+ rc = xmlTextWriterEndElement(tcxfile); XML_ERROR_CHECK; /* Lap (Is it a good idea to do it here?) */
+ rc = xmlTextWriterStartElement(tcxfile, BAD_CAST "Creator"); XML_ERROR_CHECK;
+ rc = xmlTextWriterWriteAttribute(tcxfile, BAD_CAST "xsi:type", BAD_CAST "Device_t"); XML_ERROR_CHECK;
+ rc = xmlTextWriterWriteFormatElement(tcxfile, BAD_CAST "Name", "%s", devname); XML_ERROR_CHECK;
+ rc = xmlTextWriterWriteFormatElement(tcxfile, BAD_CAST "UnitId", "%u", unitid); XML_ERROR_CHECK;
+ rc = xmlTextWriterWriteFormatElement(tcxfile, BAD_CAST "ProductID", "%u", part); XML_ERROR_CHECK;
+ rc = xmlTextWriterStartElement(tcxfile, BAD_CAST "Version"); XML_ERROR_CHECK;
+ rc = xmlTextWriterWriteFormatElement(tcxfile, BAD_CAST "VersionMajor", "%u", ver / 100); XML_ERROR_CHECK;
+ rc = xmlTextWriterWriteFormatElement(tcxfile, BAD_CAST "VersionMinor", "%u", ver % 100); XML_ERROR_CHECK;
+ rc = xmlTextWriterWriteElement(tcxfile, BAD_CAST "BuildMajor", BAD_CAST "0"); XML_ERROR_CHECK;
+ rc = xmlTextWriterWriteElement(tcxfile, BAD_CAST "BuildMinor", BAD_CAST "0"); XML_ERROR_CHECK;
+ rc = xmlTextWriterEndElement(tcxfile); XML_ERROR_CHECK; /* Version */
+ rc = xmlTextWriterEndElement(tcxfile); XML_ERROR_CHECK; /* Creator */
+ rc = xmlTextWriterEndElement(tcxfile); XML_ERROR_CHECK; /* Activity */
+ rc = xmlTextWriterEndElement(tcxfile); XML_ERROR_CHECK; /* Activities */
+ rc = xmlTextWriterStartElement(tcxfile, BAD_CAST "Author"); XML_ERROR_CHECK;
+ rc = xmlTextWriterWriteAttribute(tcxfile, BAD_CAST "xsi:type", BAD_CAST "Application_t"); XML_ERROR_CHECK;
+ rc = xmlTextWriterWriteElement(tcxfile, BAD_CAST "Name", BAD_CAST "Garmin ANT Agent(tm)"); XML_ERROR_CHECK;
+ rc = xmlTextWriterStartElement(tcxfile, BAD_CAST "Build"); XML_ERROR_CHECK;
+ rc = xmlTextWriterStartElement(tcxfile, BAD_CAST "Version"); XML_ERROR_CHECK;
+ rc = xmlTextWriterWriteFormatElement(tcxfile, BAD_CAST "VersionMajor", "%u", majorrelease); XML_ERROR_CHECK;
+ rc = xmlTextWriterWriteFormatElement(tcxfile, BAD_CAST "VersionMinor", "%u", minorrelease); XML_ERROR_CHECK;
+ rc = xmlTextWriterWriteFormatElement(tcxfile, BAD_CAST "BuildMajor", "%u", majorbuild); XML_ERROR_CHECK;
+ rc = xmlTextWriterWriteFormatElement(tcxfile, BAD_CAST "BuildMinor", "%u", minorbuild); XML_ERROR_CHECK;
+ rc = xmlTextWriterEndElement(tcxfile); XML_ERROR_CHECK; /* Version */
+ rc = xmlTextWriterWriteElement(tcxfile, BAD_CAST "Type", BAD_CAST "Release"); XML_ERROR_CHECK;
+ rc = xmlTextWriterWriteFormatElement(tcxfile, BAD_CAST "Time", "%s", releasetime); XML_ERROR_CHECK;
+ rc = xmlTextWriterWriteElement(tcxfile, BAD_CAST "Builder", BAD_CAST "sqa"); XML_ERROR_CHECK;
+ rc = xmlTextWriterEndElement(tcxfile); XML_ERROR_CHECK; /* Build */
+ rc = xmlTextWriterWriteElement(tcxfile, BAD_CAST "LangID", BAD_CAST "EN"); XML_ERROR_CHECK;
+ rc = xmlTextWriterWriteElement(tcxfile, BAD_CAST "PartNumber", BAD_CAST "006-A0214-00"); XML_ERROR_CHECK;
+ /* *INDENT-ON* */
+ return;
}
void dump_data(FILE * out, uchar *data, size_t offset, size_t size)
{
- unsigned char buf[16];
- int i, j;
- for (i=0; i < (int)size; i+=16)
- {
- memset(buf, 0, sizeof buf);
- memcpy(buf, data + offset + i, (size-i >= 16)? 16 : (size-i));
- fprintf(out, "0x%04lx:", (unsigned long)(offset + i));
-
- for (j=0; j < 16; j++)
- {
- if (j == 8)
- fprintf(out, " ");
-
- if (i+j >= (int)size)
- fprintf(out, " ");
- else
- fprintf(out, " %02x", buf[j]);
- } /* for (j=0; j < 16; j++) */
-
- fprintf(out, " ");
- for (j=0; j < 16; j++)
- {
- if (i+j >= (int)size)
- break;
-
- if (j == 8)
- fprintf(out, " ");
-
- if (isprint(buf[j]))
- fprintf(out, "%c", buf[j]);
- else
- fprintf(out, ".");
- } /* for (j=0; j < 16; j++) */
-
- fprintf(out, "\n");
- } /* for (i=0; i < size; i+=16) */
-
- return;
+ unsigned char buf[16];
+ int i, j;
+ for (i=0; i < (int)size; i+=16)
+ {
+ memset(buf, 0, sizeof buf);
+ memcpy(buf, data + offset + i, (size-i >= 16)? 16 : (size-i));
+ fprintf(out, "0x%04lx:", (unsigned long)(offset + i));
+
+ for (j=0; j < 16; j++)
+ {
+ if (j == 8)
+ fprintf(out, " ");
+
+ if (i+j >= (int)size)
+ fprintf(out, " ");
+ else
+ fprintf(out, " %02x", buf[j]);
+ } /* for (j=0; j < 16; j++) */
+
+ fprintf(out, " ");
+ for (j=0; j < 16; j++)
+ {
+ if (i+j >= (int)size)
+ break;
+
+ if (j == 8)
+ fprintf(out, " ");
+
+ if (isprint(buf[j]))
+ fprintf(out, "%c", buf[j]);
+ else
+ fprintf(out, ".");
+ } /* for (j=0; j < 16; j++) */
+
+ fprintf(out, "\n");
+ } /* for (i=0; i < size; i+=16) */
+
+ return;
} /* void dump_ata(void *data, siz... */
#pragma pack(1)
struct ack_msg {
- uchar code;
- uchar atype;
- uchar c1;
- uchar c2;
- uint id;
+ uchar code;
+ uchar atype;
+ uchar c1;
+ uchar c2;
+ uint id;
};
struct auth_msg {
- uchar code;
- uchar atype;
- uchar phase;
- uchar u1;
- uint id;
- uint auth1;
- uint auth2;
- uint fill1;
- uint fill2;
+ uchar code;
+ uchar atype;
+ uchar phase;
+ uchar u1;
+ uint id;
+ uint auth1;
+ uint auth2;
+ uint fill1;
+ uint fill2;
};
struct pair_msg {
- uchar code;
- uchar atype;
- uchar phase;
- uchar u1;
- uint id;
- char devname[16];
+ uchar code;
+ uchar atype;
+ uchar phase;
+ uchar u1;
+ uint id;
+ char devname[16];
};
#pragma pack()
-#define ACKSIZE 8 /* above structure must be this size */
-#define AUTHSIZE 24 /* ditto */
+#define ACKSIZE 8 /* above structure must be this size */
+#define AUTHSIZE 24 /* ditto */
#define PAIRSIZE 16
-#define MAXLAPS 256 /* max of saving laps data before output with trackpoint data */
-#define MAXTRACK 256*256 /* max number of tracks to be saved per download */
+#define MAXLAPS 256 /* max of saving laps data before output with trackpoint data */
+#define MAXTRACK 256*256 /* max number of tracks to be saved per download */
void decode(ushort bloblen, ushort pkttype, ushort pktlen, int dsize, uchar * data)
{
- int i;
- int hr;
- int cad;
- int u1, u2;
- int doff = 20;
- char model[256];
- char gpsver[256];
- float alt;
- float dist;
- time_t tv;
- char tbuf[100];
- double lat, lon;
- uint ndata;
- time_t tv_lap;
- static xmlTextWriterPtr tcxfile = NULL;
- static ushort track_pause = 0;
- int rc;
- static xml_pos xml_position = XML_OUTSIDE;
- static struct _activity *activities = NULL;
- static struct _lap *laps = NULL;
- static unsigned short lap_id;
- static unsigned short activity_id;
-
- DEBUG_OUT(3, "decode %d %d %d %d", bloblen, pkttype, pktlen, dsize);
- switch (pkttype)
- {
- case 255: /* Identifier */
- memset(model, 0, sizeof model);
- memcpy(model, data + doff + 4, pktlen - 4);
- part = data[doff] + data[doff + 1] * 256;
- ver = data[doff + 2] + data[doff + 3] * 256;
- DEBUG_OUT(1, "Packet %d: Part#: %d Version: %d Name: %s", pkttype, part, ver, model);
- break;
- case 248: /* GPS identifier */
- memset(gpsver, 0, sizeof gpsver);
- memcpy(gpsver, data + doff, pktlen);
- DEBUG_OUT(1, "Packet %d: GPS: %s", pkttype, gpsver);
- break;
- case 253:
- DEBUG_OUT(1, "Packet %d: Unknown", pkttype);
- if (dbg >= 2)
- dump_data(stderr, data+doff, 0, pktlen);
- break;
- case 525:
- memset(devname, 0, sizeof devname);
- memcpy(devname, data + doff, pktlen);
- DEBUG_OUT(1, "Packet %d: Devname: \"%s\"", pkttype, devname);
- break;
- case 12:
- DEBUG_OUT(1, "Packet %d: xfer complete (subtype %u)", pkttype, data[doff] + data[doff + 1] * 256);
- if (dbg >= 2)
- dump_data(stderr, data+doff, 2, pktlen-2);
- switch (data[doff] + data[doff + 1] * 256)
- {
- case 6: /* Wayboint end */
- /* last file completed, add footer and close file */
- if (tcxfile)
- {
- print_tcx_footer(tcxfile);
- xml_position = XML_OUTSIDE;
- rc = xmlTextWriterEndDocument(tcxfile); XML_ERROR_CHECK;
- xmlFreeTextWriter(tcxfile);
- tcxfile = NULL;
- }
- break;
- case 117: /* Lap informations end */
- break;
- case 450: /* Track informations end */
- break;
- default:
- break;
- }
- break;
- case 38:
- unitid = data[doff] + data[doff + 1] * 256 + data[doff + 2] * 256 * 256 + data[doff + 3] * 256 * 256 * 256;
- DEBUG_OUT(1, "Packet %d: UnitID: %u", pkttype, unitid);
- break;
- case 27: /* Number of following packages */
- ndata = data[doff] + data[doff + 1] * 256;
- DEBUG_OUT(2, "Packet %d: Number of following packages: %u", pkttype, ndata);
- break;
- case 1523: /* Max Trackpoints (?) 10000 */
- case 994: /* Drei Limits (?) 200, 25, 200 */
- case 1066: /* 20, 200, 100, ???? */
- DEBUG_OUT(1, "Packet %d", pkttype);
- if (dbg >= 2)
- dump_data(stderr, data+doff, 0, pktlen);
- break;
- case 14: /* Current time (UTC) */
- DEBUG_OUT(1, "Packet %d: Current time: %04u-%02u-%02u %02u:%02u:%02u", pkttype, data[doff + 2] + data[doff + 3] * 256, data[doff + 1], data[doff], data[doff + 4], data[doff + 6], data[doff + 7]);
- break;
- case 17:
- DEBUG_OUT(1, "Packet %d: Position?", pkttype);
- if (dbg >= 2)
- dump_data(stderr, data+doff, 0, pktlen);
- break;
- case 990: /* Activity specification */
- DEBUG_OUT(1, "Packet %d: Activity %u: laps %u-%u sport %u", pkttype, data[doff] + data[doff + 1] * 256, data[doff + 2] + data[doff + 3] * 256, data[doff + 4] + data[doff + 5] * 256, data[doff + 6]);
-
- /* Initialize memory if not done before */
- if (activities == NULL)
- {
- activities = (struct _activity *)calloc(256 * 256, sizeof(struct _activity));
- if (activities == NULL)
- {
- ERROR_OUT("Cannot calloc enough memory");
- exit(-1);
- }
- memset(activities, 0x00, sizeof(struct _activity) * 256 * 256);
- } /* if (activities == NULL) */
-
- activity_id = data[doff] + data[doff + 1] * 256;
- activities[activity_id].first_lap = data[doff + 2] + data[doff + 3] * 256;
- activities[activity_id].last_lap = data[doff + 4] + data[doff + 5] * 256;
- activities[activity_id].sport = data[doff + 6];
- activities[activity_id].valid = 1;
-
- /* leftover (Most of!) */
- if (dbg >= 2)
- dump_data(stderr, data+doff, 7, pktlen-7);
- break;
- case 99:
- DEBUG_OUT(1, "Packet %d: Activity index: %u", pkttype, data[doff] + data[doff + 1] * 256);
-
- /* close previous file */
- if (tcxfile)
- {
- /* add xml footer and close file, the next file will be open further down */
- DEBUG_OUT(1, "Closing file");
- print_tcx_footer(tcxfile);
- xml_position = XML_OUTSIDE;
- rc = xmlTextWriterEndDocument(tcxfile); XML_ERROR_CHECK;
- xmlFreeTextWriter(tcxfile);
- tcxfile = NULL;
- }
-
- activity_id = data[doff] + data[doff + 1] * 256;
-
- if (laps == NULL || activities[activity_id].valid == 0 || laps[activities[activity_id].first_lap].valid == 0)
- {
- ERROR_OUT("Something is wrong in transfer");
- exit(-1);
- }
-
- lap_id = activities[activity_id].first_lap;
-
- /* use first lap starttime as filename */
- tv_lap = laps[lap_id].timestamp;
- strftime(tbuf, sizeof(tbuf), "%Y-%m-%d-%H%M%S.tcx", localtime(&tv_lap));
- DEBUG_OUT(1, "Open file %s", tbuf);
- /* open file and start with header of xml file */
- tcxfile = xmlNewTextWriterFilename(tbuf, 0);
- if (tcxfile == NULL)
- {
- ERROR_OUT("Error in XML creation");
- exit(-1);
- }
- print_tcx_header(tcxfile);
- xml_position = XML_IN_Activities;
-
- rc = xmlTextWriterStartElement(tcxfile, BAD_CAST "Activity"); XML_ERROR_CHECK;
- xml_position++;
- switch (activities[activity_id].sport)
- {
- case 0:
- rc = xmlTextWriterWriteAttribute(tcxfile, BAD_CAST "Sport", BAD_CAST "Running");
- break;
- case 1:
- rc = xmlTextWriterWriteAttribute(tcxfile, BAD_CAST "Sport", BAD_CAST "Biking");
- break;
- case 2:
- rc = xmlTextWriterWriteAttribute(tcxfile, BAD_CAST "Sport", BAD_CAST "Other");
- break;
- default:
- rc = xmlTextWriterWriteElement(tcxfile, BAD_CAST "Notes", BAD_CAST "Unknown sport type"); XML_ERROR_CHECK;
- rc = xmlTextWriterWriteAttribute(tcxfile, BAD_CAST "Sport", BAD_CAST "Other");
- }
- XML_ERROR_CHECK;
-
- strftime(tbuf, sizeof tbuf, "%Y-%m-%dT%H:%M:%SZ", gmtime(&tv_lap));
- rc = xmlTextWriterWriteFormatElement(tcxfile, BAD_CAST "Id", "%s", tbuf); XML_ERROR_CHECK;
-
- /* leftover (5) */
- if (dbg >= 2)
- dump_data(stderr, data+doff, 2, pktlen-2);
- break;
- case 1510:
- DEBUG_OUT(1, "%d Track package with %u waypoints", pkttype, data[doff] + data[doff + 1] * 256);
-
- /* if trackpoints are split into more than one message 1510, do not add xml head again */
-
- /* Do some sanity checks */
- if (activities[activity_id].valid == 0 || laps[lap_id].valid == 0 || lap_id < activities[activity_id].first_lap || lap_id > activities[activity_id].last_lap)
- {
- ERROR_OUT("Sanity check failed");
- ERROR_OUT("Activity: %u, lap: %u", activity_id, lap_id);
- exit(-1);
- } /* if (activities[activity_id].va... */
-
- for (i = 4; i < pktlen; i += 24)
- {
- tv = data[doff + i + 8] + data[doff + i + 9] * 256 + data[doff + i + 10] * 256 * 256 + data[doff + i + 11] * 256 * 256 * 256 + garmin_epoch;
-
- if (lap_id < activities[activity_id].last_lap && laps[lap_id + 1].valid && tv >= laps[lap_id + 1].timestamp)
- {
- lap_id++;
- /* Close track and lap if still open (Should ever be) */
- if (xml_position == XML_IN_Track)
- {
- rc = xmlTextWriterEndElement(tcxfile); XML_ERROR_CHECK; /* Track */
- xml_position--;
- rc = xmlTextWriterEndElement(tcxfile); XML_ERROR_CHECK; /* Lap */
- xml_position--;
- } /* if (xml_position == XML_IN_Tra... */
- } /* if (lap_id < activities[activi... */
-
- /* New lap, handle here to only write the code once */
- if (xml_position == XML_IN_Activity)
- {
- strftime(tbuf, sizeof tbuf, "%Y-%m-%dT%H:%M:%SZ", gmtime(&laps[lap_id].timestamp));
- rc = xmlTextWriterStartElement(tcxfile, BAD_CAST "Lap"); XML_ERROR_CHECK;
- xml_position++;
- rc = xmlTextWriterWriteFormatAttribute(tcxfile, BAD_CAST "StartTime", "%s", tbuf); XML_ERROR_CHECK;
- rc = xmlTextWriterWriteFormatElement(tcxfile, BAD_CAST "TotalTimeSeconds", "%ld.%02ld00000", laps[lap_id].duration / 100, laps[lap_id].duration % 100); XML_ERROR_CHECK;
- rc = xmlTextWriterWriteFormatElement(tcxfile, BAD_CAST "DistanceMeters", "%s", ground(laps[lap_id].distance)); XML_ERROR_CHECK;
- rc = xmlTextWriterWriteFormatElement(tcxfile, BAD_CAST "MaximumSpeed", "%s", ground(laps[lap_id].max_speed)); XML_ERROR_CHECK;
- rc = xmlTextWriterWriteFormatElement(tcxfile, BAD_CAST "Calories", "%d", laps[lap_id].calories); XML_ERROR_CHECK;
-
- if (laps[lap_id].hr_avg > 0)
- {
- rc = xmlTextWriterStartElement(tcxfile, BAD_CAST "AverageHeartRateBpm"); XML_ERROR_CHECK;
- rc = xmlTextWriterWriteAttribute(tcxfile, BAD_CAST "xsi:type", BAD_CAST "HeartRateInBeatsPerMinute_t"); XML_ERROR_CHECK;
- rc = xmlTextWriterWriteFormatElement(tcxfile, BAD_CAST "Value", "%d", laps[lap_id].hr_avg); XML_ERROR_CHECK;
- rc = xmlTextWriterEndElement(tcxfile); XML_ERROR_CHECK;
- }
- if (laps[lap_id].hr_max > 0)
- {
- rc = xmlTextWriterStartElement(tcxfile, BAD_CAST "MaximumHeartRateBpm"); XML_ERROR_CHECK;
- rc = xmlTextWriterWriteAttribute(tcxfile, BAD_CAST "xsi:type", BAD_CAST "HeartRateInBeatsPerMinute_t"); XML_ERROR_CHECK;
- rc = xmlTextWriterWriteFormatElement(tcxfile, BAD_CAST "Value", "%d", laps[lap_id].hr_max); XML_ERROR_CHECK;
- rc = xmlTextWriterEndElement(tcxfile); XML_ERROR_CHECK;
- }
-
- switch (laps[lap_id].intensity)
- {
- case 0:
- rc = xmlTextWriterWriteElement(tcxfile, BAD_CAST "Intensity", BAD_CAST "Active");
- break;
- case 1:
- rc = xmlTextWriterWriteElement(tcxfile, BAD_CAST "Intensity", BAD_CAST "Resting");
- break;
- default:
- rc = xmlTextWriterWriteElement(tcxfile, BAD_CAST "Intensity", BAD_CAST "Active");
- }
- XML_ERROR_CHECK;
-
- /* for bike the average cadence of this lap is here */
- if (activities[activity_id].sport == 1)
- {
- if (laps[lap_id].cadence != 255)
- {
- rc = xmlTextWriterWriteFormatElement(tcxfile, BAD_CAST "Cadence", "%d", laps[lap_id].cadence); XML_ERROR_CHECK;
- }
- }
-
- switch (laps[lap_id].trigger)
- {
- case 4:
- rc = xmlTextWriterWriteElement(tcxfile, BAD_CAST "TriggerMethod", BAD_CAST "HeartRate");
- break;
- case 3:
- rc = xmlTextWriterWriteElement(tcxfile, BAD_CAST "TriggerMethod", BAD_CAST "Time");
- break;
- case 2:
- rc = xmlTextWriterWriteElement(tcxfile, BAD_CAST "TriggerMethod", BAD_CAST "Location");
- break;
- case 1:
- rc = xmlTextWriterWriteElement(tcxfile, BAD_CAST "TriggerMethod", BAD_CAST "Distance");
- break;
- case 0:
- rc = xmlTextWriterWriteElement(tcxfile, BAD_CAST "TriggerMethod", BAD_CAST "Manual");
- break;
- default:
- rc = xmlTextWriterWriteElement(tcxfile, BAD_CAST "TriggerMethod", BAD_CAST "Manual");
- }
- XML_ERROR_CHECK;
-
- /* I prefere the average run cadence here than at the end of this lap according windows ANTagent */
- if (activities[activity_id].sport == 0)
- {
- if (laps[lap_id].cadence != 255)
- {
- rc = xmlTextWriterStartElement(tcxfile, BAD_CAST "Extensions"); XML_ERROR_CHECK;
- rc = xmlTextWriterStartElementNS(tcxfile, NULL, BAD_CAST "LX", BAD_CAST "http://www.garmin.com/xmlschemas/ActivityExtension/v2"); XML_ERROR_CHECK;
- rc = xmlTextWriterWriteFormatElement(tcxfile, BAD_CAST "AvgRunCadence", "%d", laps[lap_id].cadence); XML_ERROR_CHECK;
- rc = xmlTextWriterEndElement(tcxfile); XML_ERROR_CHECK; /* LX */
- rc = xmlTextWriterEndElement(tcxfile); XML_ERROR_CHECK; /* Extensions */
- }
- }
- rc = xmlTextWriterStartElement(tcxfile, BAD_CAST "Track"); XML_ERROR_CHECK;
- xml_position++;
-
- track_pause = 0;
- } /* if (xml_position == XML_IN_Act... */
-
- if (xml_position != XML_IN_Track)
- {
- ERROR_OUT("Need to write trackpoint but I am not in active track (Current: %d)", xml_position);
- continue;
- }
-
- strftime(tbuf, sizeof tbuf, "%Y-%m-%dT%H:%M:%SZ", gmtime(&tv));
- memcpy((void *)&alt, data + doff + i + 12, 4);
- memcpy((void *)&dist, data + doff + i + 16, 4);
- lat = (data[doff + i] + data[doff + i + 1] * 256 + data[doff + i + 2] * 256 * 256 + data[doff + i + 3] * 256 * 256 * 256) * 180.0 / 0x80000000;
- lon = (data[doff + i + 4] + data[doff + i + 5] * 256 + data[doff + i + 6] * 256 * 256 + data[doff + i + 7] * 256 * 256 * 256) * 180.0 / 0x80000000;
- hr = data[doff + i + 20];
- cad = data[doff + i + 21];
- u1 = data[doff + i + 22];
- u2 = data[doff + i + 23];
- DEBUG_OUT(2, "lat %.10g lon %.10g hr %d cad %d u1 %d u2 %d tv %d %s alt %f dist %f %02x %02x%02x%02x%02x", lat, lon, hr, cad, u1, u2, (int)tv, tbuf, alt, dist, data[doff + i + 3], data[doff + i + 16], data[doff + i + 17], data[doff + i + 18], data[doff + i + 19]);
- /* track pause only if following trackpoint is aswell 'timemarker' with utopic distance */
- if (track_pause && dist > (float)40000000)
- {
- rc = xmlTextWriterEndElement(tcxfile); XML_ERROR_CHECK; /* Track */
- rc = xmlTextWriterStartElement(tcxfile, BAD_CAST "Track"); XML_ERROR_CHECK;
- }
-
- rc = xmlTextWriterStartElement(tcxfile, BAD_CAST "Trackpoint"); XML_ERROR_CHECK;
- xml_position++;
- rc = xmlTextWriterWriteFormatElement(tcxfile, BAD_CAST "Time", "%s", tbuf); XML_ERROR_CHECK;
-
- if (lat < 90)
- {
- rc = xmlTextWriterStartElement(tcxfile, BAD_CAST "Position"); XML_ERROR_CHECK;
- rc = xmlTextWriterWriteFormatElement(tcxfile, BAD_CAST "LatitudeDegrees", "%s", ground(lat)); XML_ERROR_CHECK;
- rc = xmlTextWriterWriteFormatElement(tcxfile, BAD_CAST "LongitudeDegrees", "%s", ground(lon)); XML_ERROR_CHECK;
- rc = xmlTextWriterEndElement(tcxfile); XML_ERROR_CHECK; /* Position */
- rc = xmlTextWriterWriteFormatElement(tcxfile, BAD_CAST "AltitudeMeters", "%s", ground(alt)); XML_ERROR_CHECK;
- }
-
- /* last trackpoint has utopic distance, 40000km should be enough, hack? */
- if (dist < (float)40000000)
- {
- rc = xmlTextWriterWriteFormatElement(tcxfile, BAD_CAST "DistanceMeters", "%s", ground(dist)); XML_ERROR_CHECK;
- }
-
- if (hr > 0)
- {
- rc = xmlTextWriterStartElement(tcxfile, BAD_CAST "HeartRateBpm"); XML_ERROR_CHECK;
- rc = xmlTextWriterWriteAttribute(tcxfile, BAD_CAST "xsi:type", BAD_CAST "HeartRateInBeatsPerMinute_t"); XML_ERROR_CHECK;
- rc = xmlTextWriterWriteFormatElement(tcxfile, BAD_CAST "Value", "%d", hr); XML_ERROR_CHECK;
- rc = xmlTextWriterEndElement(tcxfile); XML_ERROR_CHECK; /* HeartRateBpm */
- }
-
- /* for bikes the cadence is written here and for the footpod in <Extensions>, why garmin? */
- if (activities[activity_id].sport == 1)
- {
- if (cad != 255)
- {
- rc = xmlTextWriterWriteFormatElement(tcxfile, BAD_CAST "Cadence", "%d", cad); XML_ERROR_CHECK;
- }
- }
-
- if (dist < (float)40000000)
- {
- rc = xmlTextWriterWriteElement(tcxfile, BAD_CAST "SensorState", u1 ? BAD_CAST "Present" : BAD_CAST "Absent"); XML_ERROR_CHECK;
- if (u1 == 1 || cad != 255)
- {
- rc = xmlTextWriterStartElement(tcxfile, BAD_CAST "Extensions"); XML_ERROR_CHECK;
- rc = xmlTextWriterStartElementNS(tcxfile, NULL, BAD_CAST "TPX", BAD_CAST "http://www.garmin.com/xmlschemas/ActivityExtension/v2"); XML_ERROR_CHECK;
- rc = xmlTextWriterWriteFormatElement(tcxfile, BAD_CAST "AvgRunCadence", "%d", cad); XML_ERROR_CHECK;
- /* get type of pod from data, could not figure it out, so using sporttyp of first track */
- if (activities[activity_id].sport == 1)
- {
- rc = xmlTextWriterWriteAttribute(tcxfile, BAD_CAST "CadenceSensor", BAD_CAST "Bike"); XML_ERROR_CHECK;
- }
- else
- {
- rc = xmlTextWriterWriteAttribute(tcxfile, BAD_CAST "CadenceSensor", BAD_CAST "Footpod"); XML_ERROR_CHECK;
- if (cad != 255)
- {
- rc = xmlTextWriterWriteFormatElement(tcxfile, BAD_CAST "RunCadence", "%d", cad); XML_ERROR_CHECK;
- }
- }
- rc = xmlTextWriterEndElement(tcxfile); XML_ERROR_CHECK; /* TPX */
- rc = xmlTextWriterEndElement(tcxfile); XML_ERROR_CHECK; /* Extensions */
- }
- track_pause = 0;
- }
-
- rc = xmlTextWriterEndElement(tcxfile); XML_ERROR_CHECK; /* Trackpoint */
- xml_position--;
-
- /* maybe if we recieve utopic position and distance this tells pause in the run (stop and go) if not begin or end of lap */
- if (dist > (float)40000000 && track_pause == 0)
- {
- track_pause = 1;
- DEBUG_OUT(2, "Track pause (stop and go)");
- }
- else
- {
- track_pause = 0;
- }
- } /* for (i = 4; i < pktlen; i += 2... */
- break;
- case 149: /* Lap specification */
- DEBUG_OUT(1, "%d Lap data id: %u %u", pkttype, data[doff] + data[doff + 1] * 256, data[doff + 2] + data[doff + 3] * 256);
-
- /* Initialize memory if not done before */
- if (laps == NULL)
- {
- laps = (struct _lap *)calloc(256 * 256, sizeof(struct _lap));
- if (laps == NULL)
- {
- ERROR_OUT("Cannot calloc enough memory");
- exit(-1);
- }
- memset(laps, 0x00, sizeof(struct _lap) * 256 * 256);
- } /* if (laps == NULL) */
-
- lap_id = data[doff] + data[doff + 1] * 256;
- laps[lap_id].timestamp = data[doff + 4] + data[doff + 5] * 256 + data[doff + 6] * 256 * 256 + data[doff + 7] * 256 * 256 * 256 + garmin_epoch;
- laps[lap_id].duration = data[doff + 8] + data[doff + 9] * 256 + data[doff + 10] * 256 * 256 + data[doff + 11] * 256 * 256 * 256;
- memcpy(&laps[lap_id].distance, &data[doff + 12], 4); /* Dirty, but seems to work */
- memcpy(&laps[lap_id].max_speed, &data[doff + 16], 4); /* Dirty, but seems to work */
- laps[lap_id].calories = data[doff + 36] + data[doff + 37] * 256;
- laps[lap_id].hr_avg = data[doff + 38];
- laps[lap_id].hr_max = data[doff + 39];
- laps[lap_id].intensity = data[doff + 40];
- laps[lap_id].cadence = data[doff + 41];
- laps[lap_id].trigger = data[doff + 42];
-
- laps[lap_id].valid = 1;
-
- if (dbg >= 2)
- {
- dump_data(stderr, data+doff, 20, 16);
- dump_data(stderr, data+doff, 43, pktlen-43);
- }
-
- break;
- case 247: /* Software versions */
- memset(modelname, 0, sizeof modelname);
- memcpy(modelname, data + doff + 88, dsize - 88);
- DEBUG_OUT(1, "%d Device name \"%s\"\n", pkttype, modelname);
- break;
- default:
- DEBUG_OUT(1, "Don't know how to decode packet type %d", pkttype);
- if (dbg >= 2)
- dump_data(stderr, data+doff, 0, pktlen);
- }
+ int i;
+ int hr;
+ int cad;
+ int u1, u2;
+ int doff = 20;
+ char model[256];
+ char gpsver[256];
+ float alt;
+ float dist;
+ time_t tv;
+ char tbuf[100];
+ double lat, lon;
+ uint ndata;
+ time_t tv_lap;
+ static xmlTextWriterPtr tcxfile = NULL;
+ static ushort track_pause = 0;
+ int rc;
+ static xml_pos xml_position = XML_OUTSIDE;
+ static struct _activity *activities = NULL;
+ static struct _lap *laps = NULL;
+ static unsigned short lap_id;
+ static unsigned short activity_id;
+
+ DEBUG_OUT(3, "decode %d %d %d %d", bloblen, pkttype, pktlen, dsize);
+ switch (pkttype)
+ {
+ case 255: /* Identifier */
+ memset(model, 0, sizeof model);
+ memcpy(model, data + doff + 4, pktlen - 4);
+ part = data[doff] + data[doff + 1] * 256;
+ ver = data[doff + 2] + data[doff + 3] * 256;
+ DEBUG_OUT(1, "Packet %d: Part#: %d Version: %d Name: %s", pkttype, part, ver, model);
+ break;
+ case 248: /* GPS identifier */
+ memset(gpsver, 0, sizeof gpsver);
+ memcpy(gpsver, data + doff, pktlen);
+ DEBUG_OUT(1, "Packet %d: GPS: %s", pkttype, gpsver);
+ break;
+ case 253:
+ DEBUG_OUT(1, "Packet %d: Unknown", pkttype);
+ if (dbg >= 2)
+ dump_data(stderr, data+doff, 0, pktlen);
+ break;
+ case 525:
+ memset(devname, 0, sizeof devname);
+ memcpy(devname, data + doff, pktlen);
+ DEBUG_OUT(1, "Packet %d: Devname: \"%s\"", pkttype, devname);
+ break;
+ case 12:
+ DEBUG_OUT(1, "Packet %d: xfer complete (subtype %u)", pkttype, data[doff] + data[doff + 1] * 256);
+ if (dbg >= 2)
+ dump_data(stderr, data+doff, 2, pktlen-2);
+ switch (data[doff] + data[doff + 1] * 256)
+ {
+ case 6: /* Wayboint end */
+ /* last file completed, add footer and close file */
+ if (tcxfile)
+ {
+ print_tcx_footer(tcxfile);
+ xml_position = XML_OUTSIDE;
+ rc = xmlTextWriterEndDocument(tcxfile); XML_ERROR_CHECK;
+ xmlFreeTextWriter(tcxfile);
+ tcxfile = NULL;
+ }
+ break;
+ case 117: /* Lap informations end */
+ break;
+ case 450: /* Track informations end */
+ break;
+ default:
+ break;
+ }
+ break;
+ case 38:
+ unitid = data[doff] + data[doff + 1] * 256 + data[doff + 2] * 256 * 256 + data[doff + 3] * 256 * 256 * 256;
+ DEBUG_OUT(1, "Packet %d: UnitID: %u", pkttype, unitid);
+ break;
+ case 27: /* Number of following packages */
+ ndata = data[doff] + data[doff + 1] * 256;
+ DEBUG_OUT(2, "Packet %d: Number of following packages: %u", pkttype, ndata);
+ break;
+ case 1523: /* Max Trackpoints (?) 10000 */
+ case 994: /* Drei Limits (?) 200, 25, 200 */
+ case 1066: /* 20, 200, 100, ???? */
+ DEBUG_OUT(1, "Packet %d", pkttype);
+ if (dbg >= 2)
+ dump_data(stderr, data+doff, 0, pktlen);
+ break;
+ case 14: /* Current time (UTC) */
+ DEBUG_OUT(1, "Packet %d: Current time: %04u-%02u-%02u %02u:%02u:%02u", pkttype, data[doff + 2] + data[doff + 3] * 256, data[doff + 1], data[doff], data[doff + 4], data[doff + 6], data[doff + 7]);
+ break;
+ case 17:
+ DEBUG_OUT(1, "Packet %d: Position?", pkttype);
+ if (dbg >= 2)
+ dump_data(stderr, data+doff, 0, pktlen);
+ break;
+ case 990: /* Activity specification */
+ DEBUG_OUT(1, "Packet %d: Activity %u: laps %u-%u sport %u", pkttype, data[doff] + data[doff + 1] * 256, data[doff + 2] + data[doff + 3] * 256, data[doff + 4] + data[doff + 5] * 256, data[doff + 6]);
+
+ /* Initialize memory if not done before */
+ if (activities == NULL)
+ {
+ activities = (struct _activity *)calloc(256 * 256, sizeof(struct _activity));
+ if (activities == NULL)
+ {
+ ERROR_OUT("Cannot calloc enough memory");
+ exit(-1);
+ }
+ memset(activities, 0x00, sizeof(struct _activity) * 256 * 256);
+ } /* if (activities == NULL) */
+
+ activity_id = data[doff] + data[doff + 1] * 256;
+ activities[activity_id].first_lap = data[doff + 2] + data[doff + 3] * 256;
+ activities[activity_id].last_lap = data[doff + 4] + data[doff + 5] * 256;
+ activities[activity_id].sport = data[doff + 6];
+ activities[activity_id].valid = 1;
+
+ /* leftover (Most of!) */
+ if (dbg >= 2)
+ dump_data(stderr, data+doff, 7, pktlen-7);
+ break;
+ case 99:
+ DEBUG_OUT(1, "Packet %d: Activity index: %u", pkttype, data[doff] + data[doff + 1] * 256);
+
+ /* close previous file */
+ if (tcxfile)
+ {
+ /* add xml footer and close file, the next file will be open further down */
+ DEBUG_OUT(1, "Closing file");
+ print_tcx_footer(tcxfile);
+ xml_position = XML_OUTSIDE;
+ rc = xmlTextWriterEndDocument(tcxfile); XML_ERROR_CHECK;
+ xmlFreeTextWriter(tcxfile);
+ tcxfile = NULL;
+ }
+
+ activity_id = data[doff] + data[doff + 1] * 256;
+
+ if (laps == NULL || activities[activity_id].valid == 0 || laps[activities[activity_id].first_lap].valid == 0)
+ {
+ ERROR_OUT("Something is wrong in transfer");
+ exit(-1);
+ }
+
+ lap_id = activities[activity_id].first_lap;
+
+ /* use first lap starttime as filename */
+ tv_lap = laps[lap_id].timestamp;
+ strftime(tbuf, sizeof(tbuf), "%Y-%m-%d-%H%M%S.tcx", localtime(&tv_lap));
+ DEBUG_OUT(1, "Open file %s", tbuf);
+ /* open file and start with header of xml file */
+ tcxfile = xmlNewTextWriterFilename(tbuf, 0);
+ if (tcxfile == NULL)
+ {
+ ERROR_OUT("Error in XML creation");
+ exit(-1);
+ }
+ print_tcx_header(tcxfile);
+ xml_position = XML_IN_Activities;
+
+ rc = xmlTextWriterStartElement(tcxfile, BAD_CAST "Activity"); XML_ERROR_CHECK;
+ xml_position++;
+ switch (activities[activity_id].sport)
+ {
+ case 0:
+ rc = xmlTextWriterWriteAttribute(tcxfile, BAD_CAST "Sport", BAD_CAST "Running");
+ break;
+ case 1:
+ rc = xmlTextWriterWriteAttribute(tcxfile, BAD_CAST "Sport", BAD_CAST "Biking");
+ break;
+ case 2:
+ rc = xmlTextWriterWriteAttribute(tcxfile, BAD_CAST "Sport", BAD_CAST "Other");
+ break;
+ default:
+ rc = xmlTextWriterWriteElement(tcxfile, BAD_CAST "Notes", BAD_CAST "Unknown sport type"); XML_ERROR_CHECK;
+ rc = xmlTextWriterWriteAttribute(tcxfile, BAD_CAST "Sport", BAD_CAST "Other");
+ }
+ XML_ERROR_CHECK;
+
+ strftime(tbuf, sizeof tbuf, "%Y-%m-%dT%H:%M:%SZ", gmtime(&tv_lap));
+ rc = xmlTextWriterWriteFormatElement(tcxfile, BAD_CAST "Id", "%s", tbuf); XML_ERROR_CHECK;
+
+ /* leftover (5) */
+ if (dbg >= 2)
+ dump_data(stderr, data+doff, 2, pktlen-2);
+ break;
+ case 1510:
+ DEBUG_OUT(1, "%d Track package with %u waypoints", pkttype, data[doff] + data[doff + 1] * 256);
+
+ /* if trackpoints are split into more than one message 1510, do not add xml head again */
+
+ /* Do some sanity checks */
+ if (activities[activity_id].valid == 0 || laps[lap_id].valid == 0 || lap_id < activities[activity_id].first_lap || lap_id > activities[activity_id].last_lap)
+ {
+ ERROR_OUT("Sanity check failed");
+ ERROR_OUT("Activity: %u, lap: %u", activity_id, lap_id);
+ exit(-1);
+ } /* if (activities[activity_id].va... */
+
+ for (i = 4; i < pktlen; i += 24)
+ {
+ tv = data[doff + i + 8] + data[doff + i + 9] * 256 + data[doff + i + 10] * 256 * 256 + data[doff + i + 11] * 256 * 256 * 256 + garmin_epoch;
+
+ if (lap_id < activities[activity_id].last_lap && laps[lap_id + 1].valid && tv >= laps[lap_id + 1].timestamp)
+ {
+ lap_id++;
+ /* Close track and lap if still open (Should ever be) */
+ if (xml_position == XML_IN_Track)
+ {
+ rc = xmlTextWriterEndElement(tcxfile); XML_ERROR_CHECK; /* Track */
+ xml_position--;
+ rc = xmlTextWriterEndElement(tcxfile); XML_ERROR_CHECK; /* Lap */
+ xml_position--;
+ } /* if (xml_position == XML_IN_Tra... */
+ } /* if (lap_id < activities[activi... */
+
+ /* New lap, handle here to only write the code once */
+ if (xml_position == XML_IN_Activity)
+ {
+ strftime(tbuf, sizeof tbuf, "%Y-%m-%dT%H:%M:%SZ", gmtime(&laps[lap_id].timestamp));
+ rc = xmlTextWriterStartElement(tcxfile, BAD_CAST "Lap"); XML_ERROR_CHECK;
+ xml_position++;
+ rc = xmlTextWriterWriteFormatAttribute(tcxfile, BAD_CAST "StartTime", "%s", tbuf); XML_ERROR_CHECK;
+ rc = xmlTextWriterWriteFormatElement(tcxfile, BAD_CAST "TotalTimeSeconds", "%ld.%02ld00000", laps[lap_id].duration / 100, laps[lap_id].duration % 100); XML_ERROR_CHECK;
+ rc = xmlTextWriterWriteFormatElement(tcxfile, BAD_CAST "DistanceMeters", "%s", ground(laps[lap_id].distance)); XML_ERROR_CHECK;
+ rc = xmlTextWriterWriteFormatElement(tcxfile, BAD_CAST "MaximumSpeed", "%s", ground(laps[lap_id].max_speed)); XML_ERROR_CHECK;
+ rc = xmlTextWriterWriteFormatElement(tcxfile, BAD_CAST "Calories", "%d", laps[lap_id].calories); XML_ERROR_CHECK;
+
+ if (laps[lap_id].hr_avg > 0)
+ {
+ rc = xmlTextWriterStartElement(tcxfile, BAD_CAST "AverageHeartRateBpm"); XML_ERROR_CHECK;
+ rc = xmlTextWriterWriteAttribute(tcxfile, BAD_CAST "xsi:type", BAD_CAST "HeartRateInBeatsPerMinute_t"); XML_ERROR_CHECK;
+ rc = xmlTextWriterWriteFormatElement(tcxfile, BAD_CAST "Value", "%d", laps[lap_id].hr_avg); XML_ERROR_CHECK;
+ rc = xmlTextWriterEndElement(tcxfile); XML_ERROR_CHECK;
+ }
+ if (laps[lap_id].hr_max > 0)
+ {
+ rc = xmlTextWriterStartElement(tcxfile, BAD_CAST "MaximumHeartRateBpm"); XML_ERROR_CHECK;
+ rc = xmlTextWriterWriteAttribute(tcxfile, BAD_CAST "xsi:type", BAD_CAST "HeartRateInBeatsPerMinute_t"); XML_ERROR_CHECK;
+ rc = xmlTextWriterWriteFormatElement(tcxfile, BAD_CAST "Value", "%d", laps[lap_id].hr_max); XML_ERROR_CHECK;
+ rc = xmlTextWriterEndElement(tcxfile); XML_ERROR_CHECK;
+ }
+
+ switch (laps[lap_id].intensity)
+ {
+ case 0:
+ rc = xmlTextWriterWriteElement(tcxfile, BAD_CAST "Intensity", BAD_CAST "Active");
+ break;
+ case 1:
+ rc = xmlTextWriterWriteElement(tcxfile, BAD_CAST "Intensity", BAD_CAST "Resting");
+ break;
+ default:
+ rc = xmlTextWriterWriteElement(tcxfile, BAD_CAST "Intensity", BAD_CAST "Active");
+ }
+ XML_ERROR_CHECK;
+
+ /* for bike the average cadence of this lap is here */
+ if (activities[activity_id].sport == 1)
+ {
+ if (laps[lap_id].cadence != 255)
+ {
+ rc = xmlTextWriterWriteFormatElement(tcxfile, BAD_CAST "Cadence", "%d", laps[lap_id].cadence); XML_ERROR_CHECK;
+ }
+ }
+
+ switch (laps[lap_id].trigger)
+ {
+ case 4:
+ rc = xmlTextWriterWriteElement(tcxfile, BAD_CAST "TriggerMethod", BAD_CAST "HeartRate");
+ break;
+ case 3:
+ rc = xmlTextWriterWriteElement(tcxfile, BAD_CAST "TriggerMethod", BAD_CAST "Time");
+ break;
+ case 2:
+ rc = xmlTextWriterWriteElement(tcxfile, BAD_CAST "TriggerMethod", BAD_CAST "Location");
+ break;
+ case 1:
+ rc = xmlTextWriterWriteElement(tcxfile, BAD_CAST "TriggerMethod", BAD_CAST "Distance");
+ break;
+ case 0:
+ rc = xmlTextWriterWriteElement(tcxfile, BAD_CAST "TriggerMethod", BAD_CAST "Manual");
+ break;
+ default:
+ rc = xmlTextWriterWriteElement(tcxfile, BAD_CAST "TriggerMethod", BAD_CAST "Manual");
+ }
+ XML_ERROR_CHECK;
+
+ /* I prefere the average run cadence here than at the end of this lap according windows ANTagent */
+ if (activities[activity_id].sport == 0)
+ {
+ if (laps[lap_id].cadence != 255)
+ {
+ rc = xmlTextWriterStartElement(tcxfile, BAD_CAST "Extensions"); XML_ERROR_CHECK;
+ rc = xmlTextWriterStartElementNS(tcxfile, NULL, BAD_CAST "LX", BAD_CAST "http://www.garmin.com/xmlschemas/ActivityExtension/v2"); XML_ERROR_CHECK;
+ rc = xmlTextWriterWriteFormatElement(tcxfile, BAD_CAST "AvgRunCadence", "%d", laps[lap_id].cadence); XML_ERROR_CHECK;
+ rc = xmlTextWriterEndElement(tcxfile); XML_ERROR_CHECK; /* LX */
+ rc = xmlTextWriterEndElement(tcxfile); XML_ERROR_CHECK; /* Extensions */
+ }
+ }
+ rc = xmlTextWriterStartElement(tcxfile, BAD_CAST "Track"); XML_ERROR_CHECK;
+ xml_position++;
+
+ track_pause = 0;
+ } /* if (xml_position == XML_IN_Act... */
+
+ if (xml_position != XML_IN_Track)
+ {
+ ERROR_OUT("Need to write trackpoint but I am not in active track (Current: %d)", xml_position);
+ continue;
+ }
+
+ strftime(tbuf, sizeof tbuf, "%Y-%m-%dT%H:%M:%SZ", gmtime(&tv));
+ memcpy((void *)&alt, data + doff + i + 12, 4);
+ memcpy((void *)&dist, data + doff + i + 16, 4);
+ lat = (data[doff + i] + data[doff + i + 1] * 256 + data[doff + i + 2] * 256 * 256 + data[doff + i + 3] * 256 * 256 * 256) * 180.0 / 0x80000000;
+ lon = (data[doff + i + 4] + data[doff + i + 5] * 256 + data[doff + i + 6] * 256 * 256 + data[doff + i + 7] * 256 * 256 * 256) * 180.0 / 0x80000000;
+ hr = data[doff + i + 20];
+ cad = data[doff + i + 21];
+ u1 = data[doff + i + 22];
+ u2 = data[doff + i + 23];
+ DEBUG_OUT(2, "lat %.10g lon %.10g hr %d cad %d u1 %d u2 %d tv %d %s alt %f dist %f %02x %02x%02x%02x%02x", lat, lon, hr, cad, u1, u2, (int)tv, tbuf, alt, dist, data[doff + i + 3], data[doff + i + 16], data[doff + i + 17], data[doff + i + 18], data[doff + i + 19]);
+ /* track pause only if following trackpoint is aswell 'timemarker' with utopic distance */
+ if (track_pause && dist > (float)40000000)
+ {
+ rc = xmlTextWriterEndElement(tcxfile); XML_ERROR_CHECK; /* Track */
+ rc = xmlTextWriterStartElement(tcxfile, BAD_CAST "Track"); XML_ERROR_CHECK;
+ }
+
+ rc = xmlTextWriterStartElement(tcxfile, BAD_CAST "Trackpoint"); XML_ERROR_CHECK;
+ xml_position++;
+ rc = xmlTextWriterWriteFormatElement(tcxfile, BAD_CAST "Time", "%s", tbuf); XML_ERROR_CHECK;
+
+ if (lat < 90)
+ {
+ rc = xmlTextWriterStartElement(tcxfile, BAD_CAST "Position"); XML_ERROR_CHECK;
+ rc = xmlTextWriterWriteFormatElement(tcxfile, BAD_CAST "LatitudeDegrees", "%s", ground(lat)); XML_ERROR_CHECK;
+ rc = xmlTextWriterWriteFormatElement(tcxfile, BAD_CAST "LongitudeDegrees", "%s", ground(lon)); XML_ERROR_CHECK;
+ rc = xmlTextWriterEndElement(tcxfile); XML_ERROR_CHECK; /* Position */
+ rc = xmlTextWriterWriteFormatElement(tcxfile, BAD_CAST "AltitudeMeters", "%s", ground(alt)); XML_ERROR_CHECK;
+ }
+
+ /* last trackpoint has utopic distance, 40000km should be enough, hack? */
+ if (dist < (float)40000000)
+ {
+ rc = xmlTextWriterWriteFormatElement(tcxfile, BAD_CAST "DistanceMeters", "%s", ground(dist)); XML_ERROR_CHECK;
+ }
+
+ if (hr > 0)
+ {
+ rc = xmlTextWriterStartElement(tcxfile, BAD_CAST "HeartRateBpm"); XML_ERROR_CHECK;
+ rc = xmlTextWriterWriteAttribute(tcxfile, BAD_CAST "xsi:type", BAD_CAST "HeartRateInBeatsPerMinute_t"); XML_ERROR_CHECK;
+ rc = xmlTextWriterWriteFormatElement(tcxfile, BAD_CAST "Value", "%d", hr); XML_ERROR_CHECK;
+ rc = xmlTextWriterEndElement(tcxfile); XML_ERROR_CHECK; /* HeartRateBpm */
+ }
+
+ /* for bikes the cadence is written here and for the footpod in <Extensions>, why garmin? */
+ if (activities[activity_id].sport == 1)
+ {
+ if (cad != 255)
+ {
+ rc = xmlTextWriterWriteFormatElement(tcxfile, BAD_CAST "Cadence", "%d", cad); XML_ERROR_CHECK;
+ }
+ }
+
+ if (dist < (float)40000000)
+ {
+ rc = xmlTextWriterWriteElement(tcxfile, BAD_CAST "SensorState", u1 ? BAD_CAST "Present" : BAD_CAST "Absent"); XML_ERROR_CHECK;
+ if (u1 == 1 || cad != 255)
+ {
+ rc = xmlTextWriterStartElement(tcxfile, BAD_CAST "Extensions"); XML_ERROR_CHECK;
+ rc = xmlTextWriterStartElementNS(tcxfile, NULL, BAD_CAST "TPX", BAD_CAST "http://www.garmin.com/xmlschemas/ActivityExtension/v2"); XML_ERROR_CHECK;
+ rc = xmlTextWriterWriteFormatElement(tcxfile, BAD_CAST "AvgRunCadence", "%d", cad); XML_ERROR_CHECK;
+ /* get type of pod from data, could not figure it out, so using sporttyp of first track */
+ if (activities[activity_id].sport == 1)
+ {
+ rc = xmlTextWriterWriteAttribute(tcxfile, BAD_CAST "CadenceSensor", BAD_CAST "Bike"); XML_ERROR_CHECK;
+ }
+ else
+ {
+ rc = xmlTextWriterWriteAttribute(tcxfile, BAD_CAST "CadenceSensor", BAD_CAST "Footpod"); XML_ERROR_CHECK;
+ if (cad != 255)
+ {
+ rc = xmlTextWriterWriteFormatElement(tcxfile, BAD_CAST "RunCadence", "%d", cad); XML_ERROR_CHECK;
+ }
+ }
+ rc = xmlTextWriterEndElement(tcxfile); XML_ERROR_CHECK; /* TPX */
+ rc = xmlTextWriterEndElement(tcxfile); XML_ERROR_CHECK; /* Extensions */
+ }
+ track_pause = 0;
+ }
+
+ rc = xmlTextWriterEndElement(tcxfile); XML_ERROR_CHECK; /* Trackpoint */
+ xml_position--;
+
+ /* maybe if we recieve utopic position and distance this tells pause in the run (stop and go) if not begin or end of lap */
+ if (dist > (float)40000000 && track_pause == 0)
+ {
+ track_pause = 1;
+ DEBUG_OUT(2, "Track pause (stop and go)");
+ }
+ else
+ {
+ track_pause = 0;
+ }
+ } /* for (i = 4; i < pktlen; i += 2... */
+ break;
+ case 149: /* Lap specification */
+ DEBUG_OUT(1, "%d Lap data id: %u %u", pkttype, data[doff] + data[doff + 1] * 256, data[doff + 2] + data[doff + 3] * 256);
+
+ /* Initialize memory if not done before */
+ if (laps == NULL)
+ {
+ laps = (struct _lap *)calloc(256 * 256, sizeof(struct _lap));
+ if (laps == NULL)
+ {
+ ERROR_OUT("Cannot calloc enough memory");
+ exit(-1);
+ }
+ memset(laps, 0x00, sizeof(struct _lap) * 256 * 256);
+ } /* if (laps == NULL) */
+
+ lap_id = data[doff] + data[doff + 1] * 256;
+ laps[lap_id].timestamp = data[doff + 4] + data[doff + 5] * 256 + data[doff + 6] * 256 * 256 + data[doff + 7] * 256 * 256 * 256 + garmin_epoch;
+ laps[lap_id].duration = data[doff + 8] + data[doff + 9] * 256 + data[doff + 10] * 256 * 256 + data[doff + 11] * 256 * 256 * 256;
+ memcpy(&laps[lap_id].distance, &data[doff + 12], 4); /* Dirty, but seems to work */
+ memcpy(&laps[lap_id].max_speed, &data[doff + 16], 4); /* Dirty, but seems to work */
+ laps[lap_id].calories = data[doff + 36] + data[doff + 37] * 256;
+ laps[lap_id].hr_avg = data[doff + 38];
+ laps[lap_id].hr_max = data[doff + 39];
+ laps[lap_id].intensity = data[doff + 40];
+ laps[lap_id].cadence = data[doff + 41];
+ laps[lap_id].trigger = data[doff + 42];
+
+ laps[lap_id].valid = 1;
+
+ if (dbg >= 2)
+ {
+ dump_data(stderr, data+doff, 20, 16);
+ dump_data(stderr, data+doff, 43, pktlen-43);
+ }
+
+ break;
+ case 247: /* Software versions */
+ memset(modelname, 0, sizeof modelname);
+ memcpy(modelname, data + doff + 88, dsize - 88);
+ DEBUG_OUT(1, "%d Device name \"%s\"\n", pkttype, modelname);
+ break;
+ default:
+ DEBUG_OUT(1, "Don't know how to decode packet type %d", pkttype);
+ if (dbg >= 2)
+ dump_data(stderr, data+doff, 0, pktlen);
+ }
}
void usage(void)
{
- /* *INDENT-OFF* */
- fprintf(stderr, "Usage: %s -a authfile\n"
- " [ -a authfile ] Authfile (default ~/.gant)\n"
- " [ -f name ] (default garmin)\n"
- " [ -d devno ] Device no. (default 0)\n"
- " [ -i id ] ID for pairing (default random)\n"
- " [ -m mydev ] (default 0)\n"
- " [ -p ] Passive\n"
- " [ -v ] Verbose\n"
- " [ -D level ] Debug\n"
- " [ -r ] Reset the device\n"
- " [ -n ] Do not write auth file\n"
- " [ -z ] Do not pair\n"
- " [ -h ] This help\n",
- progname);
- /* *INDENT-ON* */
- exit(1);
+ /* *INDENT-OFF* */
+ fprintf(stderr, "Usage: %s -a authfile\n"
+ " [ -a authfile ] Authfile (default ~/.gant)\n"
+ " [ -f name ] (default garmin)\n"
+ " [ -d devno ] Device no. (default 0)\n"
+ " [ -i id ] ID for pairing (default random)\n"
+ " [ -m mydev ] (default 0)\n"
+ " [ -p ] Passive\n"
+ " [ -v ] Verbose\n"
+ " [ -D level ] Debug\n"
+ " [ -r ] Reset the device\n"
+ " [ -n ] Do not write auth file\n"
+ " [ -z ] Do not pair\n"
+ " [ -h ] This help\n",
+ progname);
+ /* *INDENT-ON* */
+ exit(1);
}
uchar chevent(uchar chan, uchar event)
{
- uchar status;
- uchar phase;
- /*uint newdata;*/
- struct ack_msg ack;
- struct auth_msg auth;
- struct pair_msg pair;
- uint id;
- int i;
- uint cid;
-
- DEBUG_OUT(5, "chevent %02x %02x", chan, event);
- if (event == EVENT_RX_BROADCAST)
- {
- status = cbuf[1] & 0xd7;
- /*newdata = cbuf[1] & 0x20;*/
- phase = cbuf[2];
- }
- cid = cbuf[4] + cbuf[5] * 256 + cbuf[6] * 256 * 256 + cbuf[7] * 256 * 256 * 256;
- memcpy((void *)&id, cbuf + 4, 4);
-
- DEBUG_OUT(6, "cid %08x myid %08x", cid, myid);
- if (dbg && event != EVENT_RX_BURST_PACKET)
- {
- DEBUG_OUT(5, "chan %d event %02x channel open: ", chan, event);
- for (i = 0; i < 8; i++)
- DEBUG_OUT(6, " -: %02x", cbuf[i]);
- }
-
- switch (event)
- {
- case EVENT_RX_BROADCAST:
- lastphase = phase; /* store the last phase we see the watch broadcast */
- DEBUG_OUT(3, "Lastphase %d", lastphase);
- if (!pairing && !nopairing)
- pairing = cbuf[1] & 8;
- if (!gottype)
- {
- gottype = 1;
- isa50 = cbuf[1] & 4;
- isa405 = cbuf[1] & 1;
- if ((isa50 && isa405) || (!isa50 && !isa405))
- {
- ERROR_OUT("50 %d and 405 %d", isa50, isa405);
- exit(1);
- }
- }
- if (verbose)
- {
- switch (phase)
- {
- case 0:
- DEBUG_OUT(4, "%s BC0 %02x %d %d %d PID %d %d %d %c%c", timestamp(), cbuf[0], cbuf[1] & 0xd7, cbuf[2], cbuf[3], cbuf[4] + cbuf[5] * 256, cbuf[6], cbuf[7], (cbuf[1] & 0x20) ? 'N' : ' ', (cbuf[1] & 0x08) ? 'P' : ' ');
- break;
- case 1:
- DEBUG_OUT(4, "%s BC1 %02x %d %d %d CID %08x %c%c", timestamp(), cbuf[0], cbuf[1] & 0xd7, cbuf[2], cbuf[3], cid, (cbuf[1] & 0x20) ? 'N' : ' ', (cbuf[1] & 0x08) ? 'P' : ' ');
- break;
- DEBUG_OUT(4, "%s BCX %02x %d %d %d PID %d %d %d %c%c", timestamp(), cbuf[0], cbuf[1] & 0xd7, cbuf[2], cbuf[3], cbuf[4] + cbuf[5] * 256, cbuf[6], cbuf[7], (cbuf[1] & 0x20) ? 'N' : ' ', (cbuf[1] & 0x08) ? 'P' : ' ');
- default:
- break;
- }
- }
-
- DEBUG_OUT(6, "Watch status %02x stage %d id %08x", status, phase, id);
- if (!sentid)
- {
- sentid = 1;
- ANT_RequestMessage(chan, MESG_CHANNEL_ID_ID); /* request sender id */
- }
-
- /* if we don't see a phase 0 message first, reset the watch */
- if (reset || (phase != 0 && !seenphase0))
- {
- DEBUG_OUT(1, "Resetting");
- 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);
- exit(1);
- }
- switch (phase)
- {
- case 0:
- seenphase0 = 1;
- nphase0++;
- if (nphase0 % 10 == 0)
- donebind = 0;
- if (newfreq)
- {
- /* switch to new frequency */
- ANT_SetChannelPeriod(chan, period);
- ANT_SetChannelSearchTimeout(chan, 3);
- ANT_SetChannelRFFreq(chan, newfreq);
- newfreq = 0;
- }
- /* phase 0 seen after reset at end of download */
- if (downloadfinished)
- {
- DEBUG_OUT(1, "Download finished");
- exit(0);
- }
- /* generate a random id if pairing and user didn't specify one */
- if (pairing && !myid)
- {
- myid = randno();
- DEBUG_OUT(1, "Pairing, using id %08x", myid);
- }
- /* need id codes from auth file if not pairing */
- /* TODO: handle multiple watches */
- /* BUG: myauth1 should be allowed to be 0 */
- if (!pairing && !myauth1)
- {
- int nr;
-
- DEBUG_OUT(1, "Reading auth data from %s", authfile);
- authfd = open(authfile, O_RDONLY);
- if (authfd < 0)
- {
- perror(authfile);
- ERROR_OUT("No auth data. Need to pair first");
- exit(1);
- }
- nr = read(authfd, authdata, 32);
- close(authfd);
- if (nr != 32 && nr != 24)
- {
- ERROR_OUT("Bad auth file len %d != 32 or 24", nr);
- exit(1);
- }
- /* BUG: auth file not portable */
- memcpy((void *)&myauth1, authdata + 16, 4);
- memcpy((void *)&myauth2, authdata + 20, 4);
- memcpy((void *)&mydev, authdata + 12, 4);
- memcpy((void *)&myid, authdata + 4, 4);
- DEBUG_OUT(4, "dev %08x auth %08x %08x id %08x", mydev, myauth1, myauth2, myid);
- }
- /* bind to watch */
- if (!donebind && devid)
- {
- donebind = 1;
- if (isa405)
- newfreq = 0x32;
- ack.code = 0x44;
- ack.atype = 2;
- ack.c1 = isa50 ? 0x32 : newfreq;
- ack.c2 = 0x04;
- ack.id = myid;
- ANT_SendAcknowledgedData(chan, (void *)&ack); /* bind */
- }
- else
- {
- DEBUG_OUT(6, "Donebind %d devid %x", donebind, devid);
- }
- break;
- case 1:
- DEBUG_OUT(3, "Case 1 %x", peerdev);
- if (peerdev)
- {
- DEBUG_OUT(4, " -: peerdev");
- /* if watch has sent id */
- if (mydev != 0 && peerdev != mydev)
- {
- DEBUG_OUT(1, "Don't know this device %08x != %08x", peerdev, mydev);
- }
- else if (!sentauth && !waitauth)
- {
- DEBUG_OUT(4, " -: diffdev");
- 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;
- sentauth = 1;
- ANT_SendBurstTransfer(chan, (void *)&auth, (sizeof auth) / 8); /* send our auth data */
- }
- }
- DEBUG_OUT(4, " -: cid %x myid %x", cid, myid);
- if (!sentack2 && cid == myid && !waitauth)
- {
- sentack2 = 1;
- DEBUG_OUT(4, " -: sending ack2");
- /* if it did bind to me before someone else */
- ack.code = 0x44;
- ack.atype = 4;
- ack.c1 = 0x01;
- ack.c2 = 0x00;
- ack.id = myid;
- ANT_SendAcknowledgedData(chan, (void *)&ack); /* request id */
- }
- break;
- case 2:
- /* successfully authenticated */
- if (!downloadstarted)
- {
- downloadstarted = 1;
- DEBUG_OUT(1, "Starting download");
- ack.code = 0x44;
- ack.atype = 6;
- ack.c1 = 0x01;
- ack.c2 = 0x00;
- ack.id = 0;
- /* ANT_SendAcknowledgedData(chan, (void *)&ack); // tell garmin to start upload */
- }
- if (downloadfinished)
- {
- DEBUG_OUT(1, "Finished download");
- ack.code = 0x44;
- ack.atype = 3;
- ack.c1 = 0x00;
- ack.c2 = 0x00;
- ack.id = 0;
- if (!passive)
- ANT_SendAcknowledgedData(chan, (void *)&ack); /* tell garmin we're finished */
- }
- break;
- case 3:
- if (pairing)
- {
- /* waiting for the user to pair */
- printf("Please press \"View\" on watch to confirm pairing\n");
- waitauth = 2; /* next burst data is auth data */
- }
- else
- {
- DEBUG_OUT(1, "Not sure why in phase 3");
- if (!sentgetv)
- {
- sentgetv = 1;
- /* ANT_SendBurstTransferA(chan, getversion, strlen(getversion)/16); */
- }
- }
- break;
- default:
- DEBUG_OUT(1, "Unknown phase %d", phase);
- break;
- }
- break;
- case EVENT_RX_BURST_PACKET:
- /* now handled in coalesced burst below */
- DEBUG_OUT(5, "Burst");
- break;
- case EVENT_RX_FAKE_BURST:
- DEBUG_OUT(5, "rxfake burst pairing %d blast %ld waitauth %d", pairing, (long)blast, waitauth);
- blsize = *(int *)(cbuf + 4);
- memcpy(&blast, cbuf + 8, 4);
- if (dbg)
- {
- DEBUG_OUT(6, "Fake burst %d %lx", blsize, (long)blast);
- for (i = 0; i < blsize && i < 64; i++)
- DEBUG_OUT(4, " -: %02x", blast[i]);
- for (i = 0; i < blsize; i++)
- if (isprint(blast[i]))
- {
- DEBUG_OUT(6, " --: %c", blast[i]);
- }
- else
- DEBUG_OUT(6, " --: .");
- }
- if (sentauth)
- {
- static int nacksent = 0;
- static char ackpkt[100];
-
- /* ack the last packet */
- ushort bloblen = blast[14] + 256 * blast[15];
-
- ushort pkttype = blast[16] + 256 * blast[17];
-
- ushort pktlen = blast[18] + 256 * blast[19];
-
- if (bloblen == 0)
- {
- /* request next set of data */
- const char* ackdata = acks[nacksent++];
- DEBUG_OUT(2, "bloblen %d, get next data", bloblen);
- if (!strcmp(ackdata, ""))
- { /* finished */
- DEBUG_OUT(2, "ACKs finished, resetting");
- ack.code = 0x44;
- ack.atype = 3;
- ack.c1 = 0x00;
- ack.c2 = 0x00;
- ack.id = 0;
- ANT_SendAcknowledgedData(chan, (void *)&ack); /* go to idle */
- sleep(1);
- exit(1);
- }
- DEBUG_OUT(2, "Got type 0, sending ACK %s", ackdata);
- snprintf(ackpkt, 100, "440dffff00000000%s", ackdata);
- }
- else if (bloblen == 65535)
- {
- /* repeat last ack */
- DEBUG_OUT(2, "Repeating ACK %s", ackpkt);
- ANT_SendBurstTransferA(chan, (uchar *) ackpkt, strlen(ackpkt) / 16);
- }
- else
- {
- DEBUG_OUT(2, "Non-0 bloblen %d", bloblen);
- decode(bloblen, pkttype, pktlen, blsize, blast);
- snprintf(ackpkt, 100, "440dffff0000000006000200%02x%02x0000", pkttype % 256, pkttype / 256);
- }
- DEBUG_OUT(1, "Received pkttype %d len %d", pkttype, pktlen);
- DEBUG_OUT(2, "Acking %s", ackpkt);
- ANT_SendBurstTransferA(chan, (uchar *) ackpkt, strlen(ackpkt) / 16);
- }
- else if (!nopairing && pairing && blast)
- {
- memcpy(&peerdev, blast + 12, 4);
- DEBUG_OUT(1, "Watch id %08x waitauth %d", peerdev, waitauth);
- if (mydev != 0 && peerdev != mydev)
- {
- ERROR_OUT("Don't know this device %08x != %08x", peerdev, mydev);
- exit(1);
- }
- if (waitauth == 2)
- {
- int nw;
-
- /* should be receiving auth data */
- if (nowriteauth)
- {
- ERROR_OUT("Not overwriting auth data");
- exit(1);
- }
- DEBUG_OUT(1, "Storing auth data in %s", authfile);
- authfd = open(authfile, O_WRONLY | O_CREAT, 0644);
- if (authfd < 0)
- {
- perror(authfile);
- exit(1);
- }
- nw = write(authfd, blast, blsize);
- if (nw != blsize)
- {
- ERROR_OUT("Auth write failed fd %d %d", authfd, nw);
- perror("write");
- exit(1);
- }
- close(authfd);
- /* exit(1); */
- pairing = 0;
- waitauth = 0;
- reset = 1;
- }
- if (pairing && !waitauth)
- {
- /* assert(sizeof pair == PAIRSIZE); */
- pair.code = 0x44;
- pair.atype = 4;
- pair.phase = 2;
- pair.id = myid;
- bzero(pair.devname, sizeof pair.devname);
- /* if (peerdev <= 9999999) // only allow 7 digits */
- /* sprintf(pair.devname, "%u", peerdev); */
- strcpy(pair.devname, fname);
- /* else */
- /* DEBUG_OUT(1, "Pair dev name too large %08x \"%d\"\n", peerdev, peerdev) */
- pair.u1 = strlen(pair.devname);
- DEBUG_OUT(1, "Sending pair data for dev %s", pair.devname);
- waitauth = 1;
- if (isa405 && pairing)
- {
- /* go straight to storing auth data */
- waitauth = 2;
- }
- ANT_SendBurstTransfer(chan, (void *)&pair, (sizeof pair) / 8); /* send pair data */
- }
- else
- {
- DEBUG_OUT(1, "Not pairing");
- }
- }
- else if (!gotwatchid && (lastphase == 1))
- {
- static int once = 0;
-
- gotwatchid = 1;
- /* garmin sending authentication/identification data */
- if (!once)
- {
- once = 1;
- DEBUG_OUT(3, "ID data:");
- }
- if (dbg)
- for (i = 0; i < blsize; i++)
- DEBUG_OUT(4, " -: %02x", blast[i]);
- memcpy(&peerdev, blast + 12, 4);
- DEBUG_OUT(1, "watch id %08x", peerdev);
- if (mydev != 0 && peerdev != mydev)
- {
- ERROR_OUT("Don't know this device %08x != %08x", peerdev, mydev);
- exit(1);
- }
- }
- else if (lastphase == 2)
- {
- static int once = 0;
-
- DEBUG_OUT(2, "Once %d", once)
- /* garmin uploading in response to sendack3 */
- /* in this state we're receiving the workout data */
- if (!once)
- {
- DEBUG_OUT(2, "Receiving");
- once = 1;
- }
- }
- DEBUG_OUT(1, "Continuing after burst");
- break;
- }
- return 1;
+ uchar status;
+ uchar phase;
+ /*uint newdata;*/
+ struct ack_msg ack;
+ struct auth_msg auth;
+ struct pair_msg pair;
+ uint id;
+ int i;
+ uint cid;
+
+ DEBUG_OUT(5, "chevent %02x %02x", chan, event);
+ if (event == EVENT_RX_BROADCAST)
+ {
+ status = cbuf[1] & 0xd7;
+ /*newdata = cbuf[1] & 0x20;*/
+ phase = cbuf[2];
+ }
+ cid = cbuf[4] + cbuf[5] * 256 + cbuf[6] * 256 * 256 + cbuf[7] * 256 * 256 * 256;
+ memcpy((void *)&id, cbuf + 4, 4);
+
+ DEBUG_OUT(6, "cid %08x myid %08x", cid, myid);
+ if (dbg && event != EVENT_RX_BURST_PACKET)
+ {
+ DEBUG_OUT(5, "chan %d event %02x channel open: ", chan, event);
+ for (i = 0; i < 8; i++)
+ DEBUG_OUT(6, " -: %02x", cbuf[i]);
+ }
+
+ switch (event)
+ {
+ case EVENT_RX_BROADCAST:
+ lastphase = phase; /* store the last phase we see the watch broadcast */
+ DEBUG_OUT(3, "Lastphase %d", lastphase);
+ if (!pairing && !nopairing)
+ pairing = cbuf[1] & 8;
+ if (!gottype)
+ {
+ gottype = 1;
+ isa50 = cbuf[1] & 4;
+ isa405 = cbuf[1] & 1;
+ if ((isa50 && isa405) || (!isa50 && !isa405))
+ {
+ ERROR_OUT("50 %d and 405 %d", isa50, isa405);
+ exit(1);
+ }
+ }
+ if (verbose)
+ {
+ switch (phase)
+ {
+ case 0:
+ DEBUG_OUT(4, "%s BC0 %02x %d %d %d PID %d %d %d %c%c", timestamp(), cbuf[0], cbuf[1] & 0xd7, cbuf[2], cbuf[3], cbuf[4] + cbuf[5] * 256, cbuf[6], cbuf[7], (cbuf[1] & 0x20) ? 'N' : ' ', (cbuf[1] & 0x08) ? 'P' : ' ');
+ break;
+ case 1:
+ DEBUG_OUT(4, "%s BC1 %02x %d %d %d CID %08x %c%c", timestamp(), cbuf[0], cbuf[1] & 0xd7, cbuf[2], cbuf[3], cid, (cbuf[1] & 0x20) ? 'N' : ' ', (cbuf[1] & 0x08) ? 'P' : ' ');
+ break;
+ DEBUG_OUT(4, "%s BCX %02x %d %d %d PID %d %d %d %c%c", timestamp(), cbuf[0], cbuf[1] & 0xd7, cbuf[2], cbuf[3], cbuf[4] + cbuf[5] * 256, cbuf[6], cbuf[7], (cbuf[1] & 0x20) ? 'N' : ' ', (cbuf[1] & 0x08) ? 'P' : ' ');
+ default:
+ break;
+ }
+ }
+
+ DEBUG_OUT(6, "Watch status %02x stage %d id %08x", status, phase, id);
+ if (!sentid)
+ {
+ sentid = 1;
+ ANT_RequestMessage(chan, MESG_CHANNEL_ID_ID); /* request sender id */
+ }
+
+ /* if we don't see a phase 0 message first, reset the watch */
+ if (reset || (phase != 0 && !seenphase0))
+ {
+ DEBUG_OUT(1, "Resetting");
+ 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);
+ exit(1);
+ }
+ switch (phase)
+ {
+ case 0:
+ seenphase0 = 1;
+ nphase0++;
+ if (nphase0 % 10 == 0)
+ donebind = 0;
+ if (newfreq)
+ {
+ /* switch to new frequency */
+ ANT_SetChannelPeriod(chan, period);
+ ANT_SetChannelSearchTimeout(chan, 3);
+ ANT_SetChannelRFFreq(chan, newfreq);
+ newfreq = 0;
+ }
+ /* phase 0 seen after reset at end of download */
+ if (downloadfinished)
+ {
+ DEBUG_OUT(1, "Download finished");
+ exit(0);
+ }
+ /* generate a random id if pairing and user didn't specify one */
+ if (pairing && !myid)
+ {
+ myid = randno();
+ DEBUG_OUT(1, "Pairing, using id %08x", myid);
+ }
+ /* need id codes from auth file if not pairing */
+ /* TODO: handle multiple watches */
+ /* BUG: myauth1 should be allowed to be 0 */
+ if (!pairing && !myauth1)
+ {
+ int nr;
+
+ DEBUG_OUT(1, "Reading auth data from %s", authfile);
+ authfd = open(authfile, O_RDONLY);
+ if (authfd < 0)
+ {
+ perror(authfile);
+ ERROR_OUT("No auth data. Need to pair first");
+ exit(1);
+ }
+ nr = read(authfd, authdata, 32);
+ close(authfd);
+ if (nr != 32 && nr != 24)
+ {
+ ERROR_OUT("Bad auth file len %d != 32 or 24", nr);
+ exit(1);
+ }
+ /* BUG: auth file not portable */
+ memcpy((void *)&myauth1, authdata + 16, 4);
+ memcpy((void *)&myauth2, authdata + 20, 4);
+ memcpy((void *)&mydev, authdata + 12, 4);
+ memcpy((void *)&myid, authdata + 4, 4);
+ DEBUG_OUT(4, "dev %08x auth %08x %08x id %08x", mydev, myauth1, myauth2, myid);
+ }
+ /* bind to watch */
+ if (!donebind && devid)
+ {
+ donebind = 1;
+ if (isa405)
+ newfreq = 0x32;
+ ack.code = 0x44;
+ ack.atype = 2;
+ ack.c1 = isa50 ? 0x32 : newfreq;
+ ack.c2 = 0x04;
+ ack.id = myid;
+ ANT_SendAcknowledgedData(chan, (void *)&ack); /* bind */
+ }
+ else
+ {
+ DEBUG_OUT(6, "Donebind %d devid %x", donebind, devid);
+ }
+ break;
+ case 1:
+ DEBUG_OUT(3, "Case 1 %x", peerdev);
+ if (peerdev)
+ {
+ DEBUG_OUT(4, " -: peerdev");
+ /* if watch has sent id */
+ if (mydev != 0 && peerdev != mydev)
+ {
+ DEBUG_OUT(1, "Don't know this device %08x != %08x", peerdev, mydev);
+ }
+ else if (!sentauth && !waitauth)
+ {
+ DEBUG_OUT(4, " -: diffdev");
+ 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;
+ sentauth = 1;
+ ANT_SendBurstTransfer(chan, (void *)&auth, (sizeof auth) / 8); /* send our auth data */
+ }
+ }
+ DEBUG_OUT(4, " -: cid %x myid %x", cid, myid);
+ if (!sentack2 && cid == myid && !waitauth)
+ {
+ sentack2 = 1;
+ DEBUG_OUT(4, " -: sending ack2");
+ /* if it did bind to me before someone else */
+ ack.code = 0x44;
+ ack.atype = 4;
+ ack.c1 = 0x01;
+ ack.c2 = 0x00;
+ ack.id = myid;
+ ANT_SendAcknowledgedData(chan, (void *)&ack); /* request id */
+ }
+ break;
+ case 2:
+ /* successfully authenticated */
+ if (!downloadstarted)
+ {
+ downloadstarted = 1;
+ DEBUG_OUT(1, "Starting download");
+ ack.code = 0x44;
+ ack.atype = 6;
+ ack.c1 = 0x01;
+ ack.c2 = 0x00;
+ ack.id = 0;
+ /* ANT_SendAcknowledgedData(chan, (void *)&ack); // tell garmin to start upload */
+ }
+ if (downloadfinished)
+ {
+ DEBUG_OUT(1, "Finished download");
+ ack.code = 0x44;
+ ack.atype = 3;
+ ack.c1 = 0x00;
+ ack.c2 = 0x00;
+ ack.id = 0;
+ if (!passive)
+ ANT_SendAcknowledgedData(chan, (void *)&ack); /* tell garmin we're finished */
+ }
+ break;
+ case 3:
+ if (pairing)
+ {
+ /* waiting for the user to pair */
+ printf("Please press \"View\" on watch to confirm pairing\n");
+ waitauth = 2; /* next burst data is auth data */
+ }
+ else
+ {
+ DEBUG_OUT(1, "Not sure why in phase 3");
+ if (!sentgetv)
+ {
+ sentgetv = 1;
+ /* ANT_SendBurstTransferA(chan, getversion, strlen(getversion)/16); */
+ }
+ }
+ break;
+ default:
+ DEBUG_OUT(1, "Unknown phase %d", phase);
+ break;
+ }
+ break;
+ case EVENT_RX_BURST_PACKET:
+ /* now handled in coalesced burst below */
+ DEBUG_OUT(5, "Burst");
+ break;
+ case EVENT_RX_FAKE_BURST:
+ DEBUG_OUT(5, "rxfake burst pairing %d blast %ld waitauth %d", pairing, (long)blast, waitauth);
+ blsize = *(int *)(cbuf + 4);
+ memcpy(&blast, cbuf + 8, 4);
+ if (dbg)
+ {
+ DEBUG_OUT(6, "Fake burst %d %lx", blsize, (long)blast);
+ for (i = 0; i < blsize && i < 64; i++)
+ DEBUG_OUT(4, " -: %02x", blast[i]);
+ for (i = 0; i < blsize; i++)
+ if (isprint(blast[i]))
+ {
+ DEBUG_OUT(6, " --: %c", blast[i]);
+ }
+ else
+ DEBUG_OUT(6, " --: .");
+ }
+ if (sentauth)
+ {
+ static int nacksent = 0;
+ static char ackpkt[100];
+
+ /* ack the last packet */
+ ushort bloblen = blast[14] + 256 * blast[15];
+
+ ushort pkttype = blast[16] + 256 * blast[17];
+
+ ushort pktlen = blast[18] + 256 * blast[19];
+
+ if (bloblen == 0)
+ {
+ /* request next set of data */
+ const char* ackdata = acks[nacksent++];
+ DEBUG_OUT(2, "bloblen %d, get next data", bloblen);
+ if (!strcmp(ackdata, ""))
+ { /* finished */
+ DEBUG_OUT(2, "ACKs finished, resetting");
+ ack.code = 0x44;
+ ack.atype = 3;
+ ack.c1 = 0x00;
+ ack.c2 = 0x00;
+ ack.id = 0;
+ ANT_SendAcknowledgedData(chan, (void *)&ack); /* go to idle */
+ sleep(1);
+ exit(1);
+ }
+ DEBUG_OUT(2, "Got type 0, sending ACK %s", ackdata);
+ snprintf(ackpkt, 100, "440dffff00000000%s", ackdata);
+ }
+ else if (bloblen == 65535)
+ {
+ /* repeat last ack */
+ DEBUG_OUT(2, "Repeating ACK %s", ackpkt);
+ ANT_SendBurstTransferA(chan, (uchar *) ackpkt, strlen(ackpkt) / 16);
+ }
+ else
+ {
+ DEBUG_OUT(2, "Non-0 bloblen %d", bloblen);
+ decode(bloblen, pkttype, pktlen, blsize, blast);
+ snprintf(ackpkt, 100, "440dffff0000000006000200%02x%02x0000", pkttype % 256, pkttype / 256);
+ }
+ DEBUG_OUT(1, "Received pkttype %d len %d", pkttype, pktlen);
+ DEBUG_OUT(2, "Acking %s", ackpkt);
+ ANT_SendBurstTransferA(chan, (uchar *) ackpkt, strlen(ackpkt) / 16);
+ }
+ else if (!nopairing && pairing && blast)
+ {
+ memcpy(&peerdev, blast + 12, 4);
+ DEBUG_OUT(1, "Watch id %08x waitauth %d", peerdev, waitauth);
+ if (mydev != 0 && peerdev != mydev)
+ {
+ ERROR_OUT("Don't know this device %08x != %08x", peerdev, mydev);
+ exit(1);
+ }
+ if (waitauth == 2)
+ {
+ int nw;
+
+ /* should be receiving auth data */
+ if (nowriteauth)
+ {
+ ERROR_OUT("Not overwriting auth data");
+ exit(1);
+ }
+ DEBUG_OUT(1, "Storing auth data in %s", authfile);
+ authfd = open(authfile, O_WRONLY | O_CREAT, 0644);
+ if (authfd < 0)
+ {
+ perror(authfile);
+ exit(1);
+ }
+ nw = write(authfd, blast, blsize);
+ if (nw != blsize)
+ {
+ ERROR_OUT("Auth write failed fd %d %d", authfd, nw);
+ perror("write");
+ exit(1);
+ }
+ close(authfd);
+ /* exit(1); */
+ pairing = 0;
+ waitauth = 0;
+ reset = 1;
+ }
+ if (pairing && !waitauth)
+ {
+ /* assert(sizeof pair == PAIRSIZE); */
+ pair.code = 0x44;
+ pair.atype = 4;
+ pair.phase = 2;
+ pair.id = myid;
+ bzero(pair.devname, sizeof pair.devname);
+ /* if (peerdev <= 9999999) // only allow 7 digits */
+ /* sprintf(pair.devname, "%u", peerdev); */
+ strcpy(pair.devname, fname);
+ /* else */
+ /* DEBUG_OUT(1, "Pair dev name too large %08x \"%d\"\n", peerdev, peerdev) */
+ pair.u1 = strlen(pair.devname);
+ DEBUG_OUT(1, "Sending pair data for dev %s", pair.devname);
+ waitauth = 1;
+ if (isa405 && pairing)
+ {
+ /* go straight to storing auth data */
+ waitauth = 2;
+ }
+ ANT_SendBurstTransfer(chan, (void *)&pair, (sizeof pair) / 8); /* send pair data */
+ }
+ else
+ {
+ DEBUG_OUT(1, "Not pairing");
+ }
+ }
+ else if (!gotwatchid && (lastphase == 1))
+ {
+ static int once = 0;
+
+ gotwatchid = 1;
+ /* garmin sending authentication/identification data */
+ if (!once)
+ {
+ once = 1;
+ DEBUG_OUT(3, "ID data:");
+ }
+ if (dbg)
+ for (i = 0; i < blsize; i++)
+ DEBUG_OUT(4, " -: %02x", blast[i]);
+ memcpy(&peerdev, blast + 12, 4);
+ DEBUG_OUT(1, "watch id %08x", peerdev);
+ if (mydev != 0 && peerdev != mydev)
+ {
+ ERROR_OUT("Don't know this device %08x != %08x", peerdev, mydev);
+ exit(1);
+ }
+ }
+ else if (lastphase == 2)
+ {
+ static int once = 0;
+
+ DEBUG_OUT(2, "Once %d", once)
+ /* garmin uploading in response to sendack3 */
+ /* in this state we're receiving the workout data */
+ if (!once)
+ {
+ DEBUG_OUT(2, "Receiving");
+ once = 1;
+ }
+ }
+ DEBUG_OUT(1, "Continuing after burst");
+ break;
+ }
+ return 1;
}
uchar revent(uchar chan, uchar event)
{
- int i;
-
- DEBUG_OUT(5, "Revent: %02x %02x", chan, event);
- switch (event)
- {
- case EVENT_TRANSFER_TX_COMPLETED:
- DEBUG_OUT(4, "Transfer complete: %02x", ebuf[1]);
- break;
- case INVALID_MESSAGE:
- DEBUG_OUT(4, "Invalid message: %02x", ebuf[1]);
- break;
- case RESPONSE_NO_ERROR:
- switch (ebuf[1])
- {
- case MESG_ASSIGN_CHANNEL_ID:
- ANT_AssignChannelEventFunction(chan, chevent, cbuf);
- break;
- case MESG_OPEN_CHANNEL_ID:
- DEBUG_OUT(1, "Channel open, waiting for broadcast");
- break;
- default:
- DEBUG_OUT(4, "Message: %02x NO_ERROR", ebuf[1]);
- break;
- }
- break;
- case MESG_CHANNEL_ID_ID:
- devid = ebuf[1] + ebuf[2] * 256;
- if (mydev == 0 || devid == mydev % 65536)
- {
- DEBUG_OUT(4, "DevID %08x myid %08x", devid, myid);
- }
- else
- {
- DEBUG_OUT(3, "Ignoring unknown device %08x, mydev %08x", devid, mydev);
- devid = sentid = 0; /* reset */
- }
- break;
- case MESG_NETWORK_KEY_ID:
- case MESG_SEARCH_WAVEFORM_ID:
- case MESG_OPEN_CHANNEL_ID:
- DEBUG_OUT(4, "Response event %02x code %02x", event, ebuf[2]);
- for (i = 0; i < 8; i++)
- DEBUG_OUT(4, " -: %02x", ebuf[i]);
- break;
- case MESG_CAPABILITIES_ID:
- DEBUG_OUT(4, "Capabilities chans %d nets %d opt %02x adv %02x", ebuf[0], ebuf[1], ebuf[2], ebuf[3]);
- break;
- case MESG_CHANNEL_STATUS_ID:
- DEBUG_OUT(4, "Channel status %d", ebuf[1]);
- break;
- case EVENT_RX_FAIL:
- case EVENT_TRANSFER_TX_FAILED:
- case EVENT_TRANSFER_RX_FAILED:
- /* ignore this */
- break;
- case EVENT_RX_SEARCH_TIMEOUT:
- printf("Timeout, please make sure the device is not in standby.\n");
- break;
- default:
- DEBUG_OUT(3, "Unhandled response event %02x", event);
- break;
- }
- return 1;
+ int i;
+
+ DEBUG_OUT(5, "Revent: %02x %02x", chan, event);
+ switch (event)
+ {
+ case EVENT_TRANSFER_TX_COMPLETED:
+ DEBUG_OUT(4, "Transfer complete: %02x", ebuf[1]);
+ break;
+ case INVALID_MESSAGE:
+ DEBUG_OUT(4, "Invalid message: %02x", ebuf[1]);
+ break;
+ case RESPONSE_NO_ERROR:
+ switch (ebuf[1])
+ {
+ case MESG_ASSIGN_CHANNEL_ID:
+ ANT_AssignChannelEventFunction(chan, chevent, cbuf);
+ break;
+ case MESG_OPEN_CHANNEL_ID:
+ DEBUG_OUT(1, "Channel open, waiting for broadcast");
+ break;
+ default:
+ DEBUG_OUT(4, "Message: %02x NO_ERROR", ebuf[1]);
+ break;
+ }
+ break;
+ case MESG_CHANNEL_ID_ID:
+ devid = ebuf[1] + ebuf[2] * 256;
+ if (mydev == 0 || devid == mydev % 65536)
+ {
+ DEBUG_OUT(4, "DevID %08x myid %08x", devid, myid);
+ }
+ else
+ {
+ DEBUG_OUT(3, "Ignoring unknown device %08x, mydev %08x", devid, mydev);
+ devid = sentid = 0; /* reset */
+ }
+ break;
+ case MESG_NETWORK_KEY_ID:
+ case MESG_SEARCH_WAVEFORM_ID:
+ case MESG_OPEN_CHANNEL_ID:
+ DEBUG_OUT(4, "Response event %02x code %02x", event, ebuf[2]);
+ for (i = 0; i < 8; i++)
+ DEBUG_OUT(4, " -: %02x", ebuf[i]);
+ break;
+ case MESG_CAPABILITIES_ID:
+ DEBUG_OUT(4, "Capabilities chans %d nets %d opt %02x adv %02x", ebuf[0], ebuf[1], ebuf[2], ebuf[3]);
+ break;
+ case MESG_CHANNEL_STATUS_ID:
+ DEBUG_OUT(4, "Channel status %d", ebuf[1]);
+ break;
+ case EVENT_RX_FAIL:
+ case EVENT_TRANSFER_TX_FAILED:
+ case EVENT_TRANSFER_RX_FAILED:
+ /* ignore this */
+ break;
+ case EVENT_RX_SEARCH_TIMEOUT:
+ printf("Timeout, please make sure the device is not in standby.\n");
+ break;
+ default:
+ DEBUG_OUT(3, "Unhandled response event %02x", event);
+ break;
+ }
+ return 1;
}
int main(int ac, char *av[])
{
- 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 srchto = 255; /* max timeout */
- int waveform = 0x0053; /* aids search somehow */
- int c;
- extern char *optarg;
- extern int optind;
-
- /* default auth file // */
- if (getenv("HOME"))
- {
- authfile = malloc(strlen(getenv("HOME")) + strlen("/.gant") + 1);
- if (authfile)
- sprintf(authfile, "%s/.gant", getenv("HOME"));
- }
- progname = av[0];
- while ((c = getopt(ac, av, "a:f:d:i:m:pvD:rnzh")) != -1)
- {
- switch (c)
- {
- case 'a':
- authfile = optarg;
- break;
- case 'f':
- fname = optarg;
- break;
- case 'd':
- devnum = atoi(optarg);
- break;
- case 'i':
- myid = atoi(optarg);
- break;
- case 'm':
- mydev = atoi(optarg);
- break;
- case 'p':
- passive = 1;
- break;
- case 'v':
- verbose = 1;
- break;
- case 'D':
- dbg = atoi(optarg);
- break;
- case 'r':
- reset = 1;
- break;
- case 'n':
- nowriteauth = 1;
- break;
- case 'z':
- nopairing = 1;
- break;
- case 'h':
- usage();
- default:
- ERROR_OUT("unknown option %s", optarg);
- usage();
- }
- }
-
- ac -= optind;
- av += optind;
-
- if ((!passive && !authfile) || ac)
+ 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 srchto = 255; /* max timeout */
+ int waveform = 0x0053; /* aids search somehow */
+ int c;
+ extern char *optarg;
+ extern int optind;
+
+ /* default auth file // */
+ if (getenv("HOME"))
+ {
+ authfile = malloc(strlen(getenv("HOME")) + strlen("/.gant") + 1);
+ if (authfile)
+ sprintf(authfile, "%s/.gant", getenv("HOME"));
+ }
+ progname = av[0];
+ while ((c = getopt(ac, av, "a:f:d:i:m:pvD:rnzh")) != -1)
+ {
+ switch (c)
+ {
+ case 'a':
+ authfile = optarg;
+ break;
+ case 'f':
+ fname = optarg;
+ break;
+ case 'd':
+ devnum = atoi(optarg);
+ break;
+ case 'i':
+ myid = atoi(optarg);
+ break;
+ case 'm':
+ mydev = atoi(optarg);
+ break;
+ case 'p':
+ passive = 1;
+ break;
+ case 'v':
+ verbose = 1;
+ break;
+ case 'D':
+ dbg = atoi(optarg);
+ break;
+ case 'r':
+ reset = 1;
+ break;
+ case 'n':
+ nowriteauth = 1;
+ break;
+ case 'z':
+ nopairing = 1;
+ break;
+ case 'h':
usage();
-
- if (!ANT_Init(devnum)) /* should be 115200 but doesn't fit into a short */
- {
- ERROR_OUT("Open /dev/ttyUSB%d failed", devnum);
- exit(1);
- }
- ANT_ResetSystem();
- ANT_AssignResponseFunction(revent, ebuf);
- ANT_RequestMessage(chan, MESG_CHANNEL_STATUS_ID); /* informative */
- ANT_SetNetworkKeya(net, ANTSPT_KEY);
- ANT_AssignChannel(chan, chtype, net);
- /* Wali: changed order of the following seq. according windows */
- ANT_SetChannelPeriod(chan, period);
- ANT_SetChannelSearchTimeout(chan, srchto);
- ANT_RequestMessage(chan, MESG_CAPABILITIES_ID); /* informative */
- ANT_SetChannelRFFreq(chan, freq);
- ANT_SetSearchWaveform(chan, waveform);
- ANT_SetChannelId(chan, devno, devtype, manid);
- ANT_OpenChannel(chan);
- ANT_RequestMessage(chan, MESG_CHANNEL_STATUS_ID); /* informative */
-
- /* everything handled in event functions */
- for (;;)
- sleep(10);
+ default:
+ ERROR_OUT("unknown option %s", optarg);
+ usage();
+ }
+ }
+
+ ac -= optind;
+ av += optind;
+
+ if ((!passive && !authfile) || ac)
+ usage();
+
+ if (!ANT_Init(devnum)) /* should be 115200 but doesn't fit into a short */
+ {
+ ERROR_OUT("Open /dev/ttyUSB%d failed", devnum);
+ exit(1);
+ }
+ ANT_ResetSystem();
+ ANT_AssignResponseFunction(revent, ebuf);
+ ANT_RequestMessage(chan, MESG_CHANNEL_STATUS_ID); /* informative */
+ ANT_SetNetworkKeya(net, ANTSPT_KEY);
+ ANT_AssignChannel(chan, chtype, net);
+ /* Wali: changed order of the following seq. according windows */
+ ANT_SetChannelPeriod(chan, period);
+ ANT_SetChannelSearchTimeout(chan, srchto);
+ ANT_RequestMessage(chan, MESG_CAPABILITIES_ID); /* informative */
+ ANT_SetChannelRFFreq(chan, freq);
+ ANT_SetSearchWaveform(chan, waveform);
+ ANT_SetChannelId(chan, devno, devtype, manid);
+ ANT_OpenChannel(chan);
+ ANT_RequestMessage(chan, MESG_CHANNEL_STATUS_ID); /* informative */
+
+ /* everything handled in event functions */
+ for (;;)
+ sleep(10);
}
/* vim: set shiftwidth=3 softtabstop=3: */
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-running/antpm.git
More information about the Pkg-running-devel
mailing list