From 209890daeb000cc918d916d351aae9d023efbf74 Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Tue, 2 Jul 2019 21:14:49 +0200 Subject: [PATCH 1/5] Refactor the filter functions Replace all the different internal filter functions with one generic function and a set of callback functions. --- src/descriptor.c | 123 +++++++++++++++++++++++++++-------------------- 1 file changed, 72 insertions(+), 51 deletions(-) diff --git a/src/descriptor.c b/src/descriptor.c index 228c790..a63dca4 100644 --- a/src/descriptor.c +++ b/src/descriptor.c @@ -28,6 +28,17 @@ #include "platform.h" #define C_ARRAY_SIZE(array) (sizeof (array) / sizeof *(array)) +#define C_ARRAY_ITEMSIZE(array) (sizeof *(array)) + +#define DC_FILTER_INTERNAL(key, values, isnullterminated, match) \ + dc_filter_internal( \ + key, \ + values, \ + C_ARRAY_SIZE(values) - isnullterminated, \ + C_ARRAY_ITEMSIZE(values), \ + match) + +typedef int (*dc_match_t)(const void *, const void *); static int dc_filter_uwatec (dc_transport_t transport, const void *userdata); static int dc_filter_suunto (dc_transport_t transport, const void *userdata); @@ -359,56 +370,62 @@ static const dc_descriptor_t g_descriptors[] = { }; static int -dc_filter_internal_name (const char *name, const char *values[], size_t count) +dc_match_name (const void *key, const void *value) { - if (name == NULL) + const char *k = (const char *) key; + const char *v = *(const char * const *) value; + + return strcasecmp (k, v) == 0; +} + +static int +dc_match_prefix (const void *key, const void *value) +{ + const char *k = (const char *) key; + const char *v = *(const char * const *) value; + + return strncasecmp (k, v, strlen (v)) == 0; +} + +static int +dc_match_devname (const void *key, const void *value) +{ + const char *k = (const char *) key; + const char *v = *(const char * const *) value; + + return strncmp (k, v, strlen (v)) == 0; +} + +static int +dc_match_usb (const void *key, const void *value) +{ + const dc_usb_desc_t *k = (const dc_usb_desc_t *) key; + const dc_usb_desc_t *v = (const dc_usb_desc_t *) value; + + return k->vid == v->vid && k->pid == v->pid; +} + +static int +dc_filter_internal (const void *key, const void *values, size_t count, size_t size, dc_match_t match) +{ + if (key == NULL) return 0; for (size_t i = 0; i < count; ++i) { - if (strcasecmp (name, values[i]) == 0) { + if (match (key, (const unsigned char *) values + i * size)) { return 1; } } - return 0; + return count == 0; } -static int -dc_filter_internal_usb (const dc_usb_desc_t *desc, const dc_usb_desc_t values[], size_t count) -{ - if (desc == NULL) - return 0; - - for (size_t i = 0; i < count; ++i) { - if (desc->vid == values[i].vid && - desc->pid == values[i].pid) { - return 1; - } - } - - return 0; -} - -static int -dc_filter_internal_rfcomm (const char *name) -{ - static const char *prefixes[] = { +static const char *rfcomm[] = { #if defined (__linux__) - "/dev/rfcomm", + "/dev/rfcomm", #endif - NULL - }; - - if (name == NULL) - return 0; - - for (size_t i = 0; prefixes[i] != NULL; ++i) { - if (strncmp (name, prefixes[i], strlen (prefixes[i])) == 0) - return 1; - } - - return prefixes[0] == NULL; -} + NULL +}; static int dc_filter_uwatec (dc_transport_t transport, const void *userdata) { @@ -434,11 +451,11 @@ static int dc_filter_uwatec (dc_transport_t transport, const void *userdata) }; if (transport == DC_TRANSPORT_IRDA) { - return dc_filter_internal_name ((const char *) userdata, irda, C_ARRAY_SIZE(irda)); + return DC_FILTER_INTERNAL (userdata, irda, 0, dc_match_name); } else if (transport == DC_TRANSPORT_USBHID) { - return dc_filter_internal_usb ((const dc_usb_desc_t *) userdata, usbhid, C_ARRAY_SIZE(usbhid)); + return DC_FILTER_INTERNAL (userdata, usbhid, 0, dc_match_usb); } else if (transport == DC_TRANSPORT_BLE) { - return dc_filter_internal_name ((const char *) userdata, bluetooth, C_ARRAY_SIZE(bluetooth)); + return DC_FILTER_INTERNAL (userdata, bluetooth, 0, dc_match_name); } return 1; @@ -458,9 +475,9 @@ static int dc_filter_suunto (dc_transport_t transport, const void *userdata) }; if (transport == DC_TRANSPORT_USBHID) { - return dc_filter_internal_usb ((const dc_usb_desc_t *) userdata, usbhid, C_ARRAY_SIZE(usbhid)); + return DC_FILTER_INTERNAL (userdata, usbhid, 0, dc_match_usb); } else if (transport == DC_TRANSPORT_BLE) { - return dc_filter_internal_name ((const char *) userdata, bluetooth, C_ARRAY_SIZE(bluetooth)); + return DC_FILTER_INTERNAL (userdata, bluetooth, 0, dc_match_name); } return 1; @@ -468,11 +485,15 @@ static int dc_filter_suunto (dc_transport_t transport, const void *userdata) static int dc_filter_hw (dc_transport_t transport, const void *userdata) { + static const char *bluetooth[] = { + "OSTC", + "FROG", + }; + if (transport == DC_TRANSPORT_BLUETOOTH || transport == DC_TRANSPORT_BLE) { - return strncasecmp ((const char *) userdata, "OSTC", 4) == 0 || - strncasecmp ((const char *) userdata, "FROG", 4) == 0; + return DC_FILTER_INTERNAL (userdata, bluetooth, 0, dc_match_prefix); } else if (transport == DC_TRANSPORT_SERIAL) { - return dc_filter_internal_rfcomm ((const char *) userdata); + return DC_FILTER_INTERNAL (userdata, rfcomm, 1, dc_match_devname); } return 1; @@ -489,9 +510,9 @@ static int dc_filter_shearwater (dc_transport_t transport, const void *userdata) }; if (transport == DC_TRANSPORT_BLUETOOTH || transport == DC_TRANSPORT_BLE) { - return dc_filter_internal_name ((const char *) userdata, bluetooth, C_ARRAY_SIZE(bluetooth)); + return DC_FILTER_INTERNAL (userdata, bluetooth, 0, dc_match_name); } else if (transport == DC_TRANSPORT_SERIAL) { - return dc_filter_internal_rfcomm ((const char *) userdata); + return DC_FILTER_INTERNAL (userdata, rfcomm, 1, dc_match_devname); } return 1; @@ -504,9 +525,9 @@ static int dc_filter_tecdiving (dc_transport_t transport, const void *userdata) }; if (transport == DC_TRANSPORT_BLUETOOTH) { - return dc_filter_internal_name ((const char *) userdata, bluetooth, C_ARRAY_SIZE(bluetooth)); + return DC_FILTER_INTERNAL (userdata, bluetooth, 0, dc_match_name); } else if (transport == DC_TRANSPORT_SERIAL) { - return dc_filter_internal_rfcomm ((const char *) userdata); + return DC_FILTER_INTERNAL (userdata, rfcomm, 1, dc_match_devname); } return 1; @@ -519,7 +540,7 @@ static int dc_filter_mares (dc_transport_t transport, const void *userdata) }; if (transport == DC_TRANSPORT_BLE) { - return dc_filter_internal_name ((const char *) userdata, bluetooth, C_ARRAY_SIZE(bluetooth)); + return DC_FILTER_INTERNAL (userdata, bluetooth, 0, dc_match_name); } return 1; From 708fbb02de35f7341abdfb563d782a5ec12a8d71 Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Tue, 2 Jul 2019 21:45:19 +0200 Subject: [PATCH 2/5] Mark the string tables as constant Not only the strings in the table are constant, but also the table itself. This allows the compiler to place the table in a read-only data section. --- src/descriptor.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/descriptor.c b/src/descriptor.c index a63dca4..062da5e 100644 --- a/src/descriptor.c +++ b/src/descriptor.c @@ -420,7 +420,7 @@ dc_filter_internal (const void *key, const void *values, size_t count, size_t si return count == 0; } -static const char *rfcomm[] = { +static const char * const rfcomm[] = { #if defined (__linux__) "/dev/rfcomm", #endif @@ -429,7 +429,7 @@ static const char *rfcomm[] = { static int dc_filter_uwatec (dc_transport_t transport, const void *userdata) { - static const char *irda[] = { + static const char * const irda[] = { "Aladin Smart Com", "Aladin Smart Pro", "Aladin Smart Tec", @@ -444,7 +444,7 @@ static int dc_filter_uwatec (dc_transport_t transport, const void *userdata) {0x2e6c, 0x4201}, // G2 HUD {0xc251, 0x2006}, // Aladin Square }; - static const char *bluetooth[] = { + static const char * const bluetooth[] = { "G2", "Aladin", "HUD", @@ -468,7 +468,7 @@ static int dc_filter_suunto (dc_transport_t transport, const void *userdata) {0x1493, 0x0033}, // Eon Core {0x1493, 0x0035}, // D5 }; - static const char *bluetooth[] = { + static const char * const bluetooth[] = { "EON Steel", "EON Core", "Suunto D5", @@ -485,7 +485,7 @@ static int dc_filter_suunto (dc_transport_t transport, const void *userdata) static int dc_filter_hw (dc_transport_t transport, const void *userdata) { - static const char *bluetooth[] = { + static const char * const bluetooth[] = { "OSTC", "FROG", }; @@ -501,7 +501,7 @@ static int dc_filter_hw (dc_transport_t transport, const void *userdata) static int dc_filter_shearwater (dc_transport_t transport, const void *userdata) { - static const char *bluetooth[] = { + static const char * const bluetooth[] = { "Predator", "Petrel", "Nerd", @@ -520,7 +520,7 @@ static int dc_filter_shearwater (dc_transport_t transport, const void *userdata) static int dc_filter_tecdiving (dc_transport_t transport, const void *userdata) { - static const char *bluetooth[] = { + static const char * const bluetooth[] = { "DiveComputer", }; @@ -535,7 +535,7 @@ static int dc_filter_tecdiving (dc_transport_t transport, const void *userdata) static int dc_filter_mares (dc_transport_t transport, const void *userdata) { - static const char *bluetooth[] = { + static const char * const bluetooth[] = { "Mares bluelink pro", }; From 01d89add2fa8b73cb432db80c8d3707236c5e84d Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Tue, 18 Jun 2019 20:30:32 +0200 Subject: [PATCH 3/5] Update the naming of the Ratio iX3M GPS range --- src/descriptor.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/descriptor.c b/src/descriptor.c index 062da5e..40000d7 100644 --- a/src/descriptor.c +++ b/src/descriptor.c @@ -330,12 +330,12 @@ static const dc_descriptor_t g_descriptors[] = { {"DiveSystem", "iDive Easy", DC_FAMILY_DIVESYSTEM_IDIVE, 0x09, DC_TRANSPORT_SERIAL, NULL}, {"DiveSystem", "iDive X3M", DC_FAMILY_DIVESYSTEM_IDIVE, 0x0A, DC_TRANSPORT_SERIAL, NULL}, {"DiveSystem", "iDive Deep", DC_FAMILY_DIVESYSTEM_IDIVE, 0x0B, DC_TRANSPORT_SERIAL, NULL}, - {"Ratio", "iX3M Pro ", DC_FAMILY_DIVESYSTEM_IDIVE, 0x21, DC_TRANSPORT_SERIAL, NULL}, - {"Ratio", "iX3M Easy", DC_FAMILY_DIVESYSTEM_IDIVE, 0x22, DC_TRANSPORT_SERIAL, NULL}, - {"Ratio", "iX3M Deep", DC_FAMILY_DIVESYSTEM_IDIVE, 0x23, DC_TRANSPORT_SERIAL, NULL}, - {"Ratio", "iX3M Tech+", DC_FAMILY_DIVESYSTEM_IDIVE, 0x24, DC_TRANSPORT_SERIAL, NULL}, - {"Ratio", "iX3M Reb", DC_FAMILY_DIVESYSTEM_IDIVE, 0x25, DC_TRANSPORT_SERIAL, NULL}, - {"Ratio", "iX3M Fancy", DC_FAMILY_DIVESYSTEM_IDIVE, 0x26, DC_TRANSPORT_SERIAL, NULL}, + {"Ratio", "iX3M GPS Pro ", DC_FAMILY_DIVESYSTEM_IDIVE, 0x21, DC_TRANSPORT_SERIAL, NULL}, + {"Ratio", "iX3M GPS Easy", DC_FAMILY_DIVESYSTEM_IDIVE, 0x22, DC_TRANSPORT_SERIAL, NULL}, + {"Ratio", "iX3M GPS Deep", DC_FAMILY_DIVESYSTEM_IDIVE, 0x23, DC_TRANSPORT_SERIAL, NULL}, + {"Ratio", "iX3M GPS Tech+",DC_FAMILY_DIVESYSTEM_IDIVE, 0x24, DC_TRANSPORT_SERIAL, NULL}, + {"Ratio", "iX3M GPS Reb", DC_FAMILY_DIVESYSTEM_IDIVE, 0x25, DC_TRANSPORT_SERIAL, NULL}, + {"Ratio", "iX3M GPS Fancy",DC_FAMILY_DIVESYSTEM_IDIVE, 0x26, DC_TRANSPORT_SERIAL, NULL}, {"Ratio", "iX3M Pro Fancy",DC_FAMILY_DIVESYSTEM_IDIVE, 0x31, DC_TRANSPORT_SERIAL, NULL}, {"Ratio", "iX3M Pro Easy", DC_FAMILY_DIVESYSTEM_IDIVE, 0x32, DC_TRANSPORT_SERIAL, NULL}, {"Ratio", "iX3M Pro Pro", DC_FAMILY_DIVESYSTEM_IDIVE, 0x33, DC_TRANSPORT_SERIAL, NULL}, From 07dff48a3bc8799aa299aad6bdc3115b06a27577 Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Tue, 18 Jun 2019 20:47:12 +0200 Subject: [PATCH 4/5] Enable bluetooth support for the Ratio iX3M GPS --- src/descriptor.c | 49 ++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 43 insertions(+), 6 deletions(-) diff --git a/src/descriptor.c b/src/descriptor.c index 40000d7..c434721 100644 --- a/src/descriptor.c +++ b/src/descriptor.c @@ -46,6 +46,7 @@ static int dc_filter_shearwater (dc_transport_t transport, const void *userdata) static int dc_filter_hw (dc_transport_t transport, const void *userdata); static int dc_filter_tecdiving (dc_transport_t transport, const void *userdata); static int dc_filter_mares (dc_transport_t transport, const void *userdata); +static int dc_filter_divesystem (dc_transport_t transport, const void *userdata); static dc_status_t dc_descriptor_iterator_next (dc_iterator_t *iterator, void *item); @@ -330,12 +331,12 @@ static const dc_descriptor_t g_descriptors[] = { {"DiveSystem", "iDive Easy", DC_FAMILY_DIVESYSTEM_IDIVE, 0x09, DC_TRANSPORT_SERIAL, NULL}, {"DiveSystem", "iDive X3M", DC_FAMILY_DIVESYSTEM_IDIVE, 0x0A, DC_TRANSPORT_SERIAL, NULL}, {"DiveSystem", "iDive Deep", DC_FAMILY_DIVESYSTEM_IDIVE, 0x0B, DC_TRANSPORT_SERIAL, NULL}, - {"Ratio", "iX3M GPS Pro ", DC_FAMILY_DIVESYSTEM_IDIVE, 0x21, DC_TRANSPORT_SERIAL, NULL}, - {"Ratio", "iX3M GPS Easy", DC_FAMILY_DIVESYSTEM_IDIVE, 0x22, DC_TRANSPORT_SERIAL, NULL}, - {"Ratio", "iX3M GPS Deep", DC_FAMILY_DIVESYSTEM_IDIVE, 0x23, DC_TRANSPORT_SERIAL, NULL}, - {"Ratio", "iX3M GPS Tech+",DC_FAMILY_DIVESYSTEM_IDIVE, 0x24, DC_TRANSPORT_SERIAL, NULL}, - {"Ratio", "iX3M GPS Reb", DC_FAMILY_DIVESYSTEM_IDIVE, 0x25, DC_TRANSPORT_SERIAL, NULL}, - {"Ratio", "iX3M GPS Fancy",DC_FAMILY_DIVESYSTEM_IDIVE, 0x26, DC_TRANSPORT_SERIAL, NULL}, + {"Ratio", "iX3M GPS Pro ", DC_FAMILY_DIVESYSTEM_IDIVE, 0x21, DC_TRANSPORT_SERIAL | DC_TRANSPORT_BLUETOOTH, dc_filter_divesystem}, + {"Ratio", "iX3M GPS Easy", DC_FAMILY_DIVESYSTEM_IDIVE, 0x22, DC_TRANSPORT_SERIAL | DC_TRANSPORT_BLUETOOTH, dc_filter_divesystem}, + {"Ratio", "iX3M GPS Deep", DC_FAMILY_DIVESYSTEM_IDIVE, 0x23, DC_TRANSPORT_SERIAL | DC_TRANSPORT_BLUETOOTH, dc_filter_divesystem}, + {"Ratio", "iX3M GPS Tech+",DC_FAMILY_DIVESYSTEM_IDIVE, 0x24, DC_TRANSPORT_SERIAL | DC_TRANSPORT_BLUETOOTH, dc_filter_divesystem}, + {"Ratio", "iX3M GPS Reb", DC_FAMILY_DIVESYSTEM_IDIVE, 0x25, DC_TRANSPORT_SERIAL | DC_TRANSPORT_BLUETOOTH, dc_filter_divesystem}, + {"Ratio", "iX3M GPS Fancy",DC_FAMILY_DIVESYSTEM_IDIVE, 0x26, DC_TRANSPORT_SERIAL | DC_TRANSPORT_BLUETOOTH, dc_filter_divesystem}, {"Ratio", "iX3M Pro Fancy",DC_FAMILY_DIVESYSTEM_IDIVE, 0x31, DC_TRANSPORT_SERIAL, NULL}, {"Ratio", "iX3M Pro Easy", DC_FAMILY_DIVESYSTEM_IDIVE, 0x32, DC_TRANSPORT_SERIAL, NULL}, {"Ratio", "iX3M Pro Pro", DC_FAMILY_DIVESYSTEM_IDIVE, 0x33, DC_TRANSPORT_SERIAL, NULL}, @@ -405,6 +406,29 @@ dc_match_usb (const void *key, const void *value) return k->vid == v->vid && k->pid == v->pid; } +static int +dc_match_number_with_prefix (const void *key, const void *value) +{ + const char *str = (const char *) key; + const char *prefix = *(const char * const *) value; + + size_t n = strlen (prefix); + + if (strncmp (str, prefix, n) != 0) { + return 0; + } + + while (str[n] != 0) { + const char c = str[n]; + if (c < '0' || c > '9') { + return 0; + } + n++; + } + + return 1; +} + static int dc_filter_internal (const void *key, const void *values, size_t count, size_t size, dc_match_t match) { @@ -546,6 +570,19 @@ static int dc_filter_mares (dc_transport_t transport, const void *userdata) return 1; } +static int dc_filter_divesystem (dc_transport_t transport, const void *userdata) +{ + static const char * const bluetooth[] = { + "DS", + }; + + if (transport == DC_TRANSPORT_BLUETOOTH) { + return DC_FILTER_INTERNAL (userdata, bluetooth, 0, dc_match_number_with_prefix); + } + + return 1; +} + dc_status_t dc_descriptor_iterator (dc_iterator_t **out) { From d5aa15c1c5deb4056d9bc05f8bc3bc06f7d1229f Mon Sep 17 00:00:00 2001 From: Janice McLaughlin Date: Tue, 28 May 2019 18:36:32 -0700 Subject: [PATCH 5/5] Add support for the Aqualung i550C --- src/descriptor.c | 1 + src/oceanic_atom2.c | 1 + src/oceanic_atom2_parser.c | 14 ++++++++++---- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/descriptor.c b/src/descriptor.c index c434721..73f9e62 100644 --- a/src/descriptor.c +++ b/src/descriptor.c @@ -239,6 +239,7 @@ static const dc_descriptor_t g_descriptors[] = { {"Aqualung", "i300C", DC_FAMILY_OCEANIC_ATOM2, 0x4648, DC_TRANSPORT_SERIAL, NULL}, {"Aqualung", "i100", DC_FAMILY_OCEANIC_ATOM2, 0x464E, DC_TRANSPORT_SERIAL, NULL}, {"Aqualung", "i770R", DC_FAMILY_OCEANIC_ATOM2, 0x4651, DC_TRANSPORT_SERIAL, NULL}, + {"Aqualung", "i550C", DC_FAMILY_OCEANIC_ATOM2, 0x4652, DC_TRANSPORT_SERIAL, NULL}, /* Mares Nemo */ {"Mares", "Nemo", DC_FAMILY_MARES_NEMO, 0, DC_TRANSPORT_SERIAL, NULL}, {"Mares", "Nemo Steel", DC_FAMILY_MARES_NEMO, 0, DC_TRANSPORT_SERIAL, NULL}, diff --git a/src/oceanic_atom2.c b/src/oceanic_atom2.c index 33947bd..8aed308 100644 --- a/src/oceanic_atom2.c +++ b/src/oceanic_atom2.c @@ -159,6 +159,7 @@ static const oceanic_common_version_t oceanic_oc1_version[] = { {"OC1WATCH \0\0 1024"}, {"OCSWATCH \0\0 1024"}, {"AQUAI550 \0\0 1024"}, + {"AQUA550C \0\0 1024"}, }; static const oceanic_common_version_t oceanic_oci_version[] = { diff --git a/src/oceanic_atom2_parser.c b/src/oceanic_atom2_parser.c index 6113b6f..da2ba0f 100644 --- a/src/oceanic_atom2_parser.c +++ b/src/oceanic_atom2_parser.c @@ -90,6 +90,7 @@ #define I300C 0x4648 #define I100 0x464E #define I770R 0x4651 +#define I550C 0x4652 #define NORMAL 0 #define GAUGE 1 @@ -182,6 +183,8 @@ oceanic_atom2_parser_create (dc_parser_t **out, dc_context_t *context, unsigned parser->headersize = 5 * PAGESIZE; } else if (model == PROPLUSX) { parser->headersize = 3 * PAGESIZE; + } else if (model == I550C) { + parser->headersize = 5 * PAGESIZE / 2; } parser->cached = 0; @@ -256,6 +259,7 @@ oceanic_atom2_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetim case A300AI: case OCI: case I550: + case I550C: case VISION: case XPAIR: datetime->year = ((p[5] & 0xE0) >> 5) + ((p[7] & 0xE0) >> 2) + 2000; @@ -888,7 +892,7 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_ } else { unsigned int sign; if (parser->model == DG03 || parser->model == PROPLUS3 || - parser->model == I550) + parser->model == I550 || parser->model == I550C) sign = (~data[offset + 5] & 0x04) >> 2; else if (parser->model == VOYAGER2G || parser->model == AMPHOS || parser->model == AMPHOSAIR || parser->model == ZENAIR) @@ -920,7 +924,8 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_ parser->model == ZENAIR ||parser->model == A300AI || parser->model == DG03 || parser->model == PROPLUS3 || parser->model == AMPHOSAIR || parser->model == I550 || - parser->model == VISION || parser->model == XPAIR) + parser->model == VISION || parser->model == XPAIR || + parser->model == I550C) pressure = (((data[offset + 0] & 0x03) << 8) + data[offset + 1]) * 5; else if (parser->model == TX1 || parser->model == A300CS || parser->model == VTX || parser->model == I750TC || @@ -987,7 +992,8 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_ decotime = array_uint16_le(data + offset + 6); have_deco = 1; } else if (parser->model == ATOM31 || parser->model == VISION || - parser->model == XPAIR || parser->model == I550) { + parser->model == XPAIR || parser->model == I550 || + parser->model == I550C) { decostop = (data[offset + 5] & 0xF0) >> 4; decotime = array_uint16_le(data + offset + 4) & 0x03FF; have_deco = 1; @@ -1024,7 +1030,7 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_ rbt = array_uint16_le(data + offset + 8) & 0x01FF; have_rbt = 1; } else if (parser->model == VISION || parser->model == XPAIR || - parser->model == I550) { + parser->model == I550 || parser->model == I550C) { rbt = array_uint16_le(data + offset + 6) & 0x03FF; have_rbt = 1; }