From 5loicmichel5 at wanadoo.fr Mon May 1 23:24:49 2017 From: 5loicmichel5 at wanadoo.fr (devel) Date: Tue, 2 May 2017 08:24:49 +0200 Subject: *****SPAM***** =?utf-8?B?4pyURnc6IHdoYXQgYSBuaWNlIGRheQ==?= Message-ID: <1004106571.20170502092449@wanadoo.fr> Spam detection software, running on the system "mhg.gr8dns.org", has identified this incoming email as possible spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see @@CONTACT_ADDRESS@@ for details. Content preview: Hi! I've had a really nice day and I just wanted to share something really cool with you, please take a look http://mensch.truelaserdesign.com My best to you, devel [...] Content analysis details: (5.9 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- 1.3 RCVD_IN_BL_SPAMCOP_NET RBL: Received via a relay in bl.spamcop.net [Blocked - see ] 0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail provider (5loicmichel5[at]wanadoo.fr) 0.0 HEADER_FROM_DIFFERENT_DOMAINS From and EnvelopeFrom 2nd level mail domains are different 0.0 HTML_MESSAGE BODY: HTML included in message 0.0 HTML_IMAGE_RATIO_06 BODY: HTML has a low ratio of text to image area -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] 1.7 URIBL_BLACK Contains an URL listed in the URIBL blacklist [URIs: truelaserdesign.com] 3.3 RCVD_IN_PBL RBL: Received via a relay in Spamhaus PBL [14.184.230.7 listed in zen.spamhaus.org] 0.4 RCVD_IN_XBL RBL: Received via a relay in Spamhaus XBL 0.8 RDNS_NONE Delivered to internal network by a host with no rDNS 0.2 FREEMAIL_FORGED_FROMDOMAIN 2nd level domains in From and EnvelopeFrom freemail headers are different The original message was not completely plain text, and may be unsafe to open with some email clients; in particular, it may contain a virus, or confirm that your address can receive spam. If you wish to view it, it may be safer to save it to a file and open it with an editor. -------------- next part -------------- An embedded message was scrubbed... From: "devel" <5loicmichel5 at wanadoo.fr> Subject: ?Fw: what a nice day Date: Tue, 2 May 2017 08:24:49 +0200 Size: 23317 URL: From torvalds at linux-foundation.org Thu May 25 10:21:18 2017 From: torvalds at linux-foundation.org (Linus Torvalds) Date: Thu, 25 May 2017 10:21:18 -0700 Subject: [Subsurface-divelog/libdc] Sync with Jef's upstream (#6) In-Reply-To: References: Message-ID: On Wed, May 24, 2017 at 10:13 AM, janmulder wrote: > > In addition some merge conflicts are resolved. So since I want to know what's going on, I ended up doing my own merging and re-resolving things, and while I did that I became convinced that there is a bug in the PPO2 reporting for the predator. The code does this: #ifdef SENSOR_AVERAGE sample.ppo2 = data[offset + 6] / 100.0; if (callback) callback (DC_SAMPLE_PPO2, sample, userdata); #else if ((status & PPO2_EXTERNAL) == 0) { sample.ppo2 = data[offset + 12] * parser->calibration[0]; if (callback && (data[86] & 0x01)) callback (DC_SAMPLE_PPO2, sample, userdata); sample.ppo2 = data[offset + 14] * parser->calibration[1]; if (callback && (data[86] & 0x02)) callback (DC_SAMPLE_PPO2, sample, userdata); sample.ppo2 = data[offset + 15] * parser->calibration[2]; if (callback && (data[86] & 0x04)) callback (DC_SAMPLE_PPO2, sample, userdata); } #endif which means that if you don't have SENSOR_AVERAGE defined, and if it's an external sensor, now there's no sensor reporting AT ALL. Which seems bogus. So either that average PPO2 should be sent if there's an external sensor, or that SENSOR_AVERAGE case should also be inside that "check for external sensor". The code as it stands now makes no sense. Anton, I think this is all yours. Comments? Linus ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, Slashdot.org! http://sdm.link/slashdot _______________________________________________ libdivecomputer-devel mailing list libdivecomputer-devel at lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/libdivecomputer-devel From torvalds at linux-foundation.org Thu May 25 10:37:04 2017 From: torvalds at linux-foundation.org (Linus Torvalds) Date: Thu, 25 May 2017 10:37:04 -0700 Subject: [Subsurface-divelog/libdc] Sync with Jef's upstream (#6) In-Reply-To: References: Message-ID: On Thu, May 25, 2017 at 10:21 AM, Linus Torvalds wrote: > > So since I want to know what's going on, I ended up doing my own > merging and re-resolving things, and while I did that I became > convinced that there is a bug in the PPO2 reporting for the predator. Side note: I pushed out the merge anyway, because the bug is not in the merge, it's in the original code. But let's aim to fix it. Jan, can you check my merge against yours? I noticed an older (harmless) merge error wrt the Shearwater sample size parser state initialization, so our merges may not be identical, but as usual I don't actually have any of the devices that the code changes touch, so it would be good to check. (Actually, I guess I have Dirk's Shearwater for my failed BT testing, I could try to see if I can get at least the old one working) Linus ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, Slashdot.org! http://sdm.link/slashdot _______________________________________________ libdivecomputer-devel mailing list libdivecomputer-devel at lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/libdivecomputer-devel From torvalds at linux-foundation.org Thu May 25 11:53:11 2017 From: torvalds at linux-foundation.org (Linus Torvalds) Date: Thu, 25 May 2017 11:53:11 -0700 Subject: [Subsurface-divelog/libdc] Sync with Jef's upstream (#6) In-Reply-To: References: Message-ID: On Thu, May 25, 2017 at 11:35 AM, Jef Driesen wrote: > > > The explanation is in the commit message: > > Note that the interpretation of the PPO2 status bit appears to be > reversed (0=external and 1=internal). You mis-understand. It's not the particular status bit polarity I worry about. It's simply that whole "average PPO2 data" piece. IOW, this code: #ifdef SENSOR_AVERAGE sample.ppo2 = data[offset + 6] / 100.0; if (callback) callback (DC_SAMPLE_PPO2, sample, userdata); #else fundamentally makes no sense as it is now. There are two possibilities I see for that sample.ppo2 value: (a) it too only exists for the internal sensor case (b) it exists even when we have an external sensor, and then contains the single PPO2 value that the external sensor gives us. but the code right now is wrong in *either* case. So if it's case (a), then that whole #ifdef SENSOR_AVERAGE logic should be _inside_ the PPO2_EXTERNAL check. And if it is case (b), then we should have an "else" case for that PPO2_EXTERNAL case, and give the user that single PPO2 value. See what I'm saying? As it is, the code makes no sense and absolutely cannot be right. Linus ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, Slashdot.org! http://sdm.link/slashdot _______________________________________________ libdivecomputer-devel mailing list libdivecomputer-devel at lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/libdivecomputer-devel From john at vanostrand.com Fri May 26 16:29:39 2017 From: john at vanostrand.com (john at vanostrand.com) Date: Fri, 26 May 2017 19:29:39 -0400 Subject: [PATCH] Altered model detection after seeing some bytes change after a firmware update. Message-ID: <1495841379-29285-1-git-send-email-john@vanostrand.com> From: John Van Ostrand --- src/cochran_commander.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/cochran_commander.c b/src/cochran_commander.c index 99fe369..d2c47b0 100644 --- a/src/cochran_commander.c +++ b/src/cochran_commander.c @@ -42,7 +42,7 @@ typedef enum cochran_endian_t { } cochran_endian_t; typedef struct cochran_commander_model_t { - unsigned char id[8 + 1]; + unsigned char id[2 + 1]; unsigned int model; } cochran_commander_model_t; @@ -199,10 +199,10 @@ static unsigned int cochran_commander_get_model (cochran_commander_device_t *device) { const cochran_commander_model_t models[] = { - {"AM\x11""2212\x02", COCHRAN_MODEL_COMMANDER_AIR_NITROX}, - {"AM7303\x8b\x43", COCHRAN_MODEL_EMC_14}, - {"AMA315\xC3\xC5", COCHRAN_MODEL_EMC_16}, - {"AM2315\xA3\x71", COCHRAN_MODEL_EMC_20}, + {"\x11""2", COCHRAN_MODEL_COMMANDER_AIR_NITROX}, + {"73", COCHRAN_MODEL_EMC_14}, + {"A3", COCHRAN_MODEL_EMC_16}, + {"23", COCHRAN_MODEL_EMC_20}, }; unsigned int model = 0xFFFFFFFF; -- 2.4.11 From john at vanostrand.com Wed May 31 16:24:47 2017 From: john at vanostrand.com (John Van Ostrand) Date: Wed, 31 May 2017 19:24:47 -0400 Subject: [PATCH] Cochran: Changed profile download to be incremental. It will result in a 30 minute download for full computers but it significantly reduces the time to download partial dives. Message-ID: <1496273087-12350-1-git-send-email-john@vanostrand.com> --- src/cochran_commander.c | 366 ++++++++++++++++++++++++++++-------------------- 1 file changed, 212 insertions(+), 154 deletions(-) diff --git a/src/cochran_commander.c b/src/cochran_commander.c index 83dd14a..4c15541 100644 --- a/src/cochran_commander.c +++ b/src/cochran_commander.c @@ -41,6 +41,11 @@ typedef enum cochran_endian_t { ENDIAN_BE, } cochran_endian_t; +typedef enum cochran_profile_size_t { + PROFILE_FULL_SIZE, + PROFILE_READ_SIZE, +} cochran_profile_size_t; + typedef struct cochran_commander_model_t { unsigned char id[2 + 1]; unsigned int model; @@ -53,6 +58,7 @@ typedef struct cochran_data_t { unsigned short int dive_count; int fp_dive_num; + int invalid_profile_dive_num; unsigned int logbook_size; @@ -430,23 +436,133 @@ cochran_commander_read (cochran_commander_device_t *device, dc_event_progress_t } -static void +/* + * For corrupt dives the end-of-samples pointer is 0xFFFFFFFF + * search for a reasonable size, e.g. using next dive start sample + * or end-of-samples to limit searching for recoverable samples + */ +static unsigned int +cochran_commander_guess_sample_end_address(cochran_commander_device_t *device, cochran_data_t *data, unsigned int log_num) +{ + const unsigned char *log_entry = data->logbook + device->layout->rb_logbook_entry_size * log_num; + + if (log_num == data->dive_count) + // Return next usable address from config page + return array_uint32_le(data->config + device->layout->rb_profile_end); + + // Next log's start address + return array_uint32_le(log_entry + device->layout->rb_logbook_entry_size + device->layout->pt_profile_begin); +} + + +static int +cochran_commander_profile_size(cochran_commander_device_t *device, cochran_data_t *data, int dive_num, cochran_profile_size_t type) +{ + + const unsigned char *log_entry = data->logbook + dive_num * device->layout->rb_logbook_entry_size; + unsigned int sample_start_address = -1; + unsigned int sample_end_address = array_uint32_le (log_entry + device->layout->pt_profile_end); + + if (type == PROFILE_FULL_SIZE) { + // actual size, includes pre-dive events + sample_start_address = array_uint32_le (log_entry + device->layout->pt_profile_pre); + } else if (type == PROFILE_READ_SIZE) { + // read size, only include dive profile + sample_start_address = array_uint32_le (log_entry + device->layout->pt_profile_begin); + } + + // Validate addresses + if (sample_start_address < device->layout->rb_profile_begin || + sample_start_address > device->layout->rb_profile_end || + sample_end_address < device->layout->rb_profile_begin || + (sample_end_address > device->layout->rb_profile_end && + sample_end_address != 0xFFFFFFFF)) { + return 0; + } + + if (sample_end_address == 0xFFFFFFFF) + // Corrupt dive, guess the end address + sample_end_address = cochran_commander_guess_sample_end_address(device, data, dive_num); + + // Calculate the size of the profile only + int sample_size = sample_end_address - sample_start_address; + + if (sample_size < 0) + // Adjust for ring buffer wrap-around + sample_size += device->layout->rb_profile_end - device->layout->rb_profile_begin; + + return sample_size; +} + + +/* + * Do several things. Find the log that matches the fingerprint, + * calculate the total read size for progress indicator, + * Determine the most recent dive without profile data. + */ + +static int cochran_commander_find_fingerprint(cochran_commander_device_t *device, cochran_data_t *data) { - // Skip to fingerprint to reduce time + // We track profile ringbuffer usage to determine which dives have profile data + int profile_capacity_remaining = device->layout->rb_profile_end - device->layout->rb_profile_begin; + + int dive_count = -1; + + // Start at end of log if (data->dive_count < device->layout->rb_logbook_entry_count) - data->fp_dive_num = data->dive_count; + dive_count = data->dive_count; else - data->fp_dive_num = device->layout->rb_logbook_entry_count; - data->fp_dive_num--; + dive_count = device->layout->rb_logbook_entry_count; + dive_count--; + + int sample_read_size = 0; + data->invalid_profile_dive_num = -1; + + // Remove the pre-dive events that occur after the last dive + int 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; + + // Loop through dives to find FP, Accumulate profile data size, + // and find the last dive with invalid profile + for (int i = dive_count; i > 0; i--) { + unsigned char *log_entry = data->logbook + i * device->layout->rb_logbook_entry_size; + + // We're done if we find the fingerprint + if (!memcmp(device->fingerprint, log_entry, sizeof(device->fingerprint))) { + data->fp_dive_num = i; + break; + } - while (data->fp_dive_num >= 0 && memcmp(device->fingerprint, - data->logbook + data->fp_dive_num * device->layout->rb_logbook_entry_size, - sizeof(device->fingerprint))) - data->fp_dive_num--; + int sample_size = cochran_commander_profile_size(device, data, i, PROFILE_FULL_SIZE); + int read_size = cochran_commander_profile_size(device, data, i, PROFILE_READ_SIZE); + + // Determine if sample exists + if (profile_capacity_remaining > 0) { + // Subtract this dive's profile size including post-dive events + profile_capacity_remaining -= sample_size; + if (profile_capacity_remaining < 0) { + // Save the last dive that is missing profile data + data->invalid_profile_dive_num = i; + } + // Accumulate read size for progress bar + sample_read_size += read_size; + } + + if (profile_capacity_remaining < 0) { + // There is no profile for this dive + sample_size = 0; + } + + } + + return sample_read_size; } + static void cochran_commander_get_sample_parms(cochran_commander_device_t *device, cochran_data_t *data) { @@ -509,103 +625,6 @@ cochran_commander_get_sample_parms(cochran_commander_device_t *device, cochran_d } -/* - * For corrupt dives the end-of-samples pointer is 0xFFFFFFFF - * search for a reasonable size, e.g. using next dive start sample - * or end-of-samples to limit searching for recoverable samples - */ -static unsigned int -cochran_commander_guess_sample_end_address(cochran_commander_device_t *device, cochran_data_t *data, unsigned int log_num) -{ - const unsigned char *log_entry = data->logbook + device->layout->rb_logbook_entry_size * log_num; - - if (log_num == data->dive_count) - // Return next usable address from config page - return array_uint32_le(data->config + device->layout->rb_profile_end); - - // Next log's start address - return array_uint32_le(log_entry + device->layout->rb_logbook_entry_size + device->layout->pt_profile_begin); -} - - -static dc_status_t -cochran_commander_read_all (cochran_commander_device_t *device, cochran_data_t *data) -{ - dc_device_t *abstract = (dc_device_t *) device; - dc_status_t rc = DC_STATUS_SUCCESS; - - // Calculate max data sizes - unsigned int max_config = sizeof(data->config); - unsigned int max_logbook = device->layout->rb_logbook_end - device->layout->rb_logbook_begin; - unsigned int max_sample = device->layout->rb_profile_end - device->layout->rb_profile_begin; - - dc_event_progress_t progress = EVENT_PROGRESS_INITIALIZER; - progress.maximum = max_config + max_logbook + max_sample; - device_event_emit (abstract, DC_EVENT_PROGRESS, &progress); - - // Emit ID block - dc_event_vendor_t vendor; - vendor.data = device->id; - vendor.size = sizeof (device->id); - device_event_emit (abstract, DC_EVENT_VENDOR, &vendor); - - // Read config - rc = cochran_commander_read_config(device, &progress, data->config, sizeof(data->config)); - if (rc != DC_STATUS_SUCCESS) - return rc; - - // Determine size of dive list to read. - if (device->layout->endian == ENDIAN_LE) - data->dive_count = array_uint16_le (data->config + device->layout->cf_dive_count); - else - data->dive_count = array_uint16_be (data->config + device->layout->cf_dive_count); - - if (data->dive_count > device->layout->rb_logbook_entry_count) { - data->logbook_size = device->layout->rb_logbook_entry_count * device->layout->rb_logbook_entry_size; - } else { - data->logbook_size = data->dive_count * device->layout->rb_logbook_entry_size; - } - - progress.maximum -= max_logbook - data->logbook_size; - device_event_emit (abstract, DC_EVENT_PROGRESS, &progress); - - // Allocate space for log book. - data->logbook = (unsigned char *) malloc(data->logbook_size); - if (data->logbook == NULL) { - ERROR (abstract->context, "Failed to allocate memory."); - return DC_STATUS_NOMEMORY; - } - - // Request log book - rc = cochran_commander_read(device, &progress, 0, data->logbook, data->logbook_size); - if (rc != DC_STATUS_SUCCESS) - return rc; - - // Determine sample memory to read - cochran_commander_find_fingerprint(device, data); - cochran_commander_get_sample_parms(device, data); - - progress.maximum -= max_sample - data->sample_size; - device_event_emit (abstract, DC_EVENT_PROGRESS, &progress); - - if (data->sample_size > 0) { - data->sample = (unsigned char *) malloc(data->sample_size); - if (data->sample == NULL) { - ERROR (abstract->context, "Failed to allocate memory."); - return DC_STATUS_NOMEMORY; - } - - // Read the sample data - rc = cochran_commander_read (device, &progress, data->sample_data_offset, data->sample, data->sample_size); - if (rc != DC_STATUS_SUCCESS) { - ERROR (abstract->context, "Failed to read the sample data."); - return rc; - } - } - - return DC_STATUS_SUCCESS; -} - dc_status_t cochran_commander_device_open (dc_device_t **out, dc_context_t *context, const char *name) { @@ -772,9 +791,64 @@ cochran_commander_device_foreach (dc_device_t *abstract, dc_dive_callback_t call cochran_data_t data; data.logbook = NULL; data.sample = NULL; - status = cochran_commander_read_all (device, &data); - if (status != DC_STATUS_SUCCESS) - goto error; + + // Calculate max data sizes + unsigned int max_config = sizeof(data.config); + unsigned int max_logbook = device->layout->rb_logbook_end - device->layout->rb_logbook_begin; + unsigned int max_sample = device->layout->rb_profile_end - device->layout->rb_profile_begin; + + // setup progress indication + dc_event_progress_t progress = EVENT_PROGRESS_INITIALIZER; + progress.maximum = max_config + max_logbook + max_sample; + device_event_emit (abstract, DC_EVENT_PROGRESS, &progress); + + // Emit ID block + dc_event_vendor_t vendor; + vendor.data = device->id; + vendor.size = sizeof (device->id); + device_event_emit (abstract, DC_EVENT_VENDOR, &vendor); + + // Read config + dc_status_t rc = DC_STATUS_SUCCESS; + rc = cochran_commander_read_config(device, &progress, data.config, sizeof(data.config)); + if (rc != DC_STATUS_SUCCESS) + return rc; + + // Determine size of dive list to read. + if (device->layout->endian == ENDIAN_LE) + data.dive_count = array_uint16_le (data.config + device->layout->cf_dive_count); + else + data.dive_count = array_uint16_be (data.config + device->layout->cf_dive_count); + + if (data.dive_count > device->layout->rb_logbook_entry_count) { + data.logbook_size = device->layout->rb_logbook_entry_count * device->layout->rb_logbook_entry_size; + } else { + data.logbook_size = data.dive_count * device->layout->rb_logbook_entry_size; + } + + // Update progress indicator with new maximum + progress.maximum -= max_logbook - data.logbook_size; + device_event_emit (abstract, DC_EVENT_PROGRESS, &progress); + + // Allocate space for log book. + data.logbook = (unsigned char *) malloc(data.logbook_size); + if (data.logbook == NULL) { + ERROR (abstract->context, "Failed to allocate memory."); + return DC_STATUS_NOMEMORY; + } + + // Request log book + rc = cochran_commander_read(device, &progress, 0, data.logbook, data.logbook_size); + if (rc != DC_STATUS_SUCCESS) + return rc; + + // Locate fingerprint, recent dive with invalid profile and calc read size + int profile_read_size = cochran_commander_find_fingerprint(device, &data); + // Update progress indicator with new maximum + progress.maximum -= (max_sample - profile_read_size); + device_event_emit (abstract, DC_EVENT_PROGRESS, &progress); + + cochran_commander_get_sample_parms(device, &data); // Emit a device info event. dc_event_devinfo_t devinfo; @@ -792,9 +866,6 @@ cochran_commander_device_foreach (dc_device_t *abstract, dc_dive_callback_t call goto error; } - // We track profile ringbuffer usage to determine which dives have profile data - int profile_capacity_remaining = device->layout->rb_profile_end - device->layout->rb_profile_begin; - unsigned int dive_count = 0; if (data.dive_count < device->layout->rb_logbook_entry_count) dive_count = data.dive_count; @@ -808,44 +879,11 @@ cochran_commander_device_foreach (dc_device_t *abstract, dc_dive_callback_t call unsigned int sample_start_address = array_uint32_le (log_entry + device->layout->pt_profile_begin); unsigned int sample_end_address = array_uint32_le (log_entry + device->layout->pt_profile_end); - // Validate - if (sample_start_address < device->layout->rb_profile_begin || - sample_start_address > device->layout->rb_profile_end || - sample_end_address < device->layout->rb_profile_begin || - (sample_end_address > device->layout->rb_profile_end && - sample_end_address != 0xFFFFFFFF)) { - continue; - } - - if (sample_end_address == 0xFFFFFFFF) - // Corrupt dive, guess the end address - sample_end_address = cochran_commander_guess_sample_end_address(device, &data, i); - - // Determine if sample exists - if (profile_capacity_remaining > 0) { - // Subtract this dive's profile size including post-dive events - profile_capacity_remaining -= (last_start_address - sample_start_address); - // Adjust for a dive that wraps the buffer - if (sample_start_address > last_start_address) - profile_capacity_remaining -= device->layout->rb_profile_end - device->layout->rb_profile_begin; - } - last_start_address = sample_start_address; - - unsigned char *sample = NULL; int sample_size = 0; - if (profile_capacity_remaining < 0) { - // There is no profile for this dive - sample = NULL; - sample_size = 0; - } else { - // Calculate the size of the profile only - sample = data.sample + sample_start_address - data.sample_data_offset; - sample_size = sample_end_address - sample_start_address; - - if (sample_size < 0) - // Adjust for ring buffer wrap-around - sample_size += device->layout->rb_profile_end - device->layout->rb_profile_begin; - } + + // Determine if profile exists + if (i > data.invalid_profile_dive_num) + sample_size = cochran_commander_profile_size(device, &data, i, PROFILE_READ_SIZE); // Build dive blob unsigned int dive_size = device->layout->rb_logbook_entry_size + sample_size; @@ -857,17 +895,37 @@ cochran_commander_device_foreach (dc_device_t *abstract, dc_dive_callback_t call memcpy(dive, log_entry, device->layout->rb_logbook_entry_size); // log - // Copy profile data + int tries = 0; + // Read profile data if (sample_size) { if (sample_start_address <= sample_end_address) { - memcpy(dive + device->layout->rb_logbook_entry_size, sample, sample_size); + do { + rc = cochran_commander_read (device, &progress, sample_start_address, dive + device->layout->rb_logbook_entry_size, sample_size); + } while (rc != DC_STATUS_SUCCESS && tries++ < 3); + if (rc != DC_STATUS_SUCCESS) { + ERROR (abstract->context, "Failed to read the sample data."); + return rc; + } } else { // It wrapped the buffer, copy two sections unsigned int size = device->layout->rb_profile_end - sample_start_address; - memcpy(dive + device->layout->rb_logbook_entry_size, sample, size); - memcpy(dive + device->layout->rb_logbook_entry_size + size, - data.sample, sample_end_address - device->layout->rb_profile_begin); + tries = 0; + do { + rc = cochran_commander_read (device, &progress, sample_start_address, dive + device->layout->rb_logbook_entry_size, size); + } while (rc != DC_STATUS_SUCCESS && tries++ < 3); + if (rc != DC_STATUS_SUCCESS) { + ERROR (abstract->context, "Failed to read the sample data."); + return rc; + } + tries = 0; + do { + rc = cochran_commander_read (device, &progress, device->layout->rb_profile_begin, dive + device->layout->rb_logbook_entry_size + size, sample_end_address - device->layout->rb_profile_begin); + } while (rc != DC_STATUS_SUCCESS && tries++ < 3); + if (rc != DC_STATUS_SUCCESS) { + ERROR (abstract->context, "Failed to read the sample data."); + return rc; + } } } -- 2.4.11