Subversion Repositories public

Rev

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