diff --git a/examples/universal.c b/examples/universal.c index 1d61ef8..b4d9b47 100644 --- a/examples/universal.c +++ b/examples/universal.c @@ -271,12 +271,8 @@ sample_cb (dc_sample_type_t type, dc_sample_value_t value, void *userdata) fprintf (sampledata->fp, " %.2f\n", value.temperature); break; case DC_SAMPLE_EVENT: - if (value.event.type == SAMPLE_EVENT_GASCHANGE2) { - fprintf (sampledata->fp, " \n", - value.event.value & 0xFFFF, (value.event.value >> 16) & 0xFFFF); - } else if (value.event.type == SAMPLE_EVENT_GASCHANGE) { - fprintf (sampledata->fp, " \n", - value.event.value); + if (value.event.type == SAMPLE_EVENT_GASCHANGE || value.event.type == SAMPLE_EVENT_GASCHANGE2) { + // Ignore deprecated events. } else { fprintf (sampledata->fp, " %s\n", value.event.type, value.event.time, value.event.flags, value.event.value, events[value.event.type]); @@ -310,6 +306,9 @@ sample_cb (dc_sample_type_t type, dc_sample_value_t value, void *userdata) fprintf (sampledata->fp, " %s\n", value.deco.time, value.deco.depth, decostop[value.deco.type]); break; + case DC_SAMPLE_GASMIX: + fprintf (sampledata->fp, " %u\n", value.gasmix); + break; default: break; } diff --git a/include/libdivecomputer/parser.h b/include/libdivecomputer/parser.h index 774e5e3..6718741 100644 --- a/include/libdivecomputer/parser.h +++ b/include/libdivecomputer/parser.h @@ -43,7 +43,8 @@ typedef enum dc_sample_type_t { DC_SAMPLE_SETPOINT, DC_SAMPLE_PPO2, DC_SAMPLE_CNS, - DC_SAMPLE_DECO + DC_SAMPLE_DECO, + DC_SAMPLE_GASMIX } dc_sample_type_t; typedef enum dc_field_type_t { @@ -74,7 +75,7 @@ typedef enum parser_sample_event_t { SAMPLE_EVENT_BOOKMARK, SAMPLE_EVENT_SURFACE, SAMPLE_EVENT_SAFETYSTOP, - SAMPLE_EVENT_GASCHANGE, /* The event value contains the O2 percentage. */ + SAMPLE_EVENT_GASCHANGE, /* Deprecated: replaced by DC_SAMPLE_GASMIX. */ SAMPLE_EVENT_SAFETYSTOP_VOLUNTARY, SAMPLE_EVENT_SAFETYSTOP_MANDATORY, SAMPLE_EVENT_DEEPSTOP, @@ -88,9 +89,7 @@ typedef enum parser_sample_event_t { SAMPLE_EVENT_RGBM, SAMPLE_EVENT_HEADING, SAMPLE_EVENT_TISSUELEVEL, - SAMPLE_EVENT_GASCHANGE2, /* The event value contains the O2 and He - percentages, packed as two 16bit integers in - respectively the low and high part. */ + SAMPLE_EVENT_GASCHANGE2, /* Deprecated: replaced by DC_SAMPLE_GASMIX. */ } parser_sample_event_t; /* For backwards compatibility */ @@ -211,6 +210,7 @@ typedef union dc_sample_value_t { unsigned int time; double depth; } deco; + unsigned int gasmix; /* Gas mix index */ } dc_sample_value_t; typedef struct dc_parser_t dc_parser_t; diff --git a/src/Makefile.am b/src/Makefile.am index f106c09..64c3649 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,5 +1,5 @@ AM_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include -AM_CFLAGS = $(LIBUSB_CFLAGS) +AM_CFLAGS = $(LIBUSB_CFLAGS) -DENABLE_DEPRECATED lib_LTLIBRARIES = libdivecomputer.la diff --git a/src/atomics_cobalt_parser.c b/src/atomics_cobalt_parser.c index 83bcfc7..bf4adcb 100644 --- a/src/atomics_cobalt_parser.c +++ b/src/atomics_cobalt_parser.c @@ -306,6 +306,9 @@ atomics_cobalt_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback ERROR (abstract->context, "Invalid gas mix index."); return DC_STATUS_DATAFORMAT; } + sample.gasmix = idx; + if (callback) callback (DC_SAMPLE_GASMIX, sample, userdata); +#ifdef ENABLE_DEPRECATED unsigned int o2 = data[SZ_HEADER + SZ_GASMIX * idx + 4]; unsigned int he = data[SZ_HEADER + SZ_GASMIX * idx + 5]; sample.event.type = SAMPLE_EVENT_GASCHANGE2; @@ -313,6 +316,7 @@ atomics_cobalt_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback sample.event.flags = 0; sample.event.value = o2 | (he << 16); if (callback) callback (DC_SAMPLE_EVENT, sample, userdata); +#endif gasmix_previous = gasmix; } diff --git a/src/cressi_edy_parser.c b/src/cressi_edy_parser.c index 195eb41..59898f6 100644 --- a/src/cressi_edy_parser.c +++ b/src/cressi_edy_parser.c @@ -227,11 +227,15 @@ cressi_edy_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t c return DC_STATUS_DATAFORMAT; } if (idx != gasmix) { + sample.gasmix = idx; + if (callback) callback (DC_SAMPLE_GASMIX, sample, userdata); +#ifdef ENABLE_DEPRECATED sample.event.type = SAMPLE_EVENT_GASCHANGE; sample.event.time = 0; sample.event.flags = 0; sample.event.value = bcd2dec(data[0x17 - idx]); if (callback) callback (DC_SAMPLE_EVENT, sample, userdata); +#endif gasmix = idx; } } diff --git a/src/diverite_nitekq_parser.c b/src/diverite_nitekq_parser.c index deba81b..f65ba38 100644 --- a/src/diverite_nitekq_parser.c +++ b/src/diverite_nitekq_parser.c @@ -270,11 +270,15 @@ diverite_nitekq_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callbac // Gas change if (gasmix != gasmix_previous) { + sample.gasmix = gasmix; + if (callback) callback (DC_SAMPLE_GASMIX, sample, userdata); +#ifdef ENABLE_DEPRECATED sample.event.type = SAMPLE_EVENT_GASCHANGE2; sample.event.time = 0; sample.event.flags = 0; sample.event.value = oxygen[gasmix] | (helium[gasmix] << 16); if (callback) callback (DC_SAMPLE_EVENT, sample, userdata); +#endif gasmix_previous = gasmix; } diff --git a/src/divesystem_idive_parser.c b/src/divesystem_idive_parser.c index c1ea98c..81d1b3d 100644 --- a/src/divesystem_idive_parser.c +++ b/src/divesystem_idive_parser.c @@ -275,11 +275,15 @@ divesystem_idive_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callba ngasmixes = i + 1; } + sample.gasmix = i; + if (callback) callback (DC_SAMPLE_GASMIX, sample, userdata); +#ifdef ENABLE_DEPRECATED sample.event.type = SAMPLE_EVENT_GASCHANGE2; sample.event.time = 0; sample.event.flags = 0; sample.event.value = o2 | (he << 16); if (callback) callback (DC_SAMPLE_EVENT, sample, userdata); +#endif o2_previous = o2; he_previous = he; } diff --git a/src/hw_ostc_parser.c b/src/hw_ostc_parser.c index b760d44..5a6d02f 100644 --- a/src/hw_ostc_parser.c +++ b/src/hw_ostc_parser.c @@ -616,6 +616,9 @@ hw_ostc_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t call // Initial gas mix. if (time == samplerate && parser->initial != 0xFF) { + sample.gasmix = parser->initial; + if (callback) callback (DC_SAMPLE_GASMIX, sample, userdata); +#ifdef ENABLE_DEPRECATED unsigned int idx = parser->initial; unsigned int o2 = parser->gasmix[idx].oxygen; unsigned int he = parser->gasmix[idx].helium; @@ -624,6 +627,7 @@ hw_ostc_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t call sample.event.flags = 0; sample.event.value = o2 | (he << 16); if (callback) callback (DC_SAMPLE_EVENT, sample, userdata); +#endif } // Depth (mbar). @@ -708,11 +712,16 @@ hw_ostc_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t call parser->gasmix[idx].helium = he; parser->ngasmixes = idx + 1; } + + sample.gasmix = idx; + if (callback) callback (DC_SAMPLE_GASMIX, sample, userdata); +#ifdef ENABLE_DEPRECATED sample.event.type = SAMPLE_EVENT_GASCHANGE2; sample.event.time = 0; sample.event.flags = 0; sample.event.value = o2 | (he << 16); if (callback) callback (DC_SAMPLE_EVENT, sample, userdata); +#endif offset += 2; length -= 2; } @@ -729,6 +738,9 @@ hw_ostc_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t call return DC_STATUS_DATAFORMAT; } idx--; /* Convert to a zero based index. */ + sample.gasmix = idx; + if (callback) callback (DC_SAMPLE_GASMIX, sample, userdata); +#ifdef ENABLE_DEPRECATED unsigned int o2 = parser->gasmix[idx].oxygen; unsigned int he = parser->gasmix[idx].helium; sample.event.type = SAMPLE_EVENT_GASCHANGE2; @@ -736,6 +748,7 @@ hw_ostc_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t call sample.event.flags = 0; sample.event.value = o2 | (he << 16); if (callback) callback (DC_SAMPLE_EVENT, sample, userdata); +#endif offset++; length--; } @@ -773,11 +786,15 @@ hw_ostc_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t call parser->ngasmixes = idx + 1; } + sample.gasmix = idx; + if (callback) callback (DC_SAMPLE_GASMIX, sample, userdata); +#ifdef ENABLE_DEPRECATED sample.event.type = SAMPLE_EVENT_GASCHANGE2; sample.event.time = 0; sample.event.flags = 0; sample.event.value = o2 | (he << 16); if (callback) callback (DC_SAMPLE_EVENT, sample, userdata); +#endif offset += 2; length -= 2; } @@ -877,11 +894,15 @@ hw_ostc_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t call parser->ngasmixes = idx + 1; } + sample.gasmix = idx; + if (callback) callback (DC_SAMPLE_GASMIX, sample, userdata); +#ifdef ENABLE_DEPRECATED sample.event.type = SAMPLE_EVENT_GASCHANGE2; sample.event.time = 0; sample.event.flags = 0; sample.event.value = o2 | (he << 16); if (callback) callback (DC_SAMPLE_EVENT, sample, userdata); +#endif offset += 2; length -= 2; } diff --git a/src/mares_iconhd_parser.c b/src/mares_iconhd_parser.c index 8992f64..51b1fd4 100644 --- a/src/mares_iconhd_parser.c +++ b/src/mares_iconhd_parser.c @@ -510,10 +510,14 @@ mares_iconhd_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t return DC_STATUS_DATAFORMAT; } if (gasmix != gasmix_previous) { + sample.gasmix = gasmix; + if (callback) callback (DC_SAMPLE_GASMIX, sample, userdata); +#ifdef ENABLE_DEPRECATED sample.event.type = SAMPLE_EVENT_GASCHANGE; sample.event.time = 0; sample.event.value = parser->oxygen[gasmix]; if (callback) callback (DC_SAMPLE_EVENT, sample, userdata); +#endif gasmix_previous = gasmix; } } diff --git a/src/oceanic_atom2_parser.c b/src/oceanic_atom2_parser.c index 6651519..8e52d5b 100644 --- a/src/oceanic_atom2_parser.c +++ b/src/oceanic_atom2_parser.c @@ -777,6 +777,9 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_ ERROR (abstract->context, "Invalid gas mix index (%u).", gasmix); return DC_STATUS_DATAFORMAT; } + sample.gasmix = gasmix - 1; + if (callback) callback (DC_SAMPLE_GASMIX, sample, userdata); +#ifdef ENABLE_DEPRECATED unsigned int o2 = parser->oxygen[gasmix - 1]; unsigned int he = parser->helium[gasmix - 1]; sample.event.type = SAMPLE_EVENT_GASCHANGE2; @@ -784,6 +787,7 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_ sample.event.flags = 0; sample.event.value = o2 | (he << 16); if (callback) callback (DC_SAMPLE_EVENT, sample, userdata); +#endif gasmix_previous = gasmix; } diff --git a/src/shearwater_predator_parser.c b/src/shearwater_predator_parser.c index f5ada2b..1423e77 100644 --- a/src/shearwater_predator_parser.c +++ b/src/shearwater_predator_parser.c @@ -88,6 +88,20 @@ static const dc_parser_vtable_t shearwater_petrel_parser_vtable = { }; +static unsigned int +shearwater_predator_find_gasmix (shearwater_predator_parser_t *parser, unsigned int o2, unsigned int he) +{ + unsigned int i = 0; + while (i < parser->ngasmixes) { + if (o2 == parser->oxygen[i] && he == parser->helium[i]) + break; + i++; + } + + return i; +} + + dc_status_t shearwater_common_parser_create (dc_parser_t **out, dc_context_t *context, unsigned int petrel) { @@ -418,11 +432,21 @@ shearwater_predator_parser_samples_foreach (dc_parser_t *abstract, dc_sample_cal unsigned int o2 = data[offset + 7]; unsigned int he = data[offset + 8]; if (o2 != o2_previous || he != he_previous) { + unsigned int idx = shearwater_predator_find_gasmix (parser, o2, he); + if (idx >= parser->ngasmixes) { + ERROR (abstract->context, "Invalid gas mix."); + return DC_STATUS_DATAFORMAT; + } + + sample.gasmix = idx; + if (callback) callback (DC_SAMPLE_GASMIX, sample, userdata); +#ifdef ENABLE_DEPRECATED sample.event.type = SAMPLE_EVENT_GASCHANGE2; sample.event.time = 0; sample.event.flags = 0; sample.event.value = o2 | (he << 16); if (callback) callback (DC_SAMPLE_EVENT, sample, userdata); +#endif o2_previous = o2; he_previous = he; } diff --git a/src/suunto_d9_parser.c b/src/suunto_d9_parser.c index 4fd94aa..c59ac48 100644 --- a/src/suunto_d9_parser.c +++ b/src/suunto_d9_parser.c @@ -94,6 +94,19 @@ static const dc_parser_vtable_t suunto_d9_parser_vtable = { suunto_d9_parser_destroy /* destroy */ }; +static unsigned int +suunto_d9_parser_find_gasmix (suunto_d9_parser_t *parser, unsigned int o2, unsigned int he) +{ + // Find the gasmix in the list. + unsigned int i = 0; + while (i < parser->ngasmixes) { + if (o2 == parser->oxygen[i] && he == parser->helium[i]) + break; + i++; + } + + return i; +} static dc_status_t suunto_d9_parser_cache (suunto_d9_parser_t *parser) @@ -487,12 +500,16 @@ suunto_d9_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t ca ERROR (abstract->context, "Invalid initial gas mix."); return DC_STATUS_DATAFORMAT; } + sample.gasmix = parser->gasmix; + if (callback) callback (DC_SAMPLE_GASMIX, sample, userdata); +#ifdef ENABLE_DEPRECATED unsigned int he = parser->helium[parser->gasmix]; unsigned int o2 = parser->oxygen[parser->gasmix]; sample.event.type = SAMPLE_EVENT_GASCHANGE2; sample.event.time = 0; sample.event.value = o2 | (he << 16); if (callback) callback (DC_SAMPLE_EVENT, sample, userdata); +#endif } // Events @@ -501,7 +518,7 @@ suunto_d9_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t ca unsigned int event = data[offset++]; unsigned int seconds, type, unknown, heading; unsigned int current, next; - unsigned int he, o2; + unsigned int he, o2, idx; unsigned int length; sample.event.type = SAMPLE_EVENT_NONE; @@ -668,10 +685,19 @@ suunto_d9_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t ca } o2 = data[offset + 0]; seconds = data[offset + 1]; + idx = suunto_d9_parser_find_gasmix(parser, o2, 0); + if (idx >= parser->ngasmixes) { + ERROR (abstract->context, "Invalid gas mix."); + return DC_STATUS_DATAFORMAT; + } + sample.gasmix = idx; + if (callback) callback (DC_SAMPLE_GASMIX, sample, userdata); +#ifdef ENABLE_DEPRECATED sample.event.type = SAMPLE_EVENT_GASCHANGE; sample.event.time = seconds; sample.event.value = o2; if (callback) callback (DC_SAMPLE_EVENT, sample, userdata); +#endif offset += 2; break; case 0x06: // Gas Change @@ -691,10 +717,19 @@ suunto_d9_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t ca } else { seconds = data[offset + 3]; } + idx = suunto_d9_parser_find_gasmix(parser, o2, he); + if (idx >= parser->ngasmixes) { + ERROR (abstract->context, "Invalid gas mix."); + return DC_STATUS_DATAFORMAT; + } + sample.gasmix = idx; + if (callback) callback (DC_SAMPLE_GASMIX, sample, userdata); +#ifdef ENABLE_DEPRECATED sample.event.type = SAMPLE_EVENT_GASCHANGE2; sample.event.time = seconds; sample.event.value = o2 | (he << 16); if (callback) callback (DC_SAMPLE_EVENT, sample, userdata); +#endif offset += length; break; default: diff --git a/src/suunto_eonsteel_parser.c b/src/suunto_eonsteel_parser.c index 10577b2..2e31c90 100644 --- a/src/suunto_eonsteel_parser.c +++ b/src/suunto_eonsteel_parser.c @@ -557,19 +557,22 @@ static void sample_gas_switch_event(struct sample_data *info, unsigned short idx { suunto_eonsteel_parser_t *eon = info->eon; dc_sample_value_t sample = {0}; - int o2, he; if (idx < 1 || idx > eon->cache.ngases) return; - // Horrible, broken, gas change events - o2 = 100 * eon->cache.gasmix[idx-1].oxygen; - he = 100 * eon->cache.gasmix[idx-1].helium; + sample.gasmix = idx - 1; + if (info->callback) info->callback(DC_SAMPLE_GASMIX, sample, info->userdata); +#ifdef ENABLE_DEPRECATED + unsigned int o2 = 100 * eon->cache.gasmix[idx-1].oxygen; + unsigned int he = 100 * eon->cache.gasmix[idx-1].helium; sample.event.type = SAMPLE_EVENT_GASCHANGE2; + sample.event.time = 0; + sample.event.flags = 0; sample.event.value = o2 | (he << 16); - if (info->callback) info->callback(DC_SAMPLE_EVENT, sample, info->userdata); +#endif } /* diff --git a/src/suunto_vyper_parser.c b/src/suunto_vyper_parser.c index 946dcaf..4e2d974 100644 --- a/src/suunto_vyper_parser.c +++ b/src/suunto_vyper_parser.c @@ -59,6 +59,18 @@ static const dc_parser_vtable_t suunto_vyper_parser_vtable = { suunto_vyper_parser_destroy /* destroy */ }; +static unsigned int +suunto_vyper_parser_find_gasmix (suunto_vyper_parser_t *parser, unsigned int o2) +{ + unsigned int i = 0; + while (i < parser->ngasmixes) { + if (o2 == parser->oxygen[i]) + break; + i++; + } + + return i; +} static dc_status_t suunto_vyper_parser_cache (suunto_vyper_parser_t *parser) @@ -353,6 +365,7 @@ suunto_vyper_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t complete = 1; } else { // Event. + unsigned int o2 = 0, idx = 0; sample.event.type = SAMPLE_EVENT_NONE; sample.event.time = 0; sample.event.flags = 0; @@ -382,8 +395,22 @@ suunto_vyper_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t case 0x87: // Gas Change if (offset + 1 > size) return DC_STATUS_DATAFORMAT; + + o2 = data[offset++]; + idx = suunto_vyper_parser_find_gasmix (parser, o2); + if (idx >= parser->ngasmixes) { + ERROR (abstract->context, "Maximum number of gas mixes reached."); + return DC_STATUS_DATAFORMAT; + } + + sample.gasmix = idx; + if (callback) callback (DC_SAMPLE_GASMIX, sample, userdata); +#ifdef ENABLE_DEPRECATED sample.event.type = SAMPLE_EVENT_GASCHANGE; - sample.event.value = data[offset++]; + sample.event.value = o2; +#else + sample.event.type = SAMPLE_EVENT_NONE; +#endif break; default: // Unknown WARNING (abstract->context, "Unknown event"); diff --git a/src/uwatec_smart_parser.c b/src/uwatec_smart_parser.c index 969c7e4..9009fbe 100644 --- a/src/uwatec_smart_parser.c +++ b/src/uwatec_smart_parser.c @@ -1115,6 +1115,9 @@ uwatec_smart_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t ERROR (abstract->context, "Invalid gas mix index."); return DC_STATUS_DATAFORMAT; } + sample.gasmix = idx; + if (callback) callback (DC_SAMPLE_GASMIX, sample, userdata); +#ifdef ENABLE_DEPRECATED unsigned int o2 = parser->gasmix[idx].oxygen; unsigned int he = parser->gasmix[idx].helium; sample.event.type = SAMPLE_EVENT_GASCHANGE2; @@ -1122,6 +1125,7 @@ uwatec_smart_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t sample.event.flags = 0; sample.event.value = o2 | (he << 16); if (callback) callback (DC_SAMPLE_EVENT, sample, userdata); +#endif gasmix_previous = gasmix; }