feat: add VicCAN message validity checking and core feedback data length checking

This commit is contained in:
David
2025-10-14 15:21:23 -05:00
parent d565dbe31f
commit 89015ee7a5
2 changed files with 50 additions and 3 deletions

View File

@@ -171,9 +171,37 @@ class SerialRelay(Node):
""" Relay a string message from the MCU to the appropriate VicCAN topic """ """ Relay a string message from the MCU to the appropriate VicCAN topic """
self.fromvic_debug_pub_.publish(String(data=msg)) self.fromvic_debug_pub_.publish(String(data=msg))
parts = msg.strip().split(",") parts = msg.strip().split(",")
if len(parts) < 3 or parts[0] != "can_relay_fromvic": if len(parts) > 0 and parts[0] != "can_relay_fromvic":
self.get_logger().debug(f"Ignoring non-VicCAN message: '{msg.strip()}'")
return return
# String validation
malformed: bool = False
malformed_reason: str = ""
if len(parts) < 3 or len(parts) > 7:
malformed = True
malformed_reason = f"invalid argument count (expected [3,7], got {len(parts)})"
elif parts[1] not in ["core", "arm", "digit", "citadel", "broadcast"]:
malformed = True
malformed_reason = f"invalid mcu_name '{parts[1]}'"
elif parts[2].isnumeric() is False or int(parts[2]) < 0:
malformed = True
malformed_reason = f"command_id '{parts[2]}' is not a non-negative integer"
else:
for x in parts[3:]:
try:
float(x)
except ValueError:
malformed = True
malformed_reason = f"data '{x}' is not a float"
break
if malformed:
self.get_logger().warning(f"Ignoring malformed from_vic message: '{msg.strip()}'; reason: {malformed_reason}")
return
# Have valid VicCAN message
output = VicCAN() output = VicCAN()
output.mcu_name = parts[1] output.mcu_name = parts[1]
output.command_id = int(parts[2]) output.command_id = int(parts[2])

View File

@@ -41,6 +41,20 @@ control_qos = qos.QoSProfile(
liveliness_lease_duration=Duration(seconds=5) liveliness_lease_duration=Duration(seconds=5)
) )
# Used to verify the length of an incoming VicCAN feedback message
# Key is VicCAN command_id, value is expected length of data list
viccan_msg_len_dict = {
48: 1,
49: 1,
50: 2,
51: 4,
52: 4,
53: 4,
54: 4,
56: 3,
58: 3
}
class SerialRelay(Node): class SerialRelay(Node):
def __init__(self): def __init__(self):
@@ -357,8 +371,13 @@ class SerialRelay(Node):
def relay_fromvic(self, msg: VicCAN): def relay_fromvic(self, msg: VicCAN):
# Assume that the message is coming from Core # Assume that the message is coming from Core
# skill diff if not # skill diff if not
# TODO: add len(msg.data) checks to each feedback message # Check message len to prevent crashing on bad data
if msg.command_id in viccan_msg_len_dict:
expected_len = viccan_msg_len_dict[msg.command_id]
if len(msg.data) != expected_len:
self.get_logger().warning(f"Ignoring VicCAN message with id {msg.command_id} due to unexpected data length (expected {expected_len}, got {len(msg.data)})")
return
match msg.command_id: match msg.command_id:
# GNSS # GNSS