Subversion Repositories public

Rev

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