From d572dd0bc7f59f10c8f0dd209e95399df529cb27 Mon Sep 17 00:00:00 2001 From: Charlie Boutier Date: Mon, 10 Apr 2023 18:14:23 +0000 Subject: [PATCH] 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 --- uwb/aidl/default/Android.bp | 31 +++--- uwb/aidl/default/service.cpp | 42 -------- uwb/aidl/default/src/service.rs | 47 +++++++++ uwb/aidl/default/src/uwb.rs | 53 ++++++++++ uwb/aidl/default/src/uwb_chip.rs | 168 +++++++++++++++++++++++++++++++ uwb/aidl/default/uwb-service.rc | 3 - uwb/aidl/default/uwb.cpp | 55 ---------- uwb/aidl/default/uwb.h | 49 --------- uwb/aidl/default/uwb_chip.cpp | 70 ------------- uwb/aidl/default/uwb_chip.h | 54 ---------- 10 files changed, 282 insertions(+), 290 deletions(-) delete mode 100644 uwb/aidl/default/service.cpp create mode 100644 uwb/aidl/default/src/service.rs create mode 100644 uwb/aidl/default/src/uwb.rs create mode 100644 uwb/aidl/default/src/uwb_chip.rs delete mode 100644 uwb/aidl/default/uwb-service.rc delete mode 100644 uwb/aidl/default/uwb.cpp delete mode 100644 uwb/aidl/default/uwb.h delete mode 100644 uwb/aidl/default/uwb_chip.cpp delete mode 100644 uwb/aidl/default/uwb_chip.h diff --git a/uwb/aidl/default/Android.bp b/uwb/aidl/default/Android.bp index 8c2b60e37d..9621f2cb10 100644 --- a/uwb/aidl/default/Android.bp +++ b/uwb/aidl/default/Android.bp @@ -7,29 +7,26 @@ package { default_applicable_licenses: ["hardware_interfaces_license"], } -cc_binary { +rust_binary { name: "android.hardware.uwb-service", + crate_name: "uwb_default_hal", relative_install_path: "hw", - init_rc: ["uwb-service.rc"], vintf_fragments: ["uwb-service.xml"], vendor: true, - cflags: [ - "-Wall", - "-Wextra", - "-g", + rustlibs: [ + "android.hardware.uwb-V1-rust", + "liblogger", + "liblog_rust", + "libbinder_rs", + "libbinder_tokio_rs", + "libtokio", + "libnix", + "libanyhow", ], - shared_libs: [ - "liblog", - "libbinder_ndk", - ], - static_libs: [ - "libbase", - "libutils", - "android.hardware.uwb-V1-ndk", + proc_macros: [ + "libasync_trait", ], srcs: [ - "service.cpp", - "uwb.cpp", - "uwb_chip.cpp", + "src/service.rs", ], } diff --git a/uwb/aidl/default/service.cpp b/uwb/aidl/default/service.cpp deleted file mode 100644 index 007637f5d1..0000000000 --- a/uwb/aidl/default/service.cpp +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2021, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include -#include - -#include "uwb.h" - -using ::aidl::android::hardware::uwb::IUwb; -using ::android::sp; -using ::android::base::InitLogging; -using ::android::base::StderrLogger; -using ::android::hardware::uwb::impl::Uwb; - -int main(int /*argc*/, char* argv[]) { - InitLogging(argv, StderrLogger); - LOG(INFO) << "UWB HAL starting up"; - - ABinderProcess_setThreadPoolMaxThreadCount(0); - std::shared_ptr uwb = ndk::SharedRefBase::make(); - const std::string instance = std::string() + IUwb::descriptor + "/default"; - binder_status_t status = AServiceManager_addService(uwb->asBinder().get(), instance.c_str()); - CHECK(status == STATUS_OK); - - ABinderProcess_joinThreadPool(); - return EXIT_FAILURE; // should not reach -} diff --git a/uwb/aidl/default/src/service.rs b/uwb/aidl/default/src/service.rs new file mode 100644 index 0000000000..7d5c07323f --- /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 0000000000..428f08fec0 --- /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>, +} + +impl Uwb { + pub fn from_chips( + chips: impl IntoIterator, + 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> { + log::debug!("getChips"); + self.chips.iter().map(|chip| chip.getName()).collect() + } + + fn getChip(&self, name: &str) -> Result> { + 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 0000000000..7c2c30056d --- /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, + #[allow(dead_code)] + tasks: tokio::task::JoinSet<()>, + write: File, + }, +} + +pub struct UwbChip { + name: String, + path: String, + state: Mutex, +} + +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 { + 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 { + Ok(self.name.clone()) + } + + async fn open(&self, callbacks: &Strong) -> 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 { + Ok(1) + } + + async fn sendUciMessage(&self, data: &[u8]) -> Result { + 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()) + } + } +} diff --git a/uwb/aidl/default/uwb-service.rc b/uwb/aidl/default/uwb-service.rc deleted file mode 100644 index e2c3825d35..0000000000 --- a/uwb/aidl/default/uwb-service.rc +++ /dev/null @@ -1,3 +0,0 @@ -service vendor.uwb_hal /vendor/bin/hw/android.hardware.uwb-service - class hal - user uwb diff --git a/uwb/aidl/default/uwb.cpp b/uwb/aidl/default/uwb.cpp deleted file mode 100644 index 1e2ef4e0a4..0000000000 --- a/uwb/aidl/default/uwb.cpp +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2021, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include - -#include "uwb.h" - -namespace { -static constexpr char kDefaultChipName[] = "default"; - -} // namespace - -namespace android { -namespace hardware { -namespace uwb { -namespace impl { -using namespace ::aidl::android::hardware::uwb; - -// The default implementation of the HAL assumes 1 chip on the device. -Uwb::Uwb() : chips_({{kDefaultChipName, ndk::SharedRefBase::make(kDefaultChipName)}}) {} - -Uwb::~Uwb() {} - -::ndk::ScopedAStatus Uwb::getChips(std::vector* names) { - for (const auto& chip : chips_) { - names->push_back(chip.first); - } - return ndk::ScopedAStatus::ok(); -} - -::ndk::ScopedAStatus Uwb::getChip(const std::string& name, std::shared_ptr* chip) { - const auto chip_found = chips_.find(name); - if (chip_found == chips_.end()) { - LOG(ERROR) << "Unknown chip name" << name; - return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); - } - *chip = chip_found->second; - return ndk::ScopedAStatus::ok(); -} -} // namespace impl -} // namespace uwb -} // namespace hardware -} // namespace android diff --git a/uwb/aidl/default/uwb.h b/uwb/aidl/default/uwb.h deleted file mode 100644 index ec51fd8a5c..0000000000 --- a/uwb/aidl/default/uwb.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2021, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifndef ANDROID_HARDWARE_UWB_UWB -#define ANDROID_HARDWARE_UWB_UWB - -#include -#include - -#include -#include - -#include "uwb_chip.h" - -namespace android { -namespace hardware { -namespace uwb { -namespace impl { -using namespace ::aidl::android::hardware::uwb; -// Default implementation mean't to be used on simulator targets. -class Uwb : public BnUwb { - public: - Uwb(); - virtual ~Uwb(); - - ::ndk::ScopedAStatus getChips(std::vector* names) override; - ::ndk::ScopedAStatus getChip(const std::string& name, std::shared_ptr* chip) override; - - private: - std::map> chips_; -}; -} // namespace impl -} // namespace uwb -} // namespace hardware -} // namespace android - -#endif // ANDROID_HARDWARE_UWB_UWB \ No newline at end of file diff --git a/uwb/aidl/default/uwb_chip.cpp b/uwb/aidl/default/uwb_chip.cpp deleted file mode 100644 index 41f14fd894..0000000000 --- a/uwb/aidl/default/uwb_chip.cpp +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2021, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "uwb.h" - -namespace { -constexpr static int32_t kAndroidUciVersion = 1; -} - -namespace android { -namespace hardware { -namespace uwb { -namespace impl { -using namespace ::aidl::android::hardware::uwb; - -UwbChip::UwbChip(const std::string& name) : name_(name), mClientCallback(nullptr) {} -UwbChip::~UwbChip() {} - -::ndk::ScopedAStatus UwbChip::getName(std::string* name) { - *name = name_; - return ndk::ScopedAStatus::ok(); -} - -::ndk::ScopedAStatus UwbChip::open(const std::shared_ptr& clientCallback) { - mClientCallback = clientCallback; - mClientCallback->onHalEvent(UwbEvent::OPEN_CPLT, UwbStatus::OK); - return ndk::ScopedAStatus::ok(); -} - -::ndk::ScopedAStatus UwbChip::close() { - mClientCallback->onHalEvent(UwbEvent::CLOSE_CPLT, UwbStatus::OK); - mClientCallback = nullptr; - return ndk::ScopedAStatus::ok(); -} - -::ndk::ScopedAStatus UwbChip::coreInit() { - return ndk::ScopedAStatus::ok(); -} - -::ndk::ScopedAStatus UwbChip::sessionInit(int /* sessionId */) { - return ndk::ScopedAStatus::ok(); -} - -::ndk::ScopedAStatus UwbChip::getSupportedAndroidUciVersion(int32_t* version) { - *version = kAndroidUciVersion; - return ndk::ScopedAStatus::ok(); -} - -::ndk::ScopedAStatus UwbChip::sendUciMessage(const std::vector& /* data */, - int32_t* /* bytes_written */) { - // TODO(b/195992658): Need emulator support for UCI stack. - return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); -} -} // namespace impl -} // namespace uwb -} // namespace hardware -} // namespace android diff --git a/uwb/aidl/default/uwb_chip.h b/uwb/aidl/default/uwb_chip.h deleted file mode 100644 index e900cbe123..0000000000 --- a/uwb/aidl/default/uwb_chip.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2021, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ANDROID_HARDWARE_UWB_UWBCHIP -#define ANDROID_HARDWARE_UWB_UWBCHIP - -#include - -#include -#include - -namespace android { -namespace hardware { -namespace uwb { -namespace impl { -using namespace ::aidl::android::hardware::uwb; -// Default implementation mean't to be used on simulator targets. -class UwbChip : public BnUwbChip { - public: - UwbChip(const std::string& name); - virtual ~UwbChip(); - - ::ndk::ScopedAStatus getName(std::string* name) override; - ::ndk::ScopedAStatus open(const std::shared_ptr& clientCallback) override; - ::ndk::ScopedAStatus close() override; - ::ndk::ScopedAStatus coreInit() override; - ::ndk::ScopedAStatus sessionInit(int sesionId) override; - ::ndk::ScopedAStatus getSupportedAndroidUciVersion(int32_t* version) override; - ::ndk::ScopedAStatus sendUciMessage(const std::vector& data, - int32_t* bytes_written) override; - - private: - std::string name_; - std::shared_ptr mClientCallback; -}; -} // namespace impl -} // namespace uwb -} // namespace hardware -} // namespace android - -#endif // ANDROID_HARDWARE_UWB_UWBCHIP