rubyfit 0.0.11 → 0.0.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/ext/rubyfit/fit.c +418 -412
- data/ext/rubyfit/fit.h +397 -380
- data/ext/rubyfit/fit_config.h +37 -36
- data/ext/rubyfit/fit_convert.c +619 -596
- data/ext/rubyfit/fit_convert.h +213 -203
- data/ext/rubyfit/fit_crc.c +67 -67
- data/ext/rubyfit/fit_crc.h +42 -42
- data/ext/rubyfit/fit_example.c +1512 -1431
- data/ext/rubyfit/fit_example.h +8000 -6147
- data/ext/rubyfit/fit_include.h +19 -19
- data/ext/rubyfit/fit_ram.c +211 -203
- data/ext/rubyfit/fit_ram.h +44 -39
- data/ext/rubyfit/rubyfit.c +560 -566
- data/lib/rubyfit/version.rb +1 -1
- metadata +3 -3
data/ext/rubyfit/fit_ram.h
CHANGED
@@ -1,39 +1,44 @@
|
|
1
|
-
////////////////////////////////////////////////////////////////////////////////
|
2
|
-
// The following FIT Protocol software provided may be used with FIT protocol
|
3
|
-
// devices only and remains the copyrighted property of
|
4
|
-
// The software is being provided on an "as-is" basis and as an accommodation,
|
5
|
-
// and therefore all warranties, representations, or guarantees of any kind
|
6
|
-
// (whether express, implied or statutory) including, without limitation,
|
7
|
-
// warranties of merchantability, non-infringement, or fitness for a particular
|
8
|
-
// purpose, are specifically disclaimed.
|
9
|
-
//
|
10
|
-
// Copyright
|
11
|
-
////////////////////////////////////////////////////////////////////////////////
|
12
|
-
// ****WARNING**** This file is auto-generated! Do NOT edit this file.
|
13
|
-
// Profile Version =
|
14
|
-
// Tag = production/akw/
|
15
|
-
// Product = EXAMPLE
|
16
|
-
// Alignment = 4 bytes, padding disabled.
|
17
|
-
////////////////////////////////////////////////////////////////////////////////
|
18
|
-
|
19
|
-
|
20
|
-
#if !defined(FIT_RAM_H)
|
21
|
-
#define FIT_RAM_H
|
22
|
-
|
23
|
-
#include "fit_example.h"
|
24
|
-
|
25
|
-
#if defined(FIT_RAM_INCLUDE)
|
26
|
-
|
27
|
-
///////////////////////////////////////////////////////////////////////////////
|
28
|
-
// Public Function Prototypes
|
29
|
-
///////////////////////////////////////////////////////////////////////////////
|
30
|
-
|
31
|
-
FIT_RAM_FILE FitRAM_LookupFile(FIT_FILE file);
|
32
|
-
FIT_UINT32 FitRAM_GetFileSize(FIT_RAM_FILE file);
|
33
|
-
void FitRAM_FileReadBytes(FIT_RAM_FILE file, FIT_UINT16 file_index, FIT_UINT32 file_offset, void *data, FIT_UINT32 data_size);
|
34
|
-
void FitRAM_FileWriteBytes(FIT_RAM_FILE file, FIT_UINT16 file_index, FIT_UINT32 file_offset, const void *data, FIT_UINT32 data_size);
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
1
|
+
////////////////////////////////////////////////////////////////////////////////
|
2
|
+
// The following FIT Protocol software provided may be used with FIT protocol
|
3
|
+
// devices only and remains the copyrighted property of Garmin Canada Inc.
|
4
|
+
// The software is being provided on an "as-is" basis and as an accommodation,
|
5
|
+
// and therefore all warranties, representations, or guarantees of any kind
|
6
|
+
// (whether express, implied or statutory) including, without limitation,
|
7
|
+
// warranties of merchantability, non-infringement, or fitness for a particular
|
8
|
+
// purpose, are specifically disclaimed.
|
9
|
+
//
|
10
|
+
// Copyright 2020 Garmin Canada Inc.
|
11
|
+
////////////////////////////////////////////////////////////////////////////////
|
12
|
+
// ****WARNING**** This file is auto-generated! Do NOT edit this file.
|
13
|
+
// Profile Version = 21.27Release
|
14
|
+
// Tag = production/akw/21.27.00-0-gef9575d
|
15
|
+
// Product = EXAMPLE
|
16
|
+
// Alignment = 4 bytes, padding disabled.
|
17
|
+
////////////////////////////////////////////////////////////////////////////////
|
18
|
+
|
19
|
+
|
20
|
+
#if !defined(FIT_RAM_H)
|
21
|
+
#define FIT_RAM_H
|
22
|
+
|
23
|
+
#include "fit_example.h"
|
24
|
+
|
25
|
+
#if defined(FIT_RAM_INCLUDE)
|
26
|
+
|
27
|
+
///////////////////////////////////////////////////////////////////////////////
|
28
|
+
// Public Function Prototypes
|
29
|
+
///////////////////////////////////////////////////////////////////////////////
|
30
|
+
|
31
|
+
FIT_RAM_FILE FitRAM_LookupFile(FIT_FILE file);
|
32
|
+
FIT_UINT32 FitRAM_GetFileSize(FIT_RAM_FILE file);
|
33
|
+
void FitRAM_FileReadBytes(FIT_RAM_FILE file, FIT_UINT16 file_index, FIT_UINT32 file_offset, void *data, FIT_UINT32 data_size);
|
34
|
+
void FitRAM_FileWriteBytes(FIT_RAM_FILE file, FIT_UINT16 file_index, FIT_UINT32 file_offset, const void *data, FIT_UINT32 data_size);
|
35
|
+
|
36
|
+
#if defined(FIT_CONVERT_MULTI_THREAD)
|
37
|
+
void FitRAM_FileWriteMesg(FIT_CONVERT_STATE *state, FIT_RAM_FILE file, FIT_UINT16 file_index, FIT_UINT16 mesg_num, const void *mesg_data, FIT_BOOL restore_fields);
|
38
|
+
#else
|
39
|
+
void FitRAM_FileWriteMesg(FIT_RAM_FILE file, FIT_UINT16 file_index, FIT_UINT16 mesg_num, const void *mesg_data, FIT_BOOL restore_fields);
|
40
|
+
#endif // defined(FIT_CONVERT_MULTI_THREAD)
|
41
|
+
|
42
|
+
#endif // defined(FIT_RAM_INCLUDE)
|
43
|
+
|
44
|
+
#endif // !defined(FIT_RAM_H)
|
data/ext/rubyfit/rubyfit.c
CHANGED
@@ -1,566 +1,560 @@
|
|
1
|
-
////////////////////////////////////////////////////////////////////////////////
|
2
|
-
// The following .FIT software provided may be used with .FIT devices only and
|
3
|
-
// remains the copyrighted property of Dynastream Innovations Inc.
|
4
|
-
// The software is being provided on an "as-is" basis and as an accommodation,
|
5
|
-
// and therefore all warranties, representations, or guarantees of any kind
|
6
|
-
// (whether express, implied or statutory) including, without limitation,
|
7
|
-
// warranties of merchantability, non-infringement, or fitness for a particular
|
8
|
-
// purpose, are specifically disclaimed.
|
9
|
-
//
|
10
|
-
// Copyright 2008 Dynastream Innovations Inc.
|
11
|
-
// All rights reserved. This software may not be reproduced by any means
|
12
|
-
// without express written approval of Dynastream Innovations Inc.
|
13
|
-
////////////////////////////////////////////////////////////////////////////////
|
14
|
-
|
15
|
-
#include "stdio.h"
|
16
|
-
#include "string.h"
|
17
|
-
#include "ruby.h"
|
18
|
-
#include "math.h"
|
19
|
-
|
20
|
-
#include "fit_convert.h"
|
21
|
-
#include "fit_crc.h"
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
VALUE
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
if(mesg->
|
84
|
-
rb_hash_aset(rh, rb_str_new2("
|
85
|
-
if(mesg->
|
86
|
-
rb_hash_aset(rh, rb_str_new2("
|
87
|
-
if(mesg->
|
88
|
-
rb_hash_aset(rh, rb_str_new2("
|
89
|
-
if(mesg->
|
90
|
-
rb_hash_aset(rh, rb_str_new2("
|
91
|
-
if(mesg->
|
92
|
-
rb_hash_aset(rh, rb_str_new2("
|
93
|
-
if(mesg->
|
94
|
-
rb_hash_aset(rh, rb_str_new2("
|
95
|
-
if(mesg->
|
96
|
-
rb_hash_aset(rh, rb_str_new2("
|
97
|
-
if(mesg->
|
98
|
-
rb_hash_aset(rh, rb_str_new2("
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
if(mesg->
|
113
|
-
rb_hash_aset(rh, rb_str_new2("
|
114
|
-
if(mesg->
|
115
|
-
rb_hash_aset(rh, rb_str_new2("
|
116
|
-
if(mesg->
|
117
|
-
rb_hash_aset(rh, rb_str_new2("
|
118
|
-
if(mesg->
|
119
|
-
rb_hash_aset(rh, rb_str_new2("
|
120
|
-
if(mesg->
|
121
|
-
rb_hash_aset(rh, rb_str_new2("
|
122
|
-
if(mesg->
|
123
|
-
rb_hash_aset(rh, rb_str_new2("
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
if(mesg->
|
136
|
-
rb_hash_aset(rh, rb_str_new2("
|
137
|
-
if(mesg->
|
138
|
-
rb_hash_aset(rh, rb_str_new2("
|
139
|
-
if(mesg->
|
140
|
-
rb_hash_aset(rh, rb_str_new2("
|
141
|
-
if(mesg->
|
142
|
-
rb_hash_aset(rh, rb_str_new2("
|
143
|
-
if(mesg->
|
144
|
-
rb_hash_aset(rh, rb_str_new2("
|
145
|
-
if(mesg->
|
146
|
-
rb_hash_aset(rh, rb_str_new2("
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
}
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
-
rb_define_attr(cFitParser, "handler", 1, 1);
|
562
|
-
|
563
|
-
// CRC helper
|
564
|
-
VALUE mCRC = rb_define_module_under(mRubyFit, "CRC");
|
565
|
-
rb_define_singleton_method(mCRC, "update_crc", update_crc, 2);
|
566
|
-
}
|
1
|
+
////////////////////////////////////////////////////////////////////////////////
|
2
|
+
// The following .FIT software provided may be used with .FIT devices only and
|
3
|
+
// remains the copyrighted property of Dynastream Innovations Inc.
|
4
|
+
// The software is being provided on an "as-is" basis and as an accommodation,
|
5
|
+
// and therefore all warranties, representations, or guarantees of any kind
|
6
|
+
// (whether express, implied or statutory) including, without limitation,
|
7
|
+
// warranties of merchantability, non-infringement, or fitness for a particular
|
8
|
+
// purpose, are specifically disclaimed.
|
9
|
+
//
|
10
|
+
// Copyright 2008 Dynastream Innovations Inc.
|
11
|
+
// All rights reserved. This software may not be reproduced by any means
|
12
|
+
// without express written approval of Dynastream Innovations Inc.
|
13
|
+
////////////////////////////////////////////////////////////////////////////////
|
14
|
+
|
15
|
+
#include "stdio.h"
|
16
|
+
#include "string.h"
|
17
|
+
#include "ruby.h"
|
18
|
+
#include "math.h"
|
19
|
+
|
20
|
+
#include "fit_convert.h"
|
21
|
+
#include "fit_crc.h"
|
22
|
+
|
23
|
+
/*
|
24
|
+
* garmin/dynastream, decided to pinch pennies on bits by tinkering with well
|
25
|
+
* established time offsets. This is the magic number of seconds needed to add
|
26
|
+
* to their number to get the true number of seconds since the epoch.
|
27
|
+
* This is 20 years of seconds.
|
28
|
+
*/
|
29
|
+
const long GARMIN_TIME_OFFSET = 631065600;
|
30
|
+
|
31
|
+
|
32
|
+
void pass_message(VALUE handler, char *msg) {
|
33
|
+
rb_funcall(handler, rb_intern("print_msg"), 1, rb_str_new2(msg));
|
34
|
+
}
|
35
|
+
|
36
|
+
void pass_err_message(VALUE handler, char *msg) {
|
37
|
+
rb_funcall(handler, rb_intern("print_error_msg"), 1, rb_str_new2(msg));
|
38
|
+
}
|
39
|
+
|
40
|
+
static VALUE fit_pos_to_rb(FIT_SINT32 pos) {
|
41
|
+
float tmp = pos * (180.0 / pow(2,31));
|
42
|
+
tmp -= (tmp > 180.0 ? 360.0 : 0.0);
|
43
|
+
return rb_float_new(tmp);
|
44
|
+
}
|
45
|
+
|
46
|
+
|
47
|
+
static VALUE init(VALUE self, VALUE handler) {
|
48
|
+
rb_ivar_set(self, rb_intern("@handler"), handler);
|
49
|
+
|
50
|
+
return Qnil;
|
51
|
+
}
|
52
|
+
|
53
|
+
static void pass_activity(VALUE handler, const FIT_ACTIVITY_MESG *mesg) {
|
54
|
+
VALUE rh = rb_hash_new();
|
55
|
+
|
56
|
+
if(mesg->timestamp != FIT_DATE_TIME_INVALID)
|
57
|
+
rb_hash_aset(rh, rb_str_new2("timestamp"), UINT2NUM(mesg->timestamp + GARMIN_TIME_OFFSET));
|
58
|
+
if(mesg->total_timer_time != FIT_UINT32_INVALID)
|
59
|
+
rb_hash_aset(rh, rb_str_new2("total_timer_time"), rb_float_new(mesg->total_timer_time / 1000.0));
|
60
|
+
if(mesg->local_timestamp != FIT_DATE_TIME_INVALID)
|
61
|
+
rb_hash_aset(rh, rb_str_new2("local_timestamp"), rb_float_new(mesg->local_timestamp + GARMIN_TIME_OFFSET));
|
62
|
+
if(mesg->num_sessions != FIT_UINT16_INVALID)
|
63
|
+
rb_hash_aset(rh, rb_str_new2("num_sessions"), UINT2NUM(mesg->num_sessions));
|
64
|
+
if(mesg->type != FIT_ENUM_INVALID)
|
65
|
+
rb_hash_aset(rh, rb_str_new2("type"), CHR2FIX(mesg->type));
|
66
|
+
if(mesg->event != FIT_ENUM_INVALID)
|
67
|
+
rb_hash_aset(rh, rb_str_new2("event"), CHR2FIX(mesg->event));
|
68
|
+
if(mesg->event_type != FIT_ENUM_INVALID)
|
69
|
+
rb_hash_aset(rh, rb_str_new2("event_type"), CHR2FIX(mesg->event_type));
|
70
|
+
if(mesg->event_group != FIT_UINT8_INVALID)
|
71
|
+
rb_hash_aset(rh, rb_str_new2("event_group"), UINT2NUM(mesg->event_group));
|
72
|
+
|
73
|
+
rb_funcall(handler, rb_intern("on_activity"), 1, rh);
|
74
|
+
}
|
75
|
+
|
76
|
+
static void pass_record(VALUE handler, const FIT_RECORD_MESG *mesg) {
|
77
|
+
VALUE rh = rb_hash_new();
|
78
|
+
|
79
|
+
if(mesg->timestamp != FIT_DATE_TIME_INVALID)
|
80
|
+
rb_hash_aset(rh, rb_str_new2("timestamp"), UINT2NUM(mesg->timestamp + GARMIN_TIME_OFFSET));
|
81
|
+
if(mesg->position_lat != FIT_SINT32_INVALID)
|
82
|
+
rb_hash_aset(rh, rb_str_new2("position_lat"), fit_pos_to_rb(mesg->position_lat));
|
83
|
+
if(mesg->position_long != FIT_SINT32_INVALID)
|
84
|
+
rb_hash_aset(rh, rb_str_new2("position_long"), fit_pos_to_rb(mesg->position_long));
|
85
|
+
if(mesg->distance != FIT_UINT32_INVALID)
|
86
|
+
rb_hash_aset(rh, rb_str_new2("distance"), rb_float_new(mesg->distance / 100.0));
|
87
|
+
if(mesg->time_from_course != FIT_SINT32_INVALID)
|
88
|
+
rb_hash_aset(rh, rb_str_new2("time_from_course"), rb_float_new(mesg->time_from_course / 1000.0));
|
89
|
+
if(mesg->heart_rate != FIT_UINT8_INVALID)
|
90
|
+
rb_hash_aset(rh, rb_str_new2("heart_rate"), UINT2NUM(mesg->heart_rate));
|
91
|
+
if(mesg->altitude != FIT_UINT16_INVALID)
|
92
|
+
rb_hash_aset(rh, rb_str_new2("altitude"), rb_float_new(mesg->altitude / 5.0 - 500));
|
93
|
+
if(mesg->enhanced_altitude != FIT_UINT32_INVALID)
|
94
|
+
rb_hash_aset(rh, rb_str_new2("enhanced_altitude"), rb_float_new(mesg->enhanced_altitude / 5.0 - 500));
|
95
|
+
if(mesg->speed != FIT_UINT16_INVALID)
|
96
|
+
rb_hash_aset(rh, rb_str_new2("speed"), rb_float_new(mesg->speed / 1000.0));
|
97
|
+
if(mesg->enhanced_speed != FIT_UINT32_INVALID)
|
98
|
+
rb_hash_aset(rh, rb_str_new2("enhanced_speed"), rb_float_new(mesg->enhanced_speed / 1000.0));
|
99
|
+
if(mesg->grade != FIT_SINT16_INVALID)
|
100
|
+
rb_hash_aset(rh, rb_str_new2("grade"), rb_float_new(mesg->grade / 100.0));
|
101
|
+
if(mesg->power != FIT_UINT16_INVALID)
|
102
|
+
rb_hash_aset(rh, rb_str_new2("power"), UINT2NUM(mesg->power));
|
103
|
+
if(mesg->cadence != FIT_UINT8_INVALID)
|
104
|
+
rb_hash_aset(rh, rb_str_new2("cadence"), UINT2NUM(mesg->cadence));
|
105
|
+
if(mesg->resistance != FIT_UINT8_INVALID)
|
106
|
+
rb_hash_aset(rh, rb_str_new2("resistance"), UINT2NUM(mesg->resistance));
|
107
|
+
if(mesg->cycle_length != FIT_UINT8_INVALID)
|
108
|
+
rb_hash_aset(rh, rb_str_new2("cycle_length"), UINT2NUM(mesg->cycle_length));
|
109
|
+
if(mesg->temperature != FIT_SINT8_INVALID)
|
110
|
+
rb_hash_aset(rh, rb_str_new2("temperature"), INT2FIX(mesg->temperature));
|
111
|
+
|
112
|
+
if(mesg->left_right_balance != FIT_UINT8_INVALID)
|
113
|
+
rb_hash_aset(rh, rb_str_new2("left_right_balance"), UINT2NUM(mesg->left_right_balance & FIT_LEFT_RIGHT_BALANCE_MASK));
|
114
|
+
if(mesg->left_torque_effectiveness != FIT_UINT8_INVALID)
|
115
|
+
rb_hash_aset(rh, rb_str_new2("left_torque_effectiveness"), UINT2NUM(mesg->left_torque_effectiveness));
|
116
|
+
if(mesg->right_torque_effectiveness != FIT_UINT8_INVALID)
|
117
|
+
rb_hash_aset(rh, rb_str_new2("right_torque_effectiveness"), UINT2NUM(mesg->right_torque_effectiveness));
|
118
|
+
if(mesg->left_pedal_smoothness != FIT_UINT8_INVALID)
|
119
|
+
rb_hash_aset(rh, rb_str_new2("left_pedal_smoothness"), UINT2NUM(mesg->left_pedal_smoothness));
|
120
|
+
if(mesg->right_pedal_smoothness != FIT_UINT8_INVALID)
|
121
|
+
rb_hash_aset(rh, rb_str_new2("right_pedal_smoothness"), UINT2NUM(mesg->right_pedal_smoothness));
|
122
|
+
if(mesg->combined_pedal_smoothness != FIT_UINT8_INVALID)
|
123
|
+
rb_hash_aset(rh, rb_str_new2("combined_pedal_smoothness"), UINT2NUM(mesg->combined_pedal_smoothness));
|
124
|
+
|
125
|
+
rb_funcall(handler, rb_intern("on_record"), 1, rh);
|
126
|
+
}
|
127
|
+
|
128
|
+
static void pass_lap(VALUE handler, const FIT_LAP_MESG *mesg) {
|
129
|
+
VALUE rh = rb_hash_new();
|
130
|
+
|
131
|
+
if(mesg->timestamp != FIT_DATE_TIME_INVALID)
|
132
|
+
rb_hash_aset(rh, rb_str_new2("timestamp"), UINT2NUM(mesg->timestamp + GARMIN_TIME_OFFSET));
|
133
|
+
if(mesg->start_time != FIT_DATE_TIME_INVALID)
|
134
|
+
rb_hash_aset(rh, rb_str_new2("start_time"), UINT2NUM(mesg->start_time + GARMIN_TIME_OFFSET));
|
135
|
+
if(mesg->start_position_lat != FIT_SINT32_INVALID)
|
136
|
+
rb_hash_aset(rh, rb_str_new2("start_position_lat"), fit_pos_to_rb(mesg->start_position_lat));
|
137
|
+
if(mesg->start_position_long != FIT_SINT32_INVALID)
|
138
|
+
rb_hash_aset(rh, rb_str_new2("start_position_long"), fit_pos_to_rb(mesg->start_position_long));
|
139
|
+
if(mesg->end_position_lat != FIT_SINT32_INVALID)
|
140
|
+
rb_hash_aset(rh, rb_str_new2("end_position_lat"), fit_pos_to_rb(mesg->end_position_lat));
|
141
|
+
if(mesg->end_position_long != FIT_SINT32_INVALID)
|
142
|
+
rb_hash_aset(rh, rb_str_new2("end_position_long"), fit_pos_to_rb(mesg->end_position_long));
|
143
|
+
if(mesg->total_elapsed_time != FIT_UINT32_INVALID)
|
144
|
+
rb_hash_aset(rh, rb_str_new2("total_elapsed_time"), UINT2NUM(mesg->total_elapsed_time));
|
145
|
+
if(mesg->total_timer_time != FIT_UINT32_INVALID)
|
146
|
+
rb_hash_aset(rh, rb_str_new2("total_timer_time"), rb_float_new(mesg->total_timer_time / 1000.0));
|
147
|
+
if(mesg->total_distance != FIT_UINT32_INVALID)
|
148
|
+
rb_hash_aset(rh, rb_str_new2("total_distance"), rb_float_new(mesg->total_distance / 100.0));
|
149
|
+
if(mesg->total_cycles != FIT_UINT32_INVALID)
|
150
|
+
rb_hash_aset(rh, rb_str_new2("total_cycles"), UINT2NUM(mesg->total_cycles));
|
151
|
+
if(mesg->message_index != FIT_UINT16_INVALID)
|
152
|
+
rb_hash_aset(rh, rb_str_new2("message_index"), UINT2NUM(mesg->message_index));
|
153
|
+
if(mesg->total_calories != FIT_UINT16_INVALID)
|
154
|
+
rb_hash_aset(rh, rb_str_new2("total_calories"), UINT2NUM(mesg->total_calories));
|
155
|
+
if(mesg->total_fat_calories != FIT_UINT16_INVALID)
|
156
|
+
rb_hash_aset(rh, rb_str_new2("total_fat_calories"), UINT2NUM(mesg->total_fat_calories));
|
157
|
+
if(mesg->avg_speed != FIT_UINT16_INVALID)
|
158
|
+
rb_hash_aset(rh, rb_str_new2("avg_speed"), rb_float_new(mesg->avg_speed / 1000.0));
|
159
|
+
if(mesg->max_speed != FIT_UINT16_INVALID)
|
160
|
+
rb_hash_aset(rh, rb_str_new2("max_speed"), rb_float_new(mesg->max_speed / 1000.0));
|
161
|
+
if(mesg->enhanced_avg_speed != FIT_UINT32_INVALID)
|
162
|
+
rb_hash_aset(rh, rb_str_new2("enhanced_avg_speed"), rb_float_new(mesg->enhanced_avg_speed / 1000.0));
|
163
|
+
if(mesg->enhanced_max_speed != FIT_UINT32_INVALID)
|
164
|
+
rb_hash_aset(rh, rb_str_new2("enhanced_max_speed"), rb_float_new(mesg->enhanced_max_speed / 1000.0));
|
165
|
+
if(mesg->avg_altitude != FIT_UINT16_INVALID)
|
166
|
+
rb_hash_aset(rh, rb_str_new2("avg_altitude"), rb_float_new(mesg->avg_altitude / 5.0 - 500));
|
167
|
+
if(mesg->max_altitude != FIT_UINT16_INVALID)
|
168
|
+
rb_hash_aset(rh, rb_str_new2("max_altitude"), rb_float_new(mesg->max_altitude / 5.0 - 500));
|
169
|
+
if(mesg->min_altitude != FIT_UINT16_INVALID)
|
170
|
+
rb_hash_aset(rh, rb_str_new2("min_altitude"), rb_float_new(mesg->min_altitude / 5.0 - 500));
|
171
|
+
if(mesg->enhanced_avg_altitude != FIT_UINT32_INVALID)
|
172
|
+
rb_hash_aset(rh, rb_str_new2("enhanced_avg_altitude"), rb_float_new(mesg->enhanced_avg_altitude / 5.0 - 500));
|
173
|
+
if(mesg->enhanced_max_altitude != FIT_UINT32_INVALID)
|
174
|
+
rb_hash_aset(rh, rb_str_new2("enhanced_max_altitude"), rb_float_new(mesg->enhanced_max_altitude / 5.0 - 500));
|
175
|
+
if(mesg->enhanced_min_altitude != FIT_UINT32_INVALID)
|
176
|
+
rb_hash_aset(rh, rb_str_new2("enhanced_min_altitude"), rb_float_new(mesg->enhanced_min_altitude / 5.0 - 500));
|
177
|
+
if(mesg->avg_power != FIT_UINT16_INVALID)
|
178
|
+
rb_hash_aset(rh, rb_str_new2("avg_power"), UINT2NUM(mesg->avg_power));
|
179
|
+
if(mesg->max_power != FIT_UINT16_INVALID)
|
180
|
+
rb_hash_aset(rh, rb_str_new2("max_power"), UINT2NUM(mesg->max_power));
|
181
|
+
if(mesg->total_ascent != FIT_UINT16_INVALID)
|
182
|
+
rb_hash_aset(rh, rb_str_new2("total_ascent"), UINT2NUM(mesg->total_ascent));
|
183
|
+
if(mesg->total_descent != FIT_UINT16_INVALID)
|
184
|
+
rb_hash_aset(rh, rb_str_new2("total_descent"), UINT2NUM(mesg->total_descent));
|
185
|
+
if(mesg->event != FIT_EVENT_INVALID)
|
186
|
+
rb_hash_aset(rh, rb_str_new2("event"), CHR2FIX(mesg->event));
|
187
|
+
if(mesg->event_type != FIT_EVENT_INVALID)
|
188
|
+
rb_hash_aset(rh, rb_str_new2("event_type"), CHR2FIX(mesg->event_type));
|
189
|
+
if(mesg->avg_heart_rate != FIT_UINT8_INVALID)
|
190
|
+
rb_hash_aset(rh, rb_str_new2("avg_heart_rate"), UINT2NUM(mesg->avg_heart_rate));
|
191
|
+
if(mesg->max_heart_rate != FIT_UINT8_INVALID)
|
192
|
+
rb_hash_aset(rh, rb_str_new2("max_heart_rate"), UINT2NUM(mesg->max_heart_rate));
|
193
|
+
if(mesg->avg_cadence != FIT_UINT8_INVALID)
|
194
|
+
rb_hash_aset(rh, rb_str_new2("avg_cadence"), UINT2NUM(mesg->avg_cadence));
|
195
|
+
if(mesg->max_cadence != FIT_UINT8_INVALID)
|
196
|
+
rb_hash_aset(rh, rb_str_new2("max_cadence"), UINT2NUM(mesg->max_cadence));
|
197
|
+
if(mesg->intensity != FIT_INTENSITY_INVALID)
|
198
|
+
rb_hash_aset(rh, rb_str_new2("intensity"), CHR2FIX(mesg->intensity));
|
199
|
+
if(mesg->lap_trigger != FIT_LAP_TRIGGER_INVALID)
|
200
|
+
rb_hash_aset(rh, rb_str_new2("lap_trigger"), CHR2FIX(mesg->lap_trigger));
|
201
|
+
if(mesg->sport != FIT_SPORT_INVALID)
|
202
|
+
rb_hash_aset(rh, rb_str_new2("sport"), CHR2FIX(mesg->sport));
|
203
|
+
if(mesg->event_group != FIT_UINT8_INVALID)
|
204
|
+
rb_hash_aset(rh, rb_str_new2("event_group"), UINT2NUM(mesg->event_group));
|
205
|
+
|
206
|
+
rb_funcall(handler, rb_intern("on_lap"), 1, rh);
|
207
|
+
}
|
208
|
+
|
209
|
+
static void pass_session(VALUE handler, const FIT_SESSION_MESG *mesg) {
|
210
|
+
VALUE rh = rb_hash_new();
|
211
|
+
|
212
|
+
if(mesg->timestamp != FIT_DATE_TIME_INVALID)
|
213
|
+
rb_hash_aset(rh, rb_str_new2("timestamp"), UINT2NUM(mesg->timestamp + GARMIN_TIME_OFFSET));
|
214
|
+
if(mesg->start_time != FIT_DATE_TIME_INVALID)
|
215
|
+
rb_hash_aset(rh, rb_str_new2("start_time"), UINT2NUM(mesg->start_time + GARMIN_TIME_OFFSET));
|
216
|
+
if(mesg->start_position_lat != FIT_SINT32_INVALID)
|
217
|
+
rb_hash_aset(rh, rb_str_new2("start_position_lat"), fit_pos_to_rb(mesg->start_position_lat));
|
218
|
+
if(mesg->start_position_long != FIT_SINT32_INVALID)
|
219
|
+
rb_hash_aset(rh, rb_str_new2("start_position_long"), fit_pos_to_rb(mesg->start_position_long));
|
220
|
+
if(mesg->total_elapsed_time != FIT_UINT32_INVALID)
|
221
|
+
rb_hash_aset(rh, rb_str_new2("total_elapsed_time"), rb_float_new(mesg->total_elapsed_time / 1000.0));
|
222
|
+
if(mesg->total_timer_time != FIT_UINT32_INVALID)
|
223
|
+
rb_hash_aset(rh, rb_str_new2("total_timer_time"), rb_float_new(mesg->total_timer_time / 1000.0));
|
224
|
+
if(mesg->total_distance != FIT_UINT32_INVALID)
|
225
|
+
rb_hash_aset(rh, rb_str_new2("total_distance"), rb_float_new(mesg->total_distance / 100.0));
|
226
|
+
if(mesg->total_cycles != FIT_UINT32_INVALID)
|
227
|
+
rb_hash_aset(rh, rb_str_new2("total_cycles"), UINT2NUM(mesg->total_cycles));
|
228
|
+
if(mesg->nec_lat != FIT_SINT32_INVALID)
|
229
|
+
rb_hash_aset(rh, rb_str_new2("nec_lat"), fit_pos_to_rb(mesg->nec_lat));
|
230
|
+
if(mesg->nec_long != FIT_SINT32_INVALID)
|
231
|
+
rb_hash_aset(rh, rb_str_new2("nec_long"), fit_pos_to_rb(mesg->nec_long));
|
232
|
+
if(mesg->swc_lat != FIT_SINT32_INVALID)
|
233
|
+
rb_hash_aset(rh, rb_str_new2("swc_lat"), fit_pos_to_rb(mesg->swc_lat));
|
234
|
+
if(mesg->swc_long != FIT_SINT32_INVALID)
|
235
|
+
rb_hash_aset(rh, rb_str_new2("swc_long"), fit_pos_to_rb(mesg->swc_long));
|
236
|
+
if(mesg->message_index != FIT_MESSAGE_INDEX_INVALID)
|
237
|
+
rb_hash_aset(rh, rb_str_new2("message_index"), UINT2NUM(mesg->message_index));
|
238
|
+
if(mesg->total_calories != FIT_UINT16_INVALID)
|
239
|
+
rb_hash_aset(rh, rb_str_new2("total_calories"), UINT2NUM(mesg->total_calories));
|
240
|
+
if(mesg->total_fat_calories != FIT_UINT16_INVALID)
|
241
|
+
rb_hash_aset(rh, rb_str_new2("total_fat_calories"), UINT2NUM(mesg->total_fat_calories));
|
242
|
+
if(mesg->avg_speed != FIT_UINT16_INVALID)
|
243
|
+
rb_hash_aset(rh, rb_str_new2("avg_speed"), rb_float_new(mesg->avg_speed / 1000.0));
|
244
|
+
if(mesg->max_speed != FIT_UINT16_INVALID)
|
245
|
+
rb_hash_aset(rh, rb_str_new2("max_speed"), rb_float_new(mesg->max_speed / 1000.0));
|
246
|
+
if(mesg->avg_power != FIT_UINT16_INVALID)
|
247
|
+
rb_hash_aset(rh, rb_str_new2("avg_power"), UINT2NUM(mesg->avg_power));
|
248
|
+
if(mesg->max_power != FIT_UINT16_INVALID)
|
249
|
+
rb_hash_aset(rh, rb_str_new2("max_power"), UINT2NUM(mesg->max_power));
|
250
|
+
if(mesg->total_ascent != FIT_UINT16_INVALID)
|
251
|
+
rb_hash_aset(rh, rb_str_new2("total_ascent"), UINT2NUM(mesg->total_ascent));
|
252
|
+
if(mesg->total_descent != FIT_UINT16_INVALID)
|
253
|
+
rb_hash_aset(rh, rb_str_new2("total_descent"), UINT2NUM(mesg->total_descent));
|
254
|
+
if(mesg->first_lap_index != FIT_UINT16_INVALID)
|
255
|
+
rb_hash_aset(rh, rb_str_new2("first_lap_index"), UINT2NUM(mesg->first_lap_index));
|
256
|
+
if(mesg->num_laps != FIT_UINT16_INVALID)
|
257
|
+
rb_hash_aset(rh, rb_str_new2("num_laps"), UINT2NUM(mesg->num_laps));
|
258
|
+
if(mesg->event != FIT_EVENT_INVALID)
|
259
|
+
rb_hash_aset(rh, rb_str_new2("event"), CHR2FIX(mesg->event));
|
260
|
+
if(mesg->event_type != FIT_EVENT_INVALID)
|
261
|
+
rb_hash_aset(rh, rb_str_new2("event_type"), CHR2FIX(mesg->event_type));
|
262
|
+
if(mesg->avg_heart_rate != FIT_UINT8_INVALID)
|
263
|
+
rb_hash_aset(rh, rb_str_new2("avg_heart_rate"), UINT2NUM(mesg->avg_heart_rate));
|
264
|
+
if(mesg->max_heart_rate != FIT_UINT8_INVALID)
|
265
|
+
rb_hash_aset(rh, rb_str_new2("max_heart_rate"), UINT2NUM(mesg->max_heart_rate));
|
266
|
+
if(mesg->avg_cadence != FIT_UINT8_INVALID)
|
267
|
+
rb_hash_aset(rh, rb_str_new2("avg_cadence"), UINT2NUM(mesg->avg_cadence));
|
268
|
+
if(mesg->max_cadence != FIT_UINT8_INVALID)
|
269
|
+
rb_hash_aset(rh, rb_str_new2("max_cadence"), UINT2NUM(mesg->max_cadence));
|
270
|
+
if(mesg->sport != FIT_SPORT_INVALID)
|
271
|
+
rb_hash_aset(rh, rb_str_new2("sport"), CHR2FIX(mesg->sport));
|
272
|
+
if(mesg->sub_sport != FIT_SUB_SPORT_INVALID)
|
273
|
+
rb_hash_aset(rh, rb_str_new2("sub_sport"), CHR2FIX(mesg->sub_sport));
|
274
|
+
if(mesg->event_group != FIT_UINT8_INVALID)
|
275
|
+
rb_hash_aset(rh, rb_str_new2("event_group"), UINT2NUM(mesg->event_group));
|
276
|
+
if(mesg->total_training_effect != FIT_UINT8_INVALID)
|
277
|
+
rb_hash_aset(rh, rb_str_new2("total_training_effect"), UINT2NUM(mesg->total_training_effect));
|
278
|
+
|
279
|
+
rb_funcall(handler, rb_intern("on_session"), 1, rh);
|
280
|
+
}
|
281
|
+
|
282
|
+
static void pass_user_profile(VALUE handler, const FIT_USER_PROFILE_MESG *mesg) {
|
283
|
+
VALUE rh = rb_hash_new();
|
284
|
+
|
285
|
+
if(*mesg->friendly_name != FIT_STRING_INVALID)
|
286
|
+
rb_hash_aset(rh, rb_str_new2("friendly_name"), rb_str_new2(mesg->friendly_name));
|
287
|
+
if(mesg->message_index != FIT_MESSAGE_INDEX_INVALID)
|
288
|
+
rb_hash_aset(rh, rb_str_new2("message_index"), UINT2NUM(mesg->message_index));
|
289
|
+
if(mesg->weight != FIT_UINT16_INVALID)
|
290
|
+
rb_hash_aset(rh, rb_str_new2("weight"), rb_float_new(mesg->weight / 10.0));
|
291
|
+
if(mesg->gender != FIT_GENDER_INVALID)
|
292
|
+
rb_hash_aset(rh, rb_str_new2("gender"), UINT2NUM(mesg->gender));
|
293
|
+
if(mesg->age != FIT_UINT8_INVALID)
|
294
|
+
rb_hash_aset(rh, rb_str_new2("age"), UINT2NUM(mesg->age));
|
295
|
+
if(mesg->height != FIT_UINT8_INVALID)
|
296
|
+
rb_hash_aset(rh, rb_str_new2("height"), rb_float_new(mesg->height / 100.0));
|
297
|
+
if(mesg->language != FIT_LANGUAGE_INVALID)
|
298
|
+
rb_hash_aset(rh, rb_str_new2("language"), UINT2NUM(mesg->language));
|
299
|
+
if(mesg->elev_setting != FIT_DISPLAY_MEASURE_INVALID)
|
300
|
+
rb_hash_aset(rh, rb_str_new2("elev_setting"), UINT2NUM(mesg->elev_setting));
|
301
|
+
if(mesg->weight_setting != FIT_DISPLAY_MEASURE_INVALID)
|
302
|
+
rb_hash_aset(rh, rb_str_new2("weight_setting"), UINT2NUM(mesg->weight_setting));
|
303
|
+
if(mesg->resting_heart_rate != FIT_UINT8_INVALID)
|
304
|
+
rb_hash_aset(rh, rb_str_new2("resting_heart_rate"), UINT2NUM(mesg->resting_heart_rate));
|
305
|
+
if(mesg->default_max_running_heart_rate != FIT_UINT8_INVALID)
|
306
|
+
rb_hash_aset(rh, rb_str_new2("default_max_running_heart_rate"), UINT2NUM(mesg->default_max_running_heart_rate));
|
307
|
+
if(mesg->default_max_biking_heart_rate != FIT_UINT8_INVALID)
|
308
|
+
rb_hash_aset(rh, rb_str_new2("default_max_biking_heart_rate"), UINT2NUM(mesg->default_max_biking_heart_rate));
|
309
|
+
if(mesg->default_max_heart_rate != FIT_UINT8_INVALID)
|
310
|
+
rb_hash_aset(rh, rb_str_new2("default_max_heart_rate"), UINT2NUM(mesg->default_max_heart_rate));
|
311
|
+
if(mesg->hr_setting != FIT_DISPLAY_HEART_INVALID)
|
312
|
+
rb_hash_aset(rh, rb_str_new2("hr_setting"), UINT2NUM(mesg->hr_setting));
|
313
|
+
if(mesg->speed_setting != FIT_DISPLAY_MEASURE_INVALID)
|
314
|
+
rb_hash_aset(rh, rb_str_new2("speed_setting"), UINT2NUM(mesg->speed_setting));
|
315
|
+
if(mesg->dist_setting != FIT_DISPLAY_MEASURE_INVALID)
|
316
|
+
rb_hash_aset(rh, rb_str_new2("dist_setting"), UINT2NUM(mesg->dist_setting));
|
317
|
+
if(mesg->power_setting != FIT_DISPLAY_POWER_INVALID)
|
318
|
+
rb_hash_aset(rh, rb_str_new2("power_setting"), UINT2NUM(mesg->power_setting));
|
319
|
+
if(mesg->activity_class != FIT_ACTIVITY_CLASS_INVALID)
|
320
|
+
rb_hash_aset(rh, rb_str_new2("activity_class"), UINT2NUM(mesg->activity_class));
|
321
|
+
if(mesg->position_setting != FIT_DISPLAY_POSITION_INVALID)
|
322
|
+
rb_hash_aset(rh, rb_str_new2("position_setting"), UINT2NUM(mesg->position_setting));
|
323
|
+
|
324
|
+
rb_funcall(handler, rb_intern("on_user_profile"), 1, rh);
|
325
|
+
}
|
326
|
+
|
327
|
+
static void pass_event(VALUE handler, const FIT_EVENT_MESG *mesg) {
|
328
|
+
VALUE rh = rb_hash_new();
|
329
|
+
|
330
|
+
if(mesg->timestamp != FIT_DATE_TIME_INVALID)
|
331
|
+
rb_hash_aset(rh, rb_str_new2("timestamp"), UINT2NUM(mesg->timestamp + GARMIN_TIME_OFFSET));
|
332
|
+
if(mesg->data != FIT_UINT32_INVALID)
|
333
|
+
rb_hash_aset(rh, rb_str_new2("data"), UINT2NUM(mesg->data));
|
334
|
+
if(mesg->data16 != FIT_UINT16_INVALID)
|
335
|
+
rb_hash_aset(rh, rb_str_new2("data16"), UINT2NUM(mesg->data16));
|
336
|
+
if(mesg->timestamp != FIT_EVENT_INVALID)
|
337
|
+
rb_hash_aset(rh, rb_str_new2("event"), CHR2FIX(mesg->event));
|
338
|
+
if(mesg->timestamp != FIT_EVENT_TYPE_INVALID)
|
339
|
+
rb_hash_aset(rh, rb_str_new2("event_type"), CHR2FIX(mesg->event_type));
|
340
|
+
if(mesg->event_group != FIT_UINT8_INVALID)
|
341
|
+
rb_hash_aset(rh, rb_str_new2("event_group"), UINT2NUM(mesg->event_group));
|
342
|
+
|
343
|
+
rb_funcall(handler, rb_intern("on_event"), 1, rh);
|
344
|
+
}
|
345
|
+
|
346
|
+
static void pass_device_info(VALUE handler, const FIT_DEVICE_INFO_MESG *mesg) {
|
347
|
+
VALUE rh = rb_hash_new();
|
348
|
+
|
349
|
+
if(mesg->timestamp != FIT_DATE_TIME_INVALID)
|
350
|
+
rb_hash_aset(rh, rb_str_new2("timestamp"), UINT2NUM(mesg->timestamp + GARMIN_TIME_OFFSET));
|
351
|
+
if(mesg->serial_number != FIT_UINT32Z_INVALID)
|
352
|
+
rb_hash_aset(rh, rb_str_new2("serial_number"), UINT2NUM(mesg->serial_number));
|
353
|
+
if(mesg->manufacturer != FIT_MANUFACTURER_INVALID)
|
354
|
+
rb_hash_aset(rh, rb_str_new2("manufacturer"), UINT2NUM(mesg->manufacturer));
|
355
|
+
if(mesg->product != FIT_UINT16_INVALID)
|
356
|
+
rb_hash_aset(rh, rb_str_new2("product"), UINT2NUM(mesg->product));
|
357
|
+
if(mesg->software_version != FIT_UINT16_INVALID)
|
358
|
+
rb_hash_aset(rh, rb_str_new2("software_version"), UINT2NUM(mesg->software_version));
|
359
|
+
if(mesg->battery_voltage != FIT_UINT16_INVALID)
|
360
|
+
rb_hash_aset(rh, rb_str_new2("battery_voltage"), UINT2NUM(mesg->battery_voltage));
|
361
|
+
if(mesg->device_index != FIT_DEVICE_INDEX_INVALID)
|
362
|
+
rb_hash_aset(rh, rb_str_new2("device_index"), UINT2NUM(mesg->device_index));
|
363
|
+
if(mesg->device_type != FIT_ANTPLUS_DEVICE_TYPE_INVALID)
|
364
|
+
rb_hash_aset(rh, rb_str_new2("device_type"), UINT2NUM(mesg->device_type));
|
365
|
+
if(mesg->hardware_version != FIT_UINT8_INVALID)
|
366
|
+
rb_hash_aset(rh, rb_str_new2("hardware_version"), UINT2NUM(mesg->hardware_version));
|
367
|
+
if(mesg->battery_status != FIT_BATTERY_STATUS_INVALID)
|
368
|
+
rb_hash_aset(rh, rb_str_new2("battery_status"), UINT2NUM(mesg->battery_status));
|
369
|
+
|
370
|
+
rb_funcall(handler, rb_intern("on_device_info"), 1, rh);
|
371
|
+
}
|
372
|
+
|
373
|
+
static void pass_weight_scale_info(VALUE handler, const FIT_WEIGHT_SCALE_MESG *mesg) {
|
374
|
+
VALUE rh = rb_hash_new();
|
375
|
+
|
376
|
+
if(mesg->timestamp != FIT_DATE_TIME_INVALID)
|
377
|
+
rb_hash_aset(rh, rb_str_new2("timestamp"), UINT2NUM(mesg->timestamp + GARMIN_TIME_OFFSET));
|
378
|
+
if(mesg->weight != FIT_WEIGHT_INVALID)
|
379
|
+
rb_hash_aset(rh, rb_str_new2("weight"), rb_float_new(mesg->weight / 100.0));
|
380
|
+
if(mesg->percent_fat != FIT_UINT16_INVALID)
|
381
|
+
rb_hash_aset(rh, rb_str_new2("percent_fat"), rb_float_new(mesg->percent_fat / 100.0));
|
382
|
+
if(mesg->percent_hydration != FIT_UINT16_INVALID)
|
383
|
+
rb_hash_aset(rh, rb_str_new2("percent_hydration"), rb_float_new(mesg->percent_hydration / 100.0));
|
384
|
+
if(mesg->visceral_fat_mass != FIT_UINT16_INVALID)
|
385
|
+
rb_hash_aset(rh, rb_str_new2("visceral_fat_mass"), rb_float_new(mesg->visceral_fat_mass / 100.0));
|
386
|
+
if(mesg->bone_mass != FIT_UINT16_INVALID)
|
387
|
+
rb_hash_aset(rh, rb_str_new2("bone_mass"), rb_float_new(mesg->bone_mass / 100.0));
|
388
|
+
if(mesg->muscle_mass != FIT_UINT16_INVALID)
|
389
|
+
rb_hash_aset(rh, rb_str_new2("muscle_mass"), rb_float_new(mesg->muscle_mass / 100.0));
|
390
|
+
if(mesg->basal_met != FIT_UINT16_INVALID)
|
391
|
+
rb_hash_aset(rh, rb_str_new2("basal_met"), rb_float_new(mesg->basal_met / 4.0));
|
392
|
+
if(mesg->active_met != FIT_UINT16_INVALID)
|
393
|
+
rb_hash_aset(rh, rb_str_new2("active_met"), rb_float_new(mesg->active_met / 4.0));
|
394
|
+
if(mesg->physique_rating != FIT_UINT8_INVALID)
|
395
|
+
rb_hash_aset(rh, rb_str_new2("physique_rating"), rb_float_new(mesg->physique_rating));
|
396
|
+
if(mesg->metabolic_age != FIT_UINT8_INVALID)
|
397
|
+
rb_hash_aset(rh, rb_str_new2("metabolic_age"), rb_float_new(mesg->metabolic_age));
|
398
|
+
if(mesg->visceral_fat_rating != FIT_UINT8_INVALID)
|
399
|
+
rb_hash_aset(rh, rb_str_new2("visceral_fat_rating"), rb_float_new(mesg->visceral_fat_rating));
|
400
|
+
|
401
|
+
rb_funcall(handler, rb_intern("on_weight_scale_info"), 1, rh);
|
402
|
+
}
|
403
|
+
|
404
|
+
static VALUE parse(VALUE self, VALUE original_str) {
|
405
|
+
int i = 0;
|
406
|
+
VALUE str = StringValue(original_str);
|
407
|
+
VALUE handler = rb_ivar_get(self, rb_intern("@handler"));
|
408
|
+
char *p = RSTRING_PTR(str);
|
409
|
+
char err_msg[128];
|
410
|
+
|
411
|
+
FIT_UINT8 buf[8];
|
412
|
+
FIT_CONVERT_RETURN convert_return = FIT_CONVERT_CONTINUE;
|
413
|
+
FIT_UINT32 buf_size;
|
414
|
+
FIT_CONVERT_STATE state;
|
415
|
+
FitConvert_Init(&state, FIT_TRUE);
|
416
|
+
|
417
|
+
if(RSTRING_LEN(str) == 0) {
|
418
|
+
//sprintf(err_msg, "Passed in string with length of 0!");
|
419
|
+
pass_err_message(handler, err_msg);
|
420
|
+
return Qnil;
|
421
|
+
}
|
422
|
+
|
423
|
+
while(i < RSTRING_LEN(str) && (convert_return == FIT_CONVERT_CONTINUE)) {
|
424
|
+
for(buf_size=0;(buf_size < sizeof(buf)) && (p != NULL); buf_size++) {
|
425
|
+
buf[buf_size] = *p;
|
426
|
+
p++;
|
427
|
+
i++;
|
428
|
+
}
|
429
|
+
|
430
|
+
do {
|
431
|
+
convert_return = FitConvert_Read(&state, buf, buf_size);
|
432
|
+
|
433
|
+
switch(convert_return) {
|
434
|
+
case FIT_CONVERT_MESSAGE_AVAILABLE: {
|
435
|
+
const FIT_UINT8 *mesg = FitConvert_GetMessageData(&state);
|
436
|
+
FIT_UINT16 mesg_num = FitConvert_GetMessageNumber(&state);
|
437
|
+
|
438
|
+
switch(mesg_num) {
|
439
|
+
case FIT_MESG_NUM_FILE_ID: {
|
440
|
+
break;
|
441
|
+
}
|
442
|
+
|
443
|
+
case FIT_MESG_NUM_USER_PROFILE: {
|
444
|
+
const FIT_USER_PROFILE_MESG *user_profile = (FIT_USER_PROFILE_MESG *) mesg;
|
445
|
+
pass_user_profile(handler, user_profile);
|
446
|
+
break;
|
447
|
+
}
|
448
|
+
|
449
|
+
case FIT_MESG_NUM_ACTIVITY: {
|
450
|
+
const FIT_ACTIVITY_MESG *activity = (FIT_ACTIVITY_MESG *) mesg;
|
451
|
+
pass_activity(handler, activity);
|
452
|
+
|
453
|
+
{
|
454
|
+
FIT_ACTIVITY_MESG old_mesg;
|
455
|
+
old_mesg.num_sessions = 1;
|
456
|
+
FitConvert_RestoreFields(&state, &old_mesg);
|
457
|
+
sprintf(err_msg, "Restored num_sessions=1 - Activity: timestamp=%u, type=%u, event=%u, event_type=%u, num_sessions=%u\n", activity->timestamp, activity->type, activity->event, activity->event_type, activity->num_sessions);
|
458
|
+
pass_message(handler, err_msg);
|
459
|
+
}
|
460
|
+
break;
|
461
|
+
}
|
462
|
+
|
463
|
+
case FIT_MESG_NUM_SESSION: {
|
464
|
+
const FIT_SESSION_MESG *session = (FIT_SESSION_MESG *) mesg;
|
465
|
+
pass_session(handler, session);
|
466
|
+
break;
|
467
|
+
}
|
468
|
+
|
469
|
+
case FIT_MESG_NUM_LAP: {
|
470
|
+
const FIT_LAP_MESG *lap = (FIT_LAP_MESG *) mesg;
|
471
|
+
pass_lap(handler, lap);
|
472
|
+
break;
|
473
|
+
}
|
474
|
+
|
475
|
+
case FIT_MESG_NUM_RECORD: {
|
476
|
+
const FIT_RECORD_MESG *record = (FIT_RECORD_MESG *) mesg;
|
477
|
+
pass_record(handler, record);
|
478
|
+
break;
|
479
|
+
}
|
480
|
+
|
481
|
+
case FIT_MESG_NUM_EVENT: {
|
482
|
+
const FIT_EVENT_MESG *event = (FIT_EVENT_MESG *) mesg;
|
483
|
+
pass_event(handler, event);
|
484
|
+
break;
|
485
|
+
}
|
486
|
+
|
487
|
+
case FIT_MESG_NUM_DEVICE_INFO: {
|
488
|
+
const FIT_DEVICE_INFO_MESG *device_info = (FIT_DEVICE_INFO_MESG *) mesg;
|
489
|
+
pass_device_info(handler, device_info);
|
490
|
+
break;
|
491
|
+
}
|
492
|
+
|
493
|
+
case FIT_MESG_NUM_WEIGHT_SCALE: {
|
494
|
+
const FIT_WEIGHT_SCALE_MESG *weight_scale_info = (FIT_WEIGHT_SCALE_MESG *) mesg;
|
495
|
+
pass_weight_scale_info(handler, weight_scale_info);
|
496
|
+
break;
|
497
|
+
}
|
498
|
+
|
499
|
+
default: {
|
500
|
+
sprintf(err_msg, "Unknown message\n");
|
501
|
+
pass_message(handler, err_msg);
|
502
|
+
break;
|
503
|
+
}
|
504
|
+
}
|
505
|
+
break;
|
506
|
+
}
|
507
|
+
default:
|
508
|
+
break;
|
509
|
+
}
|
510
|
+
} while (convert_return == FIT_CONVERT_MESSAGE_AVAILABLE);
|
511
|
+
}
|
512
|
+
|
513
|
+
if (convert_return == FIT_CONVERT_ERROR) {
|
514
|
+
sprintf(err_msg, "Error decoding file.\n");
|
515
|
+
pass_err_message(handler, err_msg);
|
516
|
+
return Qnil;
|
517
|
+
}
|
518
|
+
|
519
|
+
if (convert_return == FIT_CONVERT_CONTINUE) {
|
520
|
+
sprintf(err_msg, "Unexpected end of file.\n");
|
521
|
+
pass_err_message(handler, err_msg);
|
522
|
+
return Qnil;
|
523
|
+
}
|
524
|
+
|
525
|
+
if (convert_return == FIT_CONVERT_PROTOCOL_VERSION_NOT_SUPPORTED) {
|
526
|
+
sprintf(err_msg, "Protocol version not supported.\n");
|
527
|
+
pass_err_message(handler, err_msg);
|
528
|
+
return Qnil;
|
529
|
+
}
|
530
|
+
|
531
|
+
if (convert_return == FIT_CONVERT_END_OF_FILE) {
|
532
|
+
sprintf(err_msg, "File converted successfully.\n");
|
533
|
+
pass_message(handler, err_msg);
|
534
|
+
}
|
535
|
+
|
536
|
+
return Qnil;
|
537
|
+
}
|
538
|
+
|
539
|
+
static VALUE update_crc(VALUE self, VALUE r_crc, VALUE r_data) {
|
540
|
+
FIT_UINT16 crc = NUM2USHORT(r_crc);
|
541
|
+
const char* data = StringValuePtr(r_data);
|
542
|
+
const FIT_UINT16 byte_count = RSTRING_LEN(r_data);
|
543
|
+
return UINT2NUM(FitCRC_Update16(crc, data, byte_count));
|
544
|
+
}
|
545
|
+
|
546
|
+
void Init_rubyfit() {
|
547
|
+
VALUE mRubyFit = rb_define_module("RubyFit");
|
548
|
+
VALUE cFitParser = rb_define_class_under(mRubyFit, "FitParser", rb_cObject);
|
549
|
+
|
550
|
+
//instance methods
|
551
|
+
rb_define_method(cFitParser, "initialize", init, 1);
|
552
|
+
rb_define_method(cFitParser, "parse", parse, 1);
|
553
|
+
|
554
|
+
//attributes
|
555
|
+
rb_define_attr(cFitParser, "handler", 1, 1);
|
556
|
+
|
557
|
+
// CRC helper
|
558
|
+
VALUE mCRC = rb_define_module_under(mRubyFit, "CRC");
|
559
|
+
rb_define_singleton_method(mCRC, "update_crc", update_crc, 2);
|
560
|
+
}
|