Use the memory buffer class for downloading individual dives.

This commit is contained in:
Jef Driesen 2009-11-16 08:17:30 +00:00
parent e883843fca
commit 094b70aa03
2 changed files with 39 additions and 32 deletions

View File

@ -360,12 +360,15 @@ suunto_vyper_device_write (device_t *abstract, unsigned int address, const unsig
static device_status_t static device_status_t
suunto_vyper_read_dive (device_t *abstract, unsigned char data[], unsigned int size, unsigned int *result, int init, device_progress_t *progress) suunto_vyper_read_dive (device_t *abstract, dc_buffer_t *buffer, int init, device_progress_t *progress)
{ {
suunto_vyper_device_t *device = (suunto_vyper_device_t*) abstract; suunto_vyper_device_t *device = (suunto_vyper_device_t*) abstract;
if (! device_is_suunto_vyper (abstract)) // Erase the current contents of the buffer.
return DEVICE_STATUS_TYPE_MISMATCH; if (!dc_buffer_clear (buffer)) {
WARNING ("Insufficient buffer space available.");
return DEVICE_STATUS_MEMORY;
}
// Send the command to the dive computer. // Send the command to the dive computer.
unsigned char command[3] = {init ? 0x08 : 0x09, 0xA5, 0x00}; unsigned char command[3] = {init ? 0x08 : 0x09, 0xA5, 0x00};
@ -431,9 +434,7 @@ suunto_vyper_read_dive (device_t *abstract, unsigned char data[], unsigned int s
// the current dive has been overwritten with newer data. Therefore, // the current dive has been overwritten with newer data. Therefore,
// we discard the current (incomplete) dive and end the transmission. // we discard the current (incomplete) dive and end the transmission.
if (len == 0) { if (len == 0) {
WARNING ("Null package received."); dc_buffer_clear (buffer);
if (result)
*result = 0;
return DEVICE_STATUS_SUCCESS; return DEVICE_STATUS_SUCCESS;
} }
@ -444,12 +445,12 @@ suunto_vyper_read_dive (device_t *abstract, unsigned char data[], unsigned int s
} }
// Append the package to the output buffer. // Append the package to the output buffer.
// Reporting of buffer overflows is delayed until the entire // Reporting of buffer errors is delayed until the entire
// transfer is finished. This approach leaves no data behind in // transfer is finished. This approach leaves no data behind in
// the serial receive buffer, and if this packet is part of the // the serial receive buffer, and if this packet is part of the
// last incomplete dive, no error has to be reported at all. // last incomplete dive, no error has to be reported at all.
if (size >= nbytes + len) dc_buffer_append (buffer, answer + 2, len);
memcpy (data + nbytes, answer + 2, len);
nbytes += len; nbytes += len;
// If a package is smaller than $SUUNTO_VYPER_PACKET_SIZE bytes, // If a package is smaller than $SUUNTO_VYPER_PACKET_SIZE bytes,
@ -462,8 +463,8 @@ suunto_vyper_read_dive (device_t *abstract, unsigned char data[], unsigned int s
#endif #endif
} }
// Check for a buffer overflow. // Check for a buffer error.
if (size < nbytes) { if (dc_buffer_get_size (buffer) != nbytes) {
WARNING ("Insufficient buffer space available."); WARNING ("Insufficient buffer space available.");
return DEVICE_STATUS_MEMORY; return DEVICE_STATUS_MEMORY;
} }
@ -472,19 +473,19 @@ suunto_vyper_read_dive (device_t *abstract, unsigned char data[], unsigned int s
// dive is send first (which allows you to download only the new dives), // dive is send first (which allows you to download only the new dives),
// but also the contents of each dive is reversed. Therefore, we reverse // but also the contents of each dive is reversed. Therefore, we reverse
// the bytes again before returning them to the application. // the bytes again before returning them to the application.
array_reverse_bytes (data, nbytes); array_reverse_bytes (dc_buffer_get_data (buffer), dc_buffer_get_size (buffer));
if (result)
*result = nbytes;
return DEVICE_STATUS_SUCCESS; return DEVICE_STATUS_SUCCESS;
} }
device_status_t device_status_t
suunto_vyper_device_read_dive (device_t *abstract, unsigned char data[], unsigned int size, unsigned int *result, int init) suunto_vyper_device_read_dive (device_t *abstract, dc_buffer_t *buffer, int init)
{ {
return suunto_vyper_read_dive (abstract, data, size, result, init, NULL); if (! device_is_suunto_vyper (abstract))
return DEVICE_STATUS_TYPE_MISMATCH;
return suunto_vyper_read_dive (abstract, buffer, init, NULL);
} }
@ -551,30 +552,36 @@ suunto_vyper_device_foreach (device_t *abstract, dive_callback_t callback, void
devinfo.serial = array_uint32_be (header + hoffset + 2); devinfo.serial = array_uint32_be (header + hoffset + 2);
device_event_emit (abstract, DEVICE_EVENT_DEVINFO, &devinfo); device_event_emit (abstract, DEVICE_EVENT_DEVINFO, &devinfo);
// The memory layout of the Spyder is different from the Vyper // Allocate a memory buffer.
// (and all other compatible dive computers). The Spyder has dc_buffer_t *buffer = dc_buffer_new (layout->rb_profile_end - layout->rb_profile_begin);
// the largest ring buffer for the profile memory, so we use if (buffer == NULL)
// that value as the maximum size of the memory buffer. return DEVICE_STATUS_MEMORY;
unsigned char data[SUUNTO_VYPER_MEMORY_SIZE - 0x4C] = {0};
unsigned int ndives = 0; unsigned int ndives = 0;
unsigned int offset = 0; while ((rc = suunto_vyper_read_dive (abstract, buffer, (ndives == 0), &progress)) == DEVICE_STATUS_SUCCESS) {
unsigned int nbytes = 0; unsigned char *data = dc_buffer_get_data (buffer);
while ((rc = suunto_vyper_read_dive (abstract, data + offset, sizeof (data) - offset, &nbytes, (ndives == 0), &progress)) == DEVICE_STATUS_SUCCESS) { unsigned int size = dc_buffer_get_size (buffer);
if (nbytes == 0)
return DEVICE_STATUS_SUCCESS;
if (memcmp (data + offset + layout->fp_offset, device->fingerprint, sizeof (device->fingerprint)) == 0) if (size == 0) {
dc_buffer_free (buffer);
return DEVICE_STATUS_SUCCESS; return DEVICE_STATUS_SUCCESS;
}
if (callback && !callback (data + offset, nbytes, userdata)) if (memcmp (data + layout->fp_offset, device->fingerprint, sizeof (device->fingerprint)) == 0) {
dc_buffer_free (buffer);
return DEVICE_STATUS_SUCCESS; return DEVICE_STATUS_SUCCESS;
}
if (callback && !callback (data, size, userdata)) {
dc_buffer_free (buffer);
return DEVICE_STATUS_SUCCESS;
}
ndives++; ndives++;
offset += nbytes;
} }
dc_buffer_free (buffer);
return rc; return rc;
} }

View File

@ -39,7 +39,7 @@ device_status_t
suunto_vyper_device_set_delay (device_t *device, unsigned int delay); suunto_vyper_device_set_delay (device_t *device, unsigned int delay);
device_status_t device_status_t
suunto_vyper_device_read_dive (device_t *device, unsigned char data[], unsigned int size, unsigned int *result, int init); suunto_vyper_device_read_dive (device_t *device, dc_buffer_t *buffer, int init);
device_status_t device_status_t
suunto_vyper_extract_dives (device_t *device, const unsigned char data[], unsigned int size, dive_callback_t callback, void *userdata); suunto_vyper_extract_dives (device_t *device, const unsigned char data[], unsigned int size, dive_callback_t callback, void *userdata);