35
35
36
36
typedef struct cressi_edy_parser_t cressi_edy_parser_t ;
37
37
38
+ typedef struct cressi_edy_layout_t {
39
+ unsigned int datetime_y ;
40
+ unsigned int datetime_md ;
41
+ unsigned int datetime_hm ;
42
+ unsigned int avgdepth ;
43
+ unsigned int maxdepth ;
44
+ unsigned int temperature ;
45
+ unsigned int divetime ;
46
+ unsigned int gasmix ;
47
+ unsigned int gasmix_count ;
48
+ } cressi_edy_layout_t ;
49
+
38
50
struct cressi_edy_parser_t {
39
51
dc_parser_t base ;
40
52
unsigned int model ;
53
+ const cressi_edy_layout_t * layout ;
41
54
};
42
55
43
56
static dc_status_t cressi_edy_parser_get_datetime (dc_parser_t * abstract , dc_datetime_t * datetime );
@@ -56,16 +69,50 @@ static const dc_parser_vtable_t cressi_edy_parser_vtable = {
56
69
NULL /* destroy */
57
70
};
58
71
72
+ static const cressi_edy_layout_t edy = {
73
+ 8 , /* datetime_y */
74
+ 10 , /* datetime_md */
75
+ 28 , /* datetime_hm */
76
+ 1 , /* avgdepth */
77
+ 5 , /* maxdepth */
78
+ 22 , /* temperature */
79
+ 25 , /* divetime */
80
+ 46 , 3 , /* gasmix */
81
+ };
82
+
83
+ static unsigned int
84
+ decode (const unsigned char data [], unsigned int offset , unsigned int n )
85
+ {
86
+ unsigned int result = 0 ;
87
+
88
+ for (unsigned int i = 0 ; i < n ; ++ i ) {
89
+ unsigned char byte = data [offset / 2 ];
90
+
91
+ unsigned char nibble = 0 ;
92
+ if ((offset & 1 ) == 0 ) {
93
+ nibble = (byte >> 4 ) & 0x0F ;
94
+ } else {
95
+ nibble = byte & 0x0F ;
96
+ }
97
+
98
+ result *= 10 ;
99
+ result += nibble ;
100
+ offset ++ ;
101
+ }
102
+
103
+ return result ;
104
+ }
59
105
60
106
static unsigned int
61
- cressi_edy_parser_count_gasmixes (const unsigned char * data )
107
+ cressi_edy_parser_count_gasmixes (const unsigned char data [], const cressi_edy_layout_t * layout )
62
108
{
63
109
// Count the number of active gas mixes. The active gas
64
110
// mixes are always first, so we stop counting as soon
65
111
// as the first gas marked as disabled is found.
66
112
unsigned int i = 0 ;
67
- while (i < 3 ) {
68
- if ((data [0x17 - i ] & 0xF0 ) == 0xF0 )
113
+ while (i < layout -> gasmix_count ) {
114
+ unsigned int state = decode (data , layout -> gasmix - i * 2 , 1 );
115
+ if (state == 0x0F )
69
116
break ;
70
117
i ++ ;
71
118
}
@@ -89,6 +136,7 @@ cressi_edy_parser_create (dc_parser_t **out, dc_context_t *context, const unsign
89
136
90
137
// Set the default values.
91
138
parser -> model = model ;
139
+ parser -> layout = & edy ;
92
140
93
141
* out = (dc_parser_t * ) parser ;
94
142
@@ -99,17 +147,19 @@ cressi_edy_parser_create (dc_parser_t **out, dc_context_t *context, const unsign
99
147
static dc_status_t
100
148
cressi_edy_parser_get_datetime (dc_parser_t * abstract , dc_datetime_t * datetime )
101
149
{
150
+ cressi_edy_parser_t * parser = (cressi_edy_parser_t * ) abstract ;
151
+ const cressi_edy_layout_t * layout = parser -> layout ;
152
+ const unsigned char * data = abstract -> data ;
153
+
102
154
if (abstract -> size < SZ_HEADER )
103
155
return DC_STATUS_DATAFORMAT ;
104
156
105
- const unsigned char * p = abstract -> data ;
106
-
107
157
if (datetime ) {
108
- datetime -> year = bcd2dec ( p [ 4 ] ) + 2000 ;
109
- datetime -> month = ( p [ 5 ] & 0xF0 ) >> 4 ;
110
- datetime -> day = ( p [ 5 ] & 0x0F ) * 10 + (( p [ 6 ] & 0xF0 ) >> 4 );
111
- datetime -> hour = bcd2dec ( p [ 14 ] );
112
- datetime -> minute = bcd2dec ( p [ 15 ] );
158
+ datetime -> year = decode ( data , layout -> datetime_y , 2 ) + 2000 ;
159
+ datetime -> month = decode ( data , layout -> datetime_md , 1 ) ;
160
+ datetime -> day = decode ( data , layout -> datetime_md + 1 , 2 );
161
+ datetime -> hour = decode ( data , layout -> datetime_hm , 2 );
162
+ datetime -> minute = decode ( data , layout -> datetime_hm + 2 , 2 );
113
163
datetime -> second = 0 ;
114
164
datetime -> timezone = DC_TIMEZONE_NONE ;
115
165
}
@@ -122,39 +172,39 @@ static dc_status_t
122
172
cressi_edy_parser_get_field (dc_parser_t * abstract , dc_field_type_t type , unsigned int flags , void * value )
123
173
{
124
174
cressi_edy_parser_t * parser = (cressi_edy_parser_t * ) abstract ;
175
+ const cressi_edy_layout_t * layout = parser -> layout ;
176
+ const unsigned char * data = abstract -> data ;
125
177
126
178
if (abstract -> size < SZ_HEADER )
127
179
return DC_STATUS_DATAFORMAT ;
128
180
129
- const unsigned char * p = abstract -> data ;
130
-
131
181
dc_gasmix_t * gasmix = (dc_gasmix_t * ) value ;
132
182
133
183
if (value ) {
134
184
switch (type ) {
135
185
case DC_FIELD_DIVETIME :
136
186
if (parser -> model == EDY )
137
- * ((unsigned int * ) value ) = bcd2dec ( p [ 0x0C ] & 0x0F ) * 60 + bcd2dec ( p [ 0x0D ] );
187
+ * ((unsigned int * ) value ) = decode ( data , layout -> divetime , 1 ) * 60 + decode ( data , layout -> divetime + 1 , 2 );
138
188
else
139
- * ((unsigned int * ) value ) = ( bcd2dec ( p [ 0x0C ] & 0x0F ) * 100 + bcd2dec ( p [ 0x0D ]) ) * 60 ;
189
+ * ((unsigned int * ) value ) = decode ( data , layout -> divetime , 3 ) * 60 ;
140
190
break ;
141
191
case DC_FIELD_MAXDEPTH :
142
- * ((double * ) value ) = ( bcd2dec ( p [ 0x02 ] & 0x0F ) * 100 + bcd2dec ( p [ 0x03 ]) ) / 10.0 ;
192
+ * ((double * ) value ) = decode ( data , layout -> maxdepth , 3 ) / 10.0 ;
143
193
break ;
144
194
case DC_FIELD_AVGDEPTH :
145
- * ((double * ) value ) = ( bcd2dec ( p [ 0x00 ] & 0x0F ) * 100 + bcd2dec ( p [ 0x01 ]) ) / 10.0 ;
195
+ * ((double * ) value ) = decode ( data , layout -> avgdepth , 3 ) / 10.0 ;
146
196
break ;
147
197
case DC_FIELD_GASMIX_COUNT :
148
- * ((unsigned int * ) value ) = cressi_edy_parser_count_gasmixes (p );
198
+ * ((unsigned int * ) value ) = cressi_edy_parser_count_gasmixes (data , layout );
149
199
break ;
150
200
case DC_FIELD_GASMIX :
151
201
gasmix -> usage = DC_USAGE_NONE ;
152
202
gasmix -> helium = 0.0 ;
153
- gasmix -> oxygen = bcd2dec ( p [ 0x17 - flags ] ) / 100.0 ;
203
+ gasmix -> oxygen = decode ( data , layout -> gasmix - flags * 2 , 2 ) / 100.0 ;
154
204
gasmix -> nitrogen = 1.0 - gasmix -> oxygen - gasmix -> helium ;
155
205
break ;
156
206
case DC_FIELD_TEMPERATURE_MINIMUM :
157
- * ((double * ) value ) = ( bcd2dec ( p [ 0x0B ]) * 10 + (( p [ 0x0C ] & 0xF0 ) >> 4 ) ) / 10.0 ;
207
+ * ((double * ) value ) = decode ( data , layout -> temperature , 3 ) / 10.0 ;
158
208
break ;
159
209
default :
160
210
return DC_STATUS_UNSUPPORTED ;
@@ -169,6 +219,7 @@ static dc_status_t
169
219
cressi_edy_parser_samples_foreach (dc_parser_t * abstract , dc_sample_callback_t callback , void * userdata )
170
220
{
171
221
cressi_edy_parser_t * parser = (cressi_edy_parser_t * ) abstract ;
222
+ const cressi_edy_layout_t * layout = parser -> layout ;
172
223
173
224
const unsigned char * data = abstract -> data ;
174
225
unsigned int size = abstract -> size ;
@@ -182,7 +233,7 @@ cressi_edy_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t c
182
233
interval = 15 ;
183
234
}
184
235
185
- unsigned int ngasmixes = cressi_edy_parser_count_gasmixes (data );
236
+ unsigned int ngasmixes = cressi_edy_parser_count_gasmixes (data , layout );
186
237
unsigned int gasmix = 0xFFFFFFFF ;
187
238
188
239
unsigned int offset = SZ_HEADER ;
@@ -202,7 +253,7 @@ cressi_edy_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t c
202
253
if (callback ) callback (DC_SAMPLE_TIME , & sample , userdata );
203
254
204
255
// Depth (1/10 m).
205
- unsigned int depth = bcd2dec (data [ offset + 0 ] & 0x0F ) * 100 + bcd2dec ( data [ offset + 1 ] );
256
+ unsigned int depth = decode (data + offset , 1 , 3 );
206
257
sample .depth = depth / 10.0 ;
207
258
if (callback ) callback (DC_SAMPLE_DEPTH , & sample , userdata );
208
259
0 commit comments