mirror of
https://github.com/PX4/PX4-Autopilot.git
synced 2026-05-31 02:16:53 +08:00
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:
+34
-21
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user