neli icon indicating copy to clipboard operation
neli copied to clipboard

Parsing different NlAttrType Enums for different received Cmds

Open Alexandero89 opened this issue 2 years ago • 3 comments

Hey,

I'm sorry if the response to this is somewhere in the docs, but i searched them and read a lot of issues but still could not find a solution for my problem. Issue #50 seems to be relevant, but could not find an exact solution after reading it.

Neli version: 0.6.2

I am using the async Socket neli::socket::tokio::NlSocket to wait for messages from the socket via:

let mut buffer: Vec<u8> = Vec::new();
let response =  self.socket.recv::<NlTypeWrapper, Genlmsghdr<MYCMDS, ATTRIBUTES_COMMAND_ONE>>(&mut buffer);

Now i am forced to give socket the type of the attributes. But i would like to parse the attributes of the Genlmsghdr depending on the command i got in MYCMDS.

Right now my attribute enums and commands look something like this:

#[neli_enum(serialized_type = "u8")]
pub enum MYCMDS {
    COMMAND_ONE = 0,
    COMMAND_TWO = 1,
}
impl Cmd for MYCMDS {}

#[neli_enum(serialized_type = "u16")]
pub enum ATTRIBUTES_COMMAND_ONE {
    ATTRIBUTE_ONE_A = 0,
    ATTRIBUTE_ONE_B = 1,
}
impl NlAttrType for ATTRIBUTES_COMMAND_ONE {}

#[neli_enum(serialized_type = "u16")]
pub enum ATTRIBUTES_COMMAND_TWO {
    ATTRIBUTE_TWO_A = 0,
    ATTRIBUTE_TWO_B = 1,
    ATTRIBUTE_TWO_C = 2,
    ATTRIBUTE_TWO_D = 3,
}
impl NlAttrType for ATTRIBUTES_COMMAND_TWO {}

And i would like to do something like this (maybe not correct code. just as an example):

let response =  self.socket.recv::<NlTypeWrapper, Genlmsghdr<MYCMDS, u16>>(&mut buffer);
let message = response.unwrap()
let attr_handle = match nlmessage.nl_payload.get_payload().unwrap().cmd{
    MYCMDS::COMMAND_ONE => {
        nlmessage.get_payload().unwrap().get_attr_handle_as(ATTRIBUTES_COMMAND_ONE)
    }
    MYCMDS::COMMAND_TWO => {
        nlmessage.get_payload().unwrap().get_attr_handle_as(ATTRIBUTES_COMMAND_TWO)
    }
  }

Hope you understand my use case. Thanks in advance!

Alexandero89 avatar Aug 23 '22 08:08 Alexandero89

Hi @Alexandero89! Your use of u16 and then conversion to the correct type after matching on MYCMDS is generally the way to do it. It is hard to come up with a better way to handle the general case because netlink has such a wide range of formats that have to be supported by neli. Does that code cause errors that I can help you with or did you just want to check if this was the best way to do it? I'm happy to help with either.

jbaublitz avatar Aug 24 '22 14:08 jbaublitz

Hey John,

Thanks for your response!

Actually this were some function calls I thought are non existent. Because I could not find a function with an enum as an input value (like the get_attr_handle_as example I used). Because this kind of implementation would be completely fine for me.

But I will have another look and try to implement it like this.

Alexandero89 avatar Aug 24 '22 14:08 Alexandero89

Okay, I think I see what you're missing now. So the current way to do this is to get the field nla_type and parse the u16 as ATTRIBUTES_COMMAND_ONE or ATTRIBUTES_COMMAND_TWO manually using ATTRIBUTES_COMMAND_TWO::from(attribute.nla_type.nla_type). This is admittedly not very nice so let me look into adding an API like the one you specified above.

jbaublitz avatar Aug 24 '22 15:08 jbaublitz

I've been working on this and I've bumped into some complications. Changing the type of the existing attributes requires copying the data over to a newly-typed data structure. This means that mutable access means virtaally nothing in the case because it won't modify data in place. Are you looking for parsing only? If so, copying may be sufficient.

jbaublitz avatar Jan 05 '23 18:01 jbaublitz

@Alexandero89 Does the most recent commit in #182 solve this issue for you?

jbaublitz avatar Jan 21 '23 16:01 jbaublitz