Subversion Repositories public

Rev

Rev 93 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
93 andreas 1
#include "config.h"
2
#include <sys/types.h>
3
#include <sys/stat.h>
4
#include <fcntl.h>
5
#include <unistd.h>
6
#include <string.h>
7
#include <errno.h>
8
#include "garmin.h"
9
 
10
 
11
#define GETU16(x) do { x = get_uint16(*pos);  *pos += 2; } while ( 0 )
12
#define GETS16(x) do { x = get_sint16(*pos);  *pos += 2; } while ( 0 )
13
#define GETU32(x) do { x = get_uint32(*pos);  *pos += 4; } while ( 0 )
14
#define GETS32(x) do { x = get_sint32(*pos);  *pos += 4; } while ( 0 )
15
#define GETF32(x) do { x = get_float32(*pos); *pos += 4; } while ( 0 )
16
#define GETF64(x) do { x = get_float64(*pos); *pos += 8; } while ( 0 )
17
#define GETPOS(x) do { GETS32((x).lat); GETS32((x).lon); } while ( 0 )
18
#define GETRPT(x) do { GETF64((x).lat); GETF64((x).lon); } while ( 0 )
19
#define GETVST(x) x = get_vstring(pos)
20
#define GETU8(x)  x = *(*pos)++
21
#define SKIP(x)   do { memset(*pos,0,x); *pos += x; }      while ( 0 )
22
 
23
#define GETSTR(x)                                                      \
24
  do {                                                                 \
25
    memcpy(x,*pos,sizeof(x)-1); x[sizeof(x)-1] = 0; *pos += sizeof(x); \
26
  } while ( 0 )
27
 
28
 
29
/* --------------------------------------------------------------------------*/
30
/* 7.4.1   D100                                                              */
31
/* --------------------------------------------------------------------------*/
32
 
33
static void
34
garmin_unpack_d100 ( D100 * wpt, uint8 ** pos )
35
{
36
  GETSTR(wpt->ident);
37
  GETPOS(wpt->posn);
38
  SKIP(4);
39
  GETSTR(wpt->cmnt);
40
}
41
 
42
 
43
/* --------------------------------------------------------------------------*/
44
/* 7.4.2   D101                                                              */
45
/* --------------------------------------------------------------------------*/
46
 
47
static void
48
garmin_unpack_d101 ( D101 * wpt, uint8 ** pos )
49
{
50
  GETSTR(wpt->ident);
51
  GETPOS(wpt->posn);
52
  SKIP(4);
53
  GETSTR(wpt->cmnt);
54
  GETF32(wpt->dst);
55
  GETU8(wpt->smbl);
56
}
57
 
58
 
59
/* --------------------------------------------------------------------------*/
60
/* 7.4.3   D102                                                              */
61
/* --------------------------------------------------------------------------*/
62
 
63
static void
64
garmin_unpack_d102 ( D102 * wpt, uint8 ** pos )
65
{
66
  GETSTR(wpt->ident);
67
  GETPOS(wpt->posn);
68
  SKIP(4);
69
  GETSTR(wpt->cmnt);
70
  GETF32(wpt->dst);
71
  GETU16(wpt->smbl);
72
}
73
 
74
 
75
/* --------------------------------------------------------------------------*/
76
/* 7.4.4   D103                                                              */
77
/* --------------------------------------------------------------------------*/
78
 
79
static void
80
garmin_unpack_d103 ( D103 * wpt, uint8 ** pos )
81
{
82
  GETSTR(wpt->ident);
83
  GETPOS(wpt->posn);
84
  SKIP(4);
85
  GETSTR(wpt->cmnt);
86
  GETU8(wpt->smbl);
87
  GETU8(wpt->dspl);
88
}
89
 
90
 
91
/* --------------------------------------------------------------------------*/
92
/* 7.4.5   D104                                                              */
93
/* --------------------------------------------------------------------------*/
94
 
95
static void
96
garmin_unpack_d104 ( D104 * wpt, uint8 ** pos )
97
{
98
  GETSTR(wpt->ident);
99
  GETPOS(wpt->posn);
100
  SKIP(4);
101
  GETSTR(wpt->cmnt);
102
  GETF32(wpt->dst);
103
  GETU16(wpt->smbl);
104
  GETU8(wpt->dspl);
105
}
106
 
107
 
108
/* --------------------------------------------------------------------------*/
109
/* 7.4.6   D105                                                              */
110
/* --------------------------------------------------------------------------*/
111
 
112
static void
113
garmin_unpack_d105 ( D105 * wpt, uint8 ** pos )
114
{
115
  GETPOS(wpt->posn);
116
  GETU16(wpt->smbl);
117
  GETVST(wpt->wpt_ident);
118
}
119
 
120
 
121
/* --------------------------------------------------------------------------*/
122
/* 7.4.7   D106                                                              */
123
/* --------------------------------------------------------------------------*/
124
 
125
static void
126
garmin_unpack_d106 ( D106 * wpt, uint8 ** pos )
127
{
128
  GETU8(wpt->wpt_class);
129
  GETSTR(wpt->subclass);
130
  GETPOS(wpt->posn);
131
  GETU16(wpt->smbl);
132
  GETVST(wpt->wpt_ident);
133
  GETVST(wpt->lnk_ident);
134
}
135
 
136
 
137
/* --------------------------------------------------------------------------*/
138
/* 7.4.8   D107                                                              */
139
/* --------------------------------------------------------------------------*/
140
 
141
static void
142
garmin_unpack_d107 ( D107 * wpt, uint8 ** pos )
143
{
144
  GETSTR(wpt->ident);
145
  GETPOS(wpt->posn);
146
  SKIP(4);
147
  GETSTR(wpt->cmnt);
148
  GETU8(wpt->smbl);
149
  GETU8(wpt->dspl);
150
  GETF32(wpt->dst);
151
  GETU8(wpt->color);
152
}
153
 
154
 
155
/* --------------------------------------------------------------------------*/
156
/* 7.4.9   D108                                                              */
157
/* --------------------------------------------------------------------------*/
158
 
159
static void
160
garmin_unpack_d108 ( D108 * wpt, uint8 ** pos )
161
{
162
  GETU8(wpt->wpt_class);
163
  GETU8(wpt->color);
164
  GETU8(wpt->dspl);
165
  GETU8(wpt->attr);
166
  GETU16(wpt->smbl);
167
  GETSTR(wpt->subclass);
168
  GETPOS(wpt->posn);
169
  GETF32(wpt->alt);
170
  GETF32(wpt->dpth);
171
  GETF32(wpt->dist);
172
  GETSTR(wpt->state);
173
  GETSTR(wpt->cc);
174
  GETVST(wpt->ident);
175
  GETVST(wpt->comment);
176
  GETVST(wpt->facility);
177
  GETVST(wpt->city);
178
  GETVST(wpt->addr);
179
  GETVST(wpt->cross_road);
180
}
181
 
182
 
183
/* --------------------------------------------------------------------------*/
184
/* 7.4.10  D109                                                              */
185
/* --------------------------------------------------------------------------*/
186
 
187
static void
188
garmin_unpack_d109 ( D109 * wpt, uint8 ** pos )
189
{
190
  GETU8(wpt->dtyp);
191
  GETU8(wpt->wpt_class);
192
  GETU8(wpt->dspl_color);
193
  GETU8(wpt->attr);
194
  GETU16(wpt->smbl);
195
  GETSTR(wpt->subclass);
196
  GETPOS(wpt->posn);
197
  GETF32(wpt->alt);
198
  GETF32(wpt->dpth);
199
  GETF32(wpt->dist);
200
  GETSTR(wpt->state);
201
  GETSTR(wpt->cc);
202
  GETU32(wpt->ete);
203
  GETVST(wpt->ident);
204
  GETVST(wpt->comment);
205
  GETVST(wpt->facility);
206
  GETVST(wpt->city);
207
  GETVST(wpt->addr);
208
  GETVST(wpt->cross_road);
209
}
210
 
211
 
212
/* --------------------------------------------------------------------------*/
213
/* 7.4.11  D110                                                              */
214
/* --------------------------------------------------------------------------*/
215
 
216
static void
217
garmin_unpack_d110 ( D110 * wpt, uint8 ** pos )
218
{
219
  GETU8(wpt->dtyp);
220
  GETU8(wpt->wpt_class);
221
  GETU8(wpt->dspl_color);
222
  GETU8(wpt->attr);
223
  GETU16(wpt->smbl);
224
  GETSTR(wpt->subclass);
225
  GETPOS(wpt->posn);
226
  GETF32(wpt->alt);
227
  GETF32(wpt->dpth);
228
  GETF32(wpt->dist);
229
  GETSTR(wpt->state);
230
  GETSTR(wpt->cc);
231
  GETU32(wpt->ete);
232
  GETF32(wpt->temp);
233
  GETU32(wpt->time);
234
  GETU16(wpt->wpt_cat);
235
  GETVST(wpt->ident);
236
  GETVST(wpt->comment);
237
  GETVST(wpt->facility);
238
  GETVST(wpt->city);
239
  GETVST(wpt->addr);
240
  GETVST(wpt->cross_road);
241
}
242
 
243
 
244
/* --------------------------------------------------------------------------*/
245
/* 7.4.12  D120                                                              */
246
/* --------------------------------------------------------------------------*/
247
 
248
static void
249
garmin_unpack_d120 ( D120 * cat, uint8 ** pos )
250
{
251
  GETSTR(cat->name);
252
}
253
 
254
 
255
/* --------------------------------------------------------------------------*/
256
/* 7.4.13  D150                                                              */
257
/* --------------------------------------------------------------------------*/
258
 
259
static void
260
garmin_unpack_d150 ( D150 * wpt, uint8 ** pos )
261
{
262
  GETSTR(wpt->ident);
263
  GETSTR(wpt->cc);
264
  GETU8(wpt->wpt_class);
265
  GETPOS(wpt->posn);
266
  GETS16(wpt->alt);
267
  GETSTR(wpt->city);
268
  GETSTR(wpt->state);
269
  GETSTR(wpt->name);
270
  GETSTR(wpt->cmnt);
271
}
272
 
273
 
274
/* --------------------------------------------------------------------------*/
275
/* 7.4.14  D151                                                              */
276
/* --------------------------------------------------------------------------*/
277
 
278
static void
279
garmin_unpack_d151 ( D151 * wpt, uint8 ** pos )
280
{
281
  GETSTR(wpt->ident);
282
  GETPOS(wpt->posn);
283
  SKIP(4);
284
  GETSTR(wpt->cmnt);
285
  GETF32(wpt->dst);
286
  GETSTR(wpt->name);
287
  GETSTR(wpt->city);
288
  GETSTR(wpt->state);
289
  GETS16(wpt->alt);
290
  GETSTR(wpt->cc);
291
  SKIP(1);
292
  GETU8(wpt->wpt_class);
293
}
294
 
295
 
296
/* --------------------------------------------------------------------------*/
297
/* 7.4.15  D152                                                              */
298
/* --------------------------------------------------------------------------*/
299
 
300
static void
301
garmin_unpack_d152 ( D152 * wpt, uint8 ** pos )
302
{
303
  GETSTR(wpt->ident);
304
  GETPOS(wpt->posn);
305
  SKIP(4);
306
  GETSTR(wpt->cmnt);
307
  GETF32(wpt->dst);
308
  GETSTR(wpt->name);
309
  GETSTR(wpt->city);
310
  GETSTR(wpt->state);
311
  GETS16(wpt->alt);
312
  GETSTR(wpt->cc);
313
  SKIP(1);
314
  GETU8(wpt->wpt_class);
315
}
316
 
317
 
318
/* --------------------------------------------------------------------------*/
319
/* 7.4.16  D154                                                              */
320
/* --------------------------------------------------------------------------*/
321
 
322
static void
323
garmin_unpack_d154 ( D154 * wpt, uint8 ** pos )
324
{
325
  GETSTR(wpt->ident);
326
  GETPOS(wpt->posn);
327
  SKIP(4);
328
  GETSTR(wpt->cmnt);
329
  GETF32(wpt->dst);
330
  GETSTR(wpt->name);
331
  GETSTR(wpt->city);
332
  GETSTR(wpt->state);
333
  GETS16(wpt->alt);
334
  GETSTR(wpt->cc);
335
  SKIP(1);
336
  GETU8(wpt->wpt_class);
337
  GETU16(wpt->smbl);
338
}
339
 
340
 
341
/* --------------------------------------------------------------------------*/
342
/* 7.4.17  D155                                                              */
343
/* --------------------------------------------------------------------------*/
344
 
345
static void
346
garmin_unpack_d155 ( D155 * wpt, uint8 ** pos )
347
{
348
  GETSTR(wpt->ident);
349
  GETPOS(wpt->posn);
350
  SKIP(4);
351
  GETSTR(wpt->cmnt);
352
  GETF32(wpt->dst);
353
  GETSTR(wpt->name);
354
  GETSTR(wpt->city);
355
  GETSTR(wpt->state);
356
  GETS16(wpt->alt);
357
  GETSTR(wpt->cc);
358
  SKIP(1);
359
  GETU8(wpt->wpt_class);
360
  GETU16(wpt->smbl);  
361
  GETU8(wpt->dspl);
362
}
363
 
364
 
365
/* --------------------------------------------------------------------------*/
366
/* 7.4.18  D200                                                              */
367
/* --------------------------------------------------------------------------*/
368
 
369
static void
370
garmin_unpack_d200 ( D200 * hdr, uint8 ** pos )
371
{
372
  GETU8(*hdr);
373
}
374
 
375
 
376
/* --------------------------------------------------------------------------*/
377
/* 7.4.19  D201                                                              */
378
/* --------------------------------------------------------------------------*/
379
 
380
static void
381
garmin_unpack_d201 ( D201 * hdr, uint8 ** pos )
382
{
383
  GETU8(hdr->nmbr);
384
  GETSTR(hdr->cmnt);
385
}
386
 
387
 
388
/* --------------------------------------------------------------------------*/
389
/* 7.4.20  D202                                                              */
390
/* --------------------------------------------------------------------------*/
391
 
392
static void
393
garmin_unpack_d202 ( D202 * hdr, uint8 ** pos )
394
{
395
  GETVST(hdr->rte_ident);
396
}
397
 
398
 
399
/* --------------------------------------------------------------------------*/
400
/* 7.4.21  D210                                                              */
401
/* --------------------------------------------------------------------------*/
402
 
403
static void
404
garmin_unpack_d210 ( D210 * link, uint8 ** pos )
405
{
406
  GETU16(link->class);
407
  GETSTR(link->subclass);
408
  GETVST(link->ident);
409
}
410
 
411
 
412
/* --------------------------------------------------------------------------*/
413
/* 7.4.22  D300                                                              */
414
/* --------------------------------------------------------------------------*/
415
 
416
static void
417
garmin_unpack_d300 ( D300 * point, uint8 ** pos )
418
{
419
  GETPOS(point->posn);
420
  GETU32(point->time);
421
  GETU8(point->new_trk);
422
}
423
 
424
 
425
/* --------------------------------------------------------------------------*/
426
/* 7.4.23  D301                                                              */
427
/* --------------------------------------------------------------------------*/
428
 
429
static void
430
garmin_unpack_d301 ( D301 * point, uint8 ** pos )
431
{ 
432
  GETPOS(point->posn);
433
  GETU32(point->time);
434
  GETF32(point->alt);
435
  GETF32(point->dpth);
436
  GETU8(point->new_trk);
437
}
438
 
439
 
440
/* --------------------------------------------------------------------------*/
441
/* 7.4.24  D302                                                              */
442
/* --------------------------------------------------------------------------*/
443
 
444
static void
445
garmin_unpack_d302 ( D302 * point, uint8 ** pos )
446
{
447
  GETPOS(point->posn);
448
  GETU32(point->time);
449
  GETF32(point->alt);
450
  GETF32(point->dpth);
451
  GETF32(point->temp);
452
  GETU8(point->new_trk);
453
}
454
 
455
 
456
/* --------------------------------------------------------------------------*/
457
/* 7.4.25  D303                                                              */
458
/* --------------------------------------------------------------------------*/
459
 
460
static void
461
garmin_unpack_d303 ( D303 * point, uint8 ** pos )
462
{
463
  GETPOS(point->posn);
464
  GETU32(point->time);
465
  GETF32(point->alt);
466
  GETU8(point->heart_rate);
467
}
468
 
469
 
470
/* --------------------------------------------------------------------------*/
471
/* 7.4.26  D304                                                              */
472
/* --------------------------------------------------------------------------*/
473
 
474
static void
475
garmin_unpack_d304 ( D304 * point, uint8 ** pos )
476
{
477
  GETPOS(point->posn);
478
  GETU32(point->time);
479
  GETF32(point->alt);
480
  GETF32(point->distance);
481
  GETU8(point->heart_rate);
482
  GETU8(point->cadence);
483
  GETU8(point->sensor);
484
}
485
 
486
 
487
/* --------------------------------------------------------------------------*/
488
/* 7.4.27  D310                                                              */
489
/* --------------------------------------------------------------------------*/
490
 
491
static void
492
garmin_unpack_d310 ( D310 * hdr, uint8 ** pos )
493
{
494
  GETU8(hdr->dspl);
495
  GETU8(hdr->color);
496
  GETVST(hdr->trk_ident);
497
}
498
 
499
 
500
/* --------------------------------------------------------------------------*/
501
/* 7.4.28  D311                                                              */
502
/* --------------------------------------------------------------------------*/
503
 
504
static void
505
garmin_unpack_d311 ( D311 * hdr, uint8 ** pos )
506
{
507
  GETU16(hdr->index);
508
}
509
 
510
 
511
/* --------------------------------------------------------------------------*/
512
/* 7.4.29  D312                                                              */
513
/* --------------------------------------------------------------------------*/
514
 
515
static void
516
garmin_unpack_d312 ( D312 * hdr, uint8 ** pos )
517
{
518
  GETU8(hdr->dspl);
519
  GETU8(hdr->color);
520
  GETVST(hdr->trk_ident);
521
}
522
 
523
 
524
/* ------------------------------------------------------------------------- */
525
/* 7.4.30  D400                                                              */
526
/* ------------------------------------------------------------------------- */
527
 
528
static void
529
garmin_unpack_d400 ( D400 * prx, uint8 ** pos )
530
{
531
  garmin_unpack_d100(&prx->wpt,pos);
532
  SKIP(sizeof(D100));
533
  GETF32(prx->dst);
534
}
535
 
536
 
537
/* ------------------------------------------------------------------------- */
538
/* 7.4.31  D403                                                              */
539
/* ------------------------------------------------------------------------- */
540
 
541
static void
542
garmin_unpack_d403 ( D403 * prx, uint8 ** pos )
543
{
544
  garmin_unpack_d103(&prx->wpt,pos);
545
  SKIP(sizeof(D103));
546
  GETF32(prx->dst);
547
}
548
 
549
 
550
/* ------------------------------------------------------------------------- */
551
/* 7.4.32  D450                                                              */
552
/* ------------------------------------------------------------------------- */
553
 
554
static void
555
garmin_unpack_d450 ( D450 * prx, uint8 ** pos )
556
{
557
  GETU32(prx->idx);
558
  garmin_unpack_d150(&prx->wpt,pos);
559
  SKIP(sizeof(D150));
560
  GETF32(prx->dst);
561
}
562
 
563
 
564
/* ------------------------------------------------------------------------- */
565
/* 7.4.33  D500                                                              */
566
/* ------------------------------------------------------------------------- */
567
 
568
static void
569
garmin_unpack_d500 ( D500 * alm, uint8 ** pos )
570
{
571
  GETU16(alm->wn);
572
  GETF32(alm->toa);
573
  GETF32(alm->af0);
574
  GETF32(alm->af1);
575
  GETF32(alm->e);
576
  GETF32(alm->sqrta);
577
  GETF32(alm->m0);
578
  GETF32(alm->w);
579
  GETF32(alm->omg0);
580
  GETF32(alm->odot);
581
  GETF32(alm->i);
582
}
583
 
584
 
585
/* ------------------------------------------------------------------------- */
586
/* 7.4.34  D501                                                              */
587
/* ------------------------------------------------------------------------- */
588
 
589
static void
590
garmin_unpack_d501 ( D501 * alm, uint8 ** pos )
591
{
592
  GETU16(alm->wn);
593
  GETF32(alm->toa);
594
  GETF32(alm->af0);
595
  GETF32(alm->af1);
596
  GETF32(alm->e);
597
  GETF32(alm->sqrta);
598
  GETF32(alm->m0);
599
  GETF32(alm->w);
600
  GETF32(alm->omg0);
601
  GETF32(alm->odot);
602
  GETF32(alm->i);
603
  GETU8(alm->hlth);
604
}
605
 
606
 
607
/* ------------------------------------------------------------------------- */
608
/* 7.4.35  D550                                                              */
609
/* ------------------------------------------------------------------------- */
610
 
611
static void
612
garmin_unpack_d550 ( D550 * alm, uint8 ** pos )
613
{
614
  GETU8(alm->svid);
615
  GETU16(alm->wn);
616
  GETF32(alm->toa);
617
  GETF32(alm->af0);
618
  GETF32(alm->af1);
619
  GETF32(alm->e);
620
  GETF32(alm->sqrta);
621
  GETF32(alm->m0);
622
  GETF32(alm->w);
623
  GETF32(alm->omg0);
624
  GETF32(alm->odot);
625
  GETF32(alm->i);
626
}
627
 
628
 
629
/* ------------------------------------------------------------------------- */
630
/* 7.4.36  D551                                                              */
631
/* ------------------------------------------------------------------------- */
632
 
633
static void
634
garmin_unpack_d551 ( D551 * alm, uint8 ** pos )
635
{
636
  GETU8(alm->svid);
637
  GETU16(alm->wn);
638
  GETF32(alm->toa);
639
  GETF32(alm->af0);
640
  GETF32(alm->af1);
641
  GETF32(alm->e);
642
  GETF32(alm->sqrta);
643
  GETF32(alm->m0);
644
  GETF32(alm->w);
645
  GETF32(alm->omg0);
646
  GETF32(alm->odot);
647
  GETF32(alm->i);
648
  GETU8(alm->hlth);
649
}
650
 
651
 
652
/* ------------------------------------------------------------------------- */
653
/* 7.4.37  D600                                                              */
654
/* ------------------------------------------------------------------------- */
655
 
656
static void
657
garmin_unpack_d600 ( D600 * dt, uint8 ** pos )
658
{
659
  GETU8(dt->month);
660
  GETU8(dt->day);
661
  GETU16(dt->year);
662
  GETU16(dt->hour);
663
  GETU8(dt->minute);
664
  GETU8(dt->second);
665
}
666
 
667
 
668
/* ------------------------------------------------------------------------- */
669
/* 7.4.38  D650                                                              */
670
/* ------------------------------------------------------------------------- */
671
 
672
static void
673
garmin_unpack_d650 ( D650 * fbr, uint8 ** pos )
674
{
675
  GETU32(fbr->takeoff_time);
676
  GETU32(fbr->landing_time);
677
  GETPOS(fbr->takeoff_posn);
678
  GETPOS(fbr->landing_posn);
679
  GETU32(fbr->night_time);
680
  GETU32(fbr->num_landings);
681
  GETF32(fbr->max_speed);
682
  GETF32(fbr->max_alt);
683
  GETF32(fbr->distance);
684
  GETU8(fbr->cross_country_flag);
685
  GETVST(fbr->departure_name);
686
  GETVST(fbr->departure_ident);
687
  GETVST(fbr->arrival_name);
688
  GETVST(fbr->arrival_ident);
689
  GETVST(fbr->ac_id);
690
}
691
 
692
 
693
/* ------------------------------------------------------------------------- */
694
/* 7.4.39  D700                                                              */
695
/* ------------------------------------------------------------------------- */
696
 
697
static void
698
garmin_unpack_d700 ( D700 * pt, uint8 ** pos )
699
{
700
  GETRPT(*pt);
701
}
702
 
703
 
704
/* ------------------------------------------------------------------------- */
705
/* 7.4.40  D800                                                              */
706
/* ------------------------------------------------------------------------- */
707
 
708
static void
709
garmin_unpack_d800 ( D800 * pvt, uint8 ** pos )
710
{
711
  GETF32(pvt->alt);
712
  GETF32(pvt->epe);
713
  GETF32(pvt->eph);
714
  GETF32(pvt->epv);
715
  GETU16(pvt->fix);
716
  GETF64(pvt->tow);
717
  GETRPT(pvt->posn);
718
  GETF32(pvt->east);
719
  GETF32(pvt->north);
720
  GETF32(pvt->up);
721
  GETF32(pvt->msl_hght);
722
  GETS16(pvt->leap_scnds);
723
  GETU32(pvt->wn_days);
724
}
725
 
726
 
727
/* --------------------------------------------------------------------------*/
728
/* 7.4.41  D906                                                              */
729
/* --------------------------------------------------------------------------*/
730
 
731
static void
732
garmin_unpack_d906 ( D906 * lap, uint8 ** pos )
733
{
734
  GETU32(lap->start_time);
735
  GETU32(lap->total_time);
736
  GETF32(lap->total_distance);
737
  GETPOS(lap->begin);
738
  GETPOS(lap->end);
739
  GETU16(lap->calories);
740
  GETU8(lap->track_index);
741
}
742
 
743
 
744
/* --------------------------------------------------------------------------*/
745
/* 7.4.42  D1000                                                             */
746
/* --------------------------------------------------------------------------*/
747
 
748
 
749
static void garmin_unpack_d1002 ( D1002 * wkt, uint8 ** pos );
750
 
751
 
752
static void
753
garmin_unpack_d1000 ( D1000 * run, uint8 ** pos )
754
{
755
  GETU32(run->track_index);
756
  GETU32(run->first_lap_index);
757
  GETU32(run->last_lap_index);
758
  GETU8(run->sport_type);
759
  GETU8(run->program_type);
760
  SKIP(2);
761
  GETU32(run->virtual_partner.time);
762
  GETF32(run->virtual_partner.distance);
763
  garmin_unpack_d1002(&run->workout,pos);
764
}
765
 
766
 
767
/* --------------------------------------------------------------------------*/
768
/* 7.4.43  D1001                                                             */
769
/* --------------------------------------------------------------------------*/
770
 
771
static void
772
garmin_unpack_d1001 ( D1001 * lap, uint8 ** pos )
773
{
774
  GETU32(lap->index);
775
  GETU32(lap->start_time);
776
  GETU32(lap->total_time);
777
  GETF32(lap->total_dist);
778
  GETF32(lap->max_speed);
779
  GETPOS(lap->begin);
780
  GETPOS(lap->end);
781
  GETU16(lap->calories);
782
  GETU8(lap->avg_heart_rate);
783
  GETU8(lap->max_heart_rate);
784
  GETU8(lap->intensity);
785
}
786
 
787
 
788
/* --------------------------------------------------------------------------*/
789
/* 7.4.44  D1002                                                             */
790
/* --------------------------------------------------------------------------*/
791
 
792
static void
793
garmin_unpack_d1002 ( D1002 * wkt, uint8 ** pos )
794
{
795
  int i;
796
 
797
  GETU32(wkt->num_valid_steps);
798
  for ( i = 0; i < 20; i++ ) {
799
    GETSTR(wkt->steps[i].custom_name);
800
    GETF32(wkt->steps[i].target_custom_zone_low);
801
    GETF32(wkt->steps[i].target_custom_zone_high);
802
    GETU16(wkt->steps[i].duration_value);
803
    GETU8(wkt->steps[i].intensity);
804
    GETU8(wkt->steps[i].duration_type);
805
    GETU8(wkt->steps[i].target_type);
806
    GETU8(wkt->steps[i].target_value);
807
    SKIP(2);
808
  }
809
  GETSTR(wkt->name);
810
  GETU8(wkt->sport_type);
811
}
812
 
813
 
814
/* --------------------------------------------------------------------------*/
815
/* 7.4.45  D1003                                                             */
816
/* --------------------------------------------------------------------------*/
817
 
818
static void
819
garmin_unpack_d1003 ( D1003 * occ, uint8 ** pos )
820
{
821
  GETSTR(occ->workout_name);
822
  GETU32(occ->day);
823
}
824
 
825
 
826
/* --------------------------------------------------------------------------*/
827
/* 7.4.46  D1004                                                             */
828
/* --------------------------------------------------------------------------*/
829
 
830
static void
831
garmin_unpack_d1004 ( D1004 * prof, uint8 ** pos )
832
{
833
  int i;
834
  int j;
835
 
836
  for ( i = 0; i < 3; i++ ) {
837
    for ( j = 0; j < 5; j++ ) {
838
      GETU8(prof->activities[i].heart_rate_zones[j].low_heart_rate);
839
      GETU8(prof->activities[i].heart_rate_zones[j].high_heart_rate);
840
      SKIP(2);
841
    }
842
    for ( j = 0; j < 10; j++ ) {
843
      GETF32(prof->activities[i].speed_zones[j].low_speed);
844
      GETF32(prof->activities[i].speed_zones[j].high_speed);
845
      GETSTR(prof->activities[i].speed_zones[j].name);
846
    }
847
    GETF32(prof->activities[i].gear_weight);
848
    GETU8(prof->activities[i].max_heart_rate);
849
    SKIP(3);
850
  }
851
  GETF32(prof->weight);
852
  GETU16(prof->birth_year);
853
  GETU8(prof->birth_month);
854
  GETU8(prof->birth_day);
855
  GETU8(prof->gender);
856
}
857
 
858
 
859
/* --------------------------------------------------------------------------*/
860
/* 7.4.47  D1005                                                             */
861
/* --------------------------------------------------------------------------*/
862
 
863
static void
864
garmin_unpack_d1005 ( D1005 * limits, uint8 ** pos )
865
{
866
  GETU32(limits->max_workouts);
867
  GETU32(limits->max_unscheduled_workouts);
868
  GETU32(limits->max_occurrences);
869
}
870
 
871
 
872
/* --------------------------------------------------------------------------*/
873
/* 7.4.48  D1006                                                             */
874
/* --------------------------------------------------------------------------*/
875
 
876
static void
877
garmin_unpack_d1006 ( D1006 * course, uint8 ** pos )
878
{
879
  GETU16(course->index);
880
  SKIP(2);
881
  GETSTR(course->course_name);
882
  GETU16(course->track_index);
883
}
884
 
885
 
886
/* --------------------------------------------------------------------------*/
887
/* 7.4.49  D1007                                                             */
888
/* --------------------------------------------------------------------------*/
889
 
890
static void
891
garmin_unpack_d1007 ( D1007 * lap, uint8 ** pos )
892
{
893
  GETU16(lap->course_index);
894
  GETU16(lap->lap_index);
895
  GETU32(lap->total_time);
896
  GETF32(lap->total_dist);
897
  GETPOS(lap->begin);
898
  GETPOS(lap->end);
899
  GETU8(lap->avg_heart_rate);
900
  GETU8(lap->max_heart_rate);
901
  GETU8(lap->intensity);
902
  GETU8(lap->avg_cadence);
903
}
904
 
905
 
906
/* --------------------------------------------------------------------------*/
907
/* 7.4.50  D1008                                                             */
908
/* --------------------------------------------------------------------------*/
909
 
910
static void
911
garmin_unpack_d1008 ( D1008 * wkt, uint8 ** pos )
912
{
913
  garmin_unpack_d1002((D1002 *)wkt,pos);
914
}
915
 
916
 
917
/* --------------------------------------------------------------------------*/
918
/* 7.4.51  D1009                                                             */
919
/* --------------------------------------------------------------------------*/
920
 
921
static void
922
garmin_unpack_d1009 ( D1009 * run, uint8 ** pos )
923
{
924
  GETU16(run->track_index);
925
  GETU16(run->first_lap_index);
926
  GETU16(run->last_lap_index);
927
  GETU8(run->sport_type);
928
  GETU8(run->program_type);
929
  GETU8(run->multisport);
930
  SKIP(3);
931
  GETU32(run->quick_workout.time);
932
  GETF32(run->quick_workout.distance);
933
  garmin_unpack_d1008(&run->workout,pos);  
934
}
935
 
936
 
937
/* --------------------------------------------------------------------------*/
938
/* 7.4.52  D1010                                                             */
939
/* --------------------------------------------------------------------------*/
940
 
941
static void
942
garmin_unpack_d1010 ( D1010 * run, uint8 ** pos )
943
{
944
  GETU32(run->track_index);
945
  GETU32(run->first_lap_index);
946
  GETU32(run->last_lap_index);
947
  GETU8(run->sport_type);
948
  GETU8(run->program_type);
949
  GETU8(run->multisport);
950
  SKIP(1);
951
  GETU32(run->virtual_partner.time);
952
  GETF32(run->virtual_partner.distance);
953
  garmin_unpack_d1002(&run->workout,pos);
954
}
955
 
956
 
957
/* --------------------------------------------------------------------------*/
958
/* 7.4.53  D1011                                                             */
959
/* --------------------------------------------------------------------------*/
960
 
961
static void
962
garmin_unpack_d1011 ( D1011 * lap, uint8 ** pos )
963
{
964
  GETU16(lap->index);
965
  SKIP(2);
966
  GETU32(lap->start_time);
967
  GETU32(lap->total_time);
968
  GETF32(lap->total_dist);
969
  GETF32(lap->max_speed);
970
  GETPOS(lap->begin);
971
  GETPOS(lap->end);
972
  GETU16(lap->calories);
973
  GETU8(lap->avg_heart_rate);
974
  GETU8(lap->max_heart_rate);
975
  GETU8(lap->intensity);
976
  GETU8(lap->avg_cadence);
977
  GETU8(lap->trigger_method);
978
}
979
 
980
 
981
/* --------------------------------------------------------------------------*/
982
/* 7.4.54  D1012                                                             */
983
/* --------------------------------------------------------------------------*/
984
 
985
static void
986
garmin_unpack_d1012 ( D1012 * point, uint8 ** pos )
987
{
988
  GETSTR(point->name);
989
  SKIP(1);
990
  GETU16(point->course_index);
991
  SKIP(2);
992
  GETU32(point->track_point_time);
993
  GETU8(point->point_type);
994
}
995
 
996
 
997
/* --------------------------------------------------------------------------*/
998
/* 7.4.55  D1013                                                             */
999
/* --------------------------------------------------------------------------*/
1000
 
1001
static void
1002
garmin_unpack_d1013 ( D1013 * limits, uint8 ** pos )
1003
{
1004
  GETU32(limits->max_courses);
1005
  GETU32(limits->max_course_laps);
1006
  GETU32(limits->max_course_pnt);
1007
  GETU32(limits->max_course_trk_pnt);
1008
}
1009
 
1010
 
1011
/* --------------------------------------------------------------------------*/
1012
/* 7.4.XX  D1015 (Undocumented)                                              */
1013
/* --------------------------------------------------------------------------*/
1014
 
1015
static void
1016
garmin_unpack_d1015 ( D1015 * lap, uint8 ** pos )
1017
{
1018
  GETU16(lap->index);
1019
  SKIP(2);
1020
  GETU32(lap->start_time);
1021
  GETU32(lap->total_time);
1022
  GETF32(lap->total_dist);
1023
  GETF32(lap->max_speed);
1024
  GETPOS(lap->begin);
1025
  GETPOS(lap->end);
1026
  GETU16(lap->calories);
1027
  GETU8(lap->avg_heart_rate);
1028
  GETU8(lap->max_heart_rate);
1029
  GETU8(lap->intensity);
1030
  GETU8(lap->avg_cadence);
1031
  GETU8(lap->trigger_method);
1032
 
1033
  /* 
1034
     Garmin has not gotten back to me about what these fields mean, and
1035
     whether all of the bytes are needed or just, say, three of them.
1036
     This is annoying, because it means we may end up with .gmn files
1037
     that have oversized D1015 elements, but it shouldn't affect our
1038
     ability to read those files.  We don't make any assumptions about
1039
     the size of each element.
1040
  */
1041
 
1042
  GETU8(lap->unknown[0]);
1043
  GETU8(lap->unknown[1]);
1044
  GETU8(lap->unknown[2]);
1045
  GETU8(lap->unknown[3]);
1046
  GETU8(lap->unknown[4]);
1047
}
1048
 
1049
 
1050
/* List */
1051
 
1052
static void
1053
garmin_unpack_dlist ( garmin_list * list, uint8 ** pos )
1054
{
1055
  uint32             id;
1056
  uint32             elements;
1057
  uint32             type;
1058
  uint32             size;
1059
  uint32             i;
1060
 
1061
  GETU32(list->id);
1062
  GETU32(elements);
1063
 
1064
  for ( i = 0; i < elements; i++ ) {
1065
    GETU32(id);
1066
    GETU32(type);
1067
    GETU32(size);
1068
    if ( id == list->id ) {
1069
      garmin_list_append(list,garmin_unpack(pos,type));
1070
    } else {
1071
      /* list element has wrong list ID */
136 andreas 1072
      char hv0[256];
1073
      sprintf(hv0, "garmin_unpack_dlist: list element had ID %d, expected ID %d!",
93 andreas 1074
	     id,list->id);
136 andreas 1075
      garmin_queue_error(hv0, err_error);
93 andreas 1076
    }
1077
  }
1078
}
1079
 
1080
 
1081
/* Unpack a chunk of data. */
1082
 
1083
static garmin_data *
1084
garmin_unpack_chunk ( uint8 ** pos )
1085
{
1086
  garmin_data * data = NULL;
1087
  uint8 *       start;
1088
  uint32        unpacked;
1089
  uint32        version;
1090
  uint32        size;
1091
  uint32        type;
1092
  uint32        chunk;
136 andreas 1093
  char          hv0[256];
93 andreas 1094
 
1095
  /* First, read the header and check that it's satisfactory. */
1096
 
1097
  if ( memcmp(*pos,GARMIN_MAGIC,strlen(GARMIN_MAGIC)) == 0 ) {
1098
    SKIP(12);
1099
    GETU32(version);
1100
 
1101
    if ( version > GARMIN_VERSION ) {
1102
      /* warning: version is more recent than supported. */
136 andreas 1103
      sprintf(hv0, "garmin_unpack_chunk: version %.2f supported, %.2f found!",
93 andreas 1104
	     GARMIN_VERSION/100.0, version/100.0);
136 andreas 1105
      garmin_queue_error(hv0, err_warning);
93 andreas 1106
    }
1107
 
1108
    /* This is the size of the packed data (not including the header) */
1109
 
1110
    GETU32(size);
1111
 
1112
    /* Now let's get the type of the data, and the size of the chunk. */
1113
 
1114
    GETU32(type);
1115
    GETU32(chunk);
1116
 
1117
    /* Unpack from here. */
1118
 
1119
    start    = *pos;
1120
    data     = garmin_unpack(pos,type);
1121
    unpacked = *pos - start;
1122
 
1123
    /* Double check - did we unpack the number of bytes we were supposed to? */
1124
 
136 andreas 1125
    if ( unpacked != chunk ) {
93 andreas 1126
      /* unpacked the wrong number of bytes! */
136 andreas 1127
      sprintf(hv0, "garmin_unpack_chunk: unpacked %d bytes (expecting %d)!",
93 andreas 1128
	     unpacked,chunk);
136 andreas 1129
      garmin_queue_error(hv0, err_error);
93 andreas 1130
    }
1131
  } else {
1132
    /* unknown file format */
136 andreas 1133
    sprintf(hv0, "garmin_unpack_chunk: not a .gmn file!");
1134
    garmin_queue_error(hv0, err_fatal);
93 andreas 1135
  }
1136
 
1137
  return data;
1138
}
1139
 
1140
 
1141
/* ========================================================================= */
1142
/* garmin_load                                                               */
1143
/* ========================================================================= */
1144
 
1145
garmin_data *
1146
garmin_load ( const char * filename )
1147
{
1148
  garmin_data * data   = NULL;
1149
  garmin_data * data_l = NULL;
1150
  garmin_list * list;
1151
  uint32        bytes;
1152
  uint8 *       buf;
1153
  uint8 *       pos;
1154
  uint8 *       start;
1155
  struct stat   sb;
1156
  int           fd;
136 andreas 1157
  char          hv0[1024];
93 andreas 1158
 
1159
  if ( (fd = open(filename,O_RDONLY)) != -1 ) {
1160
    if ( fstat(fd,&sb) != -1 ) {
1161
      if ( (buf = malloc(sb.st_size)) != NULL ) {
1162
	if ( (bytes = read(fd,buf,sb.st_size)) == sb.st_size ) {
1163
	  data_l = garmin_alloc_data(data_Dlist);
1164
	  list   = data_l->data;
1165
	  pos    = buf;
1166
	  while ( pos - buf < bytes ) {
1167
	    start = pos;
1168
	    garmin_list_append(list,garmin_unpack_chunk(&pos));
1169
	    if ( pos == start ) {
1170
	      /* did not unpack anything! */
136 andreas 1171
	      sprintf(hv0, "garmin_load:  %s: nothing unpacked!",filename);
1172
	      garmin_queue_error(hv0, err_error);
93 andreas 1173
	      break;
1174
	    }
1175
	  }
1176
 
1177
	  /* 
1178
	     If we unpacked only a single element, return it.  Otherwise,
1179
	     return the list.
1180
	  */
1181
 
1182
	  if ( list->elements == 1 ) {
1183
	    data = list->head->data;
1184
	    list->head->data = NULL;
1185
	    garmin_free_data(data_l);
1186
	  } else {
1187
	    data = data_l;
136 andreas 1188
	  }
93 andreas 1189
 
1190
	} else {
1191
	  /* read failed */
136 andreas 1192
	  sprintf(hv0, "%s: read: %s!",filename,strerror(errno));
1193
	  garmin_queue_error(hv0, err_error);
93 andreas 1194
	}
1195
	free(buf);
1196
      } else {
1197
	/* malloc failed */
136 andreas 1198
	sprintf(hv0, "%s: malloc: %s!",filename,strerror(errno));
1199
        garmin_queue_error(hv0, err_fatal);
93 andreas 1200
      }
1201
    } else {
1202
      /* fstat failed */
136 andreas 1203
      sprintf(hv0, "%s: fstat: %s!",filename,strerror(errno));
1204
      garmin_queue_error(hv0, err_error);
93 andreas 1205
    }
1206
    close(fd);
1207
  } else {
1208
    /* open failed */
136 andreas 1209
    sprintf(hv0, "%s: open: %s!",filename,strerror(errno));
1210
    garmin_queue_error(hv0, err_error);
93 andreas 1211
  }
1212
 
1213
  return data;
1214
}
1215
 
1216
 
1217
/* ========================================================================= */
1218
/* garmin_unpack_packet                                                      */
1219
/* ========================================================================= */
1220
 
1221
garmin_data *
1222
garmin_unpack_packet ( garmin_packet * p, garmin_datatype type )
1223
{
1224
  uint8 * pos = p->packet.data;
1225
 
1226
  return garmin_unpack(&pos,type);
1227
}
1228
 
1229
 
1230
/* ========================================================================= */
1231
/* garmin_unpack                                                             */
1232
/* ========================================================================= */
1233
 
1234
garmin_data *
1235
garmin_unpack ( uint8 **         pos, 
1236
		garmin_datatype  type )
1237
{
1238
  garmin_data * d = garmin_alloc_data(type);
136 andreas 1239
  char hv0[256];
93 andreas 1240
 
1241
  /* Early exit if we were asked to allocate an unknown data type. */
1242
 
1243
  if ( d->data == NULL ) {
1244
    free(d);
1245
    return NULL;
1246
  }
1247
 
1248
  /* Now do the actual unpacking. */
1249
 
1250
#define CASE_DATA(x) \
1251
  case data_D##x: garmin_unpack_d##x(d->data,pos); break
1252
 
1253
  switch ( type ) {
1254
  CASE_DATA(list);
1255
  CASE_DATA(100);
1256
  CASE_DATA(101);
1257
  CASE_DATA(102);
1258
  CASE_DATA(103);
1259
  CASE_DATA(104);
1260
  CASE_DATA(105);
1261
  CASE_DATA(106);
1262
  CASE_DATA(107);
1263
  CASE_DATA(108);
1264
  CASE_DATA(109);
1265
  CASE_DATA(110);
1266
  CASE_DATA(120);
1267
  CASE_DATA(150);
1268
  CASE_DATA(151);
1269
  CASE_DATA(152);
1270
  CASE_DATA(154);
1271
  CASE_DATA(155);
1272
  CASE_DATA(200);
1273
  CASE_DATA(201);
1274
  CASE_DATA(202);
1275
  CASE_DATA(210);
1276
  CASE_DATA(300);
1277
  CASE_DATA(301);
1278
  CASE_DATA(302);
1279
  CASE_DATA(303);
1280
  CASE_DATA(304);
1281
  CASE_DATA(310);
1282
  CASE_DATA(311);
1283
  CASE_DATA(312);
1284
  CASE_DATA(400);
1285
  CASE_DATA(403);
1286
  CASE_DATA(450);
1287
  CASE_DATA(500);
1288
  CASE_DATA(501);
1289
  CASE_DATA(550);
1290
  CASE_DATA(551);
1291
  CASE_DATA(600);
1292
  CASE_DATA(650);
1293
  CASE_DATA(700);
1294
  CASE_DATA(800);
1295
  CASE_DATA(906);
1296
  CASE_DATA(1000);
1297
  CASE_DATA(1001);
1298
  CASE_DATA(1002);
1299
  CASE_DATA(1003);
1300
  CASE_DATA(1004);
1301
  CASE_DATA(1005);
1302
  CASE_DATA(1006);
1303
  CASE_DATA(1007);
1304
  CASE_DATA(1008);
1305
  CASE_DATA(1009);
1306
  CASE_DATA(1010);
1307
  CASE_DATA(1011);
1308
  CASE_DATA(1012);
1309
  CASE_DATA(1013);
1310
  CASE_DATA(1015);
1311
  default: 
136 andreas 1312
    sprintf(hv0, "garmin_unpack: data type %d not supported!",type);
1313
    garmin_queue_error(hv0, err_warning);
93 andreas 1314
    break;
1315
  }
1316
 
1317
  return d;
1318
 
1319
#undef CASE_DATA
1320
}