Merge "[uwb-chip] Send DeviceResetCmd and poll rsp and ntf before hal is closed." into main am: 141967eed6

Original change: https://android-review.googlesource.com/c/platform/hardware/interfaces/+/2862796

Change-Id: Ia9502591921c34b7db66803bd61d4d951f1d359e
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Bob Wang
2023-12-14 18:14:31 +00:00
committed by Automerger Merge Worker
2 changed files with 47 additions and 2 deletions

View File

@@ -24,6 +24,8 @@ rust_binary {
"libtokio_util",
"libnix",
"libanyhow",
"libpdl_runtime",
"libuwb_uci_packets",
],
proc_macros: [
"libasync_trait",

View File

@@ -16,6 +16,9 @@ use std::fs::{File, OpenOptions};
use std::io::{self, Read, Write};
use std::os::unix::fs::OpenOptionsExt;
use pdl_runtime::Packet;
use uwb_uci_packets::{DeviceResetCmdBuilder, ResetConfig, UciControlPacket, UciControlPacketHal};
enum State {
Closed,
Opened {
@@ -46,11 +49,23 @@ impl UwbChip {
impl State {
/// Terminate the reader task.
async fn close(&mut self) -> Result<()> {
if let State::Opened { ref mut token, ref callbacks, ref mut death_recipient, ref mut handle, .. } = *self {
if let State::Opened {
ref mut token,
ref callbacks,
ref mut death_recipient,
ref mut handle,
ref mut serial,
} = *self
{
log::info!("waiting for task cancellation");
callbacks.as_binder().unlink_to_death(death_recipient)?;
token.cancel();
handle.await.unwrap();
consume_device_reset_rsp_and_ntf(
&mut serial
.try_clone()
.map_err(|_| binder::StatusCode::UNKNOWN_ERROR)?,
);
log::info!("task successfully cancelled");
callbacks.onHalEvent(UwbEvent::CLOSE_CPLT, UwbStatus::OK)?;
*self = State::Closed;
@@ -59,6 +74,20 @@ impl State {
}
}
fn consume_device_reset_rsp_and_ntf(reader: &mut File) {
// Poll the DeviceResetRsp and DeviceStatusNtf before hal is closed to prevent
// the host from getting response and notifications from a 'powered down' UWBS.
// Do nothing when these packets are received.
const DEVICE_RESET_RSP: [u8; 5] = [64, 0, 0, 1, 0];
const DEVICE_STATUS_NTF: [u8; 5] = [96, 1, 0, 1, 1];
let mut buffer = vec![0; DEVICE_RESET_RSP.len() + DEVICE_STATUS_NTF.len()];
read_exact(reader, &mut buffer).unwrap();
// Make sure received packets are the expected ones.
assert_eq!(&buffer[0..DEVICE_RESET_RSP.len()], &DEVICE_RESET_RSP);
assert_eq!(&buffer[DEVICE_RESET_RSP.len()..], &DEVICE_STATUS_NTF);
}
pub fn makeraw(file: File) -> io::Result<File> {
// Configure the file descriptor as raw fd.
use nix::sys::termios::*;
@@ -209,7 +238,21 @@ impl IUwbChipAsyncServer for UwbChip {
let mut state = self.state.lock().await;
if matches!(*state, State::Opened { .. }) {
if let State::Opened { ref mut serial, .. } = *state {
let packet: UciControlPacket = DeviceResetCmdBuilder {
reset_config: ResetConfig::UwbsReset,
}
.build()
.into();
// DeviceResetCmd need to be send to reset the device to stop all running
// activities on UWBS.
let packet_vec: Vec<UciControlPacketHal> = packet.into();
for hal_packet in packet_vec.into_iter() {
serial
.write(&hal_packet.to_vec())
.map(|written| written as i32)
.map_err(|_| binder::StatusCode::UNKNOWN_ERROR)?;
}
state.close().await
} else {
Err(binder::ExceptionCode::ILLEGAL_STATE.into())