Improve the ACK/NAK error recovery to fix more errors.
This commit is contained in:
parent
3d1a29e912
commit
b9f7d4e425
@ -86,44 +86,26 @@ device_is_oceanic_atom2 (device_t *abstract)
|
|||||||
|
|
||||||
|
|
||||||
static device_status_t
|
static device_status_t
|
||||||
oceanic_atom2_transfer (oceanic_atom2_device_t *device, const unsigned char command[], unsigned int csize, unsigned char answer[], unsigned int asize)
|
oceanic_atom2_send (oceanic_atom2_device_t *device, const unsigned char command[], unsigned int csize)
|
||||||
{
|
{
|
||||||
device_t *abstract = (device_t *) device;
|
device_t *abstract = (device_t *) device;
|
||||||
|
|
||||||
// Send the command to the device. If the device responds with an
|
if (device_is_cancelled (abstract))
|
||||||
// ACK byte, the command was received successfully and the answer
|
return DEVICE_STATUS_CANCELLED;
|
||||||
// (if any) follows after the ACK byte. If the device responds with
|
|
||||||
// a NAK byte, we try to resend the command a number of times before
|
|
||||||
// returning an error.
|
|
||||||
|
|
||||||
unsigned int nretries = 0;
|
// Send the command to the dive computer.
|
||||||
|
int n = serial_write (device->port, command, csize);
|
||||||
|
if (n != csize) {
|
||||||
|
WARNING ("Failed to send the command.");
|
||||||
|
return EXITCODE (n);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Receive the response (ACK/NAK) of the dive computer.
|
||||||
unsigned char response = NAK;
|
unsigned char response = NAK;
|
||||||
while (response == NAK) {
|
n = serial_read (device->port, &response, 1);
|
||||||
if (device_is_cancelled (abstract))
|
if (n != 1) {
|
||||||
return DEVICE_STATUS_CANCELLED;
|
WARNING ("Failed to receive the answer.");
|
||||||
|
return EXITCODE (n);
|
||||||
// Send the command to the dive computer.
|
|
||||||
int n = serial_write (device->port, command, csize);
|
|
||||||
if (n != csize) {
|
|
||||||
WARNING ("Failed to send the command.");
|
|
||||||
return EXITCODE (n);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Receive the response (ACK/NAK) of the dive computer.
|
|
||||||
n = serial_read (device->port, &response, 1);
|
|
||||||
if (n != 1) {
|
|
||||||
WARNING ("Failed to receive the answer.");
|
|
||||||
return EXITCODE (n);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef NDEBUG
|
|
||||||
if (response != ACK)
|
|
||||||
message ("Received unexpected response (%02x).\n", response);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Abort if the maximum number of retries is reached.
|
|
||||||
if (nretries++ >= MAXRETRIES)
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify the response of the dive computer.
|
// Verify the response of the dive computer.
|
||||||
@ -132,12 +114,36 @@ oceanic_atom2_transfer (oceanic_atom2_device_t *device, const unsigned char comm
|
|||||||
return DEVICE_STATUS_PROTOCOL;
|
return DEVICE_STATUS_PROTOCOL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return DEVICE_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static device_status_t
|
||||||
|
oceanic_atom2_transfer (oceanic_atom2_device_t *device, const unsigned char command[], unsigned int csize, unsigned char answer[], unsigned int asize)
|
||||||
|
{
|
||||||
|
// Send the command to the device. If the device responds with an
|
||||||
|
// ACK byte, the command was received successfully and the answer
|
||||||
|
// (if any) follows after the ACK byte. If the device responds with
|
||||||
|
// a NAK byte, we try to resend the command a number of times before
|
||||||
|
// returning an error.
|
||||||
|
|
||||||
|
unsigned int nretries = 0;
|
||||||
|
device_status_t rc = DEVICE_STATUS_SUCCESS;
|
||||||
|
while ((rc = oceanic_atom2_send (device, command, csize)) != DEVICE_STATUS_SUCCESS) {
|
||||||
|
if (rc != DEVICE_STATUS_TIMEOUT && rc != DEVICE_STATUS_PROTOCOL)
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
// Abort if the maximum number of retries is reached.
|
||||||
|
if (nretries++ >= MAXRETRIES)
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
if (asize) {
|
if (asize) {
|
||||||
// Receive the answer of the dive computer.
|
// Receive the answer of the dive computer.
|
||||||
int rc = serial_read (device->port, answer, asize);
|
int n = serial_read (device->port, answer, asize);
|
||||||
if (rc != asize) {
|
if (n != asize) {
|
||||||
WARNING ("Failed to receive the answer.");
|
WARNING ("Failed to receive the answer.");
|
||||||
return EXITCODE (rc);
|
return EXITCODE (n);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify the checksum of the answer.
|
// Verify the checksum of the answer.
|
||||||
|
|||||||
@ -87,10 +87,44 @@ device_is_oceanic_veo250 (device_t *abstract)
|
|||||||
|
|
||||||
|
|
||||||
static device_status_t
|
static device_status_t
|
||||||
oceanic_veo250_transfer (oceanic_veo250_device_t *device, const unsigned char command[], unsigned int csize, unsigned char answer[], unsigned int asize)
|
oceanic_veo250_send (oceanic_veo250_device_t *device, const unsigned char command[], unsigned int csize)
|
||||||
{
|
{
|
||||||
device_t *abstract = (device_t *) device;
|
device_t *abstract = (device_t *) device;
|
||||||
|
|
||||||
|
if (device_is_cancelled (abstract))
|
||||||
|
return DEVICE_STATUS_CANCELLED;
|
||||||
|
|
||||||
|
// Discard garbage bytes.
|
||||||
|
serial_flush (device->port, SERIAL_QUEUE_INPUT);
|
||||||
|
|
||||||
|
// Send the command to the dive computer.
|
||||||
|
int n = serial_write (device->port, command, csize);
|
||||||
|
if (n != csize) {
|
||||||
|
WARNING ("Failed to send the command.");
|
||||||
|
return EXITCODE (n);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Receive the response (ACK/NAK) of the dive computer.
|
||||||
|
unsigned char response = NAK;
|
||||||
|
n = serial_read (device->port, &response, 1);
|
||||||
|
if (n != 1) {
|
||||||
|
WARNING ("Failed to receive the answer.");
|
||||||
|
return EXITCODE (n);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify the response of the dive computer.
|
||||||
|
if (response != ACK) {
|
||||||
|
WARNING ("Unexpected answer start byte(s).");
|
||||||
|
return DEVICE_STATUS_PROTOCOL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return DEVICE_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static device_status_t
|
||||||
|
oceanic_veo250_transfer (oceanic_veo250_device_t *device, const unsigned char command[], unsigned int csize, unsigned char answer[], unsigned int asize)
|
||||||
|
{
|
||||||
// Send the command to the device. If the device responds with an
|
// Send the command to the device. If the device responds with an
|
||||||
// ACK byte, the command was received successfully and the answer
|
// ACK byte, the command was received successfully and the answer
|
||||||
// (if any) follows after the ACK byte. If the device responds with
|
// (if any) follows after the ACK byte. If the device responds with
|
||||||
@ -98,42 +132,14 @@ oceanic_veo250_transfer (oceanic_veo250_device_t *device, const unsigned char co
|
|||||||
// returning an error.
|
// returning an error.
|
||||||
|
|
||||||
unsigned int nretries = 0;
|
unsigned int nretries = 0;
|
||||||
unsigned char response = NAK;
|
device_status_t rc = DEVICE_STATUS_SUCCESS;
|
||||||
while (response == NAK) {
|
while ((rc = oceanic_veo250_send (device, command, csize)) != DEVICE_STATUS_SUCCESS) {
|
||||||
if (device_is_cancelled (abstract))
|
if (rc != DEVICE_STATUS_TIMEOUT && rc != DEVICE_STATUS_PROTOCOL)
|
||||||
return DEVICE_STATUS_CANCELLED;
|
return rc;
|
||||||
|
|
||||||
// Discard garbage bytes.
|
|
||||||
serial_flush (device->port, SERIAL_QUEUE_INPUT);
|
|
||||||
|
|
||||||
// Send the command to the dive computer.
|
|
||||||
int n = serial_write (device->port, command, csize);
|
|
||||||
if (n != csize) {
|
|
||||||
WARNING ("Failed to send the command.");
|
|
||||||
return EXITCODE (n);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Receive the response (ACK/NAK) of the dive computer.
|
|
||||||
n = serial_read (device->port, &response, 1);
|
|
||||||
if (n != 1) {
|
|
||||||
WARNING ("Failed to receive the answer.");
|
|
||||||
return EXITCODE (n);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef NDEBUG
|
|
||||||
if (response != ACK)
|
|
||||||
message ("Received unexpected response (%02x).\n", response);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Abort if the maximum number of retries is reached.
|
// Abort if the maximum number of retries is reached.
|
||||||
if (nretries++ >= MAXRETRIES)
|
if (nretries++ >= MAXRETRIES)
|
||||||
break;
|
return rc;
|
||||||
}
|
|
||||||
|
|
||||||
// Verify the response of the dive computer.
|
|
||||||
if (response != ACK) {
|
|
||||||
WARNING ("Unexpected answer start byte(s).");
|
|
||||||
return DEVICE_STATUS_PROTOCOL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Receive the answer of the dive computer.
|
// Receive the answer of the dive computer.
|
||||||
|
|||||||
@ -100,10 +100,41 @@ device_is_oceanic_vtpro (device_t *abstract)
|
|||||||
|
|
||||||
|
|
||||||
static device_status_t
|
static device_status_t
|
||||||
oceanic_vtpro_transfer (oceanic_vtpro_device_t *device, const unsigned char command[], unsigned int csize, unsigned char answer[], unsigned int asize)
|
oceanic_vtpro_send (oceanic_vtpro_device_t *device, const unsigned char command[], unsigned int csize)
|
||||||
{
|
{
|
||||||
device_t *abstract = (device_t *) device;
|
device_t *abstract = (device_t *) device;
|
||||||
|
|
||||||
|
if (device_is_cancelled (abstract))
|
||||||
|
return DEVICE_STATUS_CANCELLED;
|
||||||
|
|
||||||
|
// Send the command to the dive computer.
|
||||||
|
int n = serial_write (device->port, command, csize);
|
||||||
|
if (n != csize) {
|
||||||
|
WARNING ("Failed to send the command.");
|
||||||
|
return EXITCODE (n);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Receive the response (ACK/NAK) of the dive computer.
|
||||||
|
unsigned char response = NAK;
|
||||||
|
n = serial_read (device->port, &response, 1);
|
||||||
|
if (n != 1) {
|
||||||
|
WARNING ("Failed to receive the answer.");
|
||||||
|
return EXITCODE (n);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify the response of the dive computer.
|
||||||
|
if (response != ACK) {
|
||||||
|
WARNING ("Unexpected answer start byte(s).");
|
||||||
|
return DEVICE_STATUS_PROTOCOL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return DEVICE_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static device_status_t
|
||||||
|
oceanic_vtpro_transfer (oceanic_vtpro_device_t *device, const unsigned char command[], unsigned int csize, unsigned char answer[], unsigned int asize)
|
||||||
|
{
|
||||||
// Send the command to the device. If the device responds with an
|
// Send the command to the device. If the device responds with an
|
||||||
// ACK byte, the command was received successfully and the answer
|
// ACK byte, the command was received successfully and the answer
|
||||||
// (if any) follows after the ACK byte. If the device responds with
|
// (if any) follows after the ACK byte. If the device responds with
|
||||||
@ -111,39 +142,14 @@ oceanic_vtpro_transfer (oceanic_vtpro_device_t *device, const unsigned char comm
|
|||||||
// returning an error.
|
// returning an error.
|
||||||
|
|
||||||
unsigned int nretries = 0;
|
unsigned int nretries = 0;
|
||||||
unsigned char response = NAK;
|
device_status_t rc = DEVICE_STATUS_SUCCESS;
|
||||||
while (response == NAK) {
|
while ((rc = oceanic_vtpro_send (device, command, csize)) != DEVICE_STATUS_SUCCESS) {
|
||||||
if (device_is_cancelled (abstract))
|
if (rc != DEVICE_STATUS_TIMEOUT && rc != DEVICE_STATUS_PROTOCOL)
|
||||||
return DEVICE_STATUS_CANCELLED;
|
return rc;
|
||||||
|
|
||||||
// Send the command to the dive computer.
|
|
||||||
int n = serial_write (device->port, command, csize);
|
|
||||||
if (n != csize) {
|
|
||||||
WARNING ("Failed to send the command.");
|
|
||||||
return EXITCODE (n);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Receive the response (ACK/NAK) of the dive computer.
|
|
||||||
n = serial_read (device->port, &response, 1);
|
|
||||||
if (n != 1) {
|
|
||||||
WARNING ("Failed to receive the answer.");
|
|
||||||
return EXITCODE (n);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef NDEBUG
|
|
||||||
if (response != ACK)
|
|
||||||
message ("Received unexpected response (%02x).\n", response);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Abort if the maximum number of retries is reached.
|
// Abort if the maximum number of retries is reached.
|
||||||
if (nretries++ >= MAXRETRIES)
|
if (nretries++ >= MAXRETRIES)
|
||||||
break;
|
return rc;
|
||||||
}
|
|
||||||
|
|
||||||
// Verify the response of the dive computer.
|
|
||||||
if (response != ACK) {
|
|
||||||
WARNING ("Unexpected answer start byte(s).");
|
|
||||||
return DEVICE_STATUS_PROTOCOL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Receive the answer of the dive computer.
|
// Receive the answer of the dive computer.
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user