Merge branch 'shearwater-timesync'
This commit is contained in:
commit
3d82d6796f
@ -36,6 +36,14 @@
|
||||
#define ESC_END 0xDC
|
||||
#define ESC_ESC 0xDD
|
||||
|
||||
#define RDBI_REQUEST 0x22
|
||||
#define RDBI_RESPONSE 0x62
|
||||
|
||||
#define WDBI_REQUEST 0x2E
|
||||
#define WDBI_RESPONSE 0x6E
|
||||
|
||||
#define NAK 0x7F
|
||||
|
||||
dc_status_t
|
||||
shearwater_common_setup (shearwater_common_device_t *device, dc_context_t *context, dc_iostream_t *iostream)
|
||||
{
|
||||
@ -512,39 +520,227 @@ shearwater_common_download (shearwater_common_device_t *device, dc_buffer_t *buf
|
||||
|
||||
|
||||
dc_status_t
|
||||
shearwater_common_identifier (shearwater_common_device_t *device, dc_buffer_t *buffer, unsigned int id)
|
||||
shearwater_common_rdbi (shearwater_common_device_t *device, unsigned int id, unsigned char data[], unsigned int size)
|
||||
{
|
||||
dc_status_t status = DC_STATUS_SUCCESS;
|
||||
dc_device_t *abstract = (dc_device_t *) device;
|
||||
dc_status_t rc = DC_STATUS_SUCCESS;
|
||||
|
||||
// Erase the buffer.
|
||||
if (!dc_buffer_clear (buffer)) {
|
||||
ERROR (abstract->context, "Insufficient buffer space available.");
|
||||
return DC_STATUS_NOMEMORY;
|
||||
}
|
||||
|
||||
// Transfer the request.
|
||||
unsigned int n = 0;
|
||||
unsigned char request[] = {0x22,
|
||||
unsigned char request[] = {
|
||||
RDBI_REQUEST,
|
||||
(id >> 8) & 0xFF,
|
||||
(id ) & 0xFF};
|
||||
unsigned char response[SZ_PACKET];
|
||||
rc = shearwater_common_transfer (device, request, sizeof (request), response, sizeof (response), &n);
|
||||
if (rc != DC_STATUS_SUCCESS) {
|
||||
return rc;
|
||||
status = shearwater_common_transfer (device, request, sizeof (request), response, sizeof (response), &n);
|
||||
if (status != DC_STATUS_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
// Verify the response.
|
||||
if (n < 3 || response[0] != 0x62 || response[1] != request[1] || response[2] != request[2]) {
|
||||
if (n < 3 || response[0] != RDBI_RESPONSE || response[1] != request[1] || response[2] != request[2]) {
|
||||
if (n == 3 && response[0] == NAK && response[1] == RDBI_REQUEST) {
|
||||
ERROR (abstract->context, "Received NAK packet with error code 0x%02x.", response[2]);
|
||||
return DC_STATUS_UNSUPPORTED;
|
||||
}
|
||||
ERROR (abstract->context, "Unexpected response packet.");
|
||||
return DC_STATUS_PROTOCOL;
|
||||
}
|
||||
|
||||
// Append the packet to the output buffer.
|
||||
if (!dc_buffer_append (buffer, response + 3, n - 3)) {
|
||||
ERROR (abstract->context, "Insufficient buffer space available.");
|
||||
return DC_STATUS_NOMEMORY;
|
||||
unsigned int length = n - 3;
|
||||
|
||||
if (length != size) {
|
||||
ERROR (abstract->context, "Unexpected packet size (%u bytes).", length);
|
||||
return DC_STATUS_PROTOCOL;
|
||||
}
|
||||
|
||||
return rc;
|
||||
if (length) {
|
||||
memcpy (data, response + 3, length);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
dc_status_t
|
||||
shearwater_common_wdbi (shearwater_common_device_t *device, unsigned int id, const unsigned char data[], unsigned int size)
|
||||
{
|
||||
dc_status_t status = DC_STATUS_SUCCESS;
|
||||
dc_device_t *abstract = (dc_device_t *) device;
|
||||
|
||||
if (size + 3 > SZ_PACKET) {
|
||||
return DC_STATUS_INVALIDARGS;
|
||||
}
|
||||
|
||||
// Transfer the request.
|
||||
unsigned int n = 0;
|
||||
unsigned char request[SZ_PACKET] = {
|
||||
WDBI_REQUEST,
|
||||
(id >> 8) & 0xFF,
|
||||
(id ) & 0xFF};
|
||||
if (size) {
|
||||
memcpy (request + 3, data, size);
|
||||
}
|
||||
unsigned char response[SZ_PACKET];
|
||||
status = shearwater_common_transfer (device, request, size + 3, response, sizeof (response), &n);
|
||||
if (status != DC_STATUS_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
// Verify the response.
|
||||
if (n < 3 || response[0] != WDBI_RESPONSE || response[1] != request[1] || response[2] != request[2]) {
|
||||
if (n == 3 && response[0] == NAK && response[1] == WDBI_REQUEST) {
|
||||
ERROR (abstract->context, "Received NAK packet with error code 0x%02x.", response[2]);
|
||||
return DC_STATUS_UNSUPPORTED;
|
||||
}
|
||||
ERROR (abstract->context, "Unexpected response packet.");
|
||||
return DC_STATUS_PROTOCOL;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
dc_status_t
|
||||
shearwater_common_timesync_local (shearwater_common_device_t *device, const dc_datetime_t *datetime)
|
||||
{
|
||||
dc_status_t status = DC_STATUS_SUCCESS;
|
||||
dc_device_t *abstract = (dc_device_t *) device;
|
||||
|
||||
// Convert to local time.
|
||||
dc_datetime_t local = *datetime;
|
||||
local.timezone = DC_TIMEZONE_NONE;
|
||||
|
||||
dc_ticks_t ticks = dc_datetime_mktime (&local);
|
||||
if (ticks == -1) {
|
||||
ERROR (abstract->context, "Invalid date/time value specified.");
|
||||
return DC_STATUS_INVALIDARGS;
|
||||
}
|
||||
|
||||
const unsigned char timestamp[] = {
|
||||
(ticks >> 24) & 0xFF,
|
||||
(ticks >> 16) & 0xFF,
|
||||
(ticks >> 8) & 0xFF,
|
||||
(ticks ) & 0xFF,
|
||||
};
|
||||
|
||||
status = shearwater_common_wdbi (device, ID_TIME_LOCAL, timestamp, sizeof(timestamp));
|
||||
if (status != DC_STATUS_SUCCESS) {
|
||||
ERROR (abstract->context, "Failed to write the dive computer local time.");
|
||||
return status;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
dc_status_t
|
||||
shearwater_common_timesync_utc (shearwater_common_device_t *device, const dc_datetime_t *datetime)
|
||||
{
|
||||
dc_status_t status = DC_STATUS_SUCCESS;
|
||||
dc_device_t *abstract = (dc_device_t *) device;
|
||||
|
||||
// Convert to UTC time.
|
||||
dc_ticks_t ticks = dc_datetime_mktime (datetime);
|
||||
if (ticks == -1) {
|
||||
ERROR (abstract->context, "Invalid date/time value specified.");
|
||||
return DC_STATUS_INVALIDARGS;
|
||||
}
|
||||
|
||||
const unsigned char timestamp[] = {
|
||||
(ticks >> 24) & 0xFF,
|
||||
(ticks >> 16) & 0xFF,
|
||||
(ticks >> 8) & 0xFF,
|
||||
(ticks ) & 0xFF,
|
||||
};
|
||||
|
||||
status = shearwater_common_wdbi (device, ID_TIME_UTC, timestamp, sizeof(timestamp));
|
||||
if (status != DC_STATUS_SUCCESS) {
|
||||
ERROR (abstract->context, "Failed to write the dive computer UTC time.");
|
||||
return status;
|
||||
}
|
||||
|
||||
int timezone = datetime->timezone / 60;
|
||||
const unsigned char offset[] = {
|
||||
(timezone >> 24) & 0xFF,
|
||||
(timezone >> 16) & 0xFF,
|
||||
(timezone >> 8) & 0xFF,
|
||||
(timezone ) & 0xFF,
|
||||
};
|
||||
|
||||
status = shearwater_common_wdbi (device, ID_TIME_OFFSET, offset, sizeof (offset));
|
||||
if (status != DC_STATUS_SUCCESS) {
|
||||
ERROR (abstract->context, "Failed to write the dive computer timezone offset.");
|
||||
return status;
|
||||
}
|
||||
|
||||
// We don't have a way to determine the daylight savings time setting,
|
||||
// but the required offset is already factored into the timezone offset.
|
||||
const unsigned char dst[] = {0, 0, 0, 0};
|
||||
|
||||
status = shearwater_common_wdbi (device, ID_TIME_DST, dst, sizeof (dst));
|
||||
if (status != DC_STATUS_SUCCESS) {
|
||||
ERROR (abstract->context, "Failed to write the dive computer DST setting.");
|
||||
return status;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
unsigned int
|
||||
shearwater_common_get_model (shearwater_common_device_t *device, unsigned int hardware)
|
||||
{
|
||||
unsigned int model = 0;
|
||||
|
||||
switch (hardware) {
|
||||
case 0x0101:
|
||||
case 0x0202:
|
||||
model = PREDATOR;
|
||||
break;
|
||||
case 0x0404:
|
||||
case 0x0909:
|
||||
model = PETREL;
|
||||
break;
|
||||
case 0x0505:
|
||||
case 0x0808:
|
||||
case 0x0838:
|
||||
case 0x08A5:
|
||||
case 0x0B0B:
|
||||
case 0x7828:
|
||||
case 0x7B2C:
|
||||
case 0x8838:
|
||||
model = PETREL2;
|
||||
break;
|
||||
case 0xB407:
|
||||
model = PETREL3;
|
||||
break;
|
||||
case 0x0606:
|
||||
case 0x0A0A:
|
||||
model = NERD;
|
||||
break;
|
||||
case 0x0E0D:
|
||||
case 0x7E2D:
|
||||
model = NERD2;
|
||||
break;
|
||||
case 0x0707:
|
||||
model = PERDIX;
|
||||
break;
|
||||
case 0x0C0D:
|
||||
case 0x7C2D:
|
||||
case 0x8D6C:
|
||||
model = PERDIXAI;
|
||||
break;
|
||||
case 0xC407:
|
||||
model = PERDIX2;
|
||||
break;
|
||||
case 0x0F0F:
|
||||
case 0x1F0A:
|
||||
case 0x1F0F:
|
||||
model = TERIC;
|
||||
break;
|
||||
case 0x1512:
|
||||
model = PEREGRINE;
|
||||
break;
|
||||
default:
|
||||
WARNING (device->base.context, "Unknown hardware type 0x%04x.", hardware);
|
||||
}
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
@ -35,6 +35,11 @@ extern "C" {
|
||||
#define ID_LOGUPLOAD 0x8021
|
||||
#define ID_HARDWARE 0x8050
|
||||
|
||||
#define ID_TIME_LOCAL 0x9030
|
||||
#define ID_TIME_UTC 0x9031
|
||||
#define ID_TIME_OFFSET 0x9032
|
||||
#define ID_TIME_DST 0x9033
|
||||
|
||||
#define PREDATOR 2
|
||||
#define PETREL 3
|
||||
#define PETREL2 PETREL
|
||||
@ -65,7 +70,19 @@ dc_status_t
|
||||
shearwater_common_download (shearwater_common_device_t *device, dc_buffer_t *buffer, unsigned int address, unsigned int size, unsigned int compression, dc_event_progress_t *progress);
|
||||
|
||||
dc_status_t
|
||||
shearwater_common_identifier (shearwater_common_device_t *device, dc_buffer_t *buffer, unsigned int id);
|
||||
shearwater_common_rdbi (shearwater_common_device_t *device, unsigned int id, unsigned char data[], unsigned int size);
|
||||
|
||||
dc_status_t
|
||||
shearwater_common_wdbi (shearwater_common_device_t *device, unsigned int id, const unsigned char data[], unsigned int size);
|
||||
|
||||
dc_status_t
|
||||
shearwater_common_timesync_local (shearwater_common_device_t *device, const dc_datetime_t *datetime);
|
||||
|
||||
dc_status_t
|
||||
shearwater_common_timesync_utc (shearwater_common_device_t *device, const dc_datetime_t *datetime);
|
||||
|
||||
unsigned int
|
||||
shearwater_common_get_model (shearwater_common_device_t *device, unsigned int hardware);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@ -46,6 +46,7 @@ typedef struct shearwater_petrel_device_t {
|
||||
|
||||
static dc_status_t shearwater_petrel_device_set_fingerprint (dc_device_t *abstract, const unsigned char data[], unsigned int size);
|
||||
static dc_status_t shearwater_petrel_device_foreach (dc_device_t *abstract, dc_dive_callback_t callback, void *userdata);
|
||||
static dc_status_t shearwater_petrel_device_timesync (dc_device_t *abstract, const dc_datetime_t *datetime);
|
||||
static dc_status_t shearwater_petrel_device_close (dc_device_t *abstract);
|
||||
|
||||
static const dc_device_vtable_t shearwater_petrel_device_vtable = {
|
||||
@ -56,7 +57,7 @@ static const dc_device_vtable_t shearwater_petrel_device_vtable = {
|
||||
NULL, /* write */
|
||||
NULL, /* dump */
|
||||
shearwater_petrel_device_foreach, /* foreach */
|
||||
NULL, /* timesync */
|
||||
shearwater_petrel_device_timesync,
|
||||
shearwater_petrel_device_close /* close */
|
||||
};
|
||||
|
||||
@ -152,117 +153,48 @@ shearwater_petrel_device_foreach (dc_device_t *abstract, dc_dive_callback_t call
|
||||
shearwater_petrel_device_t *device = (shearwater_petrel_device_t *) abstract;
|
||||
dc_status_t rc = DC_STATUS_SUCCESS;
|
||||
|
||||
// Allocate memory buffers for the manifests.
|
||||
dc_buffer_t *buffer = dc_buffer_new (MANIFEST_SIZE);
|
||||
dc_buffer_t *manifests = dc_buffer_new (MANIFEST_SIZE);
|
||||
if (buffer == NULL || manifests == NULL) {
|
||||
ERROR (abstract->context, "Insufficient buffer space available.");
|
||||
dc_buffer_free (buffer);
|
||||
dc_buffer_free (manifests);
|
||||
return DC_STATUS_NOMEMORY;
|
||||
}
|
||||
|
||||
// Enable progress notifications.
|
||||
unsigned int current = 0, maximum = 0;
|
||||
dc_event_progress_t progress = EVENT_PROGRESS_INITIALIZER;
|
||||
device_event_emit (abstract, DC_EVENT_PROGRESS, &progress);
|
||||
|
||||
// Read the serial number.
|
||||
rc = shearwater_common_identifier (&device->base, buffer, ID_SERIAL);
|
||||
unsigned char rsp_serial[8] = {0};
|
||||
rc = shearwater_common_rdbi (&device->base, ID_SERIAL, rsp_serial, sizeof(rsp_serial));
|
||||
if (rc != DC_STATUS_SUCCESS) {
|
||||
ERROR (abstract->context, "Failed to read the serial number.");
|
||||
dc_buffer_free (buffer);
|
||||
dc_buffer_free (manifests);
|
||||
return rc;
|
||||
}
|
||||
|
||||
// Convert to a number.
|
||||
unsigned char serial[4] = {0};
|
||||
if (array_convert_hex2bin (dc_buffer_get_data (buffer), dc_buffer_get_size (buffer),
|
||||
serial, sizeof (serial)) != 0 ) {
|
||||
if (array_convert_hex2bin (rsp_serial, sizeof(rsp_serial), serial, sizeof (serial)) != 0 ) {
|
||||
ERROR (abstract->context, "Failed to convert the serial number.");
|
||||
dc_buffer_free (buffer);
|
||||
dc_buffer_free (manifests);
|
||||
return DC_STATUS_DATAFORMAT;
|
||||
|
||||
}
|
||||
|
||||
// Read the firmware version.
|
||||
rc = shearwater_common_identifier (&device->base, buffer, ID_FIRMWARE);
|
||||
unsigned char rsp_firmware[11] = {0};
|
||||
rc = shearwater_common_rdbi (&device->base, ID_FIRMWARE, rsp_firmware, sizeof(rsp_firmware));
|
||||
if (rc != DC_STATUS_SUCCESS) {
|
||||
ERROR (abstract->context, "Failed to read the firmware version.");
|
||||
dc_buffer_free (buffer);
|
||||
dc_buffer_free (manifests);
|
||||
return rc;
|
||||
}
|
||||
|
||||
// Convert to a number.
|
||||
unsigned int firmware = str2num (dc_buffer_get_data (buffer), dc_buffer_get_size (buffer), 1);
|
||||
unsigned int firmware = str2num (rsp_firmware, sizeof(rsp_firmware), 1);
|
||||
|
||||
// Read the hardware type.
|
||||
rc = shearwater_common_identifier (&device->base, buffer, ID_HARDWARE);
|
||||
unsigned char rsp_hardware[2] = {0};
|
||||
rc = shearwater_common_rdbi (&device->base, ID_HARDWARE, rsp_hardware, sizeof(rsp_hardware));
|
||||
if (rc != DC_STATUS_SUCCESS) {
|
||||
ERROR (abstract->context, "Failed to read the hardware type.");
|
||||
dc_buffer_free (buffer);
|
||||
dc_buffer_free (manifests);
|
||||
return rc;
|
||||
}
|
||||
|
||||
// Convert and map to the model number.
|
||||
unsigned int hardware = array_uint_be (dc_buffer_get_data (buffer), dc_buffer_get_size (buffer));
|
||||
unsigned int model = 0;
|
||||
switch (hardware) {
|
||||
case 0x0101:
|
||||
case 0x0202:
|
||||
model = PREDATOR;
|
||||
break;
|
||||
case 0x0404:
|
||||
case 0x0909:
|
||||
model = PETREL;
|
||||
break;
|
||||
case 0x0505:
|
||||
case 0x0808:
|
||||
case 0x0838:
|
||||
case 0x08A5:
|
||||
case 0x0B0B:
|
||||
case 0x7828:
|
||||
case 0x7B2C:
|
||||
case 0x8838:
|
||||
model = PETREL2;
|
||||
break;
|
||||
case 0xB407:
|
||||
model = PETREL3;
|
||||
break;
|
||||
case 0x0606:
|
||||
case 0x0A0A:
|
||||
model = NERD;
|
||||
break;
|
||||
case 0x0E0D:
|
||||
case 0x7E2D:
|
||||
model = NERD2;
|
||||
break;
|
||||
case 0x0707:
|
||||
model = PERDIX;
|
||||
break;
|
||||
case 0x0C0D:
|
||||
case 0x7C2D:
|
||||
case 0x8D6C:
|
||||
model = PERDIXAI;
|
||||
break;
|
||||
case 0xC407:
|
||||
model = PERDIX2;
|
||||
break;
|
||||
case 0x0F0F:
|
||||
case 0x1F0A:
|
||||
case 0x1F0F:
|
||||
model = TERIC;
|
||||
break;
|
||||
case 0x1512:
|
||||
model = PEREGRINE;
|
||||
break;
|
||||
default:
|
||||
WARNING (abstract->context, "Unknown hardware type %04x.", hardware);
|
||||
}
|
||||
unsigned int hardware = array_uint16_be (rsp_hardware);
|
||||
unsigned int model = shearwater_common_get_model (&device->base, hardware);
|
||||
|
||||
// Emit a device info event.
|
||||
dc_event_devinfo_t devinfo;
|
||||
@ -272,22 +204,14 @@ shearwater_petrel_device_foreach (dc_device_t *abstract, dc_dive_callback_t call
|
||||
device_event_emit (abstract, DC_EVENT_DEVINFO, &devinfo);
|
||||
|
||||
// Read the logbook type
|
||||
rc = shearwater_common_identifier (&device->base, buffer, ID_LOGUPLOAD);
|
||||
unsigned char rsp_logupload[9] = {0};
|
||||
rc = shearwater_common_rdbi (&device->base, ID_LOGUPLOAD, rsp_logupload, sizeof(rsp_logupload));
|
||||
if (rc != DC_STATUS_SUCCESS) {
|
||||
ERROR (abstract->context, "Failed to read the logbook type.");
|
||||
dc_buffer_free (buffer);
|
||||
dc_buffer_free (manifests);
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (dc_buffer_get_size (buffer) != 9) {
|
||||
ERROR (abstract->context, "Unexpected packet size (" DC_PRINTF_SIZE " bytes).", dc_buffer_get_size(buffer));
|
||||
dc_buffer_free (buffer);
|
||||
dc_buffer_free (manifests);
|
||||
return DC_STATUS_DATAFORMAT;
|
||||
}
|
||||
|
||||
unsigned int base_addr = array_uint32_be (dc_buffer_get_data (buffer) + 1);
|
||||
unsigned int base_addr = array_uint32_be (rsp_logupload + 1);
|
||||
switch (base_addr) {
|
||||
case 0xDD000000: // Predator - we shouldn't get here, we could give up or we can try 0xC0000000
|
||||
case 0xC0000000: // Predator-Like Format (what we used to call the Petrel format)
|
||||
@ -300,9 +224,17 @@ shearwater_petrel_device_foreach (dc_device_t *abstract, dc_dive_callback_t call
|
||||
break;
|
||||
default: // unknown format
|
||||
ERROR (abstract->context, "Unknown logbook format %08x", base_addr);
|
||||
return DC_STATUS_DATAFORMAT;
|
||||
}
|
||||
|
||||
// Allocate memory buffers for the manifests.
|
||||
dc_buffer_t *buffer = dc_buffer_new (MANIFEST_SIZE);
|
||||
dc_buffer_t *manifests = dc_buffer_new (MANIFEST_SIZE);
|
||||
if (buffer == NULL || manifests == NULL) {
|
||||
ERROR (abstract->context, "Insufficient buffer space available.");
|
||||
dc_buffer_free (buffer);
|
||||
dc_buffer_free (manifests);
|
||||
return DC_STATUS_DATAFORMAT;
|
||||
return DC_STATUS_NOMEMORY;
|
||||
}
|
||||
|
||||
// Read the manifest pages
|
||||
@ -419,3 +351,28 @@ shearwater_petrel_device_foreach (dc_device_t *abstract, dc_dive_callback_t call
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static dc_status_t
|
||||
shearwater_petrel_device_timesync (dc_device_t *abstract, const dc_datetime_t *datetime)
|
||||
{
|
||||
dc_status_t status = DC_STATUS_SUCCESS;
|
||||
shearwater_common_device_t *device = (shearwater_common_device_t *) abstract;
|
||||
|
||||
// Read the hardware type.
|
||||
unsigned char rsp_hardware[2] = {0};
|
||||
status = shearwater_common_rdbi (device, ID_HARDWARE, rsp_hardware, sizeof(rsp_hardware));
|
||||
if (status != DC_STATUS_SUCCESS) {
|
||||
ERROR (abstract->context, "Failed to read the hardware type.");
|
||||
return status;
|
||||
}
|
||||
|
||||
// Convert and map to the model number.
|
||||
unsigned int hardware = array_uint16_be (rsp_hardware);
|
||||
unsigned int model = shearwater_common_get_model (device, hardware);
|
||||
|
||||
if (model == TERIC) {
|
||||
return shearwater_common_timesync_utc (device, datetime);
|
||||
} else {
|
||||
return shearwater_common_timesync_local (device, datetime);
|
||||
}
|
||||
}
|
||||
|
||||
@ -44,6 +44,7 @@ typedef struct shearwater_predator_device_t {
|
||||
static dc_status_t shearwater_predator_device_set_fingerprint (dc_device_t *abstract, const unsigned char data[], unsigned int size);
|
||||
static dc_status_t shearwater_predator_device_dump (dc_device_t *abstract, dc_buffer_t *buffer);
|
||||
static dc_status_t shearwater_predator_device_foreach (dc_device_t *abstract, dc_dive_callback_t callback, void *userdata);
|
||||
static dc_status_t shearwater_predator_device_timesync (dc_device_t *abstract, const dc_datetime_t *datetime);
|
||||
|
||||
static const dc_device_vtable_t shearwater_predator_device_vtable = {
|
||||
sizeof(shearwater_predator_device_t),
|
||||
@ -53,7 +54,7 @@ static const dc_device_vtable_t shearwater_predator_device_vtable = {
|
||||
NULL, /* write */
|
||||
shearwater_predator_device_dump, /* dump */
|
||||
shearwater_predator_device_foreach, /* foreach */
|
||||
NULL, /* timesync */
|
||||
shearwater_predator_device_timesync,
|
||||
NULL /* close */
|
||||
};
|
||||
|
||||
@ -357,3 +358,9 @@ shearwater_predator_extract_dives (dc_device_t *abstract, const unsigned char da
|
||||
return shearwater_predator_extract_predator (abstract, data, size, callback, userdata);
|
||||
}
|
||||
}
|
||||
|
||||
static dc_status_t
|
||||
shearwater_predator_device_timesync (dc_device_t *abstract, const dc_datetime_t *datetime)
|
||||
{
|
||||
return shearwater_common_timesync_local ((shearwater_common_device_t *) abstract, datetime);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user