Skip to main content

bacnet_client/client/
read_range.rs

1//! ReadRange: one page, checked strictly or leniently against its request.
2use super::*;
3
4use bacnet_services::read_range::{
5    RangeSpec, ReadRangeAck, ReadRangeReply, ReadRangeRequest, ReadRangeValidation,
6};
7use bacnet_types::enums::PropertyIdentifier;
8use bacnet_types::primitives::ObjectIdentifier;
9
10impl<T: TransportPort + 'static> BACnetClient<T> {
11    /// Read a range of items from a list or log-buffer property.
12    ///
13    /// The acknowledgement must keep every rule
14    /// [`ReadRangeAck::violations`] checks against the request; one that
15    /// breaks a rule fails with [`Error::ReadRangeViolation`]. Use
16    /// [`read_range_with`](Self::read_range_with) and
17    /// [`ReadRangeValidation::Lenient`] to keep such an answer.
18    pub async fn read_range(
19        &self,
20        destination_mac: &[u8],
21        object_identifier: ObjectIdentifier,
22        property_identifier: PropertyIdentifier,
23        property_array_index: Option<u32>,
24        range: Option<RangeSpec>,
25    ) -> Result<ReadRangeAck, Error> {
26        let request = ReadRangeRequest {
27            object_identifier,
28            property_identifier,
29            property_array_index,
30            range,
31        };
32        self.read_range_with(destination_mac, &request, ReadRangeValidation::Strict)
33            .await
34            .map(|reply| reply.ack)
35    }
36
37    /// Read a range of items, choosing how to treat an acknowledgement that
38    /// breaks a rule: [`Strict`](ReadRangeValidation::Strict) refuses it,
39    /// [`Lenient`](ReadRangeValidation::Lenient) returns it with the list of
40    /// rules it broke, so a device that numbers the record after its
41    /// sequence wrap 0 doesn't cost the page.
42    ///
43    /// An acknowledgement that doesn't decode fails under either mode.
44    pub async fn read_range_with(
45        &self,
46        destination_mac: &[u8],
47        request: &ReadRangeRequest,
48        validation: ReadRangeValidation,
49    ) -> Result<ReadRangeReply, Error> {
50        let mut buf = BytesMut::new();
51        request.encode(&mut buf)?;
52        let response = self
53            .confirmed_request(destination_mac, ConfirmedServiceChoice::READ_RANGE, &buf)
54            .await?;
55        ReadRangeReply::check(request, ReadRangeAck::decode(&response)?, validation)
56    }
57}