Also fixed up off-by-one pointers into logbook data.
Signed-off-by: John Van Ostrand john@vanostrand.com --- src/cochran_cmdr_parser.c | 16 ++++++++++------ src/cochran_commander.h | 10 +++++++--- src/cochran_emc_parser.c | 28 ++++++++++++++++++++-------- 3 files changed, 37 insertions(+), 17 deletions(-)
diff --git a/src/cochran_cmdr_parser.c b/src/cochran_cmdr_parser.c index 7cfd650..de25912 100644 --- a/src/cochran_cmdr_parser.c +++ b/src/cochran_cmdr_parser.c @@ -50,16 +50,20 @@ cochran_cmdr_parser_get_field (dc_parser_t *abstract, dc_field_type_t type,
if (value) { switch (type) { - case DC_FIELD_TEMPERATURE: - *((unsigned int*) value) = log[CMD_START_TEMP]; + case DC_FIELD_TEMPERATURE_SURFACE: + *((unsigned int*) value) = ((float) log[CMD_START_TEMP] - 32) / 1.8; + case DC_FIELD_TEMPERATURE_MINIMUM: + *((unsigned int*) value) = ((float) log[CMD_MIN_TEMP] / 2 + 20 - 32) / 1.8; + case DC_FIELD_TEMPERATURE_MAXIMUM: + *((unsigned int*) value) = ((float) log[CMD_MAX_TEMP] / 2 + 20 - 32) / 1.8; case DC_FIELD_DIVETIME: *((unsigned int *) value) = array_uint16_le (log + EMC_BT) * 60; break; case DC_FIELD_MAXDEPTH: - *((double *) value) = array_uint16_le (log + CMD_MAX_DEPTH) / 4 * FEET; + *((double *) value) = (float) array_uint16_le (log + CMD_MAX_DEPTH) / 4 * FEET; break; case DC_FIELD_AVGDEPTH: - *((double *) value) = array_uint16_le (log + CMD_AVG_DEPTH) / 4 * FEET; + *((double *) value) = (float) array_uint16_le (log + CMD_AVG_DEPTH) / 4 * FEET; break; case DC_FIELD_GASMIX_COUNT: *((unsigned int *) value) = 2; @@ -72,9 +76,9 @@ cochran_cmdr_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, break; case DC_FIELD_SALINITY: // 0 = low conductivity, 1 = high, maybe there's a 2? - water->type = ( log[CMD_WATER_CONDUCTIVITY] == 0 ? DC_WATER_FRESH + water->type = ( (log[CMD_WATER_CONDUCTIVITY] & 0x3) == 0 ? DC_WATER_FRESH : DC_WATER_SALT ); - water->density = 1000 + 12.5 * log[CMD_WATER_CONDUCTIVITY]; + water->density = 1000 + 12.5 * (log[CMD_WATER_CONDUCTIVITY] & 0x3); break; case DC_FIELD_ATMOSPHERIC: *(double *) value = ATM / BAR * pow(1 - 0.0000225577 diff --git a/src/cochran_commander.h b/src/cochran_commander.h index d16de42..1b040de 100644 --- a/src/cochran_commander.h +++ b/src/cochran_commander.h @@ -113,11 +113,13 @@ typedef struct cochran_device_t { #define CMD_START_DEPTH 56 // 2 byte, /4=ft #define CMD_ALTITUDE 73 // 1 byte, /4=Kilofeet #define CMD_END_OFFSET 128 // 4 bytes -#define CMD_MIN_TEMP 153 // 1 byte, F +#define CMD_END_TEMP 153 // 1 byte, F #define CMD_BT 166 // 2 bytes, minutes #define CMD_MAX_DEPTH 168 // 2 bytes, /4=ft #define CMD_AVG_DEPTH 170 // 2 bytes, /4=ft #define CMD_O2_PERCENT 210 // 8 bytes, 4 x 2 byte, /256=% +#define CMD_MIN_TEMP 232 // 1 byte, /2+20=F +#define CMD_MAX_TEMP 233 // 1 byte, /2+20=F
// EMC log fields #define EMC_SEC 0 @@ -127,17 +129,19 @@ typedef struct cochran_device_t { #define EMC_MON 4 #define EMC_YEAR 5 #define EMC_START_OFFSET 6 // 4 bytes -#define EMC_WATER_CONDUCTIVITY 25 // 1 byte, 0=low, 2=high +#define EMC_WATER_CONDUCTIVITY 24 // 1 byte, 0=low, 2=high #define EMC_START_DEPTH 42 // 2 byte, /256=ft #define EMC_START_TEMP 55 // 1 byte, F #define EMC_ALTITUDE 89 // 1 byte, /4=Kilofeet #define EMC_O2_PERCENT 144 // 20 bytes, 10 x 2 bytes, /256=% #define EMC_HE_PERCENT 164 // 20 bytes, 10 x 2 bytes, /256=% #define EMC_END_OFFSET 256 // 4 bytes -#define EMC_MIN_TEMP 293 // 1 byte, F +#define EMC_END_TEMP 293 // 1 byte, F #define EMC_BT 304 // 2 bytes, minutes #define EMC_MAX_DEPTH 306 // 2 bytes, /4=ft #define EMC_AVG_DEPTH 310 // 2 bytes, /4=ft +#define EMC_MIN_TEMP 403 // 1 byte, /2+20=F +#define EMC_MAX_TEMP 407 // 1 byte, /2+20=F
dc_status_t cochran_packet (cochran_device_t *device, diff --git a/src/cochran_emc_parser.c b/src/cochran_emc_parser.c index 37089a7..10d87a0 100644 --- a/src/cochran_emc_parser.c +++ b/src/cochran_emc_parser.c @@ -41,6 +41,7 @@ struct dive_stats { float max_depth; float avg_depth; float min_temp; + float max_temp; };
@@ -59,29 +60,38 @@ cochran_emc_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, dc_salinity_t *water = (dc_salinity_t *) value;
unsigned int dive_time; - float max_depth, avg_depth, min_temp; struct dive_stats stats;
if (value) { switch (type) { - case DC_FIELD_TEMPERATURE: + case DC_FIELD_TEMPERATURE_SURFACE: + *((unsigned int*) value) = ((float) log[EMC_START_TEMP] - 32) / 1.8; + break; + case DC_FIELD_TEMPERATURE_MINIMUM: + if (data->corrupt_dive) { + cochran_emc_parse_dive_stats(abstract, &stats); + *((unsigned int*) value) = stats.min_temp; + } else + *((unsigned int*) value) = ((float) log[EMC_MIN_TEMP] / 2 + 20 - 32) / 1.8; + break; + case DC_FIELD_TEMPERATURE_MAXIMUM: if (data->corrupt_dive) { cochran_emc_parse_dive_stats(abstract, &stats); - *((unsigned int*) value) = min_temp; + *((unsigned int*) value) = stats.max_temp; } else - *((unsigned int*) value) = (log[EMC_START_TEMP] - 32) / 1.8; + *((unsigned int*) value) = ((float) log[EMC_MAX_TEMP] / 2 + 20 - 32) / 1.8; break; case DC_FIELD_DIVETIME: if (data->corrupt_dive) { cochran_emc_parse_dive_stats(abstract, &stats); - *((unsigned int*) value) = dive_time; + *((unsigned int*) value) = stats.dive_time; } else *((unsigned int *) value) = array_uint16_le (log + EMC_BT) * 60; break; case DC_FIELD_MAXDEPTH: if (data->corrupt_dive) { cochran_emc_parse_dive_stats(abstract, &stats); - *((unsigned int*) value) = max_depth; + *((unsigned int*) value) = stats.max_depth; } else *((double *) value) = array_uint16_le (log + EMC_MAX_DEPTH) / 4 * FEET; @@ -89,7 +99,7 @@ cochran_emc_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, case DC_FIELD_AVGDEPTH: if (data->corrupt_dive) { cochran_emc_parse_dive_stats(abstract, &stats); - *((unsigned int*) value) = avg_depth; + *((unsigned int*) value) = stats.avg_depth; } else *((double *) value) = array_uint16_le (log + EMC_AVG_DEPTH) / 4 * FEET; @@ -106,7 +116,7 @@ cochran_emc_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, break; case DC_FIELD_SALINITY: // 0 = low conductivity, 2 = high, maybe there's a 1? - water->type = ( log[EMC_WATER_CONDUCTIVITY] == 0 ? DC_WATER_FRESH + water->type = ( (log[EMC_WATER_CONDUCTIVITY] & 0x3) == 0 ? DC_WATER_FRESH : DC_WATER_SALT ); water->density = 1000 + 12.5 * (log[EMC_WATER_CONDUCTIVITY] & 0x3); break; @@ -341,6 +351,7 @@ void cochran_emc_parse_dive_stats (dc_parser_t *abstract, stats->max_depth = 0; stats->min_temp = 999; stats->avg_depth = 0; + stats->max_temp = 0;
while (offset < size) { s = sdata + offset; @@ -384,6 +395,7 @@ void cochran_emc_parse_dive_stats (dc_parser_t *abstract, temp = (temp - 32.0) / 1.8;
if (temp < stats->min_temp) stats->min_temp = temp; + if (temp > stats->max_temp) stats->max_temp = temp; }
time ++;