blob: cf3269488a326b2ca46569b8867e1e9e420dcf6a [file] [log] [blame]
Charlie Boutierd572dd02023-04-10 18:14:23 +00001use android_hardware_uwb::aidl::android::hardware::uwb::{
2 IUwbChip::IUwbChipAsyncServer, IUwbClientCallback::IUwbClientCallback, UwbEvent::UwbEvent,
3 UwbStatus::UwbStatus,
4};
5use android_hardware_uwb::binder;
6use async_trait::async_trait;
7use binder::{Result, Strong};
8
Charlie Boutier3561c842023-05-02 00:06:28 +00009use tokio::fs::{self, File};
10use tokio::io::AsyncReadExt;
Charlie Boutierd572dd02023-04-10 18:14:23 +000011use tokio::sync::Mutex;
12
13use std::os::fd::AsRawFd;
14
15use std::io;
16
17use nix::sys::termios;
18
19enum State {
20 Closed,
21 Opened {
22 callbacks: Strong<dyn IUwbClientCallback>,
23 #[allow(dead_code)]
24 tasks: tokio::task::JoinSet<()>,
Charlie Boutierd572dd02023-04-10 18:14:23 +000025 },
26}
27
28pub struct UwbChip {
29 name: String,
30 path: String,
31 state: Mutex<State>,
32}
33
34impl UwbChip {
35 pub fn new(name: String, path: String) -> Self {
36 Self {
37 name,
38 path,
39 state: Mutex::new(State::Closed),
40 }
41 }
42}
43
44pub fn makeraw(file: File) -> io::Result<File> {
45 let fd = file.as_raw_fd();
46
47 let mut attrs = termios::tcgetattr(fd)?;
48
49 termios::cfmakeraw(&mut attrs);
50
51 termios::tcsetattr(fd, termios::SetArg::TCSANOW, &attrs)?;
52
53 Ok(file)
54}
55
56impl binder::Interface for UwbChip {}
57
58#[async_trait]
59impl IUwbChipAsyncServer for UwbChip {
60 async fn getName(&self) -> Result<String> {
61 Ok(self.name.clone())
62 }
63
64 async fn open(&self, callbacks: &Strong<dyn IUwbClientCallback>) -> Result<()> {
65 log::debug!("open: {:?}", &self.path);
66
Charlie Boutier3561c842023-05-02 00:06:28 +000067 let mut serial = File::open(&self.path)
Charlie Boutierd572dd02023-04-10 18:14:23 +000068 .await
69 .and_then(makeraw)
70 .map_err(|_| binder::StatusCode::UNKNOWN_ERROR)?;
71
Charlie Boutierd572dd02023-04-10 18:14:23 +000072 let mut state = self.state.lock().await;
73
74 if let State::Closed = *state {
75 let client_callbacks = callbacks.clone();
76
77 let mut tasks = tokio::task::JoinSet::new();
78
79 tasks.spawn(async move {
80 loop {
81 const UWB_HEADER_SIZE: usize = 4;
82
83 let mut buffer = vec![0; UWB_HEADER_SIZE];
Charlie Boutier3561c842023-05-02 00:06:28 +000084 serial
85 .read_exact(&mut buffer[0..UWB_HEADER_SIZE])
Charlie Boutierd572dd02023-04-10 18:14:23 +000086 .await
87 .unwrap();
88
89 let length = buffer[3] as usize + UWB_HEADER_SIZE;
90
91 buffer.resize(length, 0);
Charlie Boutier3561c842023-05-02 00:06:28 +000092 serial
93 .read_exact(&mut buffer[UWB_HEADER_SIZE..length])
Charlie Boutierd572dd02023-04-10 18:14:23 +000094 .await
95 .unwrap();
96
97 client_callbacks.onUciMessage(&buffer[..]).unwrap();
98 }
99 });
100
101 callbacks.onHalEvent(UwbEvent::OPEN_CPLT, UwbStatus::OK)?;
102
103 *state = State::Opened {
104 callbacks: callbacks.clone(),
105 tasks,
Charlie Boutierd572dd02023-04-10 18:14:23 +0000106 };
107
108 Ok(())
109 } else {
110 Err(binder::ExceptionCode::ILLEGAL_STATE.into())
111 }
112 }
113
114 async fn close(&self) -> Result<()> {
115 log::debug!("close");
116
117 let mut state = self.state.lock().await;
118
119 if let State::Opened { ref callbacks, .. } = *state {
120 callbacks.onHalEvent(UwbEvent::CLOSE_CPLT, UwbStatus::OK)?;
121 *state = State::Closed;
122 Ok(())
123 } else {
124 Err(binder::ExceptionCode::ILLEGAL_STATE.into())
125 }
126 }
127
128 async fn coreInit(&self) -> Result<()> {
129 log::debug!("coreInit");
130
131 if let State::Opened { ref callbacks, .. } = *self.state.lock().await {
132 callbacks.onHalEvent(UwbEvent::POST_INIT_CPLT, UwbStatus::OK)?;
133 Ok(())
134 } else {
135 Err(binder::ExceptionCode::ILLEGAL_STATE.into())
136 }
137 }
138
139 async fn sessionInit(&self, _id: i32) -> Result<()> {
140 log::debug!("sessionInit");
141
142 Ok(())
143 }
144
145 async fn getSupportedAndroidUciVersion(&self) -> Result<i32> {
146 Ok(1)
147 }
148
149 async fn sendUciMessage(&self, data: &[u8]) -> Result<i32> {
150 log::debug!("sendUciMessage");
151
Charlie Boutier3561c842023-05-02 00:06:28 +0000152 if let State::Opened { .. } = &mut *self.state.lock().await {
153 fs::write(&self.path, data)
Charlie Boutierd572dd02023-04-10 18:14:23 +0000154 .await
Charlie Boutier3561c842023-05-02 00:06:28 +0000155 .map(|_| data.len() as i32)
Charlie Boutierd572dd02023-04-10 18:14:23 +0000156 .map_err(|_| binder::StatusCode::UNKNOWN_ERROR.into())
157 } else {
158 Err(binder::ExceptionCode::ILLEGAL_STATE.into())
159 }
160 }
161}