1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
use std::fmt::Display;
use num_traits::FromPrimitive;
use crate::Error;
use crate::ember::Status;
use crate::ember::aps::Frame;
use crate::ember::message::Outgoing;
use crate::types::ByteSizedVec;
crate::frame::parameters::handler!(
0x003F,
{
typ: u8,
index_or_destination: u16,
aps_frame: Frame,
message_tag: u8,
status: u8,
message: ByteSizedVec<u8>,
},
impl {
impl Handler {
/// The type of message sent.
///
/// # Errors
///
/// Returns an error if the value is not a valid [`Outgoing`] variant.
pub fn typ(&self) -> Result<Outgoing, u8> {
Outgoing::try_from(self.typ)
}
/// The destination to which the message was sent, for direct unicasts,
/// or the address table or binding index for other unicasts.
///
/// The value is unspecified for multicasts and broadcasts.
#[must_use]
pub const fn index_or_destination(&self) -> u16 {
self.index_or_destination
}
/// The APS frame for the message.
#[must_use]
pub const fn aps_frame(&self) -> &Frame {
&self.aps_frame
}
/// The value supplied by the Host in the
/// [`Messaging::send_unicast`](crate::Messaging::send_unicast),
/// [`Messaging::send_broadcast`](crate::Messaging::send_broadcast) or
/// [`Messaging::send_multicast`](crate::Messaging::send_multicast) command.
#[must_use]
pub const fn message_tag(&self) -> u8 {
self.message_tag
}
/// Return the status.
///
/// # Errors
///
/// Returns the raw status value if it is not a valid status.
pub fn status(&self) -> Result<Status, u8> {
Status::from_u8(self.status).ok_or(self.status)
}
/// Returns `true` if an ACK was received from the destination or `false` if no ACK was received.
///
/// # Errors
///
/// Returns an [`Error`] if the status is not [`Status::Success`] or [`Status::DeliveryFailed`]
/// or if the value is not a valid status.
pub fn ack_received(&self) -> Result<bool, Error> {
match self.status() {
Ok(Status::Success) => Ok(true),
Ok(Status::DeliveryFailed) => Ok(false),
other => Err(other.into()),
}
}
/// The unicast message supplied by the Host.
///
/// The message contents are only included here if the decision for the
/// `messageContentsInCallback` policy is `messageTagAndContentsInCallback`.
#[must_use]
pub fn message(&self) -> &[u8] {
self.message.as_ref()
}
}
impl Display for Handler {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let message_length = self.message.len();
write!(
f,
"Handler {{ typ: {:#04X}, index_or_destination: {:#06X}, aps_frame: {}, message_tag: {:#04X}, status: {:#04X}, message_length: {message_length:#04X}, message: [",
self.typ, self.index_or_destination, self.aps_frame, self.message_tag, self.status,
)?;
let mut message_bytes = self.message.iter();
if let Some(byte) = message_bytes.next() {
write!(f, "{byte:#04X}")?;
for byte in message_bytes {
write!(f, ", {byte:#04X}")?;
}
}
write!(f, "] }}")
}
}
}
);