Subversion Repositories public

Rev

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