Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

generator/C: Don't parse messages outside CRC_EXTRA #990

Merged
merged 1 commit into from
Nov 13, 2024

Conversation

julianoes
Copy link
Contributor

I have been wondering for a while why I sometimes see MAVLink components "appear" with random sysid/compid when I leave a system running for some time.

Today I finally caught the bytes of such a case, the offending bytes were:
{253, 0, 1, 0, 0, 3, 1, 1, 42, 0, 185, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};

This is msgid 10753 from sysid 3, compid 1 with payload len 0. It's presumably signed, hence the trailing zeros.

It turns out the msgid is way out of the CRC_EXTRA table and hence the mavlink_get_msg_entry(msgid) function returns NULL. In that case 0 is ignored and we carry on parsing.

My suggestion is to reset parsing when we don't know the CRC_EXTRA of the message to avoid flagging noise as a valid message.

@julianoes
Copy link
Contributor Author

Any comment @peterbarker?

FYI @auturgy

@hamishwillee
Copy link
Contributor

@peterbarker Is probably at the conference and @auturgy is away this week. So probably they won't get back to you this week.

@julianoes
Copy link
Contributor Author

Bumping this. I would appreciate a comment @tridge or @peterbarker.

@khancyr
Copy link
Contributor

khancyr commented Nov 6, 2024

I put a message to get a review on next call next week

@tridge
Copy link
Contributor

tridge commented Nov 11, 2024

@julianoes we need to test that this is OK with a router that wants to pass through unknown messages. That is an important use case

mavlink_update_checksum(rxmsg, crc_extra);
if (c != (rxmsg->checksum & 0xFF)) {
if (e == NULL) {
// Message not found in CRC_EXTRA table.
status->parse_state = MAVLINK_PARSE_STATE_GOT_BAD_CRC1;
Copy link
Contributor

@tridge tridge Nov 11, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you also need to set rxmsg->ck[0] to the byte from the packet (c) so that this code works correctly for forwarding the message:

	if (status->msg_received == MAVLINK_FRAMING_BAD_CRC) {
		/*
		  the CRC came out wrong. We now need to overwrite the
		  msg CRC with the one on the wire so that if the
		  caller decides to forward the message anyway that
		  mavlink_msg_to_send_buffer() won't overwrite the
		  checksum
		 */
            if (r_message != NULL) {
                r_message->checksum = rxmsg->ck[0] | (rxmsg->ck[1]<<8);
            }
	}

Copy link
Contributor Author

@julianoes julianoes Nov 12, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see, so you can still forward even if you can't fully parse a message. Do you have an example of such an implementation?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it, thanks. That's interesting.

I will update as suggested to fix that case.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fix pushed.

@julianoes
Copy link
Contributor Author

@tridge thanks for the review!

@julianoes we need to test that this is OK with a router that wants to pass through unknown messages. That is an important use case

I think a router generally should not parse a message. If it did try to parse every message, it wouldn't forward unknown messages as it doesn't have the correct CRC_EXTRA. So the way to forward messages is to just look for a correct looking header.

@tpwrules
Copy link

@tridge thanks for the review!

@julianoes we need to test that this is OK with a router that wants to pass through unknown messages. That is an important use case

I think a router generally should not parse a message. If it did try to parse every message, it wouldn't forward unknown messages as it doesn't have the correct CRC_EXTRA. So the way to forward messages is to just look for a correct looking header.

A router could choose to forward a message that has a "bad CRC" and use the MAVLink library as a convenient way to decode the framing.

Copy link

@tpwrules tpwrules left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please rebase on master then squash to one commit and we will merge!

I checked and it looks like the sample data (thanks for sharing) did get through because the CRC happened to be correct if CRC_EXTRA was 0. I think it makes sense to flag a message we know we can't prove the CRC is correct as having a bad CRC, then let the consumer deal with it.

It looks like this might not interact correctly with signing so a forwarder might have trouble there but that's a separate pre-existing problem and not in scope for this PR.

I have been wondering for a while why I sometimes see MAVLink
components "appear" with random sysid/compid when I leave a system
running for some time.

Today I finally caught the bytes of such a case, the offending bytes
were:
{253, 0, 1, 0, 0, 3, 1, 1, 42, 0, 185, 186,
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};

This is msgid 10753 from sysid 3, compid 1 with payload len 0.
It's presumably signed, hence the trailing zeros.

It turns out the msgid is way out of the CRC_EXTRA table and hence the
mavlink_get_msg_entry(msgid) function returns NULL.
In that case 0 is ignored and we carry on parsing.

My suggestion is to reset parsing when we don't know the CRC_EXTRA of
the message to avoid flagging noise as a valid message.

Included fixup:
In case a message is forwarded (even with unknown/bad CRC) we need to
copy the first CRC byte.
@tridge tridge merged commit 6e1da0a into ArduPilot:master Nov 13, 2024
14 checks passed
@julianoes
Copy link
Contributor Author

Thanks @tpwrules and @tridge!

@julianoes julianoes deleted the pr-fix-msg-without-crcextra branch November 13, 2024 21:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants