sbus: add time-based hardening (only for IO and NuttX)

Since SBUS does not have CRC, we can use timing information to improve
parsing reliability and reject unexpected bytes.
This commit is contained in:
Beat Küng
2018-12-14 12:11:16 +01:00
parent 4cd8fe0a30
commit eda45b4df2
+34 -21
View File
@@ -52,6 +52,8 @@
#include "common_rc.h" #include "common_rc.h"
#include <drivers/drv_hrt.h> #include <drivers/drv_hrt.h>
using namespace time_literals;
#define SBUS_DEBUG_LEVEL 0 /* Set debug output level */ #define SBUS_DEBUG_LEVEL 0 /* Set debug output level */
#if defined(__PX4_POSIX_OCPOC) #if defined(__PX4_POSIX_OCPOC)
@@ -280,8 +282,21 @@ bool
sbus_input(int sbus_fd, uint16_t *values, uint16_t *num_values, bool *sbus_failsafe, bool *sbus_frame_drop, sbus_input(int sbus_fd, uint16_t *values, uint16_t *num_values, bool *sbus_failsafe, bool *sbus_frame_drop,
uint16_t max_channels) uint16_t max_channels)
{ {
int ret = 1; /*
hrt_abstime now; * Fetch bytes, but no more than we would need to complete
* a complete frame.
*/
uint8_t buf[SBUS_FRAME_SIZE * 2];
int ret = read(sbus_fd, &buf[0], SBUS_FRAME_SIZE);
/* if the read failed for any reason, just give up here */
if (ret < 1) {
return false;
}
const hrt_abstime now = hrt_absolute_time();
#ifdef __PX4_NUTTX /* limit time-based hardening to RTOS's where we have reliable timing */
/* /*
* The S.BUS protocol doesn't provide reliable framing, * The S.BUS protocol doesn't provide reliable framing,
@@ -298,32 +313,30 @@ sbus_input(int sbus_fd, uint16_t *values, uint16_t *num_values, bool *sbus_fails
* provides a degree of protection. Of course, it would be better * provides a degree of protection. Of course, it would be better
* if we didn't drop bytes... * if we didn't drop bytes...
*/ */
now = hrt_absolute_time(); if (now - last_rx_time > 3_ms) {
if (partial_frame_count > 0) {
partial_frame_count = 0;
sbus_decode_state = SBUS2_DECODE_STATE_DESYNC;
#if defined(SBUS_DEBUG_LEVEL) && SBUS_DEBUG_LEVEL > 0
printf("SBUS: RESET (TIME LIM)\n");
#endif
}
}
/* if (partial_frame_count == 0 && buf[0] != SBUS_START_SYMBOL) {
* Fetch bytes, but no more than we would need to complete /* don't bother going through the buffer if we don't get the
* a complete frame. * expected start symbol as a first byte */
*/ sbus_decode_state = SBUS2_DECODE_STATE_DESYNC;
uint8_t buf[SBUS_FRAME_SIZE * 2];
bool sbus_decoded = false;
ret = read(sbus_fd, &buf[0], SBUS_FRAME_SIZE);
/* if the read failed for any reason, just give up here */
if (ret < 1) {
return false; return false;
} }
#endif /* __PX4_NUTTX */
/* /*
* Try to decode something with what we got * Try to decode something with what we got
*/ */
if (sbus_parse(now, &buf[0], ret, values, num_values, sbus_failsafe, return sbus_parse(now, &buf[0], ret, values, num_values, sbus_failsafe,
sbus_frame_drop, &sbus_frame_drops, max_channels)) { sbus_frame_drop, &sbus_frame_drops, max_channels);
sbus_decoded = true;
}
return sbus_decoded;
} }
bool bool