use super::*;
impl<T: TransportPort + 'static> BACnetClient<T> {
pub(super) async fn resolve_device(
&self,
device_instance: u32,
) -> Result<(Vec<u8>, Option<(u16, Vec<u8>)>), Error> {
let dt = self.device_table.lock().await;
let device = dt.get(device_instance).ok_or_else(|| {
Error::Encoding(format!("device {device_instance} not in device table"))
})?;
let routing = match (&device.source_network, &device.source_address) {
(Some(snet), Some(sadr)) => Some((*snet, sadr.to_vec())),
_ => None,
};
Ok((device.mac_address.to_vec(), routing))
}
pub async fn who_is(
&self,
low_limit: Option<u32>,
high_limit: Option<u32>,
) -> Result<(), Error> {
use bacnet_services::who_is::WhoIsRequest;
let request = WhoIsRequest {
low_limit,
high_limit,
};
let mut buf = BytesMut::new();
request.encode(&mut buf);
self.broadcast_global_unconfirmed(UnconfirmedServiceChoice::WHO_IS, &buf)
.await
}
pub async fn who_is_directed(
&self,
destination_mac: &[u8],
low_limit: Option<u32>,
high_limit: Option<u32>,
) -> Result<(), Error> {
use bacnet_services::who_is::WhoIsRequest;
let request = WhoIsRequest {
low_limit,
high_limit,
};
let mut buf = BytesMut::new();
request.encode(&mut buf);
self.unconfirmed_request(destination_mac, UnconfirmedServiceChoice::WHO_IS, &buf)
.await
}
pub async fn who_is_network(
&self,
dest_network: u16,
low_limit: Option<u32>,
high_limit: Option<u32>,
) -> Result<(), Error> {
use bacnet_services::who_is::WhoIsRequest;
let request = WhoIsRequest {
low_limit,
high_limit,
};
let mut buf = BytesMut::new();
request.encode(&mut buf);
self.broadcast_network_unconfirmed(UnconfirmedServiceChoice::WHO_IS, &buf, dest_network)
.await
}
pub async fn who_has(
&self,
object: bacnet_services::who_has::WhoHasObject,
low_limit: Option<u32>,
high_limit: Option<u32>,
) -> Result<(), Error> {
use bacnet_services::who_has::WhoHasRequest;
let request = WhoHasRequest {
low_limit,
high_limit,
object,
};
let mut buf = BytesMut::new();
request.encode(&mut buf)?;
self.broadcast_unconfirmed(UnconfirmedServiceChoice::WHO_HAS, &buf)
.await
}
pub async fn discovered_devices(&self) -> Vec<DiscoveredDevice> {
self.device_table.lock().await.all()
}
pub async fn get_device(&self, instance: u32) -> Option<DiscoveredDevice> {
self.device_table.lock().await.get(instance).cloned()
}
pub async fn clear_devices(&self) {
self.device_table.lock().await.clear();
}
pub async fn add_device(&self, instance: u32, mac: &[u8]) -> Result<(), Error> {
let oid = bacnet_types::primitives::ObjectIdentifier::new(
bacnet_types::enums::ObjectType::DEVICE,
instance,
)?;
let device = DiscoveredDevice {
object_identifier: oid,
mac_address: MacAddr::from_slice(mac),
max_apdu_length: 1476,
segmentation_supported: bacnet_types::enums::Segmentation::NONE,
max_segments_accepted: None,
vendor_id: 0,
last_seen: std::time::Instant::now(),
source_network: None,
source_address: None,
};
self.device_table.lock().await.upsert(device);
Ok(())
}
}