From 1d360d3a1e29e47e9741e83b1a929a09f1e2e8d3 Mon Sep 17 00:00:00 2001 From: Dirk Hohndel Date: Tue, 20 Nov 2012 13:31:46 -0800 Subject: [PATCH] This adds support for a subset of the events the OSTC provides. - PO2 warnings (high and low both mapped to the same SAMPLE_EVENT_PO2 event) - SPEED warning (which according to hw isn't emitted at this point) - Deco stop violations (both deep and regular mapped to same SAMPLE_EVENT_CEILING event) - Deco ceiling and time (this is reported as a series of SAMPLE_EVENT_DECOSTOP events with packed deco stop depth (in m) and time (in seconds) A SAMPLE_EVENT_NDL event (with an optional value indicating the non-stop time remaining) indicates that the ceiling has been resolved - Gas change (reported as SAMPLE_EVENT_GASCHANGE2, using another unfortunate O2% / He% semantic that is used in the SAMPLE_EVENT_GASCHANGE This also covers the manual gas set event of the OSTC - Manual Marker (reported as SAMPLE_EVENT_BOOKMARK) The two new events (SAMPLE_EVENT_GASCHANGE2 and SAMPLE_EVENT_NDL are added to the universal app as well. Signed-off-by: Dirk Hohndel --- examples/universal.c | 3 +- include/libdivecomputer/parser.h | 4 ++- src/hw_ostc_parser.c | 48 +++++++++++++++++++++++++++++++- 3 files changed, 52 insertions(+), 3 deletions(-) diff --git a/examples/universal.c b/examples/universal.c index 5cdc6b9..c0f28ee 100644 --- a/examples/universal.c +++ b/examples/universal.c @@ -238,7 +238,8 @@ sample_cb (dc_sample_type_t type, dc_sample_value_t value, void *userdata) "violation", "bookmark", "surface", "safety stop", "gaschange", "safety stop (voluntary)", "safety stop (mandatory)", "deepstop", "ceiling (safety stop)", "unknown", "divetime", "maxdepth", - "OLF", "PO2", "airtime", "rgbm", "heading", "tissue level warning"}; + "OLF", "PO2", "airtime", "rgbm", "heading", "tissue level warning", + "gaschange2", "ndl"}; sample_data_t *sampledata = (sample_data_t *) userdata; diff --git a/include/libdivecomputer/parser.h b/include/libdivecomputer/parser.h index b0cf444..f632bd4 100644 --- a/include/libdivecomputer/parser.h +++ b/include/libdivecomputer/parser.h @@ -77,7 +77,9 @@ typedef enum parser_sample_event_t { SAMPLE_EVENT_AIRTIME, SAMPLE_EVENT_RGBM, SAMPLE_EVENT_HEADING, - SAMPLE_EVENT_TISSUELEVEL + SAMPLE_EVENT_TISSUELEVEL, + SAMPLE_EVENT_GASCHANGE2, + SAMPLE_EVENT_NDL } parser_sample_event_t; typedef enum parser_sample_flags_t { diff --git a/src/hw_ostc_parser.c b/src/hw_ostc_parser.c index 541f6ff..c209743 100644 --- a/src/hw_ostc_parser.c +++ b/src/hw_ostc_parser.c @@ -294,6 +294,7 @@ hw_ostc_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t call info[i].size = (data[37 + i] & 0xF0) >> 4; switch (i) { case 0: // Temperature + case 1: // Deco / NDL if (info[i].size != 2) return DC_STATUS_DATAFORMAT; break; @@ -337,25 +338,59 @@ hw_ostc_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t call } // Alarms + sample.event.type = 0; + sample.event.time = 0; + sample.event.flags = 0; + sample.event.value = 0; switch (events & 0x0F) { case 0: // No Alarm + break; case 1: // Slow + sample.event.type = SAMPLE_EVENT_ASCENT; + break; case 2: // Deco Stop missed + sample.event.type = SAMPLE_EVENT_CEILING; + break; case 3: // Deep Stop missed + sample.event.type = SAMPLE_EVENT_CEILING; + break; case 4: // ppO2 Low Warning + sample.event.type = SAMPLE_EVENT_PO2; + break; case 5: // ppO2 High Warning + sample.event.type = SAMPLE_EVENT_PO2; + break; case 6: // Manual Marker + sample.event.type = SAMPLE_EVENT_BOOKMARK; + break; case 7: // Low Battery break; } + if (sample.event.type && callback) + callback (DC_SAMPLE_EVENT, sample, userdata); - // Manual Gas Set + // Manual Gas Set & Change if (events & 0x10) { + if (offset + 2 > size) + return DC_STATUS_DATAFORMAT; + sample.event.type = SAMPLE_EVENT_GASCHANGE2; + sample.event.time = 0; + sample.event.flags = 0; + sample.event.value = data[offset] | (data[offset + 1] << 16); + if (callback) callback (DC_SAMPLE_EVENT, sample, userdata); offset += 2; } // Gas Change if (events & 0x20) { + if (offset + 1 > size || data[offset] >= 5) + return DC_STATUS_DATAFORMAT; + unsigned int idx = data[offset]; + sample.event.type = SAMPLE_EVENT_GASCHANGE2; + sample.event.time = 0; + sample.event.flags = 0; + sample.event.value = data[19 + 2 * idx] | (data[20 + 2 * idx] << 16); + if (callback) callback (DC_SAMPLE_EVENT, sample, userdata); offset++; } @@ -369,6 +404,17 @@ hw_ostc_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t call sample.temperature = value / 10.0; if (callback) callback (DC_SAMPLE_TEMPERATURE, sample, userdata); break; + case 1: // Deco / NDL + if (data[offset]) { + sample.event.type = SAMPLE_EVENT_DECOSTOP; + sample.event.value = data[offset] | ((data[offset + 1] * 60) << 16); + } else { + sample.event.type = SAMPLE_EVENT_NDL; + sample.event.value = data[offset + 1] * 60; + } + sample.event.time = 0; + sample.event.flags = 0; + if (callback) callback (DC_SAMPLE_EVENT, sample, userdata); default: // Not yet used. break; }