1use super::*;
2
3impl<T: TransportPort + 'static> BACnetClient<T> {
4 pub async fn device_communication_control(
6 &self,
7 destination_mac: &[u8],
8 enable_disable: bacnet_types::enums::EnableDisable,
9 time_duration: Option<u16>,
10 password: Option<String>,
11 ) -> Result<(), Error> {
12 use bacnet_services::device_mgmt::DeviceCommunicationControlRequest;
13
14 let request = DeviceCommunicationControlRequest {
15 time_duration,
16 enable_disable,
17 password,
18 };
19 let mut buf = BytesMut::new();
20 request.encode(&mut buf)?;
21
22 let _ = self
23 .confirmed_request(
24 destination_mac,
25 ConfirmedServiceChoice::DEVICE_COMMUNICATION_CONTROL,
26 &buf,
27 )
28 .await?;
29
30 Ok(())
31 }
32
33 pub async fn reinitialize_device(
35 &self,
36 destination_mac: &[u8],
37 reinitialized_state: bacnet_types::enums::ReinitializedState,
38 password: Option<String>,
39 ) -> Result<(), Error> {
40 use bacnet_services::device_mgmt::ReinitializeDeviceRequest;
41
42 let request = ReinitializeDeviceRequest {
43 reinitialized_state,
44 password,
45 };
46 let mut buf = BytesMut::new();
47 request.encode(&mut buf)?;
48
49 let _ = self
50 .confirmed_request(
51 destination_mac,
52 ConfirmedServiceChoice::REINITIALIZE_DEVICE,
53 &buf,
54 )
55 .await?;
56
57 Ok(())
58 }
59 pub async fn time_synchronization(
61 &self,
62 destination_mac: &[u8],
63 date: bacnet_types::primitives::Date,
64 time: bacnet_types::primitives::Time,
65 ) -> Result<(), Error> {
66 use bacnet_services::device_mgmt::TimeSynchronizationRequest;
67
68 let request = TimeSynchronizationRequest { date, time };
69 let mut buf = BytesMut::new();
70 request.encode(&mut buf);
71
72 self.unconfirmed_request(
73 destination_mac,
74 UnconfirmedServiceChoice::TIME_SYNCHRONIZATION,
75 &buf,
76 )
77 .await
78 }
79
80 pub async fn utc_time_synchronization(
82 &self,
83 destination_mac: &[u8],
84 date: bacnet_types::primitives::Date,
85 time: bacnet_types::primitives::Time,
86 ) -> Result<(), Error> {
87 use bacnet_services::device_mgmt::TimeSynchronizationRequest;
88
89 let request = TimeSynchronizationRequest { date, time };
90 let mut buf = BytesMut::new();
91 request.encode(&mut buf);
92
93 self.unconfirmed_request(
94 destination_mac,
95 UnconfirmedServiceChoice::UTC_TIME_SYNCHRONIZATION,
96 &buf,
97 )
98 .await
99 }
100 pub async fn device_communication_control_from_device(
105 &self,
106 device_instance: u32,
107 enable_disable: bacnet_types::enums::EnableDisable,
108 time_duration: Option<u16>,
109 password: Option<String>,
110 ) -> Result<(), Error> {
111 let (mac, routing) = self.resolve_device(device_instance).await?;
112 if let Some((network, address)) = routing {
113 let request = bacnet_services::device_mgmt::DeviceCommunicationControlRequest {
114 time_duration,
115 enable_disable,
116 password,
117 };
118 let mut buf = BytesMut::new();
119 request.encode(&mut buf)?;
120 self.confirmed_request_routed(
121 &mac,
122 network,
123 &address,
124 ConfirmedServiceChoice::DEVICE_COMMUNICATION_CONTROL,
125 &buf,
126 )
127 .await?;
128 Ok(())
129 } else {
130 self.device_communication_control(&mac, enable_disable, time_duration, password)
131 .await
132 }
133 }
134
135 pub async fn reinitialize_device_from_device(
140 &self,
141 device_instance: u32,
142 reinitialized_state: bacnet_types::enums::ReinitializedState,
143 password: Option<String>,
144 ) -> Result<(), Error> {
145 let (mac, routing) = self.resolve_device(device_instance).await?;
146 if let Some((network, address)) = routing {
147 let request = bacnet_services::device_mgmt::ReinitializeDeviceRequest {
148 reinitialized_state,
149 password,
150 };
151 let mut buf = BytesMut::new();
152 request.encode(&mut buf)?;
153 self.confirmed_request_routed(
154 &mac,
155 network,
156 &address,
157 ConfirmedServiceChoice::REINITIALIZE_DEVICE,
158 &buf,
159 )
160 .await?;
161 Ok(())
162 } else {
163 self.reinitialize_device(&mac, reinitialized_state, password)
164 .await
165 }
166 }
167
168 pub async fn time_synchronization_from_device(
173 &self,
174 device_instance: u32,
175 date: bacnet_types::primitives::Date,
176 time: bacnet_types::primitives::Time,
177 ) -> Result<(), Error> {
178 self.time_synchronization_to_device(
179 device_instance,
180 date,
181 time,
182 UnconfirmedServiceChoice::TIME_SYNCHRONIZATION,
183 )
184 .await
185 }
186
187 pub async fn utc_time_synchronization_from_device(
192 &self,
193 device_instance: u32,
194 date: bacnet_types::primitives::Date,
195 time: bacnet_types::primitives::Time,
196 ) -> Result<(), Error> {
197 self.time_synchronization_to_device(
198 device_instance,
199 date,
200 time,
201 UnconfirmedServiceChoice::UTC_TIME_SYNCHRONIZATION,
202 )
203 .await
204 }
205
206 async fn time_synchronization_to_device(
207 &self,
208 device_instance: u32,
209 date: bacnet_types::primitives::Date,
210 time: bacnet_types::primitives::Time,
211 service_choice: UnconfirmedServiceChoice,
212 ) -> Result<(), Error> {
213 let (mac, routing) = self.resolve_device(device_instance).await?;
214 let request = bacnet_services::device_mgmt::TimeSynchronizationRequest { date, time };
215 let mut data = BytesMut::new();
216 request.encode(&mut data);
217 let Some((network, address)) = routing else {
218 return self.unconfirmed_request(&mac, service_choice, &data).await;
219 };
220 check_routed_unicast(network, address.len())?;
221 if self.network.local_network_number().get() == Some(network) {
222 if self.network.transport().is_group_destination(&address) {
223 return Err(Error::Encoding(
224 "routed time synchronization requires a unicast station".into(),
225 ));
226 }
227 return self
228 .unconfirmed_request(&address, service_choice, &data)
229 .await;
230 }
231 let apdu = Apdu::UnconfirmedRequest(bacnet_encoding::apdu::UnconfirmedRequest {
232 service_choice,
233 service_request: data.freeze(),
234 });
235 let mut buf = BytesMut::new();
236 encode_apdu(&mut buf, &apdu)?;
237 self.network
238 .send_apdu_routed(
239 &buf,
240 network,
241 &address,
242 &mac,
243 false,
244 NetworkPriority::Normal,
245 )
246 .await
247 }
248}
249
250#[cfg(test)]
251#[path = "device_mgmt_tests.rs"]
252mod tests;