Refactor the code to read the device info

Move the code to read and emit the device info into a separate function
to reduce some code duplication.

As a side effect, the check for devices without a logbook and profile
ringbuffer needs to be performed earlier now, in order to prevent a
division by zero in the progress events.
This commit is contained in:
Jef Driesen 2023-11-27 21:03:58 +01:00
parent a91a7dbc38
commit ae292253ba
5 changed files with 60 additions and 43 deletions

View File

@ -86,6 +86,7 @@ static const oceanic_common_device_vtable_t oceanic_atom2_device_vtable = {
NULL, /* timesync */ NULL, /* timesync */
oceanic_atom2_device_close /* close */ oceanic_atom2_device_close /* close */
}, },
oceanic_common_device_devinfo,
oceanic_common_device_logbook, oceanic_common_device_logbook,
oceanic_common_device_profile, oceanic_common_device_profile,
}; };

View File

@ -194,11 +194,11 @@ oceanic_common_device_dump (dc_device_t *abstract, dc_buffer_t *buffer)
return DC_STATUS_NOMEMORY; return DC_STATUS_NOMEMORY;
} }
// Emit a vendor event. // Read the device info.
dc_event_vendor_t vendor; status = VTABLE(abstract)->devinfo (abstract, NULL);
vendor.data = device->version; if (status != DC_STATUS_SUCCESS) {
vendor.size = sizeof (device->version); return status;
device_event_emit (abstract, DC_EVENT_VENDOR, &vendor); }
// Download the memory dump. // Download the memory dump.
status = device_dump_read (abstract, 0, dc_buffer_get_data (buffer), status = device_dump_read (abstract, 0, dc_buffer_get_data (buffer),
@ -207,8 +207,43 @@ oceanic_common_device_dump (dc_device_t *abstract, dc_buffer_t *buffer)
return status; return status;
} }
return status;
}
dc_status_t
oceanic_common_device_devinfo (dc_device_t *abstract, dc_event_progress_t *progress)
{
dc_status_t status = DC_STATUS_SUCCESS;
oceanic_common_device_t *device = (oceanic_common_device_t *) abstract;
assert (device != NULL);
assert (device->layout != NULL);
const oceanic_common_layout_t *layout = device->layout;
// Read the device id.
unsigned char id[PAGESIZE] = {0};
status = dc_device_read (abstract, layout->cf_devinfo, id, sizeof (id));
if (status != DC_STATUS_SUCCESS) {
ERROR (abstract->context, "Failed to read the memory page.");
return status;
}
// Update and emit a progress event.
if (progress) {
progress->current += PAGESIZE;
progress->maximum += PAGESIZE;
device_event_emit (abstract, DC_EVENT_PROGRESS, progress);
}
// Emit a vendor event.
dc_event_vendor_t vendor;
vendor.data = device->version;
vendor.size = sizeof (device->version);
device_event_emit (abstract, DC_EVENT_VENDOR, &vendor);
// Emit a device info event. // Emit a device info event.
unsigned char *id = dc_buffer_get_data (buffer) + layout->cf_devinfo;
dc_event_devinfo_t devinfo; dc_event_devinfo_t devinfo;
devinfo.model = array_uint16_be (id + 8); devinfo.model = array_uint16_be (id + 8);
devinfo.firmware = device->firmware; devinfo.firmware = device->firmware;
@ -244,13 +279,6 @@ oceanic_common_device_logbook (dc_device_t *abstract, dc_event_progress_t *progr
if (!dc_buffer_clear (logbook)) if (!dc_buffer_clear (logbook))
return DC_STATUS_NOMEMORY; return DC_STATUS_NOMEMORY;
// For devices without a logbook ringbuffer, downloading dives isn't
// possible. This is not considered a fatal error, but handled as if there
// are no dives present.
if (layout->rb_logbook_begin == layout->rb_logbook_end) {
return DC_STATUS_SUCCESS;
}
// Read the pointer data. // Read the pointer data.
unsigned char pointers[PAGESIZE] = {0}; unsigned char pointers[PAGESIZE] = {0};
rc = dc_device_read (abstract, layout->cf_pointers, pointers, sizeof (pointers)); rc = dc_device_read (abstract, layout->cf_pointers, pointers, sizeof (pointers));
@ -585,6 +613,7 @@ oceanic_common_device_profile (dc_device_t *abstract, dc_event_progress_t *progr
dc_status_t dc_status_t
oceanic_common_device_foreach (dc_device_t *abstract, dc_dive_callback_t callback, void *userdata) oceanic_common_device_foreach (dc_device_t *abstract, dc_dive_callback_t callback, void *userdata)
{ {
dc_status_t rc = DC_STATUS_SUCCESS;
oceanic_common_device_t *device = (oceanic_common_device_t *) abstract; oceanic_common_device_t *device = (oceanic_common_device_t *) abstract;
assert (device != NULL); assert (device != NULL);
@ -592,46 +621,27 @@ oceanic_common_device_foreach (dc_device_t *abstract, dc_dive_callback_t callbac
const oceanic_common_layout_t *layout = device->layout; const oceanic_common_layout_t *layout = device->layout;
// For devices without a logbook and profile ringbuffer, downloading dives
// isn't possible. This is not considered a fatal error, but handled as if
// there are no dives present.
if (layout->rb_logbook_begin == layout->rb_logbook_end &&
layout->rb_profile_begin == layout->rb_profile_end) {
return DC_STATUS_SUCCESS;
}
// Enable progress notifications. // Enable progress notifications.
dc_event_progress_t progress = EVENT_PROGRESS_INITIALIZER; dc_event_progress_t progress = EVENT_PROGRESS_INITIALIZER;
progress.maximum = PAGESIZE + progress.maximum =
(layout->rb_logbook_end - layout->rb_logbook_begin) + (layout->rb_logbook_end - layout->rb_logbook_begin) +
(layout->rb_profile_end - layout->rb_profile_begin); (layout->rb_profile_end - layout->rb_profile_begin);
device_event_emit (abstract, DC_EVENT_PROGRESS, &progress); device_event_emit (abstract, DC_EVENT_PROGRESS, &progress);
// Emit a vendor event. // Read the device info.
dc_event_vendor_t vendor; rc = VTABLE(abstract)->devinfo (abstract, &progress);
vendor.data = device->version;
vendor.size = sizeof (device->version);
device_event_emit (abstract, DC_EVENT_VENDOR, &vendor);
// Read the device id.
unsigned char id[PAGESIZE] = {0};
dc_status_t rc = dc_device_read (abstract, layout->cf_devinfo, id, sizeof (id));
if (rc != DC_STATUS_SUCCESS) { if (rc != DC_STATUS_SUCCESS) {
ERROR (abstract->context, "Failed to read the memory page.");
return rc; return rc;
} }
// Update and emit a progress event.
progress.current += PAGESIZE;
device_event_emit (abstract, DC_EVENT_PROGRESS, &progress);
// Emit a device info event.
dc_event_devinfo_t devinfo;
devinfo.model = array_uint16_be (id + 8);
devinfo.firmware = device->firmware;
if (layout->pt_mode_serial == 0)
devinfo.serial = array_convert_bcd2dec (id + 10, 3);
else if (layout->pt_mode_serial == 1)
devinfo.serial = array_convert_bin2dec (id + 11, 3);
else
devinfo.serial =
(id[11] & 0x0F) * 100000 + ((id[11] & 0xF0) >> 4) * 10000 +
(id[12] & 0x0F) * 1000 + ((id[12] & 0xF0) >> 4) * 100 +
(id[13] & 0x0F) * 10 + ((id[13] & 0xF0) >> 4) * 1;
device_event_emit (abstract, DC_EVENT_DEVINFO, &devinfo);
// Memory buffer for the logbook data. // Memory buffer for the logbook data.
dc_buffer_t *logbook = dc_buffer_new (0); dc_buffer_t *logbook = dc_buffer_new (0);
if (logbook == NULL) { if (logbook == NULL) {

View File

@ -168,6 +168,7 @@ typedef struct oceanic_common_device_t {
typedef struct oceanic_common_device_vtable_t { typedef struct oceanic_common_device_vtable_t {
dc_device_vtable_t base; dc_device_vtable_t base;
dc_status_t (*devinfo) (dc_device_t *device, dc_event_progress_t *progress);
dc_status_t (*logbook) (dc_device_t *device, dc_event_progress_t *progress, dc_buffer_t *logbook); dc_status_t (*logbook) (dc_device_t *device, dc_event_progress_t *progress, dc_buffer_t *logbook);
dc_status_t (*profile) (dc_device_t *device, dc_event_progress_t *progress, dc_buffer_t *logbook, dc_dive_callback_t callback, void *userdata); dc_status_t (*profile) (dc_device_t *device, dc_event_progress_t *progress, dc_buffer_t *logbook, dc_dive_callback_t callback, void *userdata);
} oceanic_common_device_vtable_t; } oceanic_common_device_vtable_t;
@ -185,6 +186,9 @@ oceanic_common_match (const unsigned char *version, const oceanic_common_version
void void
oceanic_common_device_init (oceanic_common_device_t *device); oceanic_common_device_init (oceanic_common_device_t *device);
dc_status_t
oceanic_common_device_devinfo (dc_device_t *device, dc_event_progress_t *progress);
dc_status_t dc_status_t
oceanic_common_device_logbook (dc_device_t *device, dc_event_progress_t *progress, dc_buffer_t *logbook); oceanic_common_device_logbook (dc_device_t *device, dc_event_progress_t *progress, dc_buffer_t *logbook);

View File

@ -58,6 +58,7 @@ static const oceanic_common_device_vtable_t oceanic_veo250_device_vtable = {
NULL, /* timesync */ NULL, /* timesync */
oceanic_veo250_device_close /* close */ oceanic_veo250_device_close /* close */
}, },
oceanic_common_device_devinfo,
oceanic_common_device_logbook, oceanic_common_device_logbook,
oceanic_common_device_profile, oceanic_common_device_profile,
}; };

View File

@ -67,6 +67,7 @@ static const oceanic_common_device_vtable_t oceanic_vtpro_device_vtable = {
NULL, /* timesync */ NULL, /* timesync */
oceanic_vtpro_device_close /* close */ oceanic_vtpro_device_close /* close */
}, },
oceanic_common_device_devinfo,
oceanic_vtpro_device_logbook, oceanic_vtpro_device_logbook,
oceanic_common_device_profile, oceanic_common_device_profile,
}; };