Added a function to read individual dives from the Reefnet Sensus Ultra.

This commit is contained in:
Jef Driesen 2008-05-23 20:12:16 +00:00
parent e0151bacf4
commit a540260f61
3 changed files with 160 additions and 4 deletions

View File

@ -153,6 +153,18 @@ reefnet_sensusultra_checksum (const unsigned char *data, unsigned int size)
}
static int
reefnet_sensusultra_isempty (const unsigned char *data, unsigned int size)
{
for (unsigned int i = 0; i < size; ++i) {
if (data[i] != 0xFF)
return 0;
}
return 1;
}
static int
reefnet_sensusultra_send_uchar (sensusultra *device, unsigned char value)
{
@ -517,6 +529,100 @@ reefnet_sensusultra_sense (sensusultra *device, unsigned char *data, unsigned in
}
int
reefnet_sensusultra_read_dives (sensusultra *device, dive_callback_t callback, void *userdata)
{
if (device == NULL)
return REEFNET_ERROR;
unsigned char *data = malloc (REEFNET_SENSUSULTRA_MEMORY_DATA_SIZE * sizeof (unsigned char));
if (data == NULL) {
WARNING ("Memory allocation error.");
return REEFNET_ERROR_MEMORY;
}
const unsigned char header[4] = {0x00, 0x00, 0x00, 0x00};
const unsigned char footer[4] = {0xFF, 0xFF, 0xFF, 0xFF};
// Initialize the state for the parsing code.
unsigned int previous = REEFNET_SENSUSULTRA_MEMORY_DATA_SIZE;
unsigned int current = (REEFNET_SENSUSULTRA_MEMORY_DATA_SIZE >= 4 ?
REEFNET_SENSUSULTRA_MEMORY_DATA_SIZE - 4 : 0);
// Send the instruction code to the device.
int rc = reefnet_sensusultra_send_ushort (device, 0xB421);
if (rc != REEFNET_SUCCESS) {
free (data);
return rc;
}
unsigned int nbytes = 0;
unsigned int npages = 0;
while (nbytes < REEFNET_SENSUSULTRA_MEMORY_DATA_SIZE) {
// Receive the packet.
unsigned int index = REEFNET_SENSUSULTRA_MEMORY_DATA_SIZE -
nbytes - REEFNET_SENSUSULTRA_PACKET_SIZE;
rc = reefnet_sensusultra_page (device, data + index, REEFNET_SENSUSULTRA_PACKET_SIZE, npages);
if (rc != REEFNET_SUCCESS) {
free (data);
return rc;
}
// Abort the transfer if the page contains no useful data.
if (reefnet_sensusultra_isempty (data + index, REEFNET_SENSUSULTRA_PACKET_SIZE))
break;
// Search the page data for a start marker.
while (current > index) {
current--;
if (memcmp (data + current, header, sizeof (header)) == 0) {
// Once a start marker is found, start searching
// for the corresponding stop marker. The search is
// now limited to the start of the previous dive.
int found = 0;
unsigned int offset = current + 16; // Skip non-sample data.
while (offset + 4 <= previous) {
if (memcmp (data + offset, footer, sizeof (footer)) == 0) {
found = 1;
break;
} else {
offset++;
}
}
// Report an error if no stop marker was found.
if (!found) {
WARNING ("No stop marker present.");
free (data);
return REEFNET_ERROR;
}
if (callback)
callback (data + current, offset + 4 - current, userdata);
// Prepare for the next dive.
previous = current;
current = (current >= 4 ? current - 4 : 0);
}
}
// Accept the packet.
rc = reefnet_sensusultra_send_uchar (device, ACCEPT);
if (rc != REEFNET_SUCCESS) {
free (data);
return rc;
}
nbytes += REEFNET_SENSUSULTRA_PACKET_SIZE;
npages++;
}
free (data);
return REEFNET_SUCCESS;
}
int
reefnet_sensusultra_extract_dives (const unsigned char data[], unsigned int size, dive_callback_t callback, void *userdata)
{
@ -536,9 +642,6 @@ reefnet_sensusultra_extract_dives (const unsigned char data[], unsigned int size
unsigned int offset = current + 16; // Skip non-sample data.
while (offset + 4 <= previous) {
if (memcmp (data + offset, footer, sizeof (footer)) == 0) {
if (callback)
callback (data + current, offset + 4 - current, userdata);
found = 1;
break;
} else {
@ -547,8 +650,13 @@ reefnet_sensusultra_extract_dives (const unsigned char data[], unsigned int size
}
// Report an error if no stop marker was found.
if (!found)
if (!found) {
WARNING ("No stop marker present.");
return REEFNET_ERROR;
}
if (callback)
callback (data + current, offset + 4 - current, userdata);
// Prepare for the next dive.
previous = current;

View File

@ -34,6 +34,8 @@ int reefnet_sensusultra_write_averaging (sensusultra *device, unsigned int value
int reefnet_sensusultra_sense (sensusultra *device, unsigned char *data, unsigned int size);
int reefnet_sensusultra_read_dives (sensusultra *device, dive_callback_t callback, void *userdata);
int reefnet_sensusultra_extract_dives (const unsigned char data[], unsigned int size, dive_callback_t callback, void *userdata);
#ifdef __cplusplus

View File

@ -10,6 +10,50 @@
}
int test_dump_memory_dives (const char* name, const char* filename)
{
sensusultra *device = NULL;
unsigned char handshake[REEFNET_SENSUSULTRA_HANDSHAKE_SIZE] = {0};
message ("reefnet_sensusultra_open\n");
int rc = reefnet_sensusultra_open (&device, name);
if (rc != REEFNET_SUCCESS) {
WARNING ("Error opening serial port.");
return rc;
}
message ("reefnet_sensusultra_handshake\n");
rc = reefnet_sensusultra_handshake (device, handshake, sizeof (handshake));
if (rc != REEFNET_SUCCESS) {
WARNING ("Cannot read handshake.");
reefnet_sensusultra_close (device);
return rc;
}
time_t now = time (NULL);
unsigned char datetime[21] = {0};
strftime (datetime, sizeof (datetime), "%Y-%m-%dT%H:%M:%SZ", gmtime (&now));
message ("time=%lu (%s)\n", (unsigned long)now, datetime);
message ("reefnet_sensusultra_read_dives\n");
rc = reefnet_sensusultra_read_dives (device, NULL, NULL);
if (rc != REEFNET_SUCCESS) {
WARNING ("Cannot read dives.");
reefnet_sensusultra_close (device);
return rc;
}
message ("reefnet_sensusultra_close\n");
rc = reefnet_sensusultra_close (device);
if (rc != REEFNET_SUCCESS) {
WARNING ("Cannot close device.");
return rc;
}
return REEFNET_SUCCESS;
}
int test_dump_memory_data (const char* name, const char* filename)
{
sensusultra *device = NULL;
@ -153,11 +197,13 @@ int main(int argc, char *argv[])
int a = test_dump_memory_data (name, "SENSUSULTRA_DATA.DMP");
int b = test_dump_memory_user (name, "SENSUSULTRA_USER.DMP");
int c = test_dump_memory_dives (name, "SENSUSULTRA_DIVES.DMP");
message ("SUMMARY\n");
message ("-------\n");
message ("test_dump_memory_data: %s\n", errmsg (a));
message ("test_dump_memory_user: %s\n", errmsg (b));
message ("test_dump_memory_dives: %s\n", errmsg (c));
message_set_logfile (NULL);