Subversion Repositories public

Rev

Rev 234 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
230 andreas 1
/***************************************************************************
2
 *   Copyright (C) 2007 to 2009 by Andreas Theofilu                        *
3
 *   andreas@theosys.at                                                    *
4
 *                                                                         *
5
 *   This program is free software; you can redistribute it and/or modify  *
6
 *   it under the terms of the GNU General Public License as published by  *
7
 *   the Free Software Foundation version 3 of the License.                *
8
 *                                                                         *
9
 *   This program is distributed in the hope that it will be useful,       *
10
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
11
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
12
 *   GNU General Public License for more details.                          *
13
 *                                                                         *
14
 *   You should have received a copy of the GNU General Public License     *
15
 *   along with this program; if not, write to the                         *
16
 *   Free Software Foundation, Inc.,                                       *
17
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
18
 ***************************************************************************/
19
 
280 andreas 20
/*
21
 * This code is heavily based on the work of <paul@ant.sbrk.co.uk>
22
 */
230 andreas 23
#include "gant.h"
24
#include <sys/select.h>
25
#include <unistd.h>
26
#include <sys/types.h>
27
#include <sys/stat.h>
28
#include <fcntl.h>
29
#include <stdio.h>
30
#include <string.h>
31
#include <termios.h>
32
#include <stdlib.h>
33
#include <assert.h>
34
#include <kmessagebox.h>
35
#include <klocale.h>
234 andreas 36
#include <qfileinfo.h>
230 andreas 37
 
38
static char  G50_KEY[] = "A8A423B9F55E63C1"; // garmin network key
39
 
40
static char sendack1[] = "4402320499990000";
41
//                        44                message from pc?
42
//                        ..02              message type
43
//                        ....32            don't know
44
//                        ......04          don't know
45
//                        ........9999      my id
46
//                        ............0000  maybe id is 4 bytes
47
static char sendack2[] = "4404010099990000";
48
//                        ..04              message type
49
//                        ....01            don't know
50
//                        ......00          don't know
51
static char sendack3[] = "4406010000000000";
52
//                        ..06              message type
53
//                        ....01            don't know
54
static char sendack4[] = "4403000000000000";
55
//                        ..03              message type, go to idle
56
//                        ....01            don't know
57
 
58
ant::ant ()
59
{
60
	qFile = false;
61
	commenabled = 1;
62
	rfn = cfn = 0;
63
}
64
 
65
ant::~ant ()
66
{
67
	if (qFile)
68
	   device.close ();
69
 
70
	qFile = false;
71
	rfn = cfn = 0;
72
}
73
 
74
/*
75
 * Set the device and store it inside the class
76
 */
77
bool ant::setDevice (const QFile &fl)
78
{
79
	if (qFile)
80
	{
81
	   device.close();
82
	   qFile = false;
83
	}
84
 
234 andreas 85
	device.setFileName (fl.fileName ());
230 andreas 86
 
87
	if (!device.exists ())
88
	{
234 andreas 89
	   KMessageBox::error (0, i18n("Device %1 does not exist!").arg(fl.fileName()));
230 andreas 90
	   return false;
91
	}
92
 
234 andreas 93
	if (!device.open (QIODevice::ReadWrite))
230 andreas 94
	{
234 andreas 95
	   KMessageBox::error (0, i18n("Error opening device %1.").arg(fl.fileName()),
230 andreas 96
	   	device.errorString());
97
	   return false;
98
	}
99
 
100
	qFile = true;
101
	return true;
102
}
103
 
104
bool ant::setDevice (const QString &fl)
105
{
106
QFile f;
107
 
108
	if (qFile)
109
	{
110
	   device.close ();
111
	   qFile = false;
112
	}
113
 
234 andreas 114
	f.setFileName (fl);
230 andreas 115
	return setDevice (f);
116
}
117
 
118
/*
119
 * Send a message to the opened device.
120
 */
121
bool ant::msg_send(uchar mesg, uchar *inbuf, uchar len)
122
{
123
uchar buf[MAXMSG];
124
ssize_t nw;
125
int i;
126
uchar chk = MESG_TX_SYNC;
127
 
128
	buf[0] = MESG_TX_SYNC;
129
	buf[1] = len;
130
	chk ^= len;
131
	buf[2] = mesg;
132
	chk ^= mesg;
133
 
134
	for (i = 0; i < len; i++)
135
	{
136
	   buf[3+i] = inbuf[i];
137
	   chk ^= inbuf[i];
138
	}
139
 
140
	buf[3+i] = chk;
141
	usleep (10 * 1000);
142
 
143
	if ((4 + i) != (nw = write(device.handle(), buf, 4 + i)))
144
	{
234 andreas 145
	   KMessageBox::error (0, i18n("Error writing to device %1").arg(device.fileName()));
230 andreas 146
	   return false;
147
	}
148
 
149
	return true;
150
}
151
 
152
// two argument send
153
bool ant::msg_send(uchar mesg, uchar data1, uchar data2)
154
{
155
uchar buf[2];
156
 
157
	buf[0] = data1;
158
	buf[1] = data2;
159
	return msg_send(mesg, buf, 2);
160
}
161
 
162
// three argument send
163
bool ant::msg_send(uchar mesg, uchar data1, uchar data2, uchar data3)
164
{
165
uchar buf[3];
166
 
167
	buf[0] = data1;
168
	buf[1] = data2;
169
	buf[2] = data3;
170
	return msg_send(mesg, buf, 3);
171
}
172
 
173
bool ant::commfn ()
174
{
175
fd_set readfds, writefds, exceptfds;
176
int ready, fd;
177
struct timeval to;
178
 
179
	fd = device.handle ();
180
 
181
	for(;;)
182
	{
183
	   FD_ZERO(&readfds);
184
	   FD_ZERO(&writefds);
185
	   FD_ZERO(&exceptfds);
186
	   FD_SET(fd, &readfds);
187
	   to.tv_sec = 1;
188
	   to.tv_usec = 0;
189
	   ready = select(fd+1, &readfds, &writefds, &exceptfds, &to);
190
 
191
	   if (ready)
192
	   {
193
	      if (!get_data(fd))
194
		 return false;
195
	   }
196
	}
197
 
198
	return true;
199
}
200
 
201
bool ant::get_data(int fd)
202
{
203
static uchar buf[500];
204
static int bufc = 0;
205
int nr;
206
int dlen;
207
int i;
208
int j;
209
unsigned char chk = 0;
210
uchar event;
211
int found;
212
int srch;
213
int next;
214
 
215
	nr = read(fd, buf+bufc, 20);
216
 
217
	if (nr > 0)
218
	   bufc += nr;
219
	else
220
	   return true;
221
 
222
	if (bufc > 300)
223
	{
224
	   KMessageBox::error (0, i18n(">>buf<< too long!"));
225
	   return false;
226
	}
227
 
228
	// some data in buf
229
	// search for possible valid messages
230
	srch = 0;
231
 
232
	while (srch < bufc)
233
	{
234
	   found = 0;
235
 
236
	   for (i = srch; i < bufc; i++)
237
	   {
238
	      if (buf[i] == MESG_TX_SYNC)
239
	      {
240
		 if (i+1 < bufc && buf[i+1] >= 1 && buf[i+1] <= 13)
241
		 {
242
		    dlen = buf[i+1];
243
 
244
		    if ((i + 3 + dlen) < bufc)
245
		    {
246
		       chk = 0;
247
 
248
		       for (j = i; j <= i+3+dlen; j++)
249
			  chk ^= buf[j];
250
 
251
		       if (0 == chk)
252
		       {
253
			  found = 1; // got a valid message
254
			  break;
255
		       }
256
		       else
257
			  fprintf (stderr, "bad chk %02x\n", chk);
258
		    }
259
		 }
260
	      }
261
	   }
262
 
263
	   if (found)
264
	   {
265
	      next = j;
266
	      // got a valid message, see if any data needs to be discarded
267
	      event = 0;
268
 
269
	      switch (buf[i+2])
270
	      {
271
		 case MESG_RESPONSE_EVENT_ID:
272
		    if (rfn)
273
		    {
274
		       memcpy(rbufp, buf+i+3, dlen);
275
 
276
		       if (!(this->*rfn)(buf[i+3], buf[i+5]))
277
			  return false;
278
		    }
279
		 break;
280
 
281
		 case MESG_BROADCAST_DATA_ID:
282
		    event = EVENT_RX_BROADCAST;
283
		 break;
284
 
285
		 case MESG_ACKNOWLEDGED_DATA_ID:
286
		    event = EVENT_RX_ACKNOWLEDGED;
287
		 break;
288
 
289
		 case MESG_BURST_DATA_ID:
290
		    event = EVENT_RX_BURST_PACKET;
291
		 break;
292
 
293
		 case MESG_EXT_BROADCAST_DATA_ID:
294
		    event = EVENT_RX_EXT_BROADCAST;
295
		 break;
296
 
297
		 case MESG_EXT_ACKNOWLEDGED_DATA_ID:
298
		    event = EVENT_RX_EXT_ACKNOWLEDGED;
299
		 break;
300
 
301
		 case MESG_EXT_BURST_DATA_ID:
302
		    event = EVENT_RX_EXT_BURST_PACKET;
303
		 break;
304
 
305
		 default:
306
		    if (rfn)
307
		    {
308
		       // should be this according to the docs, but doesn't fit
309
		       if (dlen > MESG_DATA_SIZE)
310
		       {
311
			  KMessageBox::error(0, i18n("rresponse buffer too small!"));
312
			  return false;
313
		       }
314
 
315
		       memcpy(rbufp, buf+i+3, dlen);
316
 
317
		       if (!(this->*rfn)(buf[i+3], buf[i+2]))
318
			  return false;
319
		    }
320
	      }
321
 
322
	      if (event)
323
	      {
324
		 if (cfn)
325
		 {
326
		    if (dlen > MESG_DATA_SIZE)
327
		    {
328
		       KMessageBox::error(0, i18n("cresponse buffer too small!"));
329
		       return false;
330
		    }
331
 
332
		    memcpy(cbufp, buf+i+4, dlen);
333
 
334
		    if (!(this->*cfn)(buf[i+3], event))
335
		       return false;
336
		 }
337
	      }
338
 
339
	      srch = next;
340
	   }
341
	   else
342
	      break;
343
	}
344
 
345
	if (next < bufc)
346
	{
347
	   memmove(buf, buf+next, bufc-next);
348
	   bufc -= next;
349
	}
350
	else
351
	   bufc = 0;
352
}
353
 
354
bool ant::ANT_ResetSystem()
355
{
356
uchar filler = 0;
357
 
358
	return msg_send(MESG_SYSTEM_RESET_ID, &filler, 1);
359
}
360
 
361
bool ant::ANT_Cmd55(uchar chan)
362
{
363
	return msg_send(0x55, &chan, 1);
364
}
365
 
366
bool ant::ANT_OpenRxScanMode (uchar chan)
367
{
368
	return msg_send(MESG_OPEN_RX_SCAN_ID, &chan, 1);
369
}
370
 
371
bool ant::ANT_Init ()
372
{
373
//char dev[40];
374
struct termios tp;
375
 
376
	if (!qFile)
377
	   return false;
378
 
379
	if (tcgetattr(device.handle(), &tp) < 0)
380
	{
381
	   KMessageBox::error(0, i18n("Error getting terminal attributes!"));
382
	   return false;
383
	}
384
 
385
	tp.c_iflag &=
386
	~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON|IXOFF|IXANY|INPCK|IUCLC);
387
	tp.c_oflag &= ~OPOST;
388
	tp.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN|ECHOE);
389
	tp.c_cflag &= ~(CSIZE|PARENB);
390
	tp.c_cflag |= CS8 | CLOCAL | CREAD | CRTSCTS;
391
 
392
	if (cfsetispeed(&tp, B115200) < 0)
393
	{
394
	   KMessageBox::error(0, i18n("Error setting input speed of line terminal!"));
395
	   return false;
396
	}
397
 
398
	if (cfsetospeed(&tp, B115200) < 0)
399
	{
400
	   KMessageBox::error(0, i18n("Error setting output speed of line terminal!"));
401
	   return false;
402
	}
403
 
404
	tp.c_cc[VMIN] = 1;
405
	tp.c_cc[VTIME] = 0;
406
 
407
	if (tcsetattr(device.handle (), TCSANOW, &tp) < 0)
408
	{
409
	   KMessageBox::error(0, i18n("Error setting terminal attributes!"));
410
	   return false;
411
	}
412
 
413
//	return commfn ();
414
	return true;
415
}
416
 
417
bool ant::ANT_RequestMessage (uchar chan, uchar mesg)
418
{
419
	return msg_send(MESG_REQUEST_ID, chan, mesg);
420
}
421
 
422
bool ant::ANT_SetNetworkKeya (uchar net, uchar *key)
423
{
424
uchar buf[9];
425
int i;
426
 
427
	if (strlen((char *)key) != 16)
428
	{
429
	  fprintf(stderr, "Bad key length %s\n", key);
430
	  return 0;
431
	}
432
 
433
	buf[0] = net;
434
 
435
	for (i = 0; i < 8; i++)
436
	   buf[1+i] = hexval(key[i*2])*16+hexval(key[i*2+1]);
437
 
438
	return msg_send(MESG_NETWORK_KEY_ID, buf, 9);
439
}
440
 
441
bool ant::ANT_SetNetworkKey (uchar net, uchar *key)
442
{
443
uchar buf[9];
444
//int i;
445
 
446
	buf[0] = net;
447
	memcpy(buf+1, key, 8);
448
	return msg_send(MESG_NETWORK_KEY_ID, buf, 9);
449
}
450
 
451
bool ant::ANT_AssignChannel (uchar chan, uchar chtype, uchar net)
452
{
453
	return msg_send(MESG_ASSIGN_CHANNEL_ID, chan, chtype, net);
454
}
455
 
456
bool ant::ANT_UnAssignChannel (uchar chan)
457
{
458
	return msg_send(MESG_UNASSIGN_CHANNEL_ID, &chan, 1);
459
}
460
 
461
bool ant::ANT_SetChannelId (uchar chan, ushort dev, uchar devtype, uchar manid)
462
{
463
uchar buf[5];
464
 
465
	buf[0] = chan;
466
	buf[1] = dev%256;
467
	buf[2] = dev/256;
468
	buf[3] = devtype;
469
	buf[4] = manid;
470
	return msg_send(MESG_CHANNEL_ID_ID, buf, 5);
471
}
472
 
473
bool ant::ANT_SetChannelRFFreq (uchar chan, uchar freq)
474
{
475
	return msg_send(MESG_CHANNEL_RADIO_FREQ_ID, chan, freq);
476
}
477
 
478
bool ant::ANT_SetChannelPeriod (uchar chan, ushort period)
479
{
480
uchar buf[3];
481
 
482
	buf[0] = chan;
483
	buf[1] = period%256;
484
	buf[2] = period/256;
485
	return msg_send(MESG_CHANNEL_MESG_PERIOD_ID, buf, 3);
486
}
487
 
488
bool ant::ANT_SetChannelSearchTimeout (uchar chan, uchar timeout)
489
{
490
	return msg_send(MESG_CHANNEL_SEARCH_TIMEOUT_ID, chan, timeout);
491
}
492
 
493
bool ant::ANT_SetSearchWaveform (uchar chan, ushort waveform)
494
{
495
uchar buf[3];
496
 
497
	buf[0] = chan;
498
	buf[1] = waveform % 256;
499
	buf[2] = waveform / 256;
500
	return msg_send(MESG_SEARCH_WAVEFORM_ID, buf, 3);
501
}
502
 
503
bool ant::ANT_SendAcknowledgedDataA (uchar chan, uchar *data) // ascii version
504
{
505
uchar buf[9];
506
int i;
507
 
508
	if (strlen((char *)data) != 16)
509
	{
510
	   fprintf(stderr, "Bad data length %s\n", data);
511
	   return false;
512
	}
513
 
514
	buf[0] = chan;
515
 
516
	for (i = 0; i < 8; i++)
517
	   buf[1+i] = hexval (data[i*2]) * 16 + hexval(data[i*2+1]);
518
 
519
	return msg_send(MESG_ACKNOWLEDGED_DATA_ID, buf, 9);
520
}
521
 
522
bool ant::ANT_SendAcknowledgedData (uchar chan, uchar *data)
523
{
524
uchar buf[9];
525
//int i;
526
 
527
	buf[0] = chan;
528
	memcpy(buf+1, data, 8);
529
	return msg_send(MESG_ACKNOWLEDGED_DATA_ID, buf, 9);
530
}
531
 
532
unsigned short ant::ANT_SendBurstTransferA(uchar chan, uchar *data, unsigned short numpkts)
533
{
534
uchar buf[9];
535
int i;
536
int j;
537
int seq = 0;
538
 
539
	fprintf(stderr, "numpkts %d data %s\n", numpkts, data);
540
 
541
	if (strlen((char *)data) != (16 * numpkts))
542
	{
543
	   fprintf(stderr, "Bad data length %s numpkts %d\n", data, numpkts);
544
	   return 0;
545
	}
546
 
547
	for (j = 0; j < numpkts; j++)
548
	{
549
	   buf[0] = chan | (seq << 5) | ((j == (numpkts - 1)) ? 0x80 : 0);
550
 
551
	   for (i = 0; i < 8; i++)
552
	      buf[1+i] = hexval (data[j*16+i*2]) * 16 + hexval (data[j*16+i*2+1]);
553
 
554
	   usleep(20 * 1000);
555
	   msg_send(MESG_BURST_DATA_ID, buf, 9);
556
	   seq++;
557
 
558
	   if (seq > 3)
559
	      seq = 1;
560
	}
561
 
562
	return numpkts;
563
}
564
 
565
unsigned short ant::ANT_SendBurstTransfer (uchar chan, uchar *data, unsigned short numpkts)
566
{
567
uchar buf[9];
568
//int i;
569
int j;
570
int seq = 0;
571
 
572
	for (j = 0; j < numpkts; j++)
573
	{
574
	   buf[0] = chan | (seq << 5) | ((j == (numpkts - 1)) ? 0x80 : 0);
575
	   memcpy (buf+1, data+j*8, 8);
576
	   usleep (20*1000);
577
	   msg_send (MESG_BURST_DATA_ID, buf, 9);
578
	   seq++;
579
 
580
	   if (seq > 3)
581
	      seq = 1;
582
	}
583
 
584
	return numpkts;
585
}
586
 
587
bool ant::ANT_OpenChannel (uchar chan)
588
{
589
	return msg_send(MESG_OPEN_CHANNEL_ID, &chan, 1);
590
}
591
 
592
bool ant::ANT_CloseChannel (uchar chan)
593
{
594
	return msg_send(MESG_CLOSE_CHANNEL_ID, &chan, 1);
595
}
596
 
597
void ant::ANT_AssignResponseFunction (RESPONSE_FUNC rf, uchar* rbuf)
598
{
599
	rfn = rf;
600
	rbufp = rbuf;
601
}
602
 
603
void ant::ANT_AssignChannelEventFunction (uchar, CHANNEL_EVENT_FUNC rf, uchar* rbuf)
604
{
605
	cfn = rf;
606
	cbufp = rbuf;
607
}
608
 
609
int ant::ANT_fd()
610
{
611
	return device.handle();
612
}
613
 
614
/*
615
 * Following functions control the device and uses the class "ant".
616
 * This is class "gant".
617
 */
618
 
619
gant::gant (const QString &af)
620
{
621
	mydev = 0;
622
	peerdev = 0;
623
	myid = 0;
624
	state = 0;
625
	authfd = false;
626
 
234 andreas 627
	faf.setFileName (af);
230 andreas 628
 
234 andreas 629
	if (!faf.open (QIODevice::ReadWrite))
230 andreas 630
	{
631
	   KMessageBox::error (0, i18n("Error opening device %1.").arg(af),
632
	   	faf.errorString());
633
	}
634
 
635
	authfile = af;
636
	authfd = true;
234 andreas 637
	tmpOut.setFileName(QString(tmpnam(NULL)));
230 andreas 638
}
639
 
640
gant::~gant ()
641
{
642
	if (authfd)
643
	   faf.close();
234 andreas 644
 
645
	// if the file is still open, this function closes it before
646
	// it is removed.
647
	tmpOut.remove();
230 andreas 648
}
649
 
650
uint gant::randno ()
651
{
652
	return (uint)random ();
653
}
654
 
655
bool gant::chevent (uchar chan, uchar event)
656
{
657
uchar seq;
658
uchar last;
659
uchar status = cbuf[1];
660
uchar phase = cbuf[2];
661
struct ack_msg ack;
662
struct auth_msg auth;
663
struct pair_msg pair;
664
uint id;
665
//int i;
666
 
667
	//fprintf(stderr, "state %d\n", state);
668
/*	if (dbg && event != EVENT_RX_BURST_PACKET) {
669
		fprintf(stderr, "chan %d event %02x channel open: ", chan, event);
670
		for (i = 0; i < 8; i++)
671
			fprintf(stderr, "%02x", cbuf[i]);
672
		fprintf(stderr, "\n");
673
	}
674
*/
675
	// transition between garmin phases handled via state machine
676
	switch (event)
677
	{
678
	   case EVENT_RX_BROADCAST:
679
	      memcpy((void *)&id, cbuf+4, 4);
680
 
681
	      if (state == 1 && (phase & 7) == 0)
682
	      {
683
		 // received broadcast from watch in phase 0
684
		 state++;
685
 
686
		 if ((status & 8) == 8)
687
		 {
688
		    // pairing
689
		    myid = randno();
690
		    fprintf(stderr, "pairing, generated id %08x\n", myid);
691
		 }
692
		 else
693
		 {
694
		    // garmin moved to phase 1 in response to sendack1
695
		    int nr;
696
//		    printf("reading auth data from %s\n", authfile);
234 andreas 697
		    authfd = open(authfile.toAscii(), O_RDONLY);
230 andreas 698
 
699
		    if (!authfd || faf.size () < 32)
700
		    {
701
		       KMessageBox::error(0, i18n("There is no authfile available or it has wrong size!"));
702
		       return false;
703
		    }
704
 
705
		    nr = read(faf.handle(), authdata, 32);
706
 
707
		    if (nr != 32)
708
		    {
709
		       KMessageBox::error(0, i18n ("Error reading auth file %1!").arg(authfile));
710
		       return false;
711
		    }
712
 
713
		    memcpy((void *)&myauth1, authdata+16, 4);
714
		    memcpy((void *)&myauth2, authdata+20, 4);
715
		    memcpy((void *)&mydev, authdata+12, 4);
716
		    memcpy((void *)&myid, authdata+4, 4);
717
		 }
718
 
719
		 if (status & 0x20)
720
		    fprintf(stderr, "watch contains NEW data\n");
721
 
722
		 ANT_RequestMessage(chan, MESG_CHANNEL_ID_ID); /* request sender id */
723
	      }
724
	      else if (state == 3 && phase == 1)
725
	      {
726
		 state++;
727
		 ack.code = 0x44;
728
		 ack.atype = 4;
729
		 ack.c1 = 0x01;
730
		 ack.c2 = 0x00;
731
		 ack.id = myid;
732
		 ANT_SendAcknowledgedData(chan, (uchar *)&ack); // tell garmin to send id data
733
	      }
734
	      else if (state == 5 && phase == 1)
735
	      {
736
		 if ((status & 0x0f) == 4)
737
		 {
738
		    // received id/version or whatever
739
		    state++;
740
		    assert(sizeof auth == AUTHSIZE);
741
		    auth.code = 0x44;
742
		    auth.atype = 4;
743
		    auth.phase = 3;
744
		    auth.u1 = 8;
745
		    auth.id = myid;
746
		    auth.auth1 = myauth1;
747
		    auth.auth2 = myauth2;
748
		    auth.fill1 = auth.fill2 = 0;
749
		    ANT_SendBurstTransfer(chan, (uchar *)&auth, (sizeof auth)/8); // send our auth data
750
		 }
751
		 else if ((status & 0x0f) == 0x0c)
752
		 {
753
		     // pairing
754
		     assert(sizeof pair == PAIRSIZE);
755
		     state = 10;
756
		     pair.code = 0x44;
757
		     pair.atype = 4;
758
		     pair.phase = 2;
759
		     pair.u1 = 7;
760
		     pair.id = myid;
761
		     bzero(pair.devname, sizeof pair.devname);
762
 
763
		    if (peerdev <= 99999999) // only allow 8 digits
764
		       sprintf(pair.devname, "%d", peerdev);
765
		    else
766
		       fprintf(stderr, "pair dev name too large %08x \"%d\"\n", peerdev, peerdev);
767
 
768
//		    printf("sending pair data for dev %s\n", pair.devname);
769
		    ANT_SendBurstTransfer(chan, (uchar *)&pair, (sizeof pair)/8) ; // send pair data
770
		 }
771
		 else
772
		 {
773
		    fprintf(stderr, "error in gant.cpp on line %d\n", __LINE__);
774
		    return false;
775
		 }
776
	      }
777
	      else if (state == 6 && (status & 0x0f) == 4 && phase == 2)
778
	      {
779
		 // if our auth is ok, garmin has gone to phase 2
780
		 state++;
781
		 ack.code = 0x44;
782
		 ack.atype = 6;
783
		 ack.c1 = 0x01;
784
		 ack.c2 = 0x00;
785
		 ack.id = 0;
786
		 ANT_SendAcknowledgedData(chan, (uchar *)&ack); // tell garmin to start upload
787
	      }
788
	      else if (state == 8 && phase == 2)
789
	      {
790
		 // upload finished. received broadcast that still in phase 2
791
		 state++;
792
		 ack.code = 0x44;
793
		 ack.atype = 3;
794
		 ack.c1 = 0x00;
795
		 ack.c2 = 0x00;
796
		 ack.id = 0;
797
		 ANT_SendAcknowledgedData(chan, (uchar *)&ack); // tell garmin we're finished
798
	      }
799
	      else if (state == 9 && phase == 0)
800
	      {
801
		 // garmin replies it's back in phase 0
802
		 fprintf(stderr, "finished\n");
803
		 return true;
804
	      }
805
	      else if (state == 1 && phase != 0)
806
	      {
807
		 // don't know what phase we're in. let's try and reset
808
		 fprintf(stderr, "resetting\n");
809
		 ack.code = 0x44;
810
		 ack.atype = 3;
811
		 ack.c1 = 0x00;
812
		 ack.c2 = 0x00;
813
		 ack.id = 0;
814
		 ANT_SendAcknowledgedData(chan, (uchar *)&ack); // tell garmin we're finished
815
		 sleep(1);
816
		 return false;
817
	      }
818
	      else if (state == 20 && phase == 2)
819
	      {
820
		 // upload finished. tell garmin to delete logs
821
		 state++;
822
		 ack.code = 0x44;
823
		 ack.atype = 0x0b;
824
		 ack.c1 = 0x01;
825
		 ack.c2 = 0x00;
826
		 ack.id = 0;
827
		 ANT_SendAcknowledgedData(chan, (uchar *)&ack); // delete logs
828
	      }
829
	      else if (state == 21 && phase == 2)
830
	      {
831
		 state = 8;
832
	      }
833
	   break;
834
 
835
	   case EVENT_RX_BURST_PACKET:
836
	      seq = (chan & 0x60) >> 5;
837
	      last = (chan & 0x80) >> 7;
838
	      chan &= 0x1f;
839
 
840
	      if (state == 4)
841
	      {
842
		 static int once = 0;
843
		 // garmin sending authentication/identification data
844
 
845
		 if (!once)
846
		    once = 1;
847
 
848
		 memcpy(clientid[seq], cbuf, 8);
849
 
850
		 if (last)
851
		 {
852
		    state++;
853
 
854
		    memcpy(&peerdev, clientid[1]+4, 4);
855
 
856
		    if (mydev != 0 && peerdev != mydev)
857
		    {
858
		       fprintf(stderr, "Don't know this device %08x != %08x\n", peerdev, mydev);
859
		       return false;
860
		    }
861
		 }
862
	      }
863
	      else if (state == 7)
864
	      {
865
		 static int once = 0;
866
		 int nw;
867
 
868
		 // garmin uploading in response to sendack3
869
		 // in this state we're receiving the workout data
870
		 if (!once)
871
		 {
872
		    fprintf(stderr, "receiving\n");
873
		    once = 1;
234 andreas 874
		    tmpOut.open (QIODevice::ReadWrite | QIODevice::Truncate);
230 andreas 875
		 }
876
 
234 andreas 877
		 // FIXME: Here we should fill our buffer, instead of writing
878
		 // everything into a file.
879
		 nw = write(tmpOut.handle(), cbuf, 8);
230 andreas 880
 
881
		 if (nw != 8)
882
		 {
234 andreas 883
		    KMessageBox::error(0, i18n ("Failed to write to a temporary file!"));
230 andreas 884
		    return false;
885
		 }
886
 
887
		 if (last)
888
		 {
889
		    state++;    // just to exit
890
				//state = 20; // to delete logs
234 andreas 891
		    tmpOut.close();
230 andreas 892
		 }
893
	      }
894
	      else if (state == 10)
895
	      {
896
		 // receiving auth data
897
		 static int once = 0;
898
		 int nw;
899
 
900
		 if (!once)
901
		 {
902
//		    printf("storing auth data in %s\n", authfile);
903
		    once = 1;
904
//		    authfd = open(authfile, O_WRONLY|O_CREAT, 0644);
905
 
906
/*		    if (authfd < 0)
907
		    {
908
		       perror(authfile);
909
		       exit(1);
910
		    } */
911
		 }
912
 
913
		 nw = write(faf.handle(), cbuf, 8);
914
 
915
		 if (nw != 8)
916
		 {
917
		    KMessageBox::error(0, i18n ("Write to auth file %1 failed!").arg(authfile));
918
		    return false;
919
		 }
920
 
921
		 if (last)
922
		 {
923
		    //state = 6; // to download during pairing
924
		    state = 8; // to finish at end of pairing
925
		 }
926
	      }
927
	      else if (state == 6)
928
	      {
929
		 // response to authentication
930
		 static int once = 0;
931
//		 int i;
932
 
933
		 if (!once)
934
		 {
935
		    once = 1;
936
		 }
937
 
938
		 if (last)
939
		 {
940
		    if (cbuf[2] == 2)
941
		    {
942
		       fprintf(stderr, "authentication failed\n");
943
		       return false;
944
		    }
945
		 }
946
	      }
947
	      else
948
	      {
949
		 int i;
950
 
951
		 fprintf(stderr, "data in state %d: ", state);
952
 
953
		 for (i = 0; i < 8; i++)
954
		    fprintf(stderr, "%02x", cbuf[i]);
955
 
956
		 fprintf(stderr, "\n");
957
	      }
958
	   break;
959
	}
960
 
961
	return 1;
962
}
963
 
964
bool gant::revent (uchar chan, uchar event)
965
{
966
unsigned short devid;
967
struct ack_msg ack;
968
int i;
969
 
970
	switch (event)
971
	{
972
	   case EVENT_TRANSFER_TX_COMPLETED:
973
	      // ignore
974
	      // printf("Transfer complete %02x\n", ebuf[1]);
975
	   break;
976
 
977
	   case INVALID_MESSAGE:
978
	      fprintf(stderr, "Invalid message %02x\n", ebuf[1]);
979
	   break;
980
 
981
	   case RESPONSE_NO_ERROR:
982
	      switch (ebuf[1])
983
	      {
984
		 case MESG_ASSIGN_CHANNEL_ID:
985
		    ANT_AssignChannelEventFunction((uchar)chan, (CHANNEL_EVENT_FUNC)&gant::chevent, (uchar *)&cbuf);
986
		 break;
987
 
988
		 case MESG_OPEN_CHANNEL_ID:
989
		    state++;
234 andreas 990
		    fprintf(stderr, "channel open (%d), waiting for broadcast\n", state);
230 andreas 991
		 break;
992
 
993
		 default:
994
		    // ignore
995
		    // printf("Message %02x NO_ERROR\n", ebuf[1]);
996
		 break;
997
	      }
998
	   break;
999
 
1000
	   case MESG_CHANNEL_ID_ID:
1001
	      devid = ebuf[1]+ebuf[2]*256;
1002
 
1003
	      if (mydev == 0 || devid == mydev%65536)
1004
	      {
1005
		 state++;
1006
		 ack.code = 0x44; ack.atype = 2; ack.c1 = 0x32; ack.c2 = 0x04;
1007
		 ack.id = myid;
1008
		 ANT_SendAcknowledgedData(chan, (uchar *)&ack); // tell watch go to phase 1
1009
	      }
1010
	      else
1011
	      {
1012
		 fprintf(stderr, "Ignoring unknown device %08x, mydev %08x\n", devid, mydev);
1013
	      }
1014
	   break;
1015
 
1016
	   case MESG_NETWORK_KEY_ID:
1017
	   case MESG_SEARCH_WAVEFORM_ID:
1018
	   case MESG_OPEN_CHANNEL_ID:
1019
	      fprintf(stderr, "response event %02x code %02x\n", event, ebuf[2]);
1020
 
1021
	      for (i = 0; i < 8; i++)
1022
		 fprintf(stderr, "%02x", ebuf[i]);
1023
 
1024
	      fprintf(stderr, "\n");
1025
	   break;
1026
 
1027
	   case MESG_CAPABILITIES_ID:
1028
	   break;
1029
 
1030
	   case MESG_CHANNEL_STATUS_ID:
1031
	   break;
1032
 
1033
	   default:
1034
	      fprintf(stderr, "Unhandled response event %02x\n", event);
1035
	   break;
1036
	}
1037
 
1038
	return true;
1039
}
1040
 
1041
bool gant::read_device ()
1042
{
1043
//int devnum = 0;
1044
int chan = 0;
1045
int net = 0;
1046
int chtype = 0; // wildcard
1047
int devno = 0; // wildcard
1048
int devtype = 0; // wildcard
1049
int manid = 0; // wildcard
1050
int freq = 0x32; // garmin specific radio frequency
1051
int period = 0x1000; // garmin specific broadcast period
1052
int srchto = 255; // max timeout
1053
int waveform = 0x0053; // aids search somehow
1054
 
1055
	// Check if we already have a device set.
1056
//	if (!qFile)
1057
//	   return false;
1058
 
1059
	// TODO: Do this properly...
1060
/*	if (ac > 1) {
1061
		authfile = av[1];
1062
	}
1063
	else {
1064
		fprintf(stderr, "need auth file\n");
1065
		exit(1);
1066
	}
1067
 
1068
	if (ac > 2)
1069
		fn = av[2]; // store the output filename for event function
1070
	if (ac > 3)
1071
		devnum = atoi(av[3]);
1072
	if (ac > 4)
1073
		myid = atoi(av[4]);
1074
	if (ac > 5)
1075
		mydev = atoi(av[5]);
1076
*/
1077
	if (!ANT_Init())
1078
	   return false;
1079
 
1080
	if (!ANT_ResetSystem())
1081
	   return false;
1082
 
1083
	ANT_AssignResponseFunction((RESPONSE_FUNC)&gant::revent, (uchar *)&ebuf);
1084
 
1085
	if (!ANT_RequestMessage(chan, MESG_CHANNEL_STATUS_ID))	//informative
1086
	   return false;
1087
 
1088
	if (!ANT_SetNetworkKeya(net, (uchar *)G50_KEY))
1089
	   return false;
1090
 
1091
	if (!ANT_AssignChannel(chan, chtype, net))
1092
	   return false;
1093
 
1094
	if (!ANT_SetChannelId(chan, devno, devtype, manid))
1095
	   return false;
1096
 
1097
	if (!ANT_RequestMessage(chan, MESG_CAPABILITIES_ID))	//informative
1098
	   return false;
1099
 
1100
	if (!ANT_SetChannelRFFreq(chan, freq))
1101
	   return false;
1102
 
1103
	if (!ANT_SetChannelPeriod(chan, period))
1104
	   return false;
1105
 
1106
	if (!ANT_SetChannelSearchTimeout(chan, srchto))
1107
	   return false;
1108
 
1109
	if (!ANT_SetSearchWaveform(chan, waveform))
1110
	   return false;
1111
 
1112
	if (!ANT_OpenChannel(chan))	// success for this bumps us to state 1
1113
	   return false;
1114
 
1115
	if (!ANT_RequestMessage(chan, MESG_CHANNEL_STATUS_ID))	//informative
1116
	   return false;
1117
 
1118
	// everything handled in event functions
1119
//	for(;;)
1120
//		sleep(10);
1121
 
1122
	return commfn ();
1123
}
234 andreas 1124
 
1125
uchar *gant::getBuffer (int *size)
1126
{
1127
QFileInfo fi;
1128
uchar *buffer;
1129
long sz;
1130
 
1131
	fi.setFile (tmpOut);
1132
 
1133
	if (!fi.exists() || fi.size() > 1000000)
1134
	   return 0;
1135
 
1136
	sz = fi.size();
1137
	*size = 0;
1138
 
1139
	if (!(buffer = new uchar[sz+1]))
1140
	{
1141
	   KMessageBox::error(0, i18n("Error allocating %1 bytes of memory!").arg(sz+1));
1142
	   return 0;
1143
	}
1144
 
1145
	if (tmpOut.handle() == -1)
1146
	{
1147
	   if (!tmpOut.open(QIODevice::ReadOnly))
1148
	   {
1149
	      KMessageBox::error(0, i18n("Error opening a temporary file for reading!"), tmpOut.errorString());
1150
	      delete buffer;
1151
	      return 0;
1152
	   }
1153
	}
1154
 
1155
	if (read (tmpOut.handle(), buffer, sz) < sz)
1156
	{
1157
	   KMessageBox::error(0, i18n("Error reading from a temporary file!"));
1158
	   tmpOut.close();
1159
	   delete buffer;
1160
	   return 0;
1161
	}
1162
 
1163
	*size = (int)sz;
1164
	return buffer;
1165
}