crazyflie_link/
context.rs1use crate::connection::Connection;
7use crate::connection::ConnectionTrait;
8use crate::crazyflie_usb_connection::CrazyflieUSBConnection;
9use crate::crazyradio::SharedCrazyradio;
10use crate::crazyradio_connection::CrazyradioConnection;
11use crate::error::{Error, Result};
12use futures_util::lock::Mutex;
13
14use std::collections::BTreeMap;
15use std::sync::{Arc, Weak};
16
17pub struct LinkContext {
19 radios: Mutex<BTreeMap<usize, Weak<SharedCrazyradio>>>,
20}
21
22impl LinkContext {
23 pub fn new() -> Self {
25 Self {
26 radios: Mutex::new(BTreeMap::new()),
27 }
28 }
29
30 pub(crate) async fn get_radio(&self, radio_nth: usize) -> Result<Arc<SharedCrazyradio>> {
31 let mut radios = self.radios.lock().await;
32
33 radios.entry(radio_nth).or_insert_with(Weak::new);
34
35 let radio = match Weak::upgrade(&radios[&radio_nth]) {
36 Some(radio) => radio,
37 None => {
38 let new_radio = crate::crazyradio::Crazyradio::open_nth_async(radio_nth).await?;
39 let new_radio = Arc::new(SharedCrazyradio::new(new_radio));
40 radios.insert(radio_nth, Arc::downgrade(&new_radio));
41
42 new_radio
43 }
44 };
45 Ok(radio)
46 }
47
48 pub async fn scan(&self, address: [u8; 5]) -> Result<Vec<String>> {
56 let mut found = Vec::new();
57
58 found.extend(CrazyradioConnection::scan(self, address).await?);
59 found.extend(CrazyflieUSBConnection::scan().await?);
60
61 Ok(found)
62 }
63
64 pub async fn scan_selected(&self, uris: Vec<&str>) -> Result<Vec<String>> {
70 let mut found = Vec::new();
71
72 found.extend(CrazyradioConnection::scan_selected(self, uris.clone()).await?);
73 found.extend(CrazyflieUSBConnection::scan_selected(uris).await?);
74
75 Ok(found)
76 }
77
78 pub async fn open_link(&self, uri: &str) -> Result<Connection> {
82 let connection: Option<Box<dyn ConnectionTrait + Send + Sync>> =
83 if let Some(connection) = CrazyradioConnection::open(self, uri).await? {
84 Some(Box::new(connection))
85 } else if let Some(connection) = CrazyflieUSBConnection::open(self, uri).await? {
86 Some(Box::new(connection))
87 } else {
88 None
89 };
90
91 let internal_connection = connection.ok_or(Error::InvalidUri)?;
92
93 Ok(Connection::new(internal_connection))
94 }
95}