Skip to main content

ezsp/frame/parameters/green_power/handler/
incoming_message.rs

1use le_stream::{FromLeStream, ToLeStream};
2use num_traits::FromPrimitive;
3
4use crate::Error;
5use crate::ember::Status;
6use crate::ember::gp::{Address, KeyType, SecurityLevel};
7use crate::types::ByteSizedVec;
8
9crate::frame::parameters::handler!(
10    0x00C5,
11    { status: u8, payload: Payload },
12    impl {
13        impl TryFrom<Handler> for Payload {
14            type Error = Error;
15
16            fn try_from(handler: Handler) -> Result<Self, Self::Error> {
17                match Status::from_u8(handler.status).ok_or(handler.status) {
18                    Ok(Status::Success) => Ok(handler.payload),
19                    other => Err(other.into()),
20                }
21            }
22        }
23    }
24);
25
26/// The payload of the GPDF receive.
27#[derive(Clone, Debug, Eq, PartialEq, FromLeStream, ToLeStream)]
28pub struct Payload {
29    gpd_link: u8,
30    sequence_number: u8,
31    addr: Address,
32    gpdf_security_level: SecurityLevel,
33    gpdf_security_key_type: KeyType,
34    auto_commissioning: bool,
35    bidirectional_info: u8,
36    gpd_security_frame_counter: u32,
37    gpd_command_id: u8,
38    mic: u32,
39    proxy_table_index: u8,
40    #[expect(clippy::struct_field_names)]
41    gpd_command_payload: ByteSizedVec<u8>,
42}
43
44impl Payload {
45    /// The gpdLink value of the received GPDF.
46    #[must_use]
47    pub const fn gpd_link(&self) -> u8 {
48        self.gpd_link
49    }
50
51    /// The GPDF sequence number.
52    #[must_use]
53    pub const fn sequence_number(&self) -> u8 {
54        self.sequence_number
55    }
56
57    /// The address of the source GPD.
58    #[must_use]
59    pub const fn addr(&self) -> &Address {
60        &self.addr
61    }
62
63    /// The security level of the received GPDF.
64    #[must_use]
65    pub const fn gpdf_security_level(&self) -> SecurityLevel {
66        self.gpdf_security_level
67    }
68
69    /// The securityKeyType used to decrypt/authenticate the incoming GPDF.
70    #[must_use]
71    pub const fn gpdf_security_key_type(&self) -> KeyType {
72        self.gpdf_security_key_type
73    }
74
75    /// Whether the incoming GPDF had the auto-commissioning bit set.
76    #[must_use]
77    pub const fn auto_commissioning(&self) -> bool {
78        self.auto_commissioning
79    }
80
81    /// Bidirectional information represented in bitfields, where bit0 holds the rxAfterTx of
82    /// incoming gpdf and bit1 holds if tx queue is available for outgoing gpdf.
83    #[must_use]
84    pub const fn bidirectional_info(&self) -> u8 {
85        self.bidirectional_info
86    }
87
88    /// The security frame counter of the incoming GDPF.
89    #[must_use]
90    pub const fn gpd_security_frame_counter(&self) -> u32 {
91        self.gpd_security_frame_counter
92    }
93
94    /// The gpdCommandId of the incoming GPDF.
95    #[must_use]
96    pub const fn gpd_command_id(&self) -> u8 {
97        self.gpd_command_id
98    }
99
100    /// The received MIC of the GPDF.
101    #[must_use]
102    pub const fn mic(&self) -> u32 {
103        self.mic
104    }
105
106    /// The proxy table index of the corresponding proxy table entry to the incoming GPDF.
107    #[must_use]
108    pub const fn proxy_table_index(&self) -> u8 {
109        self.proxy_table_index
110    }
111
112    /// The GPD command payload.
113    #[must_use]
114    pub fn gpd_command_payload(&self) -> &[u8] {
115        self.gpd_command_payload.as_ref()
116    }
117}