bacnet_emb/common/
time_value.rs1use crate::{
2 application_protocol::primitives::data_value::{Enumerated, Time},
3 common::{
4 error::{Error, Unimplemented},
5 helper::decode_unsigned,
6 io::{Reader, Writer},
7 spec::Binary,
8 tag::{ApplicationTagNumber, Tag, TagNumber},
9 },
10};
11
12#[derive(Debug, Clone)]
14#[cfg_attr(feature = "defmt", derive(defmt::Format))]
15#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
16pub enum SimpleApplicationDataValue {
17 Boolean(bool),
18 SignedInt(i32),
19 UnsignedInt(u32),
20 Real(f32),
21 Double(f64),
22 Enumerated(Enumerated),
23}
24
25impl SimpleApplicationDataValue {
26 pub fn tag(&self) -> Tag {
27 match self {
28 Self::Boolean(_) => Tag::new(TagNumber::Application(ApplicationTagNumber::Boolean), 1),
29 Self::SignedInt(_) => {
30 Tag::new(TagNumber::Application(ApplicationTagNumber::SignedInt), 4)
31 }
32 Self::UnsignedInt(_) => {
33 Tag::new(TagNumber::Application(ApplicationTagNumber::UnsignedInt), 4)
34 }
35 Self::Real(_) => Tag::new(TagNumber::Application(ApplicationTagNumber::Real), 4),
36 Self::Double(_) => Tag::new(TagNumber::Application(ApplicationTagNumber::Double), 8),
37 Self::Enumerated(_) => {
38 Tag::new(TagNumber::Application(ApplicationTagNumber::Enumerated), 1)
39 }
40 }
41 }
42 pub fn decode(tag: &Tag, reader: &mut Reader, buf: &[u8]) -> Result<Self, Error> {
43 let tag_num = match &tag.number {
44 TagNumber::Application(x) => x,
45 unknown => {
46 return Err(Error::TagNotSupported((
47 "SimpleApplicationDataValue decode",
48 unknown.clone(),
49 )));
50 }
51 };
52
53 match tag_num {
54 ApplicationTagNumber::Boolean => {
55 let value = tag.value > 0;
56 Ok(SimpleApplicationDataValue::Boolean(value))
57 }
58 ApplicationTagNumber::UnsignedInt => {
59 let value = decode_unsigned(tag.value, reader, buf)? as u32;
60 Ok(SimpleApplicationDataValue::UnsignedInt(value))
61 }
62 ApplicationTagNumber::Real => {
63 if tag.value != 4 {
64 return Err(Error::InvalidValue(
65 "real value tag should have length of 4",
66 ));
67 }
68 Ok(SimpleApplicationDataValue::Real(f32::from_be_bytes(
69 reader.read_bytes(buf)?,
70 )))
71 }
72 ApplicationTagNumber::Enumerated => {
73 let value = decode_unsigned(tag.value, reader, buf)? as u32;
74 let value = if value > 0 { Binary::On } else { Binary::Off };
75 let value = Enumerated::Binary(value);
76 Ok(SimpleApplicationDataValue::Enumerated(value))
77 }
78
79 x => Err(Error::Unimplemented(Unimplemented::ApplicationTagNumber(
80 x.clone(),
81 ))),
82 }
83 }
84
85 pub fn encode(&self, writer: &mut Writer) {
86 match self {
87 Self::Boolean(x) => writer.push(*x as u8),
88 Self::SignedInt(x) => writer.extend_from_slice(&x.to_be_bytes()),
89 Self::UnsignedInt(x) => writer.extend_from_slice(&x.to_be_bytes()),
90 Self::Real(x) => writer.extend_from_slice(&x.to_be_bytes()),
91 Self::Double(x) => writer.extend_from_slice(&x.to_be_bytes()),
92 Self::Enumerated(Enumerated::Binary(x)) => writer.push(x.clone() as u32 as u8),
93 x => unimplemented!("{:?}", x),
94 }
95 }
96}
97
98#[derive(Debug, Clone)]
99#[cfg_attr(feature = "defmt", derive(defmt::Format))]
100#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
101pub struct TimeValue {
102 pub time: Time,
103 pub value: SimpleApplicationDataValue,
104}
105
106impl TimeValue {
107 pub const LEN: u32 = 4;
108
109 pub fn decode(reader: &mut Reader, buf: &[u8]) -> Result<TimeValue, Error> {
110 let tag = Tag::decode_expected(
111 reader,
112 buf,
113 TagNumber::Application(ApplicationTagNumber::Time),
114 "Decode weekly schedule TimeValue",
115 )?;
116
117 if tag.value != Self::LEN {
119 return Err(Error::Length((
120 "time tag should have length value 4",
121 tag.value,
122 )));
123 }
124 let time = match &tag.number {
125 TagNumber::Application(ApplicationTagNumber::Time) => Time::decode(reader, buf)?,
126 number => {
127 return Err(Error::TagNotSupported((
128 "TimeValue decode time application tag expected",
129 number.clone(),
130 )))
131 }
132 };
133 let tag = Tag::decode(reader, buf)?;
134 let value = SimpleApplicationDataValue::decode(&tag, reader, buf)?;
135 Ok(TimeValue { time, value })
136 }
137
138 pub fn encode(&self, writer: &mut Writer) {
139 let tag = Tag::new(
140 TagNumber::Application(ApplicationTagNumber::Time),
141 Self::LEN,
142 );
143 tag.encode(writer);
144 self.time.encode(writer);
145 let tag = self.value.tag();
146 tag.encode(writer);
147 self.value.encode(writer);
148 }
149}