realsense_rust/
device_hub.rs

1//! Type representing the concept of a "hub" that devices can connect to.
2
3use crate::{check_rs2_error, device::Device, kind::Rs2Exception};
4use anyhow::Result;
5use realsense_sys as sys;
6use std::{convert::From, ptr::NonNull};
7use thiserror::Error;
8
9/// Error describing when the device hub failed while attempting to wait for devices.
10///
11/// Can occur if there is an internal system exception while waiting for devices.
12#[derive(Error, Debug)]
13#[error("Could not wait for device due to internal error. Type: {0}; Reason: {1}")]
14pub struct CouldNotWaitForDeviceError(pub Rs2Exception, pub String);
15
16/// A type representing a hub for devices to connect to.
17///
18/// The device hub is a type used for waiting on a device connection or to check if a device is
19/// still connected.
20#[derive(Debug)]
21pub struct DeviceHub {
22    /// A non-null pointer to the underlying librealsense device hub.
23    devicehub_ptr: NonNull<sys::rs2_device_hub>,
24}
25
26impl Drop for DeviceHub {
27    fn drop(&mut self) {
28        unsafe {
29            sys::rs2_delete_device_hub(self.devicehub_ptr.as_ptr());
30        }
31    }
32}
33
34unsafe impl Send for DeviceHub {}
35
36impl From<NonNull<sys::rs2_device_hub>> for DeviceHub {
37    fn from(devicehub_ptr: NonNull<sys::rs2_device_hub>) -> Self {
38        Self { devicehub_ptr }
39    }
40}
41
42impl DeviceHub {
43    /// Gets a connected device, or waits for any device to be connected.
44    ///
45    /// If any device is connected, this method will return that device. It will cycle through
46    /// devices if multiple are connected. Otherwise, it blocks the calling thread until a device
47    /// is connected.
48    ///
49    /// # Errors
50    ///
51    /// Returns [`CouldNotWaitForDeviceError`] if an internal exception occurs while trying to wait
52    /// for device connections.
53    ///
54    /// Returns [`DeviceConstructionError`](crate::device::DeviceConstructionError) if a device is
55    /// found but an exception occurs during type construction.
56    ///
57    pub fn wait_for_device(&self) -> Result<Device> {
58        unsafe {
59            let mut err = std::ptr::null_mut::<sys::rs2_error>();
60            let device_ptr =
61                sys::rs2_device_hub_wait_for_device(self.devicehub_ptr.as_ptr(), &mut err);
62            check_rs2_error!(err, CouldNotWaitForDeviceError)?;
63
64            Ok(Device::from(NonNull::new(device_ptr).unwrap()))
65        }
66    }
67
68    /// Predicate to check whether a given device is connected.
69    pub fn is_device_connected(&self, device: &Device) -> bool {
70        unsafe {
71            let mut err = std::ptr::null_mut::<sys::rs2_error>();
72            let val = sys::rs2_device_hub_is_device_connected(
73                self.devicehub_ptr.as_ptr(),
74                device.get_raw().as_ptr(),
75                &mut err,
76            );
77
78            if err.as_ref().is_none() {
79                val != 0
80            } else {
81                sys::rs2_free_error(err);
82                false
83            }
84        }
85    }
86}