Subversion Repositories public

Rev

Rev 280 | 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;
311 andreas 352
 
353
        return true;
230 andreas 354
}
355
 
356
bool ant::ANT_ResetSystem()
357
{
358
uchar filler = 0;
359
 
360
	return msg_send(MESG_SYSTEM_RESET_ID, &filler, 1);
361
}
362
 
363
bool ant::ANT_Cmd55(uchar chan)
364
{
365
	return msg_send(0x55, &chan, 1);
366
}
367
 
368
bool ant::ANT_OpenRxScanMode (uchar chan)
369
{
370
	return msg_send(MESG_OPEN_RX_SCAN_ID, &chan, 1);
371
}
372
 
373
bool ant::ANT_Init ()
374
{
375
//char dev[40];
376
struct termios tp;
377
 
378
	if (!qFile)
379
	   return false;
380
 
381
	if (tcgetattr(device.handle(), &tp) < 0)
382
	{
383
	   KMessageBox::error(0, i18n("Error getting terminal attributes!"));
384
	   return false;
385
	}
386
 
387
	tp.c_iflag &=
388
	~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON|IXOFF|IXANY|INPCK|IUCLC);
389
	tp.c_oflag &= ~OPOST;
390
	tp.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN|ECHOE);
391
	tp.c_cflag &= ~(CSIZE|PARENB);
392
	tp.c_cflag |= CS8 | CLOCAL | CREAD | CRTSCTS;
393
 
394
	if (cfsetispeed(&tp, B115200) < 0)
395
	{
396
	   KMessageBox::error(0, i18n("Error setting input speed of line terminal!"));
397
	   return false;
398
	}
399
 
400
	if (cfsetospeed(&tp, B115200) < 0)
401
	{
402
	   KMessageBox::error(0, i18n("Error setting output speed of line terminal!"));
403
	   return false;
404
	}
405
 
406
	tp.c_cc[VMIN] = 1;
407
	tp.c_cc[VTIME] = 0;
408
 
409
	if (tcsetattr(device.handle (), TCSANOW, &tp) < 0)
410
	{
411
	   KMessageBox::error(0, i18n("Error setting terminal attributes!"));
412
	   return false;
413
	}
414
 
415
//	return commfn ();
416
	return true;
417
}
418
 
419
bool ant::ANT_RequestMessage (uchar chan, uchar mesg)
420
{
421
	return msg_send(MESG_REQUEST_ID, chan, mesg);
422
}
423
 
424
bool ant::ANT_SetNetworkKeya (uchar net, uchar *key)
425
{
426
uchar buf[9];
427
int i;
428
 
429
	if (strlen((char *)key) != 16)
430
	{
431
	  fprintf(stderr, "Bad key length %s\n", key);
432
	  return 0;
433
	}
434
 
435
	buf[0] = net;
436
 
437
	for (i = 0; i < 8; i++)
438
	   buf[1+i] = hexval(key[i*2])*16+hexval(key[i*2+1]);
439
 
440
	return msg_send(MESG_NETWORK_KEY_ID, buf, 9);
441
}
442
 
443
bool ant::ANT_SetNetworkKey (uchar net, uchar *key)
444
{
445
uchar buf[9];
446
//int i;
447
 
448
	buf[0] = net;
449
	memcpy(buf+1, key, 8);
450
	return msg_send(MESG_NETWORK_KEY_ID, buf, 9);
451
}
452
 
453
bool ant::ANT_AssignChannel (uchar chan, uchar chtype, uchar net)
454
{
455
	return msg_send(MESG_ASSIGN_CHANNEL_ID, chan, chtype, net);
456
}
457
 
458
bool ant::ANT_UnAssignChannel (uchar chan)
459
{
460
	return msg_send(MESG_UNASSIGN_CHANNEL_ID, &chan, 1);
461
}
462
 
463
bool ant::ANT_SetChannelId (uchar chan, ushort dev, uchar devtype, uchar manid)
464
{
465
uchar buf[5];
466
 
467
	buf[0] = chan;
468
	buf[1] = dev%256;
469
	buf[2] = dev/256;
470
	buf[3] = devtype;
471
	buf[4] = manid;
472
	return msg_send(MESG_CHANNEL_ID_ID, buf, 5);
473
}
474
 
475
bool ant::ANT_SetChannelRFFreq (uchar chan, uchar freq)
476
{
477
	return msg_send(MESG_CHANNEL_RADIO_FREQ_ID, chan, freq);
478
}
479
 
480
bool ant::ANT_SetChannelPeriod (uchar chan, ushort period)
481
{
482
uchar buf[3];
483
 
484
	buf[0] = chan;
485
	buf[1] = period%256;
486
	buf[2] = period/256;
487
	return msg_send(MESG_CHANNEL_MESG_PERIOD_ID, buf, 3);
488
}
489
 
490
bool ant::ANT_SetChannelSearchTimeout (uchar chan, uchar timeout)
491
{
492
	return msg_send(MESG_CHANNEL_SEARCH_TIMEOUT_ID, chan, timeout);
493
}
494
 
495
bool ant::ANT_SetSearchWaveform (uchar chan, ushort waveform)
496
{
497
uchar buf[3];
498
 
499
	buf[0] = chan;
500
	buf[1] = waveform % 256;
501
	buf[2] = waveform / 256;
502
	return msg_send(MESG_SEARCH_WAVEFORM_ID, buf, 3);
503
}
504
 
505
bool ant::ANT_SendAcknowledgedDataA (uchar chan, uchar *data) // ascii version
506
{
507
uchar buf[9];
508
int i;
509
 
510
	if (strlen((char *)data) != 16)
511
	{
512
	   fprintf(stderr, "Bad data length %s\n", data);
513
	   return false;
514
	}
515
 
516
	buf[0] = chan;
517
 
518
	for (i = 0; i < 8; i++)
519
	   buf[1+i] = hexval (data[i*2]) * 16 + hexval(data[i*2+1]);
520
 
521
	return msg_send(MESG_ACKNOWLEDGED_DATA_ID, buf, 9);
522
}
523
 
524
bool ant::ANT_SendAcknowledgedData (uchar chan, uchar *data)
525
{
526
uchar buf[9];
527
//int i;
528
 
529
	buf[0] = chan;
530
	memcpy(buf+1, data, 8);
531
	return msg_send(MESG_ACKNOWLEDGED_DATA_ID, buf, 9);
532
}
533
 
534
unsigned short ant::ANT_SendBurstTransferA(uchar chan, uchar *data, unsigned short numpkts)
535
{
536
uchar buf[9];
537
int i;
538
int j;
539
int seq = 0;
540
 
541
	fprintf(stderr, "numpkts %d data %s\n", numpkts, data);
542
 
543
	if (strlen((char *)data) != (16 * numpkts))
544
	{
545
	   fprintf(stderr, "Bad data length %s numpkts %d\n", data, numpkts);
546
	   return 0;
547
	}
548
 
549
	for (j = 0; j < numpkts; j++)
550
	{
551
	   buf[0] = chan | (seq << 5) | ((j == (numpkts - 1)) ? 0x80 : 0);
552
 
553
	   for (i = 0; i < 8; i++)
554
	      buf[1+i] = hexval (data[j*16+i*2]) * 16 + hexval (data[j*16+i*2+1]);
555
 
556
	   usleep(20 * 1000);
557
	   msg_send(MESG_BURST_DATA_ID, buf, 9);
558
	   seq++;
559
 
560
	   if (seq > 3)
561
	      seq = 1;
562
	}
563
 
564
	return numpkts;
565
}
566
 
567
unsigned short ant::ANT_SendBurstTransfer (uchar chan, uchar *data, unsigned short numpkts)
568
{
569
uchar buf[9];
570
//int i;
571
int j;
572
int seq = 0;
573
 
574
	for (j = 0; j < numpkts; j++)
575
	{
576
	   buf[0] = chan | (seq << 5) | ((j == (numpkts - 1)) ? 0x80 : 0);
577
	   memcpy (buf+1, data+j*8, 8);
578
	   usleep (20*1000);
579
	   msg_send (MESG_BURST_DATA_ID, buf, 9);
580
	   seq++;
581
 
582
	   if (seq > 3)
583
	      seq = 1;
584
	}
585
 
586
	return numpkts;
587
}
588
 
589
bool ant::ANT_OpenChannel (uchar chan)
590
{
591
	return msg_send(MESG_OPEN_CHANNEL_ID, &chan, 1);
592
}
593
 
594
bool ant::ANT_CloseChannel (uchar chan)
595
{
596
	return msg_send(MESG_CLOSE_CHANNEL_ID, &chan, 1);
597
}
598
 
599
void ant::ANT_AssignResponseFunction (RESPONSE_FUNC rf, uchar* rbuf)
600
{
601
	rfn = rf;
602
	rbufp = rbuf;
603
}
604
 
605
void ant::ANT_AssignChannelEventFunction (uchar, CHANNEL_EVENT_FUNC rf, uchar* rbuf)
606
{
607
	cfn = rf;
608
	cbufp = rbuf;
609
}
610
 
611
int ant::ANT_fd()
612
{
613
	return device.handle();
614
}
615
 
616
/*
617
 * Following functions control the device and uses the class "ant".
618
 * This is class "gant".
619
 */
620
 
621
gant::gant (const QString &af)
622
{
623
	mydev = 0;
624
	peerdev = 0;
625
	myid = 0;
626
	state = 0;
627
	authfd = false;
628
 
234 andreas 629
	faf.setFileName (af);
230 andreas 630
 
234 andreas 631
	if (!faf.open (QIODevice::ReadWrite))
230 andreas 632
	{
633
	   KMessageBox::error (0, i18n("Error opening device %1.").arg(af),
634
	   	faf.errorString());
635
	}
636
 
637
	authfile = af;
638
	authfd = true;
234 andreas 639
	tmpOut.setFileName(QString(tmpnam(NULL)));
230 andreas 640
}
641
 
642
gant::~gant ()
643
{
644
	if (authfd)
645
	   faf.close();
234 andreas 646
 
647
	// if the file is still open, this function closes it before
648
	// it is removed.
649
	tmpOut.remove();
230 andreas 650
}
651
 
652
uint gant::randno ()
653
{
654
	return (uint)random ();
655
}
656
 
657
bool gant::chevent (uchar chan, uchar event)
658
{
659
uchar seq;
660
uchar last;
661
uchar status = cbuf[1];
662
uchar phase = cbuf[2];
663
struct ack_msg ack;
664
struct auth_msg auth;
665
struct pair_msg pair;
666
uint id;
667
//int i;
668
 
669
	//fprintf(stderr, "state %d\n", state);
670
/*	if (dbg && event != EVENT_RX_BURST_PACKET) {
671
		fprintf(stderr, "chan %d event %02x channel open: ", chan, event);
672
		for (i = 0; i < 8; i++)
673
			fprintf(stderr, "%02x", cbuf[i]);
674
		fprintf(stderr, "\n");
675
	}
676
*/
677
	// transition between garmin phases handled via state machine
678
	switch (event)
679
	{
680
	   case EVENT_RX_BROADCAST:
681
	      memcpy((void *)&id, cbuf+4, 4);
682
 
683
	      if (state == 1 && (phase & 7) == 0)
684
	      {
685
		 // received broadcast from watch in phase 0
686
		 state++;
687
 
688
		 if ((status & 8) == 8)
689
		 {
690
		    // pairing
691
		    myid = randno();
692
		    fprintf(stderr, "pairing, generated id %08x\n", myid);
693
		 }
694
		 else
695
		 {
696
		    // garmin moved to phase 1 in response to sendack1
697
		    int nr;
698
//		    printf("reading auth data from %s\n", authfile);
234 andreas 699
		    authfd = open(authfile.toAscii(), O_RDONLY);
230 andreas 700
 
701
		    if (!authfd || faf.size () < 32)
702
		    {
703
		       KMessageBox::error(0, i18n("There is no authfile available or it has wrong size!"));
704
		       return false;
705
		    }
706
 
707
		    nr = read(faf.handle(), authdata, 32);
708
 
709
		    if (nr != 32)
710
		    {
711
		       KMessageBox::error(0, i18n ("Error reading auth file %1!").arg(authfile));
712
		       return false;
713
		    }
714
 
715
		    memcpy((void *)&myauth1, authdata+16, 4);
716
		    memcpy((void *)&myauth2, authdata+20, 4);
717
		    memcpy((void *)&mydev, authdata+12, 4);
718
		    memcpy((void *)&myid, authdata+4, 4);
719
		 }
720
 
721
		 if (status & 0x20)
722
		    fprintf(stderr, "watch contains NEW data\n");
723
 
724
		 ANT_RequestMessage(chan, MESG_CHANNEL_ID_ID); /* request sender id */
725
	      }
726
	      else if (state == 3 && phase == 1)
727
	      {
728
		 state++;
729
		 ack.code = 0x44;
730
		 ack.atype = 4;
731
		 ack.c1 = 0x01;
732
		 ack.c2 = 0x00;
733
		 ack.id = myid;
734
		 ANT_SendAcknowledgedData(chan, (uchar *)&ack); // tell garmin to send id data
735
	      }
736
	      else if (state == 5 && phase == 1)
737
	      {
738
		 if ((status & 0x0f) == 4)
739
		 {
740
		    // received id/version or whatever
741
		    state++;
742
		    assert(sizeof auth == AUTHSIZE);
743
		    auth.code = 0x44;
744
		    auth.atype = 4;
745
		    auth.phase = 3;
746
		    auth.u1 = 8;
747
		    auth.id = myid;
748
		    auth.auth1 = myauth1;
749
		    auth.auth2 = myauth2;
750
		    auth.fill1 = auth.fill2 = 0;
751
		    ANT_SendBurstTransfer(chan, (uchar *)&auth, (sizeof auth)/8); // send our auth data
752
		 }
753
		 else if ((status & 0x0f) == 0x0c)
754
		 {
755
		     // pairing
756
		     assert(sizeof pair == PAIRSIZE);
757
		     state = 10;
758
		     pair.code = 0x44;
759
		     pair.atype = 4;
760
		     pair.phase = 2;
761
		     pair.u1 = 7;
762
		     pair.id = myid;
763
		     bzero(pair.devname, sizeof pair.devname);
764
 
765
		    if (peerdev <= 99999999) // only allow 8 digits
766
		       sprintf(pair.devname, "%d", peerdev);
767
		    else
768
		       fprintf(stderr, "pair dev name too large %08x \"%d\"\n", peerdev, peerdev);
769
 
770
//		    printf("sending pair data for dev %s\n", pair.devname);
771
		    ANT_SendBurstTransfer(chan, (uchar *)&pair, (sizeof pair)/8) ; // send pair data
772
		 }
773
		 else
774
		 {
775
		    fprintf(stderr, "error in gant.cpp on line %d\n", __LINE__);
776
		    return false;
777
		 }
778
	      }
779
	      else if (state == 6 && (status & 0x0f) == 4 && phase == 2)
780
	      {
781
		 // if our auth is ok, garmin has gone to phase 2
782
		 state++;
783
		 ack.code = 0x44;
784
		 ack.atype = 6;
785
		 ack.c1 = 0x01;
786
		 ack.c2 = 0x00;
787
		 ack.id = 0;
788
		 ANT_SendAcknowledgedData(chan, (uchar *)&ack); // tell garmin to start upload
789
	      }
790
	      else if (state == 8 && phase == 2)
791
	      {
792
		 // upload finished. received broadcast that still in phase 2
793
		 state++;
794
		 ack.code = 0x44;
795
		 ack.atype = 3;
796
		 ack.c1 = 0x00;
797
		 ack.c2 = 0x00;
798
		 ack.id = 0;
799
		 ANT_SendAcknowledgedData(chan, (uchar *)&ack); // tell garmin we're finished
800
	      }
801
	      else if (state == 9 && phase == 0)
802
	      {
803
		 // garmin replies it's back in phase 0
804
		 fprintf(stderr, "finished\n");
805
		 return true;
806
	      }
807
	      else if (state == 1 && phase != 0)
808
	      {
809
		 // don't know what phase we're in. let's try and reset
810
		 fprintf(stderr, "resetting\n");
811
		 ack.code = 0x44;
812
		 ack.atype = 3;
813
		 ack.c1 = 0x00;
814
		 ack.c2 = 0x00;
815
		 ack.id = 0;
816
		 ANT_SendAcknowledgedData(chan, (uchar *)&ack); // tell garmin we're finished
817
		 sleep(1);
818
		 return false;
819
	      }
820
	      else if (state == 20 && phase == 2)
821
	      {
822
		 // upload finished. tell garmin to delete logs
823
		 state++;
824
		 ack.code = 0x44;
825
		 ack.atype = 0x0b;
826
		 ack.c1 = 0x01;
827
		 ack.c2 = 0x00;
828
		 ack.id = 0;
829
		 ANT_SendAcknowledgedData(chan, (uchar *)&ack); // delete logs
830
	      }
831
	      else if (state == 21 && phase == 2)
832
	      {
833
		 state = 8;
834
	      }
835
	   break;
836
 
837
	   case EVENT_RX_BURST_PACKET:
838
	      seq = (chan & 0x60) >> 5;
839
	      last = (chan & 0x80) >> 7;
840
	      chan &= 0x1f;
841
 
842
	      if (state == 4)
843
	      {
844
		 static int once = 0;
845
		 // garmin sending authentication/identification data
846
 
847
		 if (!once)
848
		    once = 1;
849
 
850
		 memcpy(clientid[seq], cbuf, 8);
851
 
852
		 if (last)
853
		 {
854
		    state++;
855
 
856
		    memcpy(&peerdev, clientid[1]+4, 4);
857
 
858
		    if (mydev != 0 && peerdev != mydev)
859
		    {
860
		       fprintf(stderr, "Don't know this device %08x != %08x\n", peerdev, mydev);
861
		       return false;
862
		    }
863
		 }
864
	      }
865
	      else if (state == 7)
866
	      {
867
		 static int once = 0;
868
		 int nw;
869
 
870
		 // garmin uploading in response to sendack3
871
		 // in this state we're receiving the workout data
872
		 if (!once)
873
		 {
874
		    fprintf(stderr, "receiving\n");
875
		    once = 1;
234 andreas 876
		    tmpOut.open (QIODevice::ReadWrite | QIODevice::Truncate);
230 andreas 877
		 }
878
 
234 andreas 879
		 // FIXME: Here we should fill our buffer, instead of writing
880
		 // everything into a file.
881
		 nw = write(tmpOut.handle(), cbuf, 8);
230 andreas 882
 
883
		 if (nw != 8)
884
		 {
234 andreas 885
		    KMessageBox::error(0, i18n ("Failed to write to a temporary file!"));
230 andreas 886
		    return false;
887
		 }
888
 
889
		 if (last)
890
		 {
891
		    state++;    // just to exit
892
				//state = 20; // to delete logs
234 andreas 893
		    tmpOut.close();
230 andreas 894
		 }
895
	      }
896
	      else if (state == 10)
897
	      {
898
		 // receiving auth data
899
		 static int once = 0;
900
		 int nw;
901
 
902
		 if (!once)
903
		 {
904
//		    printf("storing auth data in %s\n", authfile);
905
		    once = 1;
906
//		    authfd = open(authfile, O_WRONLY|O_CREAT, 0644);
907
 
908
/*		    if (authfd < 0)
909
		    {
910
		       perror(authfile);
911
		       exit(1);
912
		    } */
913
		 }
914
 
915
		 nw = write(faf.handle(), cbuf, 8);
916
 
917
		 if (nw != 8)
918
		 {
919
		    KMessageBox::error(0, i18n ("Write to auth file %1 failed!").arg(authfile));
920
		    return false;
921
		 }
922
 
923
		 if (last)
924
		 {
925
		    //state = 6; // to download during pairing
926
		    state = 8; // to finish at end of pairing
927
		 }
928
	      }
929
	      else if (state == 6)
930
	      {
931
		 // response to authentication
932
		 static int once = 0;
933
//		 int i;
934
 
935
		 if (!once)
936
		 {
937
		    once = 1;
938
		 }
939
 
940
		 if (last)
941
		 {
942
		    if (cbuf[2] == 2)
943
		    {
944
		       fprintf(stderr, "authentication failed\n");
945
		       return false;
946
		    }
947
		 }
948
	      }
949
	      else
950
	      {
951
		 int i;
952
 
953
		 fprintf(stderr, "data in state %d: ", state);
954
 
955
		 for (i = 0; i < 8; i++)
956
		    fprintf(stderr, "%02x", cbuf[i]);
957
 
958
		 fprintf(stderr, "\n");
959
	      }
960
	   break;
961
	}
962
 
963
	return 1;
964
}
965
 
966
bool gant::revent (uchar chan, uchar event)
967
{
968
unsigned short devid;
969
struct ack_msg ack;
970
int i;
971
 
972
	switch (event)
973
	{
974
	   case EVENT_TRANSFER_TX_COMPLETED:
975
	      // ignore
976
	      // printf("Transfer complete %02x\n", ebuf[1]);
977
	   break;
978
 
979
	   case INVALID_MESSAGE:
980
	      fprintf(stderr, "Invalid message %02x\n", ebuf[1]);
981
	   break;
982
 
983
	   case RESPONSE_NO_ERROR:
984
	      switch (ebuf[1])
985
	      {
986
		 case MESG_ASSIGN_CHANNEL_ID:
987
		    ANT_AssignChannelEventFunction((uchar)chan, (CHANNEL_EVENT_FUNC)&gant::chevent, (uchar *)&cbuf);
988
		 break;
989
 
990
		 case MESG_OPEN_CHANNEL_ID:
991
		    state++;
234 andreas 992
		    fprintf(stderr, "channel open (%d), waiting for broadcast\n", state);
230 andreas 993
		 break;
994
 
995
		 default:
996
		    // ignore
997
		    // printf("Message %02x NO_ERROR\n", ebuf[1]);
998
		 break;
999
	      }
1000
	   break;
1001
 
1002
	   case MESG_CHANNEL_ID_ID:
1003
	      devid = ebuf[1]+ebuf[2]*256;
1004
 
1005
	      if (mydev == 0 || devid == mydev%65536)
1006
	      {
1007
		 state++;
1008
		 ack.code = 0x44; ack.atype = 2; ack.c1 = 0x32; ack.c2 = 0x04;
1009
		 ack.id = myid;
1010
		 ANT_SendAcknowledgedData(chan, (uchar *)&ack); // tell watch go to phase 1
1011
	      }
1012
	      else
1013
	      {
1014
		 fprintf(stderr, "Ignoring unknown device %08x, mydev %08x\n", devid, mydev);
1015
	      }
1016
	   break;
1017
 
1018
	   case MESG_NETWORK_KEY_ID:
1019
	   case MESG_SEARCH_WAVEFORM_ID:
1020
	   case MESG_OPEN_CHANNEL_ID:
1021
	      fprintf(stderr, "response event %02x code %02x\n", event, ebuf[2]);
1022
 
1023
	      for (i = 0; i < 8; i++)
1024
		 fprintf(stderr, "%02x", ebuf[i]);
1025
 
1026
	      fprintf(stderr, "\n");
1027
	   break;
1028
 
1029
	   case MESG_CAPABILITIES_ID:
1030
	   break;
1031
 
1032
	   case MESG_CHANNEL_STATUS_ID:
1033
	   break;
1034
 
1035
	   default:
1036
	      fprintf(stderr, "Unhandled response event %02x\n", event);
1037
	   break;
1038
	}
1039
 
1040
	return true;
1041
}
1042
 
1043
bool gant::read_device ()
1044
{
1045
//int devnum = 0;
1046
int chan = 0;
1047
int net = 0;
1048
int chtype = 0; // wildcard
1049
int devno = 0; // wildcard
1050
int devtype = 0; // wildcard
1051
int manid = 0; // wildcard
1052
int freq = 0x32; // garmin specific radio frequency
1053
int period = 0x1000; // garmin specific broadcast period
1054
int srchto = 255; // max timeout
1055
int waveform = 0x0053; // aids search somehow
1056
 
1057
	// Check if we already have a device set.
1058
//	if (!qFile)
1059
//	   return false;
1060
 
1061
	// TODO: Do this properly...
1062
/*	if (ac > 1) {
1063
		authfile = av[1];
1064
	}
1065
	else {
1066
		fprintf(stderr, "need auth file\n");
1067
		exit(1);
1068
	}
1069
 
1070
	if (ac > 2)
1071
		fn = av[2]; // store the output filename for event function
1072
	if (ac > 3)
1073
		devnum = atoi(av[3]);
1074
	if (ac > 4)
1075
		myid = atoi(av[4]);
1076
	if (ac > 5)
1077
		mydev = atoi(av[5]);
1078
*/
1079
	if (!ANT_Init())
1080
	   return false;
1081
 
1082
	if (!ANT_ResetSystem())
1083
	   return false;
1084
 
1085
	ANT_AssignResponseFunction((RESPONSE_FUNC)&gant::revent, (uchar *)&ebuf);
1086
 
1087
	if (!ANT_RequestMessage(chan, MESG_CHANNEL_STATUS_ID))	//informative
1088
	   return false;
1089
 
1090
	if (!ANT_SetNetworkKeya(net, (uchar *)G50_KEY))
1091
	   return false;
1092
 
1093
	if (!ANT_AssignChannel(chan, chtype, net))
1094
	   return false;
1095
 
1096
	if (!ANT_SetChannelId(chan, devno, devtype, manid))
1097
	   return false;
1098
 
1099
	if (!ANT_RequestMessage(chan, MESG_CAPABILITIES_ID))	//informative
1100
	   return false;
1101
 
1102
	if (!ANT_SetChannelRFFreq(chan, freq))
1103
	   return false;
1104
 
1105
	if (!ANT_SetChannelPeriod(chan, period))
1106
	   return false;
1107
 
1108
	if (!ANT_SetChannelSearchTimeout(chan, srchto))
1109
	   return false;
1110
 
1111
	if (!ANT_SetSearchWaveform(chan, waveform))
1112
	   return false;
1113
 
1114
	if (!ANT_OpenChannel(chan))	// success for this bumps us to state 1
1115
	   return false;
1116
 
1117
	if (!ANT_RequestMessage(chan, MESG_CHANNEL_STATUS_ID))	//informative
1118
	   return false;
1119
 
1120
	// everything handled in event functions
1121
//	for(;;)
1122
//		sleep(10);
1123
 
1124
	return commfn ();
1125
}
234 andreas 1126
 
1127
uchar *gant::getBuffer (int *size)
1128
{
1129
QFileInfo fi;
1130
uchar *buffer;
1131
long sz;
1132
 
1133
	fi.setFile (tmpOut);
1134
 
1135
	if (!fi.exists() || fi.size() > 1000000)
1136
	   return 0;
1137
 
1138
	sz = fi.size();
1139
	*size = 0;
1140
 
1141
	if (!(buffer = new uchar[sz+1]))
1142
	{
1143
	   KMessageBox::error(0, i18n("Error allocating %1 bytes of memory!").arg(sz+1));
1144
	   return 0;
1145
	}
1146
 
1147
	if (tmpOut.handle() == -1)
1148
	{
1149
	   if (!tmpOut.open(QIODevice::ReadOnly))
1150
	   {
1151
	      KMessageBox::error(0, i18n("Error opening a temporary file for reading!"), tmpOut.errorString());
1152
	      delete buffer;
1153
	      return 0;
1154
	   }
1155
	}
1156
 
1157
	if (read (tmpOut.handle(), buffer, sz) < sz)
1158
	{
1159
	   KMessageBox::error(0, i18n("Error reading from a temporary file!"));
1160
	   tmpOut.close();
1161
	   delete buffer;
1162
	   return 0;
1163
	}
1164
 
1165
	*size = (int)sz;
1166
	return buffer;
1167
}