static device_status_t suunto_eon_device_dump (device_t *abstract, dc_buffer_t *buffer) { suunto_eon_device_t *device = (suunto_eon_device_t*) abstract; if (! device_is_suunto_eon (abstract)) return DEVICE_STATUS_TYPE_MISMATCH; // Erase the current contents of the buffer and // pre-allocate the required amount of memory. if (!dc_buffer_clear (buffer) || !dc_buffer_reserve (buffer, SUUNTO_EON_MEMORY_SIZE)) { WARNING ("Insufficient buffer space available."); return DEVICE_STATUS_MEMORY; } // Enable progress notifications. device_progress_t progress = DEVICE_PROGRESS_INITIALIZER; progress.maximum = SUUNTO_EON_MEMORY_SIZE + 1; device_event_emit (abstract, DEVICE_EVENT_PROGRESS, &progress); // Send the command. unsigned char command[1] = {'P'}; int rc = serial_write (device->port, command, sizeof (command)); if (rc != sizeof (command)) { WARNING ("Failed to send the command."); return EXITCODE (rc); } // Receive the answer. unsigned char answer[SUUNTO_EON_MEMORY_SIZE + 1] = {0}; rc = serial_read (device->port, answer, sizeof (answer)); if (rc != sizeof (answer)) { WARNING ("Failed to receive the answer."); return EXITCODE (rc); } // Update and emit a progress event. progress.current += sizeof (answer); device_event_emit (abstract, DEVICE_EVENT_PROGRESS, &progress); // Verify the checksum of the package. unsigned char crc = answer[sizeof (answer) - 1]; unsigned char ccrc = checksum_add_uint8 (answer, sizeof (answer) - 1, 0x00); if (crc != ccrc) { WARNING ("Unexpected answer CRC."); return DEVICE_STATUS_PROTOCOL; } dc_buffer_append (buffer, answer, SUUNTO_EON_MEMORY_SIZE); return DEVICE_STATUS_SUCCESS; }
static dc_status_t oceanic_vtpro_device_read (dc_device_t *abstract, unsigned int address, unsigned char data[], unsigned int size) { oceanic_vtpro_device_t *device = (oceanic_vtpro_device_t*) abstract; if ((address % PAGESIZE != 0) || (size % PAGESIZE != 0)) return DC_STATUS_INVALIDARGS; unsigned int nbytes = 0; while (nbytes < size) { // Calculate the number of packages. unsigned int npackets = (size - nbytes) / PAGESIZE; if (npackets > MULTIPAGE) npackets = MULTIPAGE; // Read the package. unsigned int first = address / PAGESIZE; unsigned int last = first + npackets - 1; unsigned char answer[(PAGESIZE + 1) * MULTIPAGE] = {0}; unsigned char command[6] = {0x34, (first >> 8) & 0xFF, // high (first ) & 0xFF, // low (last >> 8) & 0xFF, // high (last ) & 0xFF, // low 0x00}; dc_status_t rc = oceanic_vtpro_transfer (device, command, sizeof (command), answer, (PAGESIZE + 1) * npackets); if (rc != DC_STATUS_SUCCESS) return rc; unsigned int offset = 0; for (unsigned int i = 0; i < npackets; ++i) { // Verify the checksum of the answer. unsigned char crc = answer[offset + PAGESIZE]; unsigned char ccrc = checksum_add_uint8 (answer + offset, PAGESIZE, 0x00); if (crc != ccrc) { ERROR (abstract->context, "Unexpected answer checksum."); return DC_STATUS_PROTOCOL; } memcpy (data, answer + offset, PAGESIZE); offset += PAGESIZE + 1; nbytes += PAGESIZE; address += PAGESIZE; data += PAGESIZE; } } return DC_STATUS_SUCCESS; }