[PATCH 3/4] Cochran: Bad profiles when profile ringbuffer wraps around

John Van Ostrand john at vanostrand.com
Fri Jun 30 11:12:58 PDT 2017


The method used to calculate the data used by dives (to determine
when we run out of ringbuffer) incorrectly didn't include
surface sample data. Ten to twenty minute of sample data is
recorded at the surface in case the diver re-descends, continuing
the dive. The code then thought that older dive profiles were
not yet overwritten. The improper data was returned to the user.
---
 src/cochran_commander.c | 26 ++++++++++++++++++--------
 1 file changed, 18 insertions(+), 8 deletions(-)

diff --git a/src/cochran_commander.c b/src/cochran_commander.c
index 247da81..ac4c596 100644
--- a/src/cochran_commander.c
+++ b/src/cochran_commander.c
@@ -145,8 +145,8 @@ static const cochran_device_layout_t cochran_cmdr_device_layout = {
 	ENDIAN_WORD_BE,  // endian
 	115200,     // baudrate
 	0x046,      // cf_dive_count
-	0x070,      // cf_last_log
-	0x06C,      // cf_last_interdive
+	0x06C,      // cf_last_log
+	0x070,      // cf_last_interdive
 	0x0AA,      // cf_serial_number
 	0x00000000, // rb_logbook_begin
 	0x00020000, // rb_logbook_end
@@ -555,12 +555,9 @@ cochran_commander_find_fingerprint(cochran_commander_device_t *device, cochran_d
 	// Remove the pre-dive events that occur after the last dive
 	int rb_head_ptr;
 	if (device->layout->endian == ENDIAN_WORD_BE)
-		rb_head_ptr = (array_uint32_word_be(data->config + device->layout->cf_last_interdive) & 0xfffff000) + 0x2000;
+		rb_head_ptr = (array_uint32_word_be(data->config + device->layout->cf_last_log) & 0xfffff000) + 0x2000;
 	else
-		rb_head_ptr = (array_uint32_le(data->config + device->layout->cf_last_interdive) & 0xfffff000) + 0x2000;
-	int last_dive_end_address = array_uint32_le(data->logbook + dive_count * device->layout->rb_logbook_entry_size + device->layout->pt_profile_end);
-	if (rb_head_ptr > last_dive_end_address)
-		profile_capacity_remaining -= rb_head_ptr - last_dive_end_address;
+		rb_head_ptr = (array_uint32_le(data->config + device->layout->cf_last_log) & 0xfffff000) + 0x2000;
 
 	unsigned int head_dive = 0, tail_dive = 0;
 
@@ -573,6 +570,18 @@ cochran_commander_find_fingerprint(cochran_commander_device_t *device, cochran_d
 		head_dive = tail_dive;
 	}
 
+	unsigned int last_profile_idx = (device->layout->rb_logbook_entry_count + head_dive - 1) % device->layout->rb_logbook_entry_count;
+	unsigned int last_profile_end = array_uint32_le(data->logbook + last_profile_idx * device->layout->rb_logbook_entry_size + device->layout->pt_profile_end);
+	unsigned int last_profile_pre = 0xFFFFFFFF;
+
+	if (device->layout->endian == ENDIAN_WORD_BE)
+		last_profile_pre = array_uint32_word_be(data->config + device->layout->cf_last_log);
+	else
+		last_profile_pre = array_uint32_le(data->config + device->layout->cf_last_log);
+
+	if (rb_head_ptr > last_profile_end)
+		profile_capacity_remaining -= rb_head_ptr - last_profile_end;
+
 	// Loop through dives to find FP, Accumulate profile data size,
 	// and find the last dive with invalid profile
 	for (int x = dive_count; x >= 0; x--) {
@@ -590,7 +599,8 @@ cochran_commander_find_fingerprint(cochran_commander_device_t *device, cochran_d
 		unsigned int profile_begin = array_uint32_le(log_entry + device->layout->pt_profile_begin);
 		unsigned int profile_end = array_uint32_le(log_entry + device->layout->pt_profile_end);
 
-		unsigned int sample_size = cochran_commander_profile_size(device, data, i, profile_pre, profile_end);
+		unsigned int sample_size = cochran_commander_profile_size(device, data, i, profile_pre, last_profile_pre);
+		last_profile_pre = profile_pre;
 		unsigned int read_size = cochran_commander_profile_size(device, data, i, profile_begin, profile_end);
 
 		// Determine if sample exists
-- 
2.4.11



More information about the devel mailing list