Resend the command after timeouts and protocol errors.
This commit is contained in:
parent
39f3a5b757
commit
20cdb4b188
@ -41,6 +41,11 @@
|
|||||||
message ("%s:%d: %s\n", __FILE__, __LINE__, expr); \
|
message ("%s:%d: %s\n", __FILE__, __LINE__, expr); \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define EXITCODE(rc) \
|
||||||
|
( \
|
||||||
|
rc == -1 ? DEVICE_STATUS_IO : DEVICE_STATUS_TIMEOUT \
|
||||||
|
)
|
||||||
|
|
||||||
#define MINIMUM 8
|
#define MINIMUM 8
|
||||||
|
|
||||||
#define RB_PROFILE_BEGIN 0x019A
|
#define RB_PROFILE_BEGIN 0x019A
|
||||||
@ -189,12 +194,10 @@ suunto_d9_send (suunto_d9_device_t *device, const unsigned char command[], unsig
|
|||||||
// Receive the echo.
|
// Receive the echo.
|
||||||
unsigned char echo[128] = {0};
|
unsigned char echo[128] = {0};
|
||||||
assert (sizeof (echo) >= csize);
|
assert (sizeof (echo) >= csize);
|
||||||
int rc = serial_read (device->port, echo, csize);
|
int n = serial_read (device->port, echo, csize);
|
||||||
if (rc != csize) {
|
if (n != csize) {
|
||||||
WARNING ("Failed to receive the echo.");
|
WARNING ("Failed to receive the echo.");
|
||||||
if (rc == -1)
|
return EXITCODE (n);
|
||||||
return DEVICE_STATUS_IO;
|
|
||||||
return DEVICE_STATUS_TIMEOUT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify the echo.
|
// Verify the echo.
|
||||||
@ -210,6 +213,43 @@ suunto_d9_send (suunto_d9_device_t *device, const unsigned char command[], unsig
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static device_status_t
|
||||||
|
suunto_d9_packet (suunto_d9_device_t *device, const unsigned char command[], unsigned int csize, unsigned char answer[], unsigned int asize, unsigned int size)
|
||||||
|
{
|
||||||
|
// Send the command to the dive computer.
|
||||||
|
device_status_t rc = suunto_d9_send (device, command, csize);
|
||||||
|
if (rc != DEVICE_STATUS_SUCCESS) {
|
||||||
|
WARNING ("Failed to send the command.");
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Receive the answer of the dive computer.
|
||||||
|
int n = serial_read (device->port, answer, asize);
|
||||||
|
if (n != asize) {
|
||||||
|
WARNING ("Failed to receive the answer.");
|
||||||
|
return EXITCODE (n);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify the header of the package.
|
||||||
|
answer[2] -= size; // Adjust the package size for the comparision.
|
||||||
|
if (memcmp (command, answer, asize - size - 1) != 0) {
|
||||||
|
WARNING ("Unexpected answer start byte(s).");
|
||||||
|
return DEVICE_STATUS_PROTOCOL;
|
||||||
|
}
|
||||||
|
answer[2] += size; // Restore the package size again.
|
||||||
|
|
||||||
|
// Verify the checksum of the package.
|
||||||
|
unsigned char crc = answer[asize - 1];
|
||||||
|
unsigned char ccrc = checksum_xor_uint8 (answer, asize - 1, 0x00);
|
||||||
|
if (crc != ccrc) {
|
||||||
|
WARNING ("Unexpected answer CRC.");
|
||||||
|
return DEVICE_STATUS_PROTOCOL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return DEVICE_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static device_status_t
|
static device_status_t
|
||||||
suunto_d9_transfer (suunto_d9_device_t *device, const unsigned char command[], unsigned int csize, unsigned char answer[], unsigned int asize, unsigned int size)
|
suunto_d9_transfer (suunto_d9_device_t *device, const unsigned char command[], unsigned int csize, unsigned char answer[], unsigned int asize, unsigned int size)
|
||||||
{
|
{
|
||||||
@ -220,43 +260,20 @@ suunto_d9_transfer (suunto_d9_device_t *device, const unsigned char command[], u
|
|||||||
// returning an error. Usually the dive computer will respond
|
// returning an error. Usually the dive computer will respond
|
||||||
// again during one of the retries.
|
// again during one of the retries.
|
||||||
|
|
||||||
for (unsigned int i = 0;; ++i) {
|
unsigned int nretries = 0;
|
||||||
// Send the command to the dive computer.
|
device_status_t rc = DEVICE_STATUS_SUCCESS;
|
||||||
device_status_t rc = suunto_d9_send (device, command, csize);
|
while ((rc = suunto_d9_packet (device, command, csize, answer, asize, size)) != DEVICE_STATUS_SUCCESS) {
|
||||||
if (rc != DEVICE_STATUS_SUCCESS) {
|
// Automatically discard a corrupted packet,
|
||||||
WARNING ("Failed to send the command.");
|
// and request a new one.
|
||||||
|
if (rc != DEVICE_STATUS_TIMEOUT && rc != DEVICE_STATUS_PROTOCOL)
|
||||||
return rc;
|
return rc;
|
||||||
}
|
|
||||||
|
|
||||||
// Receive the answer of the dive computer.
|
// Abort if the maximum number of retries is reached.
|
||||||
int n = serial_read (device->port, answer, asize);
|
if (nretries++ >= MAXRETRIES)
|
||||||
if (n != asize) {
|
return rc;
|
||||||
WARNING ("Failed to receive the answer.");
|
|
||||||
if (n == -1)
|
|
||||||
return DEVICE_STATUS_IO;
|
|
||||||
if (i < MAXRETRIES)
|
|
||||||
continue; // Retry.
|
|
||||||
return DEVICE_STATUS_TIMEOUT;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify the header of the package.
|
|
||||||
answer[2] -= size; // Adjust the package size for the comparision.
|
|
||||||
if (memcmp (command, answer, asize - size - 1) != 0) {
|
|
||||||
WARNING ("Unexpected answer start byte(s).");
|
|
||||||
return DEVICE_STATUS_PROTOCOL;
|
|
||||||
}
|
|
||||||
answer[2] += size; // Restore the package size again.
|
|
||||||
|
|
||||||
// Verify the checksum of the package.
|
|
||||||
unsigned char crc = answer[asize - 1];
|
|
||||||
unsigned char ccrc = checksum_xor_uint8 (answer, asize - 1, 0x00);
|
|
||||||
if (crc != ccrc) {
|
|
||||||
WARNING ("Unexpected answer CRC.");
|
|
||||||
return DEVICE_STATUS_PROTOCOL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return DEVICE_STATUS_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -41,6 +41,11 @@
|
|||||||
message ("%s:%d: %s\n", __FILE__, __LINE__, expr); \
|
message ("%s:%d: %s\n", __FILE__, __LINE__, expr); \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define EXITCODE(rc) \
|
||||||
|
( \
|
||||||
|
rc == -1 ? DEVICE_STATUS_IO : DEVICE_STATUS_TIMEOUT \
|
||||||
|
)
|
||||||
|
|
||||||
#define MINIMUM 8
|
#define MINIMUM 8
|
||||||
|
|
||||||
#define RB_PROFILE_BEGIN 0x019A
|
#define RB_PROFILE_BEGIN 0x019A
|
||||||
@ -197,6 +202,43 @@ suunto_vyper2_send (suunto_vyper2_device_t *device, const unsigned char command[
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static device_status_t
|
||||||
|
suunto_vyper2_packet (suunto_vyper2_device_t *device, const unsigned char command[], unsigned int csize, unsigned char answer[], unsigned int asize, unsigned int size)
|
||||||
|
{
|
||||||
|
// Send the command to the dive computer.
|
||||||
|
device_status_t rc = suunto_vyper2_send (device, command, csize);
|
||||||
|
if (rc != DEVICE_STATUS_SUCCESS) {
|
||||||
|
WARNING ("Failed to send the command.");
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Receive the answer of the dive computer.
|
||||||
|
int n = serial_read (device->port, answer, asize);
|
||||||
|
if (n != asize) {
|
||||||
|
WARNING ("Failed to receive the answer.");
|
||||||
|
return EXITCODE (n);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify the header of the package.
|
||||||
|
answer[2] -= size; // Adjust the package size for the comparision.
|
||||||
|
if (memcmp (command, answer, asize - size - 1) != 0) {
|
||||||
|
WARNING ("Unexpected answer start byte(s).");
|
||||||
|
return DEVICE_STATUS_PROTOCOL;
|
||||||
|
}
|
||||||
|
answer[2] += size; // Restore the package size again.
|
||||||
|
|
||||||
|
// Verify the checksum of the package.
|
||||||
|
unsigned char crc = answer[asize - 1];
|
||||||
|
unsigned char ccrc = checksum_xor_uint8 (answer, asize - 1, 0x00);
|
||||||
|
if (crc != ccrc) {
|
||||||
|
WARNING ("Unexpected answer CRC.");
|
||||||
|
return DEVICE_STATUS_PROTOCOL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return DEVICE_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static device_status_t
|
static device_status_t
|
||||||
suunto_vyper2_transfer (suunto_vyper2_device_t *device, const unsigned char command[], unsigned int csize, unsigned char answer[], unsigned int asize, unsigned int size)
|
suunto_vyper2_transfer (suunto_vyper2_device_t *device, const unsigned char command[], unsigned int csize, unsigned char answer[], unsigned int asize, unsigned int size)
|
||||||
{
|
{
|
||||||
@ -207,43 +249,20 @@ suunto_vyper2_transfer (suunto_vyper2_device_t *device, const unsigned char comm
|
|||||||
// returning an error. Usually the dive computer will respond
|
// returning an error. Usually the dive computer will respond
|
||||||
// again during one of the retries.
|
// again during one of the retries.
|
||||||
|
|
||||||
for (unsigned int i = 0;; ++i) {
|
unsigned int nretries = 0;
|
||||||
// Send the command to the dive computer.
|
device_status_t rc = DEVICE_STATUS_SUCCESS;
|
||||||
device_status_t rc = suunto_vyper2_send (device, command, csize);
|
while ((rc = suunto_vyper2_packet (device, command, csize, answer, asize, size)) != DEVICE_STATUS_SUCCESS) {
|
||||||
if (rc != DEVICE_STATUS_SUCCESS) {
|
// Automatically discard a corrupted packet,
|
||||||
WARNING ("Failed to send the command.");
|
// and request a new one.
|
||||||
|
if (rc != DEVICE_STATUS_TIMEOUT && rc != DEVICE_STATUS_PROTOCOL)
|
||||||
return rc;
|
return rc;
|
||||||
}
|
|
||||||
|
|
||||||
// Receive the answer of the dive computer.
|
// Abort if the maximum number of retries is reached.
|
||||||
int n = serial_read (device->port, answer, asize);
|
if (nretries++ >= MAXRETRIES)
|
||||||
if (n != asize) {
|
return rc;
|
||||||
WARNING ("Failed to receive the answer.");
|
|
||||||
if (n == -1)
|
|
||||||
return DEVICE_STATUS_IO;
|
|
||||||
if (i < MAXRETRIES)
|
|
||||||
continue; // Retry.
|
|
||||||
return DEVICE_STATUS_TIMEOUT;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify the header of the package.
|
|
||||||
answer[2] -= size; // Adjust the package size for the comparision.
|
|
||||||
if (memcmp (command, answer, asize - size - 1) != 0) {
|
|
||||||
WARNING ("Unexpected answer start byte(s).");
|
|
||||||
return DEVICE_STATUS_PROTOCOL;
|
|
||||||
}
|
|
||||||
answer[2] += size; // Restore the package size again.
|
|
||||||
|
|
||||||
// Verify the checksum of the package.
|
|
||||||
unsigned char crc = answer[asize - 1];
|
|
||||||
unsigned char ccrc = checksum_xor_uint8 (answer, asize - 1, 0x00);
|
|
||||||
if (crc != ccrc) {
|
|
||||||
WARNING ("Unexpected answer CRC.");
|
|
||||||
return DEVICE_STATUS_PROTOCOL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return DEVICE_STATUS_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user