diff --git a/uwatec.h b/uwatec.h index f8b0a1c..11c0b23 100644 --- a/uwatec.h +++ b/uwatec.h @@ -8,6 +8,8 @@ #define UWATEC_ERROR_PROTOCOL -4 #define UWATEC_ERROR_TIMEOUT -5 +typedef void (*dive_callback_t) (const unsigned char *data, unsigned int size, void *userdata); + #include "uwatec_aladin.h" #include "uwatec_memomouse.h" diff --git a/uwatec_memomouse.c b/uwatec_memomouse.c index dd98c79..d63ec7c 100644 --- a/uwatec_memomouse.c +++ b/uwatec_memomouse.c @@ -347,3 +347,35 @@ uwatec_memomouse_read (memomouse *device, unsigned char data[], unsigned int siz return UWATEC_SUCCESS; } + + +int +uwatec_memomouse_extract_dives (const unsigned char data[], unsigned int size, dive_callback_t callback, void *userdata) +{ + unsigned int previous = 0; + unsigned int current = 5; + while (current + 18 <= size) { + // Memomouse sends all the data twice. The first time, it sends + // the data starting from the oldest dive towards the newest dive. + // Next, it send the same data in reverse order (newest to oldest). + // We abort the parsing once we detect the first duplicate dive. + if (previous && memcmp (data + previous, data + current, 18) == 0) + break; + + // Get the length of the profile data. + unsigned int len = data[current + 16] + (data[current + 17] << 8); + + // Check for a buffer overflow. + if (current + len + 18 > size) + return UWATEC_ERROR; + + if (callback) + callback (data + current, len + 18, userdata); + + // Move to the next dive. + previous = current; + current += len + 18; + } + + return UWATEC_SUCCESS; +} diff --git a/uwatec_memomouse.h b/uwatec_memomouse.h index 99f2692..e0d9b6f 100644 --- a/uwatec_memomouse.h +++ b/uwatec_memomouse.h @@ -15,6 +15,8 @@ int uwatec_memomouse_close (memomouse *device); int uwatec_memomouse_read (memomouse *device, unsigned char data[], unsigned int size); +int uwatec_memomouse_extract_dives (const unsigned char data[], unsigned int size, dive_callback_t callback, void *userdata); + #ifdef __cplusplus } #endif /* __cplusplus */