diff --git a/examples/common.c b/examples/common.c
index ebc1542..1458e88 100644
--- a/examples/common.c
+++ b/examples/common.c
@@ -92,6 +92,7 @@ static const backend_table_t g_backends[] = {
{"divecomputereu", DC_FAMILY_TECDIVING_DIVECOMPUTEREU, 0},
{"descentmk1", DC_FAMILY_GARMIN, 0},
{"cosmiq", DC_FAMILY_DEEPBLU, 0},
+ {"oceans", DC_FAMILY_OCEANS_S1, 0},
};
static const transport_table_t g_transports[] = {
diff --git a/include/libdivecomputer/common.h b/include/libdivecomputer/common.h
index 0819843..8581dbb 100644
--- a/include/libdivecomputer/common.h
+++ b/include/libdivecomputer/common.h
@@ -112,6 +112,8 @@ typedef enum dc_family_t {
DC_FAMILY_GARMIN = (16 << 16),
/* Deepblu */
DC_FAMILY_DEEPBLU = (17 << 16),
+ /* Oceans S1 */
+ DC_FAMILY_OCEANS_S1 = (18 << 16),
} dc_family_t;
#ifdef __cplusplus
diff --git a/msvc/libdivecomputer.vcproj b/msvc/libdivecomputer.vcproj
index 0ae0ed6..a752c83 100644
--- a/msvc/libdivecomputer.vcproj
+++ b/msvc/libdivecomputer.vcproj
@@ -514,6 +514,14 @@
RelativePath="..\src\deepblu_parser.c"
>
+
+
+
+
@@ -868,6 +876,10 @@
RelativePath="..\src\deepblu.h"
>
+
+
diff --git a/src/Makefile.am b/src/Makefile.am
index af2bc6d..38b7b27 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -75,6 +75,7 @@ libdivecomputer_la_SOURCES = \
tecdiving_divecomputereu.h tecdiving_divecomputereu.c tecdiving_divecomputereu_parser.c \
garmin.h garmin.c garmin_parser.c \
deepblu.h deepblu.c deepblu_parser.c \
+ oceans_s1.h oceans_s1.c oceans_s1_parser.c \
socket.h socket.c \
irda.c \
usbhid.c \
diff --git a/src/descriptor.c b/src/descriptor.c
index 9836d52..cba294a 100644
--- a/src/descriptor.c
+++ b/src/descriptor.c
@@ -50,6 +50,7 @@ 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 int dc_filter_oceanic (dc_transport_t transport, const void *userdata);
static int dc_filter_deepblu (dc_transport_t transport, const void *userdata);
+static int dc_filter_oceans(dc_transport_t transport, const void *userdata);
static dc_status_t dc_descriptor_iterator_next (dc_iterator_t *iterator, void *item);
@@ -382,6 +383,8 @@ static const dc_descriptor_t g_descriptors[] = {
{"Garmin", "Descent Mk1", DC_FAMILY_GARMIN, 2859, DC_TRANSPORT_USBSTORAGE, dc_filter_garmin},
/* Deepblu */
{"Deepblu", "Cosmiq+", DC_FAMILY_DEEPBLU, 0, DC_TRANSPORT_BLE, dc_filter_deepblu},
+ /* Oceans S1 */
+ { "Oceans", "S1", DC_FAMILY_OCEANS_S1, 0, DC_TRANSPORT_BLE, dc_filter_oceans },
};
static int
@@ -661,6 +664,19 @@ static int dc_filter_deepblu (dc_transport_t transport, const void *userdata)
return 1;
}
+static int dc_filter_oceans(dc_transport_t transport, const void* userdata)
+{
+ static const char* const ble[] = {
+ "S1",
+ };
+
+ if (transport == DC_TRANSPORT_BLE) {
+ return DC_FILTER_INTERNAL(userdata, ble, 0, dc_match_prefix);
+ }
+
+ return 1;
+}
+
dc_status_t
dc_descriptor_iterator (dc_iterator_t **out)
{
diff --git a/src/device.c b/src/device.c
index 15bfcf3..f8d1e04 100644
--- a/src/device.c
+++ b/src/device.c
@@ -59,6 +59,7 @@
#include "tecdiving_divecomputereu.h"
#include "garmin.h"
#include "deepblu.h"
+#include "oceans_s1.h"
#include "device-private.h"
#include "context-private.h"
@@ -219,6 +220,9 @@ dc_device_open (dc_device_t **out, dc_context_t *context, dc_descriptor_t *descr
case DC_FAMILY_DEEPBLU:
rc = deepblu_device_open (&device, context, iostream);
break;
+ case DC_FAMILY_OCEANS_S1:
+ rc = oceans_s1_device_open(&device, context, iostream);
+ break;
default:
return DC_STATUS_INVALIDARGS;
}
diff --git a/src/oceans_s1.c b/src/oceans_s1.c
new file mode 100644
index 0000000..dafbcc7
--- /dev/null
+++ b/src/oceans_s1.c
@@ -0,0 +1,108 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (C) 2020 Linus Torvalds
+
+#include // memcmp, memcpy
+#include // malloc, free
+#include
+
+#include "oceans_s1.h"
+#include "context-private.h"
+#include "device-private.h"
+#include "array.h"
+
+#define ISINSTANCE(device) dc_device_isinstance((device), &oceans_s1_device_vtable)
+
+typedef struct oceans_s1_device_t {
+ dc_device_t base;
+ dc_iostream_t* iostream;
+ unsigned char fingerprint[4];
+} oceans_s1_device_t;
+
+static dc_status_t oceans_s1_device_set_fingerprint(dc_device_t *abstract, const unsigned char data[], unsigned int size);
+static dc_status_t oceans_s1_device_foreach(dc_device_t *abstract, dc_dive_callback_t callback, void *userdata);
+static dc_status_t oceans_s1_device_close(dc_device_t *abstract);
+
+static const dc_device_vtable_t oceans_s1_device_vtable = {
+ sizeof(oceans_s1_device_t),
+ DC_FAMILY_OCEANS_S1,
+ oceans_s1_device_set_fingerprint, /* set_fingerprint */
+ NULL, /* read */
+ NULL, /* write */
+ NULL, /* dump */
+ oceans_s1_device_foreach, /* foreach */
+ NULL, /* timesync */
+ oceans_s1_device_close, /* close */
+};
+
+dc_status_t
+oceans_s1_device_open(dc_device_t **out, dc_context_t *context, dc_iostream_t *iostream)
+{
+ char buffer[128];
+ dc_status_t status = DC_STATUS_SUCCESS;
+ oceans_s1_device_t *s1 = NULL;
+
+ if (out == NULL)
+ return DC_STATUS_INVALIDARGS;
+
+ // Allocate memory.
+ s1 = (oceans_s1_device_t*)dc_device_allocate(context, &oceans_s1_device_vtable);
+ if (s1 == NULL) {
+ ERROR(context, "Failed to allocate memory.");
+ return DC_STATUS_NOMEMORY;
+ }
+
+ // Set the default values.
+ s1->iostream = iostream;
+ memset(s1->fingerprint, 0, sizeof(s1->fingerprint));
+
+ *out = (dc_device_t*)s1;
+
+ // Fill in
+
+ return DC_STATUS_IO;
+}
+
+static dc_status_t
+oceans_s1_device_close(dc_device_t *abstract)
+{
+ dc_status_t status = DC_STATUS_SUCCESS;
+ oceans_s1_device_t *s1 = (oceans_s1_device_t*)abstract;
+
+ // Fill in
+
+ return DC_STATUS_SUCCESS;
+}
+
+static dc_status_t
+oceans_s1_device_set_fingerprint(dc_device_t *abstract, const unsigned char data[], unsigned int size)
+{
+ oceans_s1_device_t *s1 = (oceans_s1_device_t*)abstract;
+
+ if (size && size != sizeof(s1->fingerprint))
+ return DC_STATUS_INVALIDARGS;
+
+ if (size)
+ memcpy(s1->fingerprint, data, sizeof(s1->fingerprint));
+ else
+ memset(s1->fingerprint, 0, sizeof(s1->fingerprint));
+
+ return DC_STATUS_SUCCESS;
+}
+
+static dc_status_t
+oceans_s1_device_foreach(dc_device_t *abstract, dc_dive_callback_t callback, void *userdata)
+{
+ dc_status_t status = DC_STATUS_SUCCESS;
+ oceans_s1_device_t *s1 = (oceans_s1_device_t*)abstract;
+
+ dc_event_progress_t progress = EVENT_PROGRESS_INITIALIZER;
+ device_event_emit(abstract, DC_EVENT_PROGRESS, &progress);
+
+ progress.current = 0;
+ progress.maximum = 0;
+ device_event_emit(abstract, DC_EVENT_PROGRESS, &progress);
+
+ // Fill in
+
+ return status;
+}
diff --git a/src/oceans_s1.h b/src/oceans_s1.h
new file mode 100644
index 0000000..483b144
--- /dev/null
+++ b/src/oceans_s1.h
@@ -0,0 +1,25 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (C) 2020 Linus Torvalds
+
+#ifndef OCEANS_S1_H
+#define OCEANS_S1_H
+
+#include
+#include
+#include
+#include
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+dc_status_t
+oceans_s1_device_open (dc_device_t **device, dc_context_t *context, dc_iostream_t *iostream);
+
+dc_status_t
+oceans_s1_parser_create (dc_parser_t **parser, dc_context_t *context);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* OCEANS_S1_H */
diff --git a/src/oceans_s1_parser.c b/src/oceans_s1_parser.c
new file mode 100644
index 0000000..f545c15
--- /dev/null
+++ b/src/oceans_s1_parser.c
@@ -0,0 +1,85 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (C) 2020 Linus Torvalds
+
+#include
+#include
+#include
+#include
+
+#include "oceans_s1.h"
+#include "context-private.h"
+#include "parser-private.h"
+#include "field-cache.h"
+#include "array.h"
+
+typedef struct oceans_s1_parser_t oceans_s1_parser_t;
+
+struct oceans_s1_parser_t {
+ dc_parser_t base;
+ struct dc_field_cache cache;
+};
+
+static dc_status_t oceans_s1_parser_set_data(dc_parser_t *abstract, const unsigned char *data, unsigned int size);
+static dc_status_t oceans_s1_parser_get_datetime(dc_parser_t *abstract, dc_datetime_t *datetime);
+static dc_status_t oceans_s1_parser_get_field(dc_parser_t *abstract, dc_field_type_t type, unsigned int flags, void *value);
+static dc_status_t oceans_s1_parser_samples_foreach(dc_parser_t *abstract, dc_sample_callback_t callback, void *userdata);
+
+static const dc_parser_vtable_t oceans_s1_parser_vtable = {
+ sizeof(oceans_s1_parser_t),
+ DC_FAMILY_OCEANS_S1,
+ oceans_s1_parser_set_data, /* set_data */
+ oceans_s1_parser_get_datetime, /* datetime */
+ oceans_s1_parser_get_field, /* fields */
+ oceans_s1_parser_samples_foreach, /* samples_foreach */
+ NULL /* destroy */
+};
+
+dc_status_t
+oceans_s1_parser_create(dc_parser_t **out, dc_context_t *context)
+{
+ oceans_s1_parser_t* parser = NULL;
+
+ if (out == NULL)
+ return DC_STATUS_INVALIDARGS;
+
+ // Allocate memory.
+ parser = (oceans_s1_parser_t*)dc_parser_allocate(context, &oceans_s1_parser_vtable);
+ if (parser == NULL) {
+ ERROR(context, "Failed to allocate memory.");
+ return DC_STATUS_NOMEMORY;
+ }
+
+ *out = (dc_parser_t*)parser;
+
+ return DC_STATUS_SUCCESS;
+}
+
+static dc_status_t
+oceans_s1_parser_set_data(dc_parser_t *abstract, const unsigned char *data, unsigned int size)
+{
+ dc_status_t status = DC_STATUS_SUCCESS;
+ // Fill me
+ return DC_STATUS_SUCCESS;
+}
+
+static dc_status_t
+oceans_s1_parser_get_datetime(dc_parser_t* abstract, dc_datetime_t* datetime)
+{
+ // Fill me
+ return DC_STATUS_SUCCESS;
+}
+
+static dc_status_t
+oceans_s1_parser_get_field(dc_parser_t* abstract, dc_field_type_t type, unsigned int flags, void* value)
+{
+ oceans_s1_parser_t *s1 = (oceans_s1_parser_t *)abstract;
+
+ return dc_field_get(&s1->cache, type, flags, value);
+}
+
+static dc_status_t
+oceans_s1_parser_samples_foreach(dc_parser_t* abstract, dc_sample_callback_t callback, void* userdata)
+{
+ // Fill me
+ return DC_STATUS_SUCCESS;
+}
diff --git a/src/parser.c b/src/parser.c
index 8fd16ee..453797c 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -59,6 +59,7 @@
#include "tecdiving_divecomputereu.h"
#include "garmin.h"
#include "deepblu.h"
+#include "oceans_s1.h"
#include "context-private.h"
#include "parser-private.h"
@@ -180,6 +181,9 @@ dc_parser_new_internal (dc_parser_t **out, dc_context_t *context, dc_family_t fa
case DC_FAMILY_DEEPBLU:
rc = deepblu_parser_create (&parser, context);
break;
+ case DC_FAMILY_OCEANS_S1:
+ rc = oceans_s1_parser_create(&parser, context);
+ break;
default:
return DC_STATUS_INVALIDARGS;
}