Integrate the new packet I/O in the backends
Replace the custom packet handling code in the iconhd and ostc3 backends with the new layered packet I/O, and also integrate it into the idive and extreme backends.
This commit is contained in:
parent
40c95ca02a
commit
1c8cd096b5
@ -29,6 +29,7 @@
|
|||||||
#include "platform.h"
|
#include "platform.h"
|
||||||
#include "checksum.h"
|
#include "checksum.h"
|
||||||
#include "array.h"
|
#include "array.h"
|
||||||
|
#include "packet.h"
|
||||||
|
|
||||||
#define ISINSTANCE(device) dc_device_isinstance((device), &divesystem_idive_device_vtable)
|
#define ISINSTANCE(device) dc_device_isinstance((device), &divesystem_idive_device_vtable)
|
||||||
|
|
||||||
@ -102,6 +103,7 @@ typedef struct divesystem_idive_device_t {
|
|||||||
static dc_status_t divesystem_idive_device_set_fingerprint (dc_device_t *abstract, const unsigned char data[], unsigned int size);
|
static dc_status_t divesystem_idive_device_set_fingerprint (dc_device_t *abstract, const unsigned char data[], unsigned int size);
|
||||||
static dc_status_t divesystem_idive_device_foreach (dc_device_t *abstract, dc_dive_callback_t callback, void *userdata);
|
static dc_status_t divesystem_idive_device_foreach (dc_device_t *abstract, dc_dive_callback_t callback, void *userdata);
|
||||||
static dc_status_t divesystem_idive_device_timesync (dc_device_t *abstract, const dc_datetime_t *datetime);
|
static dc_status_t divesystem_idive_device_timesync (dc_device_t *abstract, const dc_datetime_t *datetime);
|
||||||
|
static dc_status_t divesystem_idive_device_close (dc_device_t *abstract);
|
||||||
|
|
||||||
static const dc_device_vtable_t divesystem_idive_device_vtable = {
|
static const dc_device_vtable_t divesystem_idive_device_vtable = {
|
||||||
sizeof(divesystem_idive_device_t),
|
sizeof(divesystem_idive_device_t),
|
||||||
@ -112,7 +114,7 @@ static const dc_device_vtable_t divesystem_idive_device_vtable = {
|
|||||||
NULL, /* dump */
|
NULL, /* dump */
|
||||||
divesystem_idive_device_foreach, /* foreach */
|
divesystem_idive_device_foreach, /* foreach */
|
||||||
divesystem_idive_device_timesync, /* timesync */
|
divesystem_idive_device_timesync, /* timesync */
|
||||||
NULL /* close */
|
divesystem_idive_device_close /* close */
|
||||||
};
|
};
|
||||||
|
|
||||||
static const divesystem_idive_commands_t idive = {
|
static const divesystem_idive_commands_t idive = {
|
||||||
@ -152,6 +154,7 @@ divesystem_idive_device_open (dc_device_t **out, dc_context_t *context, dc_iostr
|
|||||||
{
|
{
|
||||||
dc_status_t status = DC_STATUS_SUCCESS;
|
dc_status_t status = DC_STATUS_SUCCESS;
|
||||||
divesystem_idive_device_t *device = NULL;
|
divesystem_idive_device_t *device = NULL;
|
||||||
|
dc_transport_t transport = dc_iostream_get_transport (iostream);
|
||||||
|
|
||||||
if (out == NULL)
|
if (out == NULL)
|
||||||
return DC_STATUS_INVALIDARGS;
|
return DC_STATUS_INVALIDARGS;
|
||||||
@ -164,22 +167,32 @@ divesystem_idive_device_open (dc_device_t **out, dc_context_t *context, dc_iostr
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set the default values.
|
// Set the default values.
|
||||||
device->iostream = iostream;
|
|
||||||
memset (device->fingerprint, 0, sizeof (device->fingerprint));
|
memset (device->fingerprint, 0, sizeof (device->fingerprint));
|
||||||
device->model = model;
|
device->model = model;
|
||||||
|
|
||||||
|
// Create the packet stream.
|
||||||
|
if (transport == DC_TRANSPORT_BLE) {
|
||||||
|
status = dc_packet_open (&device->iostream, context, iostream, 244, 244);
|
||||||
|
if (status != DC_STATUS_SUCCESS) {
|
||||||
|
ERROR (context, "Failed to create the packet stream.");
|
||||||
|
goto error_free;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
device->iostream = iostream;
|
||||||
|
}
|
||||||
|
|
||||||
// Set the serial communication protocol (115200 8N1).
|
// Set the serial communication protocol (115200 8N1).
|
||||||
status = dc_iostream_configure (device->iostream, 115200, 8, DC_PARITY_NONE, DC_STOPBITS_ONE, DC_FLOWCONTROL_NONE);
|
status = dc_iostream_configure (device->iostream, 115200, 8, DC_PARITY_NONE, DC_STOPBITS_ONE, DC_FLOWCONTROL_NONE);
|
||||||
if (status != DC_STATUS_SUCCESS) {
|
if (status != DC_STATUS_SUCCESS) {
|
||||||
ERROR (context, "Failed to set the terminal attributes.");
|
ERROR (context, "Failed to set the terminal attributes.");
|
||||||
goto error_free;
|
goto error_free_iostream;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the timeout for receiving data (1000ms).
|
// Set the timeout for receiving data (1000ms).
|
||||||
status = dc_iostream_set_timeout (device->iostream, 1000);
|
status = dc_iostream_set_timeout (device->iostream, 1000);
|
||||||
if (status != DC_STATUS_SUCCESS) {
|
if (status != DC_STATUS_SUCCESS) {
|
||||||
ERROR (context, "Failed to set the timeout.");
|
ERROR (context, "Failed to set the timeout.");
|
||||||
goto error_free;
|
goto error_free_iostream;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure everything is in a sane state.
|
// Make sure everything is in a sane state.
|
||||||
@ -190,11 +203,27 @@ divesystem_idive_device_open (dc_device_t **out, dc_context_t *context, dc_iostr
|
|||||||
|
|
||||||
return DC_STATUS_SUCCESS;
|
return DC_STATUS_SUCCESS;
|
||||||
|
|
||||||
|
error_free_iostream:
|
||||||
|
if (transport == DC_TRANSPORT_BLE) {
|
||||||
|
dc_iostream_close (device->iostream);
|
||||||
|
}
|
||||||
error_free:
|
error_free:
|
||||||
dc_device_deallocate ((dc_device_t *) device);
|
dc_device_deallocate ((dc_device_t *) device);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static dc_status_t
|
||||||
|
divesystem_idive_device_close (dc_device_t *abstract)
|
||||||
|
{
|
||||||
|
divesystem_idive_device_t *device = (divesystem_idive_device_t *) abstract;
|
||||||
|
|
||||||
|
// Close the packet stream.
|
||||||
|
if (dc_iostream_get_transport (device->iostream) == DC_TRANSPORT_BLE) {
|
||||||
|
return dc_iostream_close (device->iostream);
|
||||||
|
}
|
||||||
|
|
||||||
|
return DC_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
static dc_status_t
|
static dc_status_t
|
||||||
divesystem_idive_device_set_fingerprint (dc_device_t *abstract, const unsigned char data[], unsigned int size)
|
divesystem_idive_device_set_fingerprint (dc_device_t *abstract, const unsigned char data[], unsigned int size)
|
||||||
|
|||||||
@ -30,6 +30,7 @@
|
|||||||
#include "array.h"
|
#include "array.h"
|
||||||
#include "aes.h"
|
#include "aes.h"
|
||||||
#include "platform.h"
|
#include "platform.h"
|
||||||
|
#include "packet.h"
|
||||||
|
|
||||||
#define ISINSTANCE(device) dc_device_isinstance((device), &hw_ostc3_device_vtable)
|
#define ISINSTANCE(device) dc_device_isinstance((device), &hw_ostc3_device_vtable)
|
||||||
|
|
||||||
@ -119,9 +120,6 @@ typedef struct hw_ostc3_device_t {
|
|||||||
unsigned int firmware;
|
unsigned int firmware;
|
||||||
unsigned char fingerprint[5];
|
unsigned char fingerprint[5];
|
||||||
hw_ostc3_state_t state;
|
hw_ostc3_state_t state;
|
||||||
unsigned char cache[244];
|
|
||||||
unsigned int available;
|
|
||||||
unsigned int offset;
|
|
||||||
} hw_ostc3_device_t;
|
} hw_ostc3_device_t;
|
||||||
|
|
||||||
typedef struct hw_ostc3_logbook_t {
|
typedef struct hw_ostc3_logbook_t {
|
||||||
@ -207,41 +205,20 @@ static dc_status_t
|
|||||||
hw_ostc3_read (hw_ostc3_device_t *device, dc_event_progress_t *progress, unsigned char data[], size_t size)
|
hw_ostc3_read (hw_ostc3_device_t *device, dc_event_progress_t *progress, unsigned char data[], size_t size)
|
||||||
{
|
{
|
||||||
dc_status_t rc = DC_STATUS_SUCCESS;
|
dc_status_t rc = DC_STATUS_SUCCESS;
|
||||||
dc_transport_t transport = dc_iostream_get_transport(device->iostream);
|
|
||||||
|
|
||||||
size_t nbytes = 0;
|
size_t nbytes = 0;
|
||||||
while (nbytes < size) {
|
while (nbytes < size) {
|
||||||
if (transport == DC_TRANSPORT_BLE) {
|
|
||||||
if (device->available == 0) {
|
|
||||||
// Read a packet into the cache.
|
|
||||||
size_t len = 0;
|
|
||||||
rc = dc_iostream_read (device->iostream, device->cache, sizeof(device->cache), &len);
|
|
||||||
if (rc != DC_STATUS_SUCCESS)
|
|
||||||
return rc;
|
|
||||||
|
|
||||||
device->available = len;
|
|
||||||
device->offset = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the minimum packet size.
|
// Set the minimum packet size.
|
||||||
size_t length = (transport == DC_TRANSPORT_BLE) ? device->available : 1024;
|
size_t length = 1024;
|
||||||
|
|
||||||
// Limit the packet size to the total size.
|
// Limit the packet size to the total size.
|
||||||
if (nbytes + length > size)
|
if (nbytes + length > size)
|
||||||
length = size - nbytes;
|
length = size - nbytes;
|
||||||
|
|
||||||
if (transport == DC_TRANSPORT_BLE) {
|
// Read the packet.
|
||||||
// Copy the data from the cached packet.
|
rc = dc_iostream_read (device->iostream, data + nbytes, length, NULL);
|
||||||
memcpy (data + nbytes, device->cache + device->offset, length);
|
if (rc != DC_STATUS_SUCCESS)
|
||||||
device->available -= length;
|
return rc;
|
||||||
device->offset += length;
|
|
||||||
} else {
|
|
||||||
// Read the packet.
|
|
||||||
rc = dc_iostream_read (device->iostream, data + nbytes, length, NULL);
|
|
||||||
if (rc != DC_STATUS_SUCCESS)
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update and emit a progress event.
|
// Update and emit a progress event.
|
||||||
if (progress) {
|
if (progress) {
|
||||||
@ -259,12 +236,11 @@ static dc_status_t
|
|||||||
hw_ostc3_write (hw_ostc3_device_t *device, dc_event_progress_t *progress, const unsigned char data[], size_t size)
|
hw_ostc3_write (hw_ostc3_device_t *device, dc_event_progress_t *progress, const unsigned char data[], size_t size)
|
||||||
{
|
{
|
||||||
dc_status_t rc = DC_STATUS_SUCCESS;
|
dc_status_t rc = DC_STATUS_SUCCESS;
|
||||||
dc_transport_t transport = dc_iostream_get_transport(device->iostream);
|
|
||||||
|
|
||||||
size_t nbytes = 0;
|
size_t nbytes = 0;
|
||||||
while (nbytes < size) {
|
while (nbytes < size) {
|
||||||
// Set the maximum packet size.
|
// Set the maximum packet size.
|
||||||
size_t length = (transport == DC_TRANSPORT_BLE) ? sizeof(device->cache) : 64;
|
size_t length = 1024;
|
||||||
|
|
||||||
// Limit the packet size to the total size.
|
// Limit the packet size to the total size.
|
||||||
if (nbytes + length > size)
|
if (nbytes + length > size)
|
||||||
@ -313,7 +289,7 @@ hw_ostc3_transfer (hw_ostc3_device_t *device,
|
|||||||
|
|
||||||
// Send the command.
|
// Send the command.
|
||||||
unsigned char command[1] = {cmd};
|
unsigned char command[1] = {cmd};
|
||||||
status = hw_ostc3_write (device, NULL, command, sizeof (command));
|
status = dc_iostream_write (device->iostream, command, sizeof (command), NULL);
|
||||||
if (status != DC_STATUS_SUCCESS) {
|
if (status != DC_STATUS_SUCCESS) {
|
||||||
ERROR (abstract->context, "Failed to send the command.");
|
ERROR (abstract->context, "Failed to send the command.");
|
||||||
return status;
|
return status;
|
||||||
@ -321,7 +297,7 @@ hw_ostc3_transfer (hw_ostc3_device_t *device,
|
|||||||
|
|
||||||
// Read the echo.
|
// Read the echo.
|
||||||
unsigned char echo[1] = {0};
|
unsigned char echo[1] = {0};
|
||||||
status = hw_ostc3_read (device, NULL, echo, sizeof (echo));
|
status = dc_iostream_read (device->iostream, echo, sizeof (echo), NULL);
|
||||||
if (status != DC_STATUS_SUCCESS) {
|
if (status != DC_STATUS_SUCCESS) {
|
||||||
ERROR (abstract->context, "Failed to receive the echo.");
|
ERROR (abstract->context, "Failed to receive the echo.");
|
||||||
return status;
|
return status;
|
||||||
@ -407,14 +383,14 @@ hw_ostc3_transfer (hw_ostc3_device_t *device,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (delay && device->available == 0) {
|
if (delay) {
|
||||||
dc_iostream_poll (device->iostream, delay);
|
dc_iostream_poll (device->iostream, delay);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cmd != EXIT) {
|
if (cmd != EXIT) {
|
||||||
// Read the ready byte.
|
// Read the ready byte.
|
||||||
unsigned char answer[1] = {0};
|
unsigned char answer[1] = {0};
|
||||||
status = hw_ostc3_read (device, NULL, answer, sizeof (answer));
|
status = dc_iostream_read (device->iostream, answer, sizeof (answer), NULL);
|
||||||
if (status != DC_STATUS_SUCCESS) {
|
if (status != DC_STATUS_SUCCESS) {
|
||||||
ERROR (abstract->context, "Failed to receive the ready byte.");
|
ERROR (abstract->context, "Failed to receive the ready byte.");
|
||||||
return status;
|
return status;
|
||||||
@ -439,6 +415,7 @@ hw_ostc3_device_open (dc_device_t **out, dc_context_t *context, dc_iostream_t *i
|
|||||||
{
|
{
|
||||||
dc_status_t status = DC_STATUS_SUCCESS;
|
dc_status_t status = DC_STATUS_SUCCESS;
|
||||||
hw_ostc3_device_t *device = NULL;
|
hw_ostc3_device_t *device = NULL;
|
||||||
|
dc_transport_t transport = dc_iostream_get_transport (iostream);
|
||||||
|
|
||||||
if (out == NULL)
|
if (out == NULL)
|
||||||
return DC_STATUS_INVALIDARGS;
|
return DC_STATUS_INVALIDARGS;
|
||||||
@ -451,29 +428,36 @@ hw_ostc3_device_open (dc_device_t **out, dc_context_t *context, dc_iostream_t *i
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set the default values.
|
// Set the default values.
|
||||||
device->iostream = iostream;
|
|
||||||
device->hardware = INVALID;
|
device->hardware = INVALID;
|
||||||
device->feature = 0;
|
device->feature = 0;
|
||||||
device->model = 0;
|
device->model = 0;
|
||||||
device->serial = 0;
|
device->serial = 0;
|
||||||
device->firmware = 0;
|
device->firmware = 0;
|
||||||
memset (device->fingerprint, 0, sizeof (device->fingerprint));
|
memset (device->fingerprint, 0, sizeof (device->fingerprint));
|
||||||
memset (device->cache, 0, sizeof (device->cache));
|
|
||||||
device->available = 0;
|
// Create the packet stream.
|
||||||
device->offset = 0;
|
if (transport == DC_TRANSPORT_BLE) {
|
||||||
|
status = dc_packet_open (&device->iostream, context, iostream, 244, 244);
|
||||||
|
if (status != DC_STATUS_SUCCESS) {
|
||||||
|
ERROR (context, "Failed to create the packet stream.");
|
||||||
|
goto error_free;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
device->iostream = iostream;
|
||||||
|
}
|
||||||
|
|
||||||
// Set the serial communication protocol (115200 8N1).
|
// Set the serial communication protocol (115200 8N1).
|
||||||
status = dc_iostream_configure (device->iostream, 115200, 8, DC_PARITY_NONE, DC_STOPBITS_ONE, DC_FLOWCONTROL_NONE);
|
status = dc_iostream_configure (device->iostream, 115200, 8, DC_PARITY_NONE, DC_STOPBITS_ONE, DC_FLOWCONTROL_NONE);
|
||||||
if (status != DC_STATUS_SUCCESS) {
|
if (status != DC_STATUS_SUCCESS) {
|
||||||
ERROR (context, "Failed to set the terminal attributes.");
|
ERROR (context, "Failed to set the terminal attributes.");
|
||||||
goto error_free;
|
goto error_free_iostream;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the timeout for receiving data (3000ms).
|
// Set the timeout for receiving data (3000ms).
|
||||||
status = dc_iostream_set_timeout (device->iostream, 3000);
|
status = dc_iostream_set_timeout (device->iostream, 3000);
|
||||||
if (status != DC_STATUS_SUCCESS) {
|
if (status != DC_STATUS_SUCCESS) {
|
||||||
ERROR (context, "Failed to set the timeout.");
|
ERROR (context, "Failed to set the timeout.");
|
||||||
goto error_free;
|
goto error_free_iostream;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure everything is in a sane state.
|
// Make sure everything is in a sane state.
|
||||||
@ -486,6 +470,10 @@ hw_ostc3_device_open (dc_device_t **out, dc_context_t *context, dc_iostream_t *i
|
|||||||
|
|
||||||
return DC_STATUS_SUCCESS;
|
return DC_STATUS_SUCCESS;
|
||||||
|
|
||||||
|
error_free_iostream:
|
||||||
|
if (transport == DC_TRANSPORT_BLE) {
|
||||||
|
dc_iostream_close (device->iostream);
|
||||||
|
}
|
||||||
error_free:
|
error_free:
|
||||||
dc_device_deallocate ((dc_device_t *) device);
|
dc_device_deallocate ((dc_device_t *) device);
|
||||||
return status;
|
return status;
|
||||||
@ -548,14 +536,14 @@ hw_ostc3_device_init_service (hw_ostc3_device_t *device)
|
|||||||
unsigned char answer[5] = {0};
|
unsigned char answer[5] = {0};
|
||||||
|
|
||||||
// Send the command and service key.
|
// Send the command and service key.
|
||||||
status = hw_ostc3_write (device, NULL, command, sizeof (command));
|
status = dc_iostream_write (device->iostream, command, sizeof (command), NULL);
|
||||||
if (status != DC_STATUS_SUCCESS) {
|
if (status != DC_STATUS_SUCCESS) {
|
||||||
ERROR (abstract->context, "Failed to send the command.");
|
ERROR (abstract->context, "Failed to send the command.");
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read the response.
|
// Read the response.
|
||||||
status = hw_ostc3_read (device, NULL, answer, sizeof (answer));
|
status = dc_iostream_read (device->iostream, answer, sizeof (answer), NULL);
|
||||||
if (status != DC_STATUS_SUCCESS) {
|
if (status != DC_STATUS_SUCCESS) {
|
||||||
ERROR (abstract->context, "Failed to receive the answer.");
|
ERROR (abstract->context, "Failed to receive the answer.");
|
||||||
return status;
|
return status;
|
||||||
@ -656,6 +644,15 @@ hw_ostc3_device_close (dc_device_t *abstract)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Close the packet stream.
|
||||||
|
if (dc_iostream_get_transport (device->iostream) == DC_TRANSPORT_BLE) {
|
||||||
|
rc = dc_iostream_close (device->iostream);
|
||||||
|
if (rc != DC_STATUS_SUCCESS) {
|
||||||
|
ERROR (abstract->context, "Failed to close the packet stream.");
|
||||||
|
dc_status_set_error(&status, rc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -29,6 +29,7 @@
|
|||||||
#include "array.h"
|
#include "array.h"
|
||||||
#include "rbstream.h"
|
#include "rbstream.h"
|
||||||
#include "platform.h"
|
#include "platform.h"
|
||||||
|
#include "packet.h"
|
||||||
|
|
||||||
#define ISINSTANCE(device) dc_device_isinstance((device), &mares_iconhd_device_vtable)
|
#define ISINSTANCE(device) dc_device_isinstance((device), &mares_iconhd_device_vtable)
|
||||||
|
|
||||||
@ -93,15 +94,13 @@ typedef struct mares_iconhd_device_t {
|
|||||||
unsigned char version[140];
|
unsigned char version[140];
|
||||||
unsigned int model;
|
unsigned int model;
|
||||||
unsigned int packetsize;
|
unsigned int packetsize;
|
||||||
unsigned char cache[20];
|
|
||||||
unsigned int available;
|
|
||||||
unsigned int offset;
|
|
||||||
} mares_iconhd_device_t;
|
} mares_iconhd_device_t;
|
||||||
|
|
||||||
static dc_status_t mares_iconhd_device_set_fingerprint (dc_device_t *abstract, const unsigned char data[], unsigned int size);
|
static dc_status_t mares_iconhd_device_set_fingerprint (dc_device_t *abstract, const unsigned char data[], unsigned int size);
|
||||||
static dc_status_t mares_iconhd_device_read (dc_device_t *abstract, unsigned int address, unsigned char data[], unsigned int size);
|
static dc_status_t mares_iconhd_device_read (dc_device_t *abstract, unsigned int address, unsigned char data[], unsigned int size);
|
||||||
static dc_status_t mares_iconhd_device_dump (dc_device_t *abstract, dc_buffer_t *buffer);
|
static dc_status_t mares_iconhd_device_dump (dc_device_t *abstract, dc_buffer_t *buffer);
|
||||||
static dc_status_t mares_iconhd_device_foreach (dc_device_t *abstract, dc_dive_callback_t callback, void *userdata);
|
static dc_status_t mares_iconhd_device_foreach (dc_device_t *abstract, dc_dive_callback_t callback, void *userdata);
|
||||||
|
static dc_status_t mares_iconhd_device_close (dc_device_t *abstract);
|
||||||
|
|
||||||
static const dc_device_vtable_t mares_iconhd_device_vtable = {
|
static const dc_device_vtable_t mares_iconhd_device_vtable = {
|
||||||
sizeof(mares_iconhd_device_t),
|
sizeof(mares_iconhd_device_t),
|
||||||
@ -112,7 +111,7 @@ static const dc_device_vtable_t mares_iconhd_device_vtable = {
|
|||||||
mares_iconhd_device_dump, /* dump */
|
mares_iconhd_device_dump, /* dump */
|
||||||
mares_iconhd_device_foreach, /* foreach */
|
mares_iconhd_device_foreach, /* foreach */
|
||||||
NULL, /* timesync */
|
NULL, /* timesync */
|
||||||
NULL /* close */
|
mares_iconhd_device_close /* close */
|
||||||
};
|
};
|
||||||
|
|
||||||
static const mares_iconhd_layout_t mares_iconhd_layout = {
|
static const mares_iconhd_layout_t mares_iconhd_layout = {
|
||||||
@ -177,78 +176,6 @@ mares_iconhd_get_model (mares_iconhd_device_t *device)
|
|||||||
return model;
|
return model;
|
||||||
}
|
}
|
||||||
|
|
||||||
static dc_status_t
|
|
||||||
mares_iconhd_read (mares_iconhd_device_t *device, unsigned char data[], size_t size)
|
|
||||||
{
|
|
||||||
dc_status_t rc = DC_STATUS_SUCCESS;
|
|
||||||
dc_transport_t transport = dc_iostream_get_transport(device->iostream);
|
|
||||||
|
|
||||||
size_t nbytes = 0;
|
|
||||||
while (nbytes < size) {
|
|
||||||
if (transport == DC_TRANSPORT_BLE) {
|
|
||||||
if (device->available == 0) {
|
|
||||||
// Read a packet into the cache.
|
|
||||||
size_t len = 0;
|
|
||||||
rc = dc_iostream_read (device->iostream, device->cache, sizeof(device->cache), &len);
|
|
||||||
if (rc != DC_STATUS_SUCCESS)
|
|
||||||
return rc;
|
|
||||||
|
|
||||||
device->available = len;
|
|
||||||
device->offset = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the minimum packet size.
|
|
||||||
size_t length = (transport == DC_TRANSPORT_BLE) ? device->available : size - nbytes;
|
|
||||||
|
|
||||||
// Limit the packet size to the total size.
|
|
||||||
if (nbytes + length > size)
|
|
||||||
length = size - nbytes;
|
|
||||||
|
|
||||||
if (transport == DC_TRANSPORT_BLE) {
|
|
||||||
// Copy the data from the cached packet.
|
|
||||||
memcpy (data + nbytes, device->cache + device->offset, length);
|
|
||||||
device->available -= length;
|
|
||||||
device->offset += length;
|
|
||||||
} else {
|
|
||||||
// Read the packet.
|
|
||||||
rc = dc_iostream_read (device->iostream, data + nbytes, length, &length);
|
|
||||||
if (rc != DC_STATUS_SUCCESS)
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
nbytes += length;
|
|
||||||
}
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
static dc_status_t
|
|
||||||
mares_iconhd_write (mares_iconhd_device_t *device, const unsigned char data[], size_t size)
|
|
||||||
{
|
|
||||||
dc_status_t rc = DC_STATUS_SUCCESS;
|
|
||||||
dc_transport_t transport = dc_iostream_get_transport(device->iostream);
|
|
||||||
|
|
||||||
size_t nbytes = 0;
|
|
||||||
while (nbytes < size) {
|
|
||||||
// Set the maximum packet size.
|
|
||||||
size_t length = (transport == DC_TRANSPORT_BLE) ? sizeof(device->cache) : size - nbytes;
|
|
||||||
|
|
||||||
// Limit the packet size to the total size.
|
|
||||||
if (nbytes + length > size)
|
|
||||||
length = size - nbytes;
|
|
||||||
|
|
||||||
// Write the packet.
|
|
||||||
rc = dc_iostream_write (device->iostream, data + nbytes, length, &length);
|
|
||||||
if (rc != DC_STATUS_SUCCESS)
|
|
||||||
return rc;
|
|
||||||
|
|
||||||
nbytes += length;
|
|
||||||
}
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
static dc_status_t
|
static dc_status_t
|
||||||
mares_iconhd_packet (mares_iconhd_device_t *device,
|
mares_iconhd_packet (mares_iconhd_device_t *device,
|
||||||
const unsigned char command[], unsigned int csize,
|
const unsigned char command[], unsigned int csize,
|
||||||
@ -263,7 +190,7 @@ mares_iconhd_packet (mares_iconhd_device_t *device,
|
|||||||
return DC_STATUS_CANCELLED;
|
return DC_STATUS_CANCELLED;
|
||||||
|
|
||||||
// Send the command header to the dive computer.
|
// Send the command header to the dive computer.
|
||||||
status = mares_iconhd_write (device, command, 2);
|
status = dc_iostream_write (device->iostream, command, 2, NULL);
|
||||||
if (status != DC_STATUS_SUCCESS) {
|
if (status != DC_STATUS_SUCCESS) {
|
||||||
ERROR (abstract->context, "Failed to send the command.");
|
ERROR (abstract->context, "Failed to send the command.");
|
||||||
return status;
|
return status;
|
||||||
@ -271,7 +198,7 @@ mares_iconhd_packet (mares_iconhd_device_t *device,
|
|||||||
|
|
||||||
// Receive the header byte.
|
// Receive the header byte.
|
||||||
unsigned char header[1] = {0};
|
unsigned char header[1] = {0};
|
||||||
status = mares_iconhd_read (device, header, sizeof (header));
|
status = dc_iostream_read (device->iostream, header, sizeof (header), NULL);
|
||||||
if (status != DC_STATUS_SUCCESS) {
|
if (status != DC_STATUS_SUCCESS) {
|
||||||
ERROR (abstract->context, "Failed to receive the answer.");
|
ERROR (abstract->context, "Failed to receive the answer.");
|
||||||
return status;
|
return status;
|
||||||
@ -285,7 +212,7 @@ mares_iconhd_packet (mares_iconhd_device_t *device,
|
|||||||
|
|
||||||
// Send the command payload to the dive computer.
|
// Send the command payload to the dive computer.
|
||||||
if (csize > 2) {
|
if (csize > 2) {
|
||||||
status = mares_iconhd_write (device, command + 2, csize - 2);
|
status = dc_iostream_write (device->iostream, command + 2, csize - 2, NULL);
|
||||||
if (status != DC_STATUS_SUCCESS) {
|
if (status != DC_STATUS_SUCCESS) {
|
||||||
ERROR (abstract->context, "Failed to send the command.");
|
ERROR (abstract->context, "Failed to send the command.");
|
||||||
return status;
|
return status;
|
||||||
@ -293,7 +220,7 @@ mares_iconhd_packet (mares_iconhd_device_t *device,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Read the packet.
|
// Read the packet.
|
||||||
status = mares_iconhd_read (device, answer, asize);
|
status = dc_iostream_read (device->iostream, answer, asize, NULL);
|
||||||
if (status != DC_STATUS_SUCCESS) {
|
if (status != DC_STATUS_SUCCESS) {
|
||||||
ERROR (abstract->context, "Failed to receive the answer.");
|
ERROR (abstract->context, "Failed to receive the answer.");
|
||||||
return status;
|
return status;
|
||||||
@ -301,7 +228,7 @@ mares_iconhd_packet (mares_iconhd_device_t *device,
|
|||||||
|
|
||||||
// Receive the trailer byte.
|
// Receive the trailer byte.
|
||||||
unsigned char trailer[1] = {0};
|
unsigned char trailer[1] = {0};
|
||||||
status = mares_iconhd_read (device, trailer, sizeof (trailer));
|
status = dc_iostream_read (device->iostream, trailer, sizeof (trailer), NULL);
|
||||||
if (status != DC_STATUS_SUCCESS) {
|
if (status != DC_STATUS_SUCCESS) {
|
||||||
ERROR (abstract->context, "Failed to receive the answer.");
|
ERROR (abstract->context, "Failed to receive the answer.");
|
||||||
return status;
|
return status;
|
||||||
@ -334,8 +261,6 @@ mares_iconhd_transfer (mares_iconhd_device_t *device, const unsigned char comman
|
|||||||
// Discard any garbage bytes.
|
// Discard any garbage bytes.
|
||||||
dc_iostream_sleep (device->iostream, 100);
|
dc_iostream_sleep (device->iostream, 100);
|
||||||
dc_iostream_purge (device->iostream, DC_DIRECTION_INPUT);
|
dc_iostream_purge (device->iostream, DC_DIRECTION_INPUT);
|
||||||
device->available = 0;
|
|
||||||
device->offset = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return DC_STATUS_SUCCESS;
|
return DC_STATUS_SUCCESS;
|
||||||
@ -459,6 +384,7 @@ mares_iconhd_device_open (dc_device_t **out, dc_context_t *context, dc_iostream_
|
|||||||
{
|
{
|
||||||
dc_status_t status = DC_STATUS_SUCCESS;
|
dc_status_t status = DC_STATUS_SUCCESS;
|
||||||
mares_iconhd_device_t *device = NULL;
|
mares_iconhd_device_t *device = NULL;
|
||||||
|
dc_transport_t transport = dc_iostream_get_transport (iostream);
|
||||||
|
|
||||||
if (out == NULL)
|
if (out == NULL)
|
||||||
return DC_STATUS_INVALIDARGS;
|
return DC_STATUS_INVALIDARGS;
|
||||||
@ -471,43 +397,50 @@ mares_iconhd_device_open (dc_device_t **out, dc_context_t *context, dc_iostream_
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set the default values.
|
// Set the default values.
|
||||||
device->iostream = iostream;
|
|
||||||
device->layout = NULL;
|
device->layout = NULL;
|
||||||
memset (device->fingerprint, 0, sizeof (device->fingerprint));
|
memset (device->fingerprint, 0, sizeof (device->fingerprint));
|
||||||
device->fingerprint_size = sizeof (device->fingerprint);
|
device->fingerprint_size = sizeof (device->fingerprint);
|
||||||
memset (device->version, 0, sizeof (device->version));
|
memset (device->version, 0, sizeof (device->version));
|
||||||
device->model = 0;
|
device->model = 0;
|
||||||
device->packetsize = 0;
|
device->packetsize = 0;
|
||||||
memset (device->cache, 0, sizeof (device->cache));
|
|
||||||
device->available = 0;
|
// Create the packet stream.
|
||||||
device->offset = 0;
|
if (transport == DC_TRANSPORT_BLE) {
|
||||||
|
status = dc_packet_open (&device->iostream, context, iostream, 20, 20);
|
||||||
|
if (status != DC_STATUS_SUCCESS) {
|
||||||
|
ERROR (context, "Failed to create the packet stream.");
|
||||||
|
goto error_free;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
device->iostream = iostream;
|
||||||
|
}
|
||||||
|
|
||||||
// Set the serial communication protocol (115200 8E1).
|
// Set the serial communication protocol (115200 8E1).
|
||||||
status = dc_iostream_configure (device->iostream, 115200, 8, DC_PARITY_EVEN, DC_STOPBITS_ONE, DC_FLOWCONTROL_NONE);
|
status = dc_iostream_configure (device->iostream, 115200, 8, DC_PARITY_EVEN, DC_STOPBITS_ONE, DC_FLOWCONTROL_NONE);
|
||||||
if (status != DC_STATUS_SUCCESS) {
|
if (status != DC_STATUS_SUCCESS) {
|
||||||
ERROR (context, "Failed to set the terminal attributes.");
|
ERROR (context, "Failed to set the terminal attributes.");
|
||||||
goto error_free;
|
goto error_free_iostream;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the timeout for receiving data (3000 ms).
|
// Set the timeout for receiving data (3000 ms).
|
||||||
status = dc_iostream_set_timeout (device->iostream, 3000);
|
status = dc_iostream_set_timeout (device->iostream, 3000);
|
||||||
if (status != DC_STATUS_SUCCESS) {
|
if (status != DC_STATUS_SUCCESS) {
|
||||||
ERROR (context, "Failed to set the timeout.");
|
ERROR (context, "Failed to set the timeout.");
|
||||||
goto error_free;
|
goto error_free_iostream;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear the DTR line.
|
// Clear the DTR line.
|
||||||
status = dc_iostream_set_dtr (device->iostream, 0);
|
status = dc_iostream_set_dtr (device->iostream, 0);
|
||||||
if (status != DC_STATUS_SUCCESS) {
|
if (status != DC_STATUS_SUCCESS) {
|
||||||
ERROR (context, "Failed to clear the DTR line.");
|
ERROR (context, "Failed to clear the DTR line.");
|
||||||
goto error_free;
|
goto error_free_iostream;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear the RTS line.
|
// Clear the RTS line.
|
||||||
status = dc_iostream_set_rts (device->iostream, 0);
|
status = dc_iostream_set_rts (device->iostream, 0);
|
||||||
if (status != DC_STATUS_SUCCESS) {
|
if (status != DC_STATUS_SUCCESS) {
|
||||||
ERROR (context, "Failed to clear the RTS line.");
|
ERROR (context, "Failed to clear the RTS line.");
|
||||||
goto error_free;
|
goto error_free_iostream;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure everything is in a sane state.
|
// Make sure everything is in a sane state.
|
||||||
@ -518,7 +451,7 @@ mares_iconhd_device_open (dc_device_t **out, dc_context_t *context, dc_iostream_
|
|||||||
status = mares_iconhd_transfer (device, command, sizeof (command),
|
status = mares_iconhd_transfer (device, command, sizeof (command),
|
||||||
device->version, sizeof (device->version));
|
device->version, sizeof (device->version));
|
||||||
if (status != DC_STATUS_SUCCESS) {
|
if (status != DC_STATUS_SUCCESS) {
|
||||||
goto error_free;
|
goto error_free_iostream;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Autodetect the model using the version packet.
|
// Autodetect the model using the version packet.
|
||||||
@ -586,12 +519,31 @@ mares_iconhd_device_open (dc_device_t **out, dc_context_t *context, dc_iostream_
|
|||||||
|
|
||||||
return DC_STATUS_SUCCESS;
|
return DC_STATUS_SUCCESS;
|
||||||
|
|
||||||
|
|
||||||
|
error_free_iostream:
|
||||||
|
if (transport == DC_TRANSPORT_BLE) {
|
||||||
|
dc_iostream_close (device->iostream);
|
||||||
|
}
|
||||||
error_free:
|
error_free:
|
||||||
dc_device_deallocate ((dc_device_t *) device);
|
dc_device_deallocate ((dc_device_t *) device);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static dc_status_t
|
||||||
|
mares_iconhd_device_close (dc_device_t *abstract)
|
||||||
|
{
|
||||||
|
mares_iconhd_device_t *device = (mares_iconhd_device_t *) abstract;
|
||||||
|
|
||||||
|
// Close the packet stream.
|
||||||
|
if (dc_iostream_get_transport (device->iostream) == DC_TRANSPORT_BLE) {
|
||||||
|
return dc_iostream_close (device->iostream);
|
||||||
|
}
|
||||||
|
|
||||||
|
return DC_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static dc_status_t
|
static dc_status_t
|
||||||
mares_iconhd_device_set_fingerprint (dc_device_t *abstract, const unsigned char data[], unsigned int size)
|
mares_iconhd_device_set_fingerprint (dc_device_t *abstract, const unsigned char data[], unsigned int size)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -26,6 +26,7 @@
|
|||||||
#include "context-private.h"
|
#include "context-private.h"
|
||||||
#include "device-private.h"
|
#include "device-private.h"
|
||||||
#include "array.h"
|
#include "array.h"
|
||||||
|
#include "packet.h"
|
||||||
|
|
||||||
#define ISINSTANCE(device) dc_device_isinstance((device), &mclean_extreme_device_vtable)
|
#define ISINSTANCE(device) dc_device_isinstance((device), &mclean_extreme_device_vtable)
|
||||||
|
|
||||||
@ -391,6 +392,7 @@ mclean_extreme_device_open(dc_device_t **out, dc_context_t *context, dc_iostream
|
|||||||
{
|
{
|
||||||
dc_status_t status = DC_STATUS_SUCCESS;
|
dc_status_t status = DC_STATUS_SUCCESS;
|
||||||
mclean_extreme_device_t *device = NULL;
|
mclean_extreme_device_t *device = NULL;
|
||||||
|
dc_transport_t transport = dc_iostream_get_transport (iostream);
|
||||||
|
|
||||||
if (out == NULL)
|
if (out == NULL)
|
||||||
return DC_STATUS_INVALIDARGS;
|
return DC_STATUS_INVALIDARGS;
|
||||||
@ -403,21 +405,31 @@ mclean_extreme_device_open(dc_device_t **out, dc_context_t *context, dc_iostream
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set the default values.
|
// Set the default values.
|
||||||
device->iostream = iostream;
|
|
||||||
memset(device->fingerprint, 0, sizeof(device->fingerprint));
|
memset(device->fingerprint, 0, sizeof(device->fingerprint));
|
||||||
|
|
||||||
|
// Create the packet stream.
|
||||||
|
if (transport == DC_TRANSPORT_BLE) {
|
||||||
|
status = dc_packet_open (&device->iostream, context, iostream, 244, 244);
|
||||||
|
if (status != DC_STATUS_SUCCESS) {
|
||||||
|
ERROR (context, "Failed to create the packet stream.");
|
||||||
|
goto error_free;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
device->iostream = iostream;
|
||||||
|
}
|
||||||
|
|
||||||
// Set the serial communication protocol (115200 8N1).
|
// Set the serial communication protocol (115200 8N1).
|
||||||
status = dc_iostream_configure(device->iostream, 115200, 8, DC_PARITY_NONE, DC_STOPBITS_ONE, DC_FLOWCONTROL_NONE);
|
status = dc_iostream_configure(device->iostream, 115200, 8, DC_PARITY_NONE, DC_STOPBITS_ONE, DC_FLOWCONTROL_NONE);
|
||||||
if (status != DC_STATUS_SUCCESS) {
|
if (status != DC_STATUS_SUCCESS) {
|
||||||
ERROR(context, "Failed to set the terminal attributes.");
|
ERROR(context, "Failed to set the terminal attributes.");
|
||||||
goto error_free;
|
goto error_free_iostream;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the timeout for receiving data (1000ms).
|
// Set the timeout for receiving data (1000ms).
|
||||||
status = dc_iostream_set_timeout(device->iostream, 1000);
|
status = dc_iostream_set_timeout(device->iostream, 1000);
|
||||||
if (status != DC_STATUS_SUCCESS) {
|
if (status != DC_STATUS_SUCCESS) {
|
||||||
ERROR(context, "Failed to set the timeout.");
|
ERROR(context, "Failed to set the timeout.");
|
||||||
goto error_free;
|
goto error_free_iostream;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure everything is in a sane state.
|
// Make sure everything is in a sane state.
|
||||||
@ -428,6 +440,10 @@ mclean_extreme_device_open(dc_device_t **out, dc_context_t *context, dc_iostream
|
|||||||
|
|
||||||
return DC_STATUS_SUCCESS;
|
return DC_STATUS_SUCCESS;
|
||||||
|
|
||||||
|
error_free_iostream:
|
||||||
|
if (transport == DC_TRANSPORT_BLE) {
|
||||||
|
dc_iostream_close (device->iostream);
|
||||||
|
}
|
||||||
error_free:
|
error_free:
|
||||||
dc_device_deallocate((dc_device_t *)device);
|
dc_device_deallocate((dc_device_t *)device);
|
||||||
return status;
|
return status;
|
||||||
@ -438,14 +454,24 @@ mclean_extreme_device_close(dc_device_t *abstract)
|
|||||||
{
|
{
|
||||||
dc_status_t status = DC_STATUS_SUCCESS;
|
dc_status_t status = DC_STATUS_SUCCESS;
|
||||||
mclean_extreme_device_t *device = (mclean_extreme_device_t *)abstract;
|
mclean_extreme_device_t *device = (mclean_extreme_device_t *)abstract;
|
||||||
|
dc_status_t rc = DC_STATUS_SUCCESS;
|
||||||
|
|
||||||
status = mclean_extreme_send(device, CMD_CLOSE, NULL, 0);
|
rc = mclean_extreme_send(device, CMD_CLOSE, NULL, 0);
|
||||||
if (status != DC_STATUS_SUCCESS) {
|
if (rc != DC_STATUS_SUCCESS) {
|
||||||
ERROR(abstract->context, "Failed to send the exit command.");
|
ERROR(abstract->context, "Failed to send the exit command.");
|
||||||
return status;
|
dc_status_set_error(&status, rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
return DC_STATUS_SUCCESS;
|
// Close the packet stream.
|
||||||
|
if (dc_iostream_get_transport (device->iostream) == DC_TRANSPORT_BLE) {
|
||||||
|
rc = dc_iostream_close (device->iostream);
|
||||||
|
if (rc != DC_STATUS_SUCCESS) {
|
||||||
|
ERROR (abstract->context, "Failed to close the packet stream.");
|
||||||
|
dc_status_set_error(&status, rc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
static dc_status_t
|
static dc_status_t
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user