Improve the empty ringbuffer detection.

The logbook ringbuffer is now considered empty if any of the pointers is
outside the valid ringbuffer area. Compared to checking only against a
special empty value, this approach makes the code more robust against
invalid pointers.
This commit is contained in:
Jef Driesen 2009-10-20 13:43:07 +00:00
parent bf0dd700c1
commit 407ff06fb9
5 changed files with 11 additions and 14 deletions

View File

@ -69,10 +69,8 @@ static const device_backend_t oceanic_atom2_device_backend = {
static const oceanic_common_layout_t oceanic_atom2_layout = {
0x0000, /* cf_devinfo */
0x0040, /* cf_pointers */
0x0230, /* rb_logbook_empty */
0x0240, /* rb_logbook_begin */
0x0A40, /* rb_logbook_end */
0x0A40, /* rb_profile_empty */
0x0A50, /* rb_profile_begin */
0x10000, /* rb_profile_end */
0 /* mode */

View File

@ -173,15 +173,19 @@ oceanic_common_device_foreach (oceanic_common_device_t *device, const oceanic_co
// Convert the first/last pointers to begin/end/count pointers.
unsigned int rb_logbook_entry_begin, rb_logbook_entry_end,
rb_logbook_entry_size;
if (rb_logbook_first == layout->rb_logbook_empty &&
rb_logbook_last == layout->rb_logbook_empty)
if (rb_logbook_first < layout->rb_logbook_begin ||
rb_logbook_first >= layout->rb_logbook_end ||
rb_logbook_last < layout->rb_logbook_begin ||
rb_logbook_last >= layout->rb_logbook_begin)
{
// Empty ringbuffer.
// One of the pointers is outside the valid ringbuffer area.
// Because some devices use invalid pointers to indicate an
// empty ringbuffer, we silently ignore the error and always
// consider the ringbuffer empty.
rb_logbook_entry_begin = layout->rb_logbook_begin;
rb_logbook_entry_end = layout->rb_logbook_begin;
rb_logbook_entry_size = 0;
} else {
// Non-empty ringbuffer.
if (layout->mode == 0) {
rb_logbook_entry_begin = rb_logbook_first;
rb_logbook_entry_end = RB_LOGBOOK_INCR (rb_logbook_last, PAGESIZE / 2, layout);
@ -192,8 +196,9 @@ oceanic_common_device_foreach (oceanic_common_device_t *device, const oceanic_co
rb_logbook_entry_size = RB_LOGBOOK_DISTANCE (rb_logbook_first, rb_logbook_last, layout);
// In a typical ringbuffer implementation with only two begin/end
// pointers, there is no distinction possible between an empty and
// a full ringbuffer. Fortunately, the empty ringbuffer is stored
// differently, and we can detect the difference correctly.
// a full ringbuffer. We always consider the ringbuffer full in
// that case, because an empty ringbuffer can be detected by
// inspecting the logbook entries once they are downloaded.
if (rb_logbook_first == rb_logbook_last)
rb_logbook_entry_size = layout->rb_logbook_end - layout->rb_logbook_begin;
}

View File

@ -39,11 +39,9 @@ typedef struct oceanic_common_layout_t {
// Ringbuffer pointers.
unsigned int cf_pointers;
// Logbook ringbuffer.
unsigned int rb_logbook_empty;
unsigned int rb_logbook_begin;
unsigned int rb_logbook_end;
// Profile ringbuffer
unsigned int rb_profile_empty;
unsigned int rb_profile_begin;
unsigned int rb_profile_end;
// The pointer mode indicates how the global ringbuffer pointers

View File

@ -69,10 +69,8 @@ static const device_backend_t oceanic_veo250_device_backend = {
static const oceanic_common_layout_t oceanic_veo250_layout = {
0x0000, /* cf_devinfo */
0x0040, /* cf_pointers */
0x03F0, /* rb_logbook_empty */
0x0400, /* rb_logbook_begin */
0x0600, /* rb_logbook_end */
0x05F0, /* rb_profile_empty */
0x0600, /* rb_profile_begin */
0x8000, /* rb_profile_end */
1 /* mode */

View File

@ -68,10 +68,8 @@ static const device_backend_t oceanic_vtpro_device_backend = {
static const oceanic_common_layout_t oceanic_vtpro_layout = {
0x0000, /* cf_devinfo */
0x0040, /* cf_pointers */
0x0230, /* rb_logbook_empty */
0x0240, /* rb_logbook_begin */
0x0440, /* rb_logbook_end */
0x0430, /* rb_profile_empty */
0x0440, /* rb_profile_begin */
0x8000, /* rb_profile_end */
0 /* mode */