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

Feature: Option to compute and verify checksums (CRC) #111

Open
miquelmassot opened this issue Apr 27, 2023 · 1 comment
Open

Feature: Option to compute and verify checksums (CRC) #111

miquelmassot opened this issue Apr 27, 2023 · 1 comment

Comments

@miquelmassot
Copy link

Hi!

I am in the process of defining a set of messages and I'd like to add a simple checksum at the "end" of the messages (similar to NMEA0183). Before using DCCL I was using this simple two-byte checksum below:

def rs232_checksum(the_bytes):
    """Compute the checksum of a byte array."""
    return b"%02X" % (sum(the_bytes) & 0xFF)

I am thinking about 📦 ➡️ 📦 wrapping my message (without checksum) into another with checksum so that I can pack it - compute its checksum - and write it. I thought this is quite convolved and maybe there is a better solution. Any suggestions?

The icing on the 🍰 would be to be able to verify (and trust!) the messages received over dodgy 🌊 comms channels.

@tsaubergine
Copy link
Member

tsaubergine commented Apr 27, 2023

Hi -

Thanks for the suggestion. Usually when I need a checksum I build it into the driver layer (e.g. Goby ModemDriver) e.g.,

[DCCL message (encoded)][CRC16 or CRC32]

and verify the checksum upon receipt before calling dccl::Codec::decode.

That said I can see some utility with adding a checksum as a custom codec in dccl, e.g.

syntax="proto2";
import "dccl/option_extensions.proto";
 
message NavigationReport {
  option ([dccl](https://libdccl.org/4.0/namespacedccl.html).msg) = { codec_version: 4
                        id: 124
                        max_bytes: 32 };
  required double x = 1 [(dccl.field) = { min: -10000 max: 10000 precision: 1 }];
 //.... other fields

  required uint32 crc = 100 [(dccl.field) = { codec: "dccl.crc16" } ];
// or   required uint32 crc = 100 [(dccl.field) = { codec: "dccl.crc32" } ];
}

An 8 bit checksum (such as the one you suggested) is pretty prone to missed detections with multiple bit errors (since you have a 1/256 chance to have the same checksum), but that would be an option too (also CRC algorithms tend to be more robust than the NMEA-0183 XOR checksum).

To implement the above custom codec ("dccl.crc16"), I'd need to add something to allow the DCCL FieldCodecs to access the full Bitset for encoding and decoding, probably a function like FieldCodecBase::const Bitset& root_bitset(); which returns the top level Bitset for encode and decode operations.

Then the codec itself can throw an exception if the checksum doesn't match upon receipt. It would have to be defined as the last field in the message to be effective.

I'll take a look at this if I get bored, though it's not a top priority for me. I'd likely merge this effort with two other somewhat related tasks: 1) implementing #92 and 2) adding a custom codec (e.g. "dccl.descriptor_hash") that does a hash of the current google::protobuf::Descriptor to catch mismatches with the sender and receiver .proto file definitions.

@tsaubergine tsaubergine changed the title Option to compute and verify checksums Feature: Option to compute and verify checksums (CRC) Oct 24, 2023
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

No branches or pull requests

2 participants