Skip to content

Commit

Permalink
dynamic
Browse files Browse the repository at this point in the history
  • Loading branch information
jefdriesen committed May 15, 2024
1 parent 8fe598e commit 8aeedc6
Showing 1 changed file with 45 additions and 23 deletions.
68 changes: 45 additions & 23 deletions src/cressi_goa.c
Original file line number Diff line number Diff line change
Expand Up @@ -113,13 +113,16 @@ cressi_goa_device_send (cressi_goa_device_t *device, unsigned char cmd, const un
}

static dc_status_t
cressi_goa_device_receive (cressi_goa_device_t *device, unsigned char data[], unsigned int size)
cressi_goa_device_receive (cressi_goa_device_t *device, dc_buffer_t *buffer)
{
dc_status_t status = DC_STATUS_SUCCESS;
dc_device_t *abstract = (dc_device_t *) device;

unsigned char packet[SZ_PACKET + 8];

// Clear the buffer.
dc_buffer_clear (buffer);

// Read the header of the data packet.
status = dc_iostream_read (device->iostream, packet, 4, NULL);
if (status != DC_STATUS_SUCCESS) {
Expand Down Expand Up @@ -161,14 +164,11 @@ cressi_goa_device_receive (cressi_goa_device_t *device, unsigned char data[], un
return DC_STATUS_PROTOCOL;
}

// Verify the payload length.
if (length != size) {
ERROR (abstract->context, "Unexpected payload size (%u).", length);
return DC_STATUS_PROTOCOL;
}

if (length) {
memcpy (data, packet + 5, length);
if (!dc_buffer_append (buffer, packet + 5, length)) {
ERROR (abstract->context, "Insufficient buffer space available.");
return DC_STATUS_NOMEMORY;
}
}

return status;
Expand Down Expand Up @@ -270,25 +270,28 @@ cressi_goa_device_download (cressi_goa_device_t *device, dc_buffer_t *buffer, dc
static dc_status_t
cressi_goa_device_transfer (cressi_goa_device_t *device,
unsigned char cmd,
const unsigned char input[], unsigned int isize,
unsigned char output[], unsigned int osize,
const unsigned char data[], unsigned int size,
dc_buffer_t *buffer,
dc_event_progress_t *progress)
{
dc_status_t status = DC_STATUS_SUCCESS;

// Send the command to the dive computer.
status = cressi_goa_device_send (device, cmd, input, isize);
status = cressi_goa_device_send (device, cmd, data, size);
if (status != DC_STATUS_SUCCESS) {
return status;
}

// Receive the answer from the dive computer.
status = cressi_goa_device_receive (device, output, osize);
status = cressi_goa_device_receive (device, buffer);
if (status != DC_STATUS_SUCCESS) {
return status;
}

if (dc_buffer_get_size (buffer) != 0) {
return status;
}

// Download the optional and variable sized payload.
if (buffer) {
status = cressi_goa_device_download (device, buffer, progress);
Expand Down Expand Up @@ -382,43 +385,60 @@ cressi_goa_device_foreach (dc_device_t *abstract, dc_dive_callback_t callback, v
{
dc_status_t status = DC_STATUS_SUCCESS;
cressi_goa_device_t *device = (cressi_goa_device_t *) abstract;
dc_buffer_t *version = NULL;
dc_buffer_t *logbook = NULL;
dc_buffer_t *dive = NULL;

// Enable progress notifications.
dc_event_progress_t progress = EVENT_PROGRESS_INITIALIZER;
device_event_emit (abstract, DC_EVENT_PROGRESS, &progress);

// Allocate memory for the version data.
version = dc_buffer_new(9);
if (version == NULL) {
ERROR (abstract->context, "Failed to allocate memory.");
status = DC_STATUS_NOMEMORY;
goto error_exit;
}

// Read the version information.
unsigned char id[9] = {0};
status = cressi_goa_device_transfer (device, CMD_VERSION, NULL, 0, id, sizeof(id), NULL, NULL);
status = cressi_goa_device_transfer (device, CMD_VERSION, NULL, 0, version, NULL);
if (status != DC_STATUS_SUCCESS) {
ERROR (abstract->context, "Failed to read the version information.");
goto error_exit;
goto error_free_version;
}

const unsigned char *version_data = dc_buffer_get_data (version);
size_t version_size = dc_buffer_get_size (version);

// Emit a vendor event.
dc_event_vendor_t vendor;
vendor.data = id;
vendor.size = sizeof (id);
vendor.data = version_data;
vendor.size = version_size;
device_event_emit (abstract, DC_EVENT_VENDOR, &vendor);

if (version_size < 9) {
ERROR (abstract->context, "Unexpected version size (" DC_PRINTF_SIZE ").", version_size);
status = DC_STATUS_PROTOCOL;
goto error_free_version;
}

// Emit a device info event.
dc_event_devinfo_t devinfo;
devinfo.model = id[4];
devinfo.firmware = array_uint16_le (id + 5);
devinfo.serial = array_uint32_le (id + 0);
devinfo.model = version_data[4];
devinfo.firmware = array_uint16_le (version_data + 5);
devinfo.serial = array_uint32_le (version_data + 0);
device_event_emit (abstract, DC_EVENT_DEVINFO, &devinfo);

// Allocate memory for the logbook data.
logbook = dc_buffer_new(4096);
if (logbook == NULL) {
ERROR (abstract->context, "Failed to allocate memory.");
goto error_exit;
goto error_free_version;
}

// Read the logbook data.
status = cressi_goa_device_transfer (device, CMD_LOGBOOK, NULL, 0, NULL, 0, logbook, &progress);
status = cressi_goa_device_transfer (device, CMD_LOGBOOK, NULL, 0, logbook, &progress);
if (status != DC_STATUS_SUCCESS) {
ERROR (abstract->context, "Failed to read the logbook data.");
goto error_free_logbook;
Expand Down Expand Up @@ -465,7 +485,7 @@ cressi_goa_device_foreach (dc_device_t *abstract, dc_dive_callback_t callback, v
offset -= SZ_HEADER;

// Read the dive data.
status = cressi_goa_device_transfer (device, CMD_DIVE, logbook_data + offset, 2, NULL, 0, dive, &progress);
status = cressi_goa_device_transfer (device, CMD_DIVE, logbook_data + offset, 2, dive, &progress);
if (status != DC_STATUS_SUCCESS) {
ERROR (abstract->context, "Failed to read the dive data.");
goto error_free_dive;
Expand Down Expand Up @@ -505,6 +525,8 @@ cressi_goa_device_foreach (dc_device_t *abstract, dc_dive_callback_t callback, v
dc_buffer_free(dive);
error_free_logbook:
dc_buffer_free(logbook);
error_free_version:
dc_buffer_free(version);
error_exit:
return status;
}

0 comments on commit 8aeedc6

Please sign in to comment.