1use crate::config::AssistantConfig;
9use banc_icd::node::Identity;
10use banc_icd::{IdentifyEndpoint, PROTOCOL_VERSION};
11use postcard_rpc::header::VarSeqKind;
12use postcard_rpc::host_client::HostClient;
13use postcard_rpc::standard_icd::{WireError, ERROR_PATH};
14
15pub struct Node {
16 client: HostClient<WireError>,
17 pub identity: Identity,
18}
19
20impl Node {
21 pub async fn connect(cfg: &AssistantConfig) -> anyhow::Result<Node> {
23 let serial = cfg.serial.clone();
24 let product = cfg.product.clone();
25 let name = cfg.name.clone();
26 let client = HostClient::try_new_raw_nusb(
27 move |d| {
28 let serial_ok = serial
29 .as_deref()
30 .is_none_or(|want| d.serial_number() == Some(want));
31 let product_ok = product
32 .as_deref()
33 .is_none_or(|want| d.product_string() == Some(want));
34 serial_ok && product_ok
35 },
36 ERROR_PATH,
37 8,
38 VarSeqKind::Seq2,
39 )
40 .map_err(|e| anyhow::anyhow!("connecting to node '{name}': {e}"))?;
41
42 let identity = client
43 .send_resp::<IdentifyEndpoint>(&())
44 .await
45 .map_err(|e| anyhow::anyhow!("identify on node '{}': {e:?}", cfg.name))?;
46 anyhow::ensure!(
47 identity.protocol_version == PROTOCOL_VERSION,
48 "node '{}' speaks banc protocol v{}, host expects v{PROTOCOL_VERSION}",
49 cfg.name,
50 identity.protocol_version,
51 );
52 Ok(Node { client, identity })
53 }
54
55 pub fn client(&self) -> &HostClient<WireError> {
57 &self.client
58 }
59
60 pub async fn reset(&self) -> anyhow::Result<()> {
62 self.client
63 .send_resp::<banc_icd::ResetEndpoint>(&())
64 .await
65 .map_err(|e| anyhow::anyhow!("reset: {e:?}"))?;
66 Ok(())
67 }
68}