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

Replace handwritten encoding/decoding code #8

Open
hannobraun opened this issue Sep 27, 2018 · 1 comment
Open

Replace handwritten encoding/decoding code #8

hannobraun opened this issue Sep 27, 2018 · 1 comment
Labels
enhancement New feature or request good first issue Good for newcomers help wanted Extra attention is needed

Comments

@hannobraun
Copy link
Contributor

I've handwritten all the code I needed for encoding and decoding frames. While this gets the job done, it's an error-prone approach, and hard to maintain. Ideally, all this code would be generated from a declarative definition of the messages.

There's probably a third-party crate that can help here.

@hannobraun hannobraun added enhancement New feature or request help wanted Extra attention is needed good first issue Good for newcomers labels Sep 27, 2018
@rudihorn
Copy link

rudihorn commented Mar 29, 2022

I'm not sure if there are better crates out there, but I have been experimenting with doing some code generation similar to the crate svd2rust does in https://github.com/rudihorn/prot2rust (edit: the generation is now done in https://github.com/rudihorn/rust-ieee802.15.4-gen).

My main motivation for this was to reduce the memory footprint currently required by a field for each flag and to get rid of serialization / de-serialization while still providing a nice interface. So for the frame control one can do something like:

    let mut v = frame_control::W::new(0);
    v.frame_type()
        .data()
        .ack_request()
        .ack_requested()
        .dest_addr_mode()
        .address_16bit();
    v

and then in theory this should be able to inline to a more efficient representation that just constructs the 16 bit field.

I'd also suggest the use of generics to support different field configurations.

// trait for addresses
pub trait Address {}
// each address type is declared as a struct
pub struct AddrNone {}
pub struct AddrShort {
    pub address: u16,
}
pub struct AddrExtended {
    pub address: u32,
}
// each address type implements the Address trait
impl Address for AddrNone {}
impl Address for AddrShort {}
impl Address for AddrExtended {}

Then a frame header can be constructed with mac_frame::Mhr::<PanNone, AddrNone, PanNone, AddrNone>::new() and should be transmutable from raw memory. There are some issues using packed structs one would still need to figure out (a warning is thrown during compilation of the generated project). It would be nice if one could combine the generics of the header type with the frame control reader / writer, but this may be more tricky.

The code generated by this project is available at https://github.com/rudihorn/rust-ieee802.15.4

Are you aware of any declarative definition of 802.15.4 one could use as the source of such a code generator? Or crates that already do something like this? I know there are some for bitfield related projects, but nothing more complete. It would be nice if such a project could be used for the zigbee protocol as well. Let me know what you think.

(Disclaimer: These contributions are my own and are not related to my employment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request good first issue Good for newcomers help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

2 participants