Skip to main content

bacnet_client/client/
object_mgmt.rs

1use super::*;
2
3impl<T: TransportPort + 'static> BACnetClient<T> {
4    /// Delete an object on a remote device (DeleteObject, Clause 15.4).
5    pub async fn delete_object(
6        &self,
7        destination_mac: &[u8],
8        object_identifier: bacnet_types::primitives::ObjectIdentifier,
9    ) -> Result<(), Error> {
10        use bacnet_services::object_mgmt::DeleteObjectRequest;
11
12        let request = DeleteObjectRequest { object_identifier };
13        let mut buf = BytesMut::new();
14        request.encode(&mut buf);
15
16        let _ = self
17            .confirmed_request(destination_mac, ConfirmedServiceChoice::DELETE_OBJECT, &buf)
18            .await?;
19
20        Ok(())
21    }
22
23    /// Create an object on a remote device (CreateObject, Clause 15.3).
24    ///
25    /// Returns the identifier the device's CreateObject-ACK names, which
26    /// tells a create by type the instance the device chose. An ACK that
27    /// doesn't decode is an error, though the device may have created the
28    /// object.
29    pub async fn create_object(
30        &self,
31        destination_mac: &[u8],
32        object_specifier: bacnet_services::object_mgmt::ObjectSpecifier,
33        initial_values: Vec<bacnet_services::common::BACnetPropertyValue>,
34    ) -> Result<bacnet_types::primitives::ObjectIdentifier, Error> {
35        use bacnet_services::object_mgmt::CreateObjectRequest;
36
37        let request = CreateObjectRequest {
38            object_specifier,
39            list_of_initial_values: initial_values,
40        };
41        let mut buf = BytesMut::new();
42        request.encode(&mut buf);
43
44        let ack = self
45            .confirmed_request(destination_mac, ConfirmedServiceChoice::CREATE_OBJECT, &buf)
46            .await?;
47        created_object(&ack)
48    }
49    /// Delete an object on a discovered device, routing when needed.
50    ///
51    /// Uses the same confirmation and error semantics as [`Self::delete_object`].
52    /// A missing device fails before sending.
53    pub async fn delete_object_from_device(
54        &self,
55        device_instance: u32,
56        object_identifier: bacnet_types::primitives::ObjectIdentifier,
57    ) -> Result<(), Error> {
58        let (mac, routing) = self.resolve_device(device_instance).await?;
59        if let Some((network, address)) = routing {
60            let request = bacnet_services::object_mgmt::DeleteObjectRequest { object_identifier };
61            let mut buf = BytesMut::new();
62            request.encode(&mut buf);
63            self.confirmed_request_routed(
64                &mac,
65                network,
66                &address,
67                ConfirmedServiceChoice::DELETE_OBJECT,
68                &buf,
69            )
70            .await?;
71            Ok(())
72        } else {
73            self.delete_object(&mac, object_identifier).await
74        }
75    }
76
77    /// Create an object on a discovered device, routing when needed.
78    ///
79    /// Retains the initial values and decoded acknowledgement of [`Self::create_object`].
80    /// A missing device fails before sending.
81    pub async fn create_object_from_device(
82        &self,
83        device_instance: u32,
84        object_specifier: bacnet_services::object_mgmt::ObjectSpecifier,
85        initial_values: Vec<bacnet_services::common::BACnetPropertyValue>,
86    ) -> Result<bacnet_types::primitives::ObjectIdentifier, Error> {
87        let (mac, routing) = self.resolve_device(device_instance).await?;
88        if let Some((network, address)) = routing {
89            let request = bacnet_services::object_mgmt::CreateObjectRequest {
90                object_specifier,
91                list_of_initial_values: initial_values,
92            };
93            let mut buf = BytesMut::new();
94            request.encode(&mut buf);
95            let ack = self
96                .confirmed_request_routed(
97                    &mac,
98                    network,
99                    &address,
100                    ConfirmedServiceChoice::CREATE_OBJECT,
101                    &buf,
102                )
103                .await?;
104            created_object(&ack)
105        } else {
106            self.create_object(&mac, object_specifier, initial_values)
107                .await
108        }
109    }
110}
111
112/// The object a CreateObject-ACK names.
113fn created_object(ack: &[u8]) -> Result<bacnet_types::primitives::ObjectIdentifier, Error> {
114    bacnet_services::object_mgmt::CreateObjectAck::decode(ack).map(|ack| ack.object_identifier)
115}
116
117#[cfg(test)]
118#[path = "object_mgmt_tests.rs"]
119mod tests;