Revert "Revert "uwb(hal): Implement UCI over serial in the defau..."

Revert submission 2528605-revert-2215484-pica_cf-BZDQSZLKEP

Reason for revert: revert^2

Reverted changes: /q/submissionid:2528605-revert-2215484-pica_cf-BZDQSZLKEP

Change-Id: I0c64b449c5da236a7cd63f88a605d48b9c471c67
diff --git a/uwb/aidl/default/src/service.rs b/uwb/aidl/default/src/service.rs
new file mode 100644
index 0000000..7d5c073
--- /dev/null
+++ b/uwb/aidl/default/src/service.rs
@@ -0,0 +1,47 @@
+use android_hardware_uwb::aidl::android::hardware::uwb::IUwb::{self, IUwb as _};
+use android_hardware_uwb::binder;
+
+use tokio::runtime::Runtime;
+
+use std::env;
+use std::panic;
+
+use log::Level;
+
+mod uwb;
+mod uwb_chip;
+
+fn main() -> anyhow::Result<()> {
+    logger::init(
+        logger::Config::default()
+            .with_min_level(Level::Debug)
+            .with_tag_on_device("android.hardware.uwb"),
+    );
+
+    // Redirect panic messages to logcat.
+    panic::set_hook(Box::new(|panic_info| {
+        log::error!("{}", panic_info);
+    }));
+
+    log::info!("UWB HAL starting up");
+
+    // Create the tokio runtime
+    let rt = Runtime::new()?;
+
+    let chips = env::args()
+        .skip(1) // Skip binary name
+        .enumerate()
+        .map(|(i, arg)| uwb_chip::UwbChip::new(i.to_string(), arg));
+
+    binder::add_service(
+        &format!("{}/default", IUwb::BpUwb::get_descriptor()),
+        IUwb::BnUwb::new_binder(
+            uwb::Uwb::from_chips(chips, rt.handle().clone()),
+            binder::BinderFeatures::default(),
+        )
+        .as_binder(),
+    )?;
+
+    binder::ProcessState::join_thread_pool();
+    Ok(())
+}
diff --git a/uwb/aidl/default/src/uwb.rs b/uwb/aidl/default/src/uwb.rs
new file mode 100644
index 0000000..428f08f
--- /dev/null
+++ b/uwb/aidl/default/src/uwb.rs
@@ -0,0 +1,53 @@
+use android_hardware_uwb::aidl::android::hardware::uwb::{IUwb, IUwbChip};
+use android_hardware_uwb::binder;
+use binder::{Result, Strong};
+use binder_tokio::TokioRuntime;
+use tokio::runtime::Handle as TokioHandle;
+
+use crate::uwb_chip;
+
+pub struct Uwb {
+    chips: Vec<Strong<dyn IUwbChip::IUwbChip>>,
+}
+
+impl Uwb {
+    pub fn from_chips(
+        chips: impl IntoIterator<Item = uwb_chip::UwbChip>,
+        handle: TokioHandle,
+    ) -> Self {
+        Self {
+            chips: chips
+                .into_iter()
+                .map(|chip| {
+                    IUwbChip::BnUwbChip::new_async_binder(
+                        chip,
+                        TokioRuntime(handle.clone()),
+                        binder::BinderFeatures::default(),
+                    )
+                })
+                .collect(),
+        }
+    }
+}
+
+impl binder::Interface for Uwb {}
+
+impl IUwb::IUwb for Uwb {
+    fn getChips(&self) -> Result<Vec<String>> {
+        log::debug!("getChips");
+        self.chips.iter().map(|chip| chip.getName()).collect()
+    }
+
+    fn getChip(&self, name: &str) -> Result<Strong<dyn IUwbChip::IUwbChip>> {
+        log::debug!("getChip {}", name);
+        let chip = self
+            .chips
+            .iter()
+            .find(|chip| chip.getName().as_deref() == Ok(name));
+        if let Some(chip) = chip {
+            Ok(chip.clone())
+        } else {
+            Err(binder::ExceptionCode::ILLEGAL_ARGUMENT.into())
+        }
+    }
+}
diff --git a/uwb/aidl/default/src/uwb_chip.rs b/uwb/aidl/default/src/uwb_chip.rs
new file mode 100644
index 0000000..7c2c300
--- /dev/null
+++ b/uwb/aidl/default/src/uwb_chip.rs
@@ -0,0 +1,168 @@
+use android_hardware_uwb::aidl::android::hardware::uwb::{
+    IUwbChip::IUwbChipAsyncServer, IUwbClientCallback::IUwbClientCallback, UwbEvent::UwbEvent,
+    UwbStatus::UwbStatus,
+};
+use android_hardware_uwb::binder;
+use async_trait::async_trait;
+use binder::{Result, Strong};
+
+use tokio::fs::File;
+use tokio::io::{AsyncReadExt, AsyncWriteExt};
+use tokio::sync::Mutex;
+
+use std::os::fd::AsRawFd;
+
+use std::io;
+
+use nix::sys::termios;
+
+enum State {
+    Closed,
+    Opened {
+        callbacks: Strong<dyn IUwbClientCallback>,
+        #[allow(dead_code)]
+        tasks: tokio::task::JoinSet<()>,
+        write: File,
+    },
+}
+
+pub struct UwbChip {
+    name: String,
+    path: String,
+    state: Mutex<State>,
+}
+
+impl UwbChip {
+    pub fn new(name: String, path: String) -> Self {
+        Self {
+            name,
+            path,
+            state: Mutex::new(State::Closed),
+        }
+    }
+}
+
+pub fn makeraw(file: File) -> io::Result<File> {
+    let fd = file.as_raw_fd();
+
+    let mut attrs = termios::tcgetattr(fd)?;
+
+    termios::cfmakeraw(&mut attrs);
+
+    termios::tcsetattr(fd, termios::SetArg::TCSANOW, &attrs)?;
+
+    Ok(file)
+}
+
+impl binder::Interface for UwbChip {}
+
+#[async_trait]
+impl IUwbChipAsyncServer for UwbChip {
+    async fn getName(&self) -> Result<String> {
+        Ok(self.name.clone())
+    }
+
+    async fn open(&self, callbacks: &Strong<dyn IUwbClientCallback>) -> Result<()> {
+        log::debug!("open: {:?}", &self.path);
+
+        let serial = File::open(&self.path)
+            .await
+            .and_then(makeraw)
+            .map_err(|_| binder::StatusCode::UNKNOWN_ERROR)?;
+
+        let mut read = serial
+            .try_clone()
+            .await
+            .map_err(|_| binder::StatusCode::UNKNOWN_ERROR)?;
+        let write = serial;
+
+        let mut state = self.state.lock().await;
+
+        if let State::Closed = *state {
+            let client_callbacks = callbacks.clone();
+
+            let mut tasks = tokio::task::JoinSet::new();
+
+            tasks.spawn(async move {
+                loop {
+                    const UWB_HEADER_SIZE: usize = 4;
+
+                    let mut buffer = vec![0; UWB_HEADER_SIZE];
+                    read.read_exact(&mut buffer[0..UWB_HEADER_SIZE])
+                        .await
+                        .unwrap();
+
+                    let length = buffer[3] as usize + UWB_HEADER_SIZE;
+
+                    buffer.resize(length, 0);
+                    read.read_exact(&mut buffer[UWB_HEADER_SIZE..length])
+                        .await
+                        .unwrap();
+
+                    client_callbacks.onUciMessage(&buffer[..]).unwrap();
+                }
+            });
+
+            callbacks.onHalEvent(UwbEvent::OPEN_CPLT, UwbStatus::OK)?;
+
+            *state = State::Opened {
+                callbacks: callbacks.clone(),
+                tasks,
+                write,
+            };
+
+            Ok(())
+        } else {
+            Err(binder::ExceptionCode::ILLEGAL_STATE.into())
+        }
+    }
+
+    async fn close(&self) -> Result<()> {
+        log::debug!("close");
+
+        let mut state = self.state.lock().await;
+
+        if let State::Opened { ref callbacks, .. } = *state {
+            callbacks.onHalEvent(UwbEvent::CLOSE_CPLT, UwbStatus::OK)?;
+            *state = State::Closed;
+            Ok(())
+        } else {
+            Err(binder::ExceptionCode::ILLEGAL_STATE.into())
+        }
+    }
+
+    async fn coreInit(&self) -> Result<()> {
+        log::debug!("coreInit");
+
+        if let State::Opened { ref callbacks, .. } = *self.state.lock().await {
+            callbacks.onHalEvent(UwbEvent::POST_INIT_CPLT, UwbStatus::OK)?;
+            Ok(())
+        } else {
+            Err(binder::ExceptionCode::ILLEGAL_STATE.into())
+        }
+    }
+
+    async fn sessionInit(&self, _id: i32) -> Result<()> {
+        log::debug!("sessionInit");
+
+        Ok(())
+    }
+
+    async fn getSupportedAndroidUciVersion(&self) -> Result<i32> {
+        Ok(1)
+    }
+
+    async fn sendUciMessage(&self, data: &[u8]) -> Result<i32> {
+        log::debug!("sendUciMessage");
+
+        if let State::Opened { write, .. } = &mut *self.state.lock().await {
+            write
+                .write(data)
+                .await
+                .map(|written| written as i32)
+                .map_err(|_| binder::StatusCode::UNKNOWN_ERROR.into())
+        } else {
+            Err(binder::ExceptionCode::ILLEGAL_STATE.into())
+        }
+    }
+}