diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2023-03-28 17:19:17 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2023-03-28 17:19:17 +0000 |
commit | 141d58fff201c057b3576810cf2f1007bdda86cd (patch) | |
tree | 37c4f0391a822d753eb3c261ebe8656e34f72ae7 | |
parent | 17aa0f9c3367a54caac1ea7f0acb7d61c0801007 (diff) | |
parent | 8bae0d26ba5856dadbea4925ea131a80c228f812 (diff) | |
download | uwb-android13-mainline-wifi-release.tar.gz |
Snap for 9834661 from 8bae0d26ba5856dadbea4925ea131a80c228f812 to mainline-wifi-releaseaml_wif_331810010android13-mainline-wifi-release
Change-Id: I5bd2e3eb713ad7663f66d29c5fcbfde3afcdd711
24 files changed, 356 insertions, 203 deletions
diff --git a/src/Android.bp b/src/Android.bp index 4ceec78..1854c37 100755 --- a/src/Android.bp +++ b/src/Android.bp @@ -69,10 +69,7 @@ rust_library { genrule { name: "UwbGeneratedPackets_rust", - tools: [ - "bluetooth_packetgen", - ], - cmd: "$(location bluetooth_packetgen) --include=external/uwb/src --out=$(genDir) $(in) --rust", + defaults: ["pdl_rust_generator_defaults"], srcs: [ "rust/uwb_uci_packets/uci_packets.pdl", ], @@ -312,7 +309,7 @@ rust_library { genrule { name: "uwb_core_artifacts", tools: [ - "bluetooth_packetgen", + "pdl", "soong_zip", ], cmd: @@ -324,10 +321,9 @@ genrule { " $(genDir)/artifacts;" + // Generate uci_packets.rs at $(genDir)/artifacts/uwb_uci_packets/. - "$(location bluetooth_packetgen) --rust " + - " --include=external/uwb/src/rust" + - " --out=$(genDir)/artifacts " + - " external/uwb/src/rust/uwb_uci_packets/uci_packets.pdl;" + + "$(location pdl) --output-format rust " + + " external/uwb/src/rust/uwb_uci_packets/uci_packets.pdl " + + " > $(genDir)/artifacts/uwb_uci_packets/uci_packets.rs;" + // Pack the artifacts directory and clean up the directory. "$(location soong_zip) -o $(out) " + diff --git a/src/rust/uci_hal_android/uci_hal_android.rs b/src/rust/uci_hal_android/uci_hal_android.rs index e0971c1..1b32344 100644 --- a/src/rust/uci_hal_android/uci_hal_android.rs +++ b/src/rust/uci_hal_android/uci_hal_android.rs @@ -39,10 +39,10 @@ use uwb_uci_packets::{DeviceState, DeviceStatusNtfBuilder}; use crate::error::{Error, Result}; -fn input_uci_hal_packet<T: Into<uwb_uci_packets::UciControlPacketPacket>>( +fn input_uci_hal_packet<T: Into<uwb_uci_packets::UciControlPacket>>( builder: T, ) -> Vec<UciHalPacket> { - let packets: Vec<uwb_uci_packets::UciControlPacketHalPacket> = builder.into().into(); + let packets: Vec<uwb_uci_packets::UciControlPacketHal> = builder.into().into(); packets.into_iter().map(|packet| packet.into()).collect() } diff --git a/src/rust/uwb_core/README.md b/src/rust/uwb_core/README.md index ec3a2cf..0601af1 100644 --- a/src/rust/uwb_core/README.md +++ b/src/rust/uwb_core/README.md @@ -5,11 +5,11 @@ build and test the library by cargo. ## Building `uwb_uci_packets` package -The `uwb_uci_packets` package depends on `bluetooth_packetgen` and thus simply -using `cargo build` will fail. Follow the steps below before using cargo. +The `uwb_uci_packets` package depends on `pdl` and thus simply using `cargo +build` will fail. Follow the steps below before using cargo. 1. Enter Android environment by `source build/make/rbesetup.sh; lunch <target>` -2. Run `m -j32 bluetooth_packetgen` to compile `bluetooth_packetgen` c++ binary. +2. Run `m pdl` to compile the `pdl` Rust binary. After that, we could build or test the package by `cargo test --features proto`. diff --git a/src/rust/uwb_core/protos/uwb_service.proto b/src/rust/uwb_core/protos/uwb_service.proto index 171747f..0f99fef 100644 --- a/src/rust/uwb_core/protos/uwb_service.proto +++ b/src/rust/uwb_core/protos/uwb_service.proto @@ -103,6 +103,7 @@ enum StatusCode { UCI_STATUS_ERROR_CCC_SE_BUSY = 80; UCI_STATUS_ERROR_CCC_LIFECYCLE = 81; + UCI_STATUS_ERROR_STOPPED_DUE_TO_OTHER_SESSION_CONFLICT = 82; } // Represents uwb_uci_packets::OwrAoaStatusCode @@ -131,13 +132,46 @@ enum ReasonCode { STATE_CHANGE_WITH_SESSION_MANAGEMENT_COMMANDS = 0; MAX_RANGING_ROUND_RETRY_COUNT_REACHED = 1; MAX_NUMBER_OF_MEASUREMENTS_REACHED = 2; + SESSION_SUSPENDED_DUE_TO_INBAND_SIGNAL = 3; + SESSION_RESUMED_DUE_TO_INBAND_SIGNAL = 4; + SESSION_STOPPED_DUE_TO_INBAND_SIGNAL = 5; ERROR_INVALID_UL_TDOA_RANDOM_WINDOW = 29; + ERROR_MIN_RFRAMES_PER_RR_NOT_SUPPORTED = 30; + ERROR_TX_DELAY_NOT_SUPPORTED = 31; ERROR_SLOT_LENGTH_NOT_SUPPORTED = 32; ERROR_INSUFFICIENT_SLOTS_PER_RR = 33; ERROR_MAC_ADDRESS_MODE_NOT_SUPPORTED = 34; - ERROR_INVALID_RANGING_INTERVAL = 35; + ERROR_INVALID_RANGING_DURATION = 35; ERROR_INVALID_STS_CONFIG = 36; ERROR_INVALID_RFRAME_CONFIG = 37; + ERROR_HUS_NOT_ENOUGH_SLOTS = 38; + ERROR_HUS_CFP_PHASE_TOO_SHORT = 39; + ERROR_HUS_CAP_PHASE_TOO_SHORT = 40; + ERROR_HUS_OTHERS = 41; + ERROR_STATUS_SESSION_KEY_NOT_FOUND = 42; + ERROR_STATUS_SUB_SESSION_KEY_NOT_FOUND = 43; + ERROR_INVALID_PREAMBLE_CODE_INDEX = 44; + ERROR_INVALID_SFD_ID = 45; + ERROR_INVALID_PSDU_DATA_RATE = 46; + ERROR_INVALID_PHR_DATA_RATE = 47; + ERROR_INVALID_PREAMBLE_DURATION = 48; + ERROR_INVALID_STS_LENGTH = 49; + ERROR_INVALID_NUM_OF_STS_SEGMENTS = 50; + ERROR_INVALID_NUM_OF_CONTROLEES = 51; + ERROR_MAX_RANGING_REPLY_TIME_EXCEEDED = 52; + ERROR_INVALID_DST_ADDRESS_LIST = 53; + ERROR_INVALID_OR_NOT_FOUND_SUB_SESSION_ID = 54; + ERROR_INVALID_RESULT_REPORT_CONFIG = 55; + ERROR_INVALID_RANGING_ROUND_CONTROL_CONFIG = 56; + ERROR_INVALID_RANGING_ROUND_USAGE = 57; + ERROR_INVALID_MULTI_NODE_MODE = 58; + ERROR_RDS_FETCH_FAILURE = 59; + ERROR_REF_UWB_SESSION_DOES_NOT_EXIST = 60; + ERROR_REF_UWB_SESSION_RANGING_DURATION_MISMATCH = 61; + ERROR_REF_UWB_SESSION_INVALID_OFFSET_TIME = 62; + ERROR_REF_UWB_SESSION_LOST = 63; + ERROR_INVALID_CHANNEL_WITH_AOA = 128; + ERROR_STOPPED_DUE_TO_OTHER_SESSION_CONFLICT = 129; } // Represent uwb_uci_packets::RangingMeasurementType. diff --git a/src/rust/uwb_core/src/params/uci_packets.rs b/src/rust/uwb_core/src/params/uci_packets.rs index 6717a9b..e66856a 100644 --- a/src/rust/uwb_core/src/params/uci_packets.rs +++ b/src/rust/uwb_core/src/params/uci_packets.rs @@ -30,9 +30,7 @@ pub use uwb_uci_packets::{ ShortAddressOwrAoaRangingMeasurement, ShortAddressTwoWayRangingMeasurement, StatusCode, UpdateMulticastListAction, }; -pub(crate) use uwb_uci_packets::{ - UciControlPacketPacket, UciDataPacketHalPacket, UciDataPacketPacket, UciDataSndPacket, -}; +pub(crate) use uwb_uci_packets::{UciControlPacket, UciDataPacket, UciDataPacketHal, UciDataSnd}; use crate::error::Error; @@ -205,8 +203,8 @@ pub struct RawUciMessage { pub payload: Vec<u8>, } -impl From<UciControlPacketPacket> for RawUciMessage { - fn from(packet: UciControlPacketPacket) -> Self { +impl From<UciControlPacket> for RawUciMessage { + fn from(packet: UciControlPacket) -> Self { Self { gid: packet.get_group_id() as u32, oid: packet.get_opcode() as u32, diff --git a/src/rust/uwb_core/src/proto/mappings.rs b/src/rust/uwb_core/src/proto/mappings.rs index 2722307..328b675 100644 --- a/src/rust/uwb_core/src/proto/mappings.rs +++ b/src/rust/uwb_core/src/proto/mappings.rs @@ -145,6 +145,7 @@ enum_mapping! { UCI_STATUS_DATA_RX_CRC_ERROR => UciStatusDataRxCrcError, UCI_STATUS_ERROR_CCC_SE_BUSY => UciStatusErrorCccSeBusy, UCI_STATUS_ERROR_CCC_LIFECYCLE => UciStatusErrorCccLifecycle, + UCI_STATUS_ERROR_STOPPED_DUE_TO_OTHER_SESSION_CONFLICT => UciStatusErrorStoppedDueToOtherSessionConflict, } enum_mapping! { @@ -173,13 +174,46 @@ enum_mapping! { STATE_CHANGE_WITH_SESSION_MANAGEMENT_COMMANDS => StateChangeWithSessionManagementCommands, MAX_RANGING_ROUND_RETRY_COUNT_REACHED => MaxRangingRoundRetryCountReached, MAX_NUMBER_OF_MEASUREMENTS_REACHED => MaxNumberOfMeasurementsReached, + SESSION_SUSPENDED_DUE_TO_INBAND_SIGNAL => SessionSuspendedDueToInbandSignal, + SESSION_RESUMED_DUE_TO_INBAND_SIGNAL => SessionResumedDueToInbandSignal, + SESSION_STOPPED_DUE_TO_INBAND_SIGNAL => SessionStoppedDueToInbandSignal, ERROR_INVALID_UL_TDOA_RANDOM_WINDOW => ErrorInvalidUlTdoaRandomWindow, + ERROR_MIN_RFRAMES_PER_RR_NOT_SUPPORTED => ErrorMinRframesPerRrNotSupported, + ERROR_TX_DELAY_NOT_SUPPORTED => ErrorTxDelayNotSupported, ERROR_SLOT_LENGTH_NOT_SUPPORTED => ErrorSlotLengthNotSupported, ERROR_INSUFFICIENT_SLOTS_PER_RR => ErrorInsufficientSlotsPerRr, ERROR_MAC_ADDRESS_MODE_NOT_SUPPORTED => ErrorMacAddressModeNotSupported, - ERROR_INVALID_RANGING_INTERVAL => ErrorInvalidRangingInterval, + ERROR_INVALID_RANGING_DURATION => ErrorInvalidRangingDuration, ERROR_INVALID_STS_CONFIG => ErrorInvalidStsConfig, ERROR_INVALID_RFRAME_CONFIG => ErrorInvalidRframeConfig, + ERROR_HUS_NOT_ENOUGH_SLOTS => ErrorHusNotEnoughSlots, + ERROR_HUS_CFP_PHASE_TOO_SHORT => ErrorHusCfpPhaseTooShort, + ERROR_HUS_CAP_PHASE_TOO_SHORT => ErrorHusCapPhaseTooShort, + ERROR_HUS_OTHERS => ErrorHusOthers, + ERROR_STATUS_SESSION_KEY_NOT_FOUND => ErrorStatusSessionKeyNotFound, + ERROR_STATUS_SUB_SESSION_KEY_NOT_FOUND => ErrorStatusSubSessionKeyNotFound, + ERROR_INVALID_PREAMBLE_CODE_INDEX => ErrorInvalidPreambleCodeIndex, + ERROR_INVALID_SFD_ID => ErrorInvalidSfdId, + ERROR_INVALID_PSDU_DATA_RATE => ErrorInvalidPsduDataRate, + ERROR_INVALID_PHR_DATA_RATE => ErrorInvalidPhrDataRate, + ERROR_INVALID_PREAMBLE_DURATION => ErrorInvalidPreambleDuration, + ERROR_INVALID_STS_LENGTH => ErrorInvalidStsLength, + ERROR_INVALID_NUM_OF_STS_SEGMENTS => ErrorInvalidNumOfStsSegments, + ERROR_INVALID_NUM_OF_CONTROLEES => ErrorInvalidNumOfControlees, + ERROR_MAX_RANGING_REPLY_TIME_EXCEEDED => ErrorMaxRangingReplyTimeExceeded, + ERROR_INVALID_DST_ADDRESS_LIST => ErrorInvalidDstAddressList, + ERROR_INVALID_OR_NOT_FOUND_SUB_SESSION_ID => ErrorInvalidOrNotFoundSubSessionId, + ERROR_INVALID_RESULT_REPORT_CONFIG => ErrorInvalidResultReportConfig, + ERROR_INVALID_RANGING_ROUND_CONTROL_CONFIG => ErrorInvalidRangingRoundControlConfig, + ERROR_INVALID_RANGING_ROUND_USAGE => ErrorInvalidRangingRoundUsage, + ERROR_INVALID_MULTI_NODE_MODE => ErrorInvalidMultiNodeMode, + ERROR_RDS_FETCH_FAILURE => ErrorRdsFetchFailure, + ERROR_REF_UWB_SESSION_DOES_NOT_EXIST => ErrorRefUwbSessionDoesNotExist, + ERROR_REF_UWB_SESSION_RANGING_DURATION_MISMATCH => ErrorRefUwbSessionRangingDurationMismatch, + ERROR_REF_UWB_SESSION_INVALID_OFFSET_TIME => ErrorRefUwbSessionInvalidOffsetTime, + ERROR_REF_UWB_SESSION_LOST => ErrorRefUwbSessionLost, + ERROR_INVALID_CHANNEL_WITH_AOA => ErrorInvalidChannelWithAoa, + ERROR_STOPPED_DUE_TO_OTHER_SESSION_CONFLICT => ErrorStoppedDueToOtherSessionConflict, } enum_mapping! { diff --git a/src/rust/uwb_core/src/service/proto_uwb_service.rs b/src/rust/uwb_core/src/service/proto_uwb_service.rs index 6cf7d5a..747865a 100644 --- a/src/rust/uwb_core/src/service/proto_uwb_service.rs +++ b/src/rust/uwb_core/src/service/proto_uwb_service.rs @@ -267,7 +267,7 @@ impl<C: ProtoUwbServiceCallback> UwbServiceCallback for C { } fn on_uci_device_status_changed(&mut self, state: DeviceState) { - debug!("UCI device status is changed: {}", state); + debug!("UCI device status is changed: {:?}", state); let mut msg = UciDeviceStatusChangedSignal::new(); msg.set_state(state.into()); if let Ok(payload) = write_to_bytes(&msg) { diff --git a/src/rust/uwb_core/src/service/uwb_service.rs b/src/rust/uwb_core/src/service/uwb_service.rs index 8c47243..a2ecb85 100644 --- a/src/rust/uwb_core/src/service/uwb_service.rs +++ b/src/rust/uwb_core/src/service/uwb_service.rs @@ -60,7 +60,7 @@ pub trait UwbServiceCallback: 'static { /// Notify the vendor notification is received. fn on_vendor_notification_received(&mut self, gid: u32, oid: u32, payload: Vec<u8>); - // TODO(b/261762781): In the future, add a callback here to notify the Data Rx packet. + // TODO(b/270443790): In the future, add a callback here to notify the Data Rx packet. } /// A placeholder implementation for UwbServiceCallback that does nothing. diff --git a/src/rust/uwb_core/src/session/session_manager.rs b/src/rust/uwb_core/src/session/session_manager.rs index 92e7923..3b08b52 100644 --- a/src/rust/uwb_core/src/session/session_manager.rs +++ b/src/rust/uwb_core/src/session/session_manager.rs @@ -26,6 +26,7 @@ use crate::session::uwb_session::{Response as SessionResponse, ResponseSender, U use crate::uci::notification::{SessionNotification as UciSessionNotification, SessionRangeData}; use crate::uci::uci_manager::UciManager; use crate::utils::clean_mpsc_receiver; +use num_traits::FromPrimitive; const MAX_SESSION_COUNT: usize = 5; @@ -295,6 +296,16 @@ impl<T: UciManager> SessionManagerActor<T> { fn handle_uci_notification(&mut self, notf: UciSessionNotification) { match notf { UciSessionNotification::Status { session_id, session_state, reason_code } => { + let reason_code = match ReasonCode::from_u8(reason_code) { + Some(r) => r, + None => { + error!( + "Received unknown reason_code {:?} in UciSessionNotification", + reason_code + ); + return; + } + }; if session_state == SessionState::SessionStateDeinit { debug!("Session {} is deinitialized", session_id); let _ = self.active_sessions.remove(&session_id); @@ -350,7 +361,7 @@ impl<T: UciManager> SessionManagerActor<T> { match self.active_sessions.get(&session_id) { Some(_) => { /* - * TODO(b/261886903): Handle the DataCredit notification in the new + * TODO(b/270443790): Handle the DataCredit notification in the new * code flow. */ } @@ -370,7 +381,7 @@ impl<T: UciManager> SessionManagerActor<T> { match self.active_sessions.get(&session_id) { Some(_) => { /* - * TODO(b/261886903): Handle the DataTransferStatus notification in the + * TODO(b/270443790): Handle the DataTransferStatus notification in the * new code flow. */ } @@ -435,6 +446,7 @@ pub(crate) mod test_utils { use crate::uci::mock_uci_manager::MockUciManager; use crate::uci::notification::{RangingMeasurements, UciNotification}; use crate::utils::init_test_logging; + use num_traits::ToPrimitive; pub(crate) fn generate_params() -> AppConfigParams { FiraAppConfigParamsBuilder::new() @@ -504,7 +516,7 @@ pub(crate) mod test_utils { UciNotification::Session(UciSessionNotification::Status { session_id, session_state, - reason_code: ReasonCode::StateChangeWithSessionManagementCommands, + reason_code: ReasonCode::StateChangeWithSessionManagementCommands.to_u8().unwrap(), }) } @@ -545,7 +557,7 @@ mod tests { use crate::params::ccc_started_app_config_params::CccStartedAppConfigParams; use crate::params::uci_packets::{ AppConfigTlv, AppConfigTlvType, ControleeStatus, Controlees, MulticastUpdateStatusCode, - SetAppConfigResponse, StatusCode, + ReasonCode, SetAppConfigResponse, StatusCode, }; use crate::params::utils::{u32_to_bytes, u64_to_bytes, u8_to_bytes}; use crate::params::{FiraAppConfigParamsBuilder, KeyRotation}; diff --git a/src/rust/uwb_core/src/uci/command.rs b/src/rust/uwb_core/src/uci/command.rs index 3230531..eb3b3df 100644 --- a/src/rust/uwb_core/src/uci/command.rs +++ b/src/rust/uwb_core/src/uci/command.rs @@ -89,7 +89,7 @@ pub enum UciCommand { }, } -impl TryFrom<UciCommand> for uwb_uci_packets::UciControlPacketPacket { +impl TryFrom<UciCommand> for uwb_uci_packets::UciControlPacket { type Error = Error; fn try_from(cmd: UciCommand) -> std::result::Result<Self, Self::Error> { let packet = match cmd { @@ -183,7 +183,7 @@ fn build_raw_uci_cmd_packet( gid: u32, oid: u32, payload: Vec<u8>, -) -> Result<uwb_uci_packets::UciControlPacketPacket> { +) -> Result<uwb_uci_packets::UciControlPacket> { let group_id = GroupId::from_u32(gid).ok_or_else(|| { error!("Invalid GroupId: {}", gid); Error::BadParameters diff --git a/src/rust/uwb_core/src/uci/message.rs b/src/rust/uwb_core/src/uci/message.rs index 2f4f573..fcbc65d 100644 --- a/src/rust/uwb_core/src/uci/message.rs +++ b/src/rust/uwb_core/src/uci/message.rs @@ -26,9 +26,9 @@ pub(super) enum UciMessage { Notification(UciNotification), } -impl TryFrom<uwb_uci_packets::UciControlPacketPacket> for UciMessage { +impl TryFrom<uwb_uci_packets::UciControlPacket> for UciMessage { type Error = Error; - fn try_from(packet: uwb_uci_packets::UciControlPacketPacket) -> Result<Self, Self::Error> { + fn try_from(packet: uwb_uci_packets::UciControlPacket) -> Result<Self, Self::Error> { match packet.specialize() { uwb_uci_packets::UciControlPacketChild::UciResponse(evt) => { Ok(UciMessage::Response(evt.try_into()?)) diff --git a/src/rust/uwb_core/src/uci/mock_uci_logger.rs b/src/rust/uwb_core/src/uci/mock_uci_logger.rs index 544569c..e21fb71 100644 --- a/src/rust/uwb_core/src/uci/mock_uci_logger.rs +++ b/src/rust/uwb_core/src/uci/mock_uci_logger.rs @@ -15,7 +15,7 @@ use std::convert::TryFrom; use tokio::sync::mpsc; -use uwb_uci_packets::{UciControlPacketPacket, UciDataPacketPacket}; +use uwb_uci_packets::{UciControlPacket, UciDataPacket}; use crate::error::{Error, Result}; use crate::uci::uci_logger::UciLogger; @@ -57,11 +57,11 @@ impl UciLogger for MockUciLogger { let _ = self.log_sender.send(UciLogEvent::HalOpen(result)); } - fn log_uci_control_packet(&mut self, packet: UciControlPacketPacket) { + fn log_uci_control_packet(&mut self, packet: UciControlPacket) { let _ = self.log_sender.send(UciLogEvent::Packet(packet.into())); } - fn log_uci_data_packet(&mut self, packet: &UciDataPacketPacket) { + fn log_uci_data_packet(&mut self, packet: &UciDataPacket) { let _ = self.log_sender.send(UciLogEvent::Packet(packet.clone().into())); } } diff --git a/src/rust/uwb_core/src/uci/notification.rs b/src/rust/uwb_core/src/uci/notification.rs index a390d58..d68bd1c 100644 --- a/src/rust/uwb_core/src/uci/notification.rs +++ b/src/rust/uwb_core/src/uci/notification.rs @@ -16,7 +16,7 @@ use std::convert::{TryFrom, TryInto}; use log::{debug, error}; use num_traits::ToPrimitive; -use uwb_uci_packets::{parse_diagnostics_ntf, Packet}; +use uwb_uci_packets::{parse_diagnostics_ntf, Packet, UCI_PACKET_HEADER_LEN}; use crate::error::{Error, Result}; use crate::params::fira_app_config_params::UwbAddress; @@ -24,16 +24,16 @@ use crate::params::uci_packets::{ ControleeStatus, CreditAvailability, DataRcvStatusCode, DataTransferNtfStatusCode, DeviceState, ExtendedAddressDlTdoaRangingMeasurement, ExtendedAddressOwrAoaRangingMeasurement, ExtendedAddressTwoWayRangingMeasurement, FiraComponent, RangingMeasurementType, RawUciMessage, - ReasonCode, SessionId, SessionState, ShortAddressDlTdoaRangingMeasurement, + SessionId, SessionState, ShortAddressDlTdoaRangingMeasurement, ShortAddressOwrAoaRangingMeasurement, ShortAddressTwoWayRangingMeasurement, StatusCode, }; /// enum of all UCI notifications with structured fields. #[derive(Debug, Clone, PartialEq)] pub enum UciNotification { - /// CoreNotificationPacket equivalent. + /// CoreNotification equivalent. Core(CoreNotification), - /// SessionNotificationPacket equivalent. + /// SessionNotification equivalent. Session(SessionNotification), /// UciVendor_X_Notification equivalent. Vendor(RawUciMessage), @@ -58,7 +58,7 @@ pub enum SessionNotification { /// uwb_uci_packets::SessionState. session_state: SessionState, /// uwb_uci_packets::Reasoncode. - reason_code: ReasonCode, + reason_code: u8, }, /// SessionUpdateControllerMulticastListNtf equivalent. UpdateControllerMulticastList { @@ -162,11 +162,9 @@ pub struct DataRcvNotification { pub payload: Vec<u8>, } -impl TryFrom<uwb_uci_packets::UciDataPacketPacket> for DataRcvNotification { +impl TryFrom<uwb_uci_packets::UciDataPacket> for DataRcvNotification { type Error = Error; - fn try_from( - evt: uwb_uci_packets::UciDataPacketPacket, - ) -> std::result::Result<Self, Self::Error> { + fn try_from(evt: uwb_uci_packets::UciDataPacket) -> std::result::Result<Self, Self::Error> { match evt.specialize() { uwb_uci_packets::UciDataPacketChild::UciDataRcv(evt) => Ok(DataRcvNotification { session_id: evt.get_session_id(), @@ -194,11 +192,9 @@ impl UciNotification { } } -impl TryFrom<uwb_uci_packets::UciNotificationPacket> for UciNotification { +impl TryFrom<uwb_uci_packets::UciNotification> for UciNotification { type Error = Error; - fn try_from( - evt: uwb_uci_packets::UciNotificationPacket, - ) -> std::result::Result<Self, Self::Error> { + fn try_from(evt: uwb_uci_packets::UciNotification) -> std::result::Result<Self, Self::Error> { use uwb_uci_packets::UciNotificationChild; match evt.specialize() { UciNotificationChild::CoreNotification(evt) => Ok(Self::Core(evt.try_into()?)), @@ -215,18 +211,16 @@ impl TryFrom<uwb_uci_packets::UciNotificationPacket> for UciNotification { UciNotificationChild::UciVendor_E_Notification(evt) => vendor_notification(evt.into()), UciNotificationChild::UciVendor_F_Notification(evt) => vendor_notification(evt.into()), _ => { - error!("Unknown UciNotificationPacket: {:?}", evt); + error!("Unknown UciNotification: {:?}", evt); Err(Error::Unknown) } } } } -impl TryFrom<uwb_uci_packets::CoreNotificationPacket> for CoreNotification { +impl TryFrom<uwb_uci_packets::CoreNotification> for CoreNotification { type Error = Error; - fn try_from( - evt: uwb_uci_packets::CoreNotificationPacket, - ) -> std::result::Result<Self, Self::Error> { + fn try_from(evt: uwb_uci_packets::CoreNotification) -> std::result::Result<Self, Self::Error> { use uwb_uci_packets::CoreNotificationChild; match evt.specialize() { CoreNotificationChild::DeviceStatusNtf(evt) => { @@ -234,17 +228,17 @@ impl TryFrom<uwb_uci_packets::CoreNotificationPacket> for CoreNotification { } CoreNotificationChild::GenericError(evt) => Ok(Self::GenericError(evt.get_status())), _ => { - error!("Unknown CoreNotificationPacket: {:?}", evt); + error!("Unknown CoreNotification: {:?}", evt); Err(Error::Unknown) } } } } -impl TryFrom<uwb_uci_packets::SessionConfigNotificationPacket> for SessionNotification { +impl TryFrom<uwb_uci_packets::SessionConfigNotification> for SessionNotification { type Error = Error; fn try_from( - evt: uwb_uci_packets::SessionConfigNotificationPacket, + evt: uwb_uci_packets::SessionConfigNotification, ) -> std::result::Result<Self, Self::Error> { use uwb_uci_packets::SessionConfigNotificationChild; match evt.specialize() { @@ -261,17 +255,17 @@ impl TryFrom<uwb_uci_packets::SessionConfigNotificationPacket> for SessionNotifi }) } _ => { - error!("Unknown SessionConfigNotificationPacket: {:?}", evt); + error!("Unknown SessionConfigNotification: {:?}", evt); Err(Error::Unknown) } } } } -impl TryFrom<uwb_uci_packets::SessionControlNotificationPacket> for SessionNotification { +impl TryFrom<uwb_uci_packets::SessionControlNotification> for SessionNotification { type Error = Error; fn try_from( - evt: uwb_uci_packets::SessionControlNotificationPacket, + evt: uwb_uci_packets::SessionControlNotification, ) -> std::result::Result<Self, Self::Error> { use uwb_uci_packets::SessionControlNotificationChild; match evt.specialize() { @@ -288,19 +282,17 @@ impl TryFrom<uwb_uci_packets::SessionControlNotificationPacket> for SessionNotif }) } _ => { - error!("Unknown SessionControlNotificationPacket: {:?}", evt); + error!("Unknown SessionControlNotification: {:?}", evt); Err(Error::Unknown) } } } } -impl TryFrom<uwb_uci_packets::SessionInfoNtfPacket> for SessionNotification { +impl TryFrom<uwb_uci_packets::SessionInfoNtf> for SessionNotification { type Error = Error; - fn try_from( - evt: uwb_uci_packets::SessionInfoNtfPacket, - ) -> std::result::Result<Self, Self::Error> { - let raw_ranging_data = evt.clone().to_vec(); + fn try_from(evt: uwb_uci_packets::SessionInfoNtf) -> std::result::Result<Self, Self::Error> { + let raw_ranging_data = evt.clone().to_bytes()[UCI_PACKET_HEADER_LEN..].to_vec(); use uwb_uci_packets::SessionInfoNtfChild; let ranging_measurements = match evt.specialize() { SessionInfoNtfChild::ShortMacTwoWaySessionInfoNtf(evt) => { @@ -366,7 +358,7 @@ impl TryFrom<uwb_uci_packets::SessionInfoNtfPacket> for SessionNotification { } } _ => { - error!("Unknown SessionInfoNtfPacket: {:?}", evt); + error!("Unknown SessionInfoNtf: {:?}", evt); return Err(Error::Unknown); } }; @@ -382,10 +374,10 @@ impl TryFrom<uwb_uci_packets::SessionInfoNtfPacket> for SessionNotification { } } -impl TryFrom<uwb_uci_packets::AndroidNotificationPacket> for UciNotification { +impl TryFrom<uwb_uci_packets::AndroidNotification> for UciNotification { type Error = Error; fn try_from( - evt: uwb_uci_packets::AndroidNotificationPacket, + evt: uwb_uci_packets::AndroidNotification, ) -> std::result::Result<Self, Self::Error> { use uwb_uci_packets::AndroidNotificationChild; @@ -393,13 +385,13 @@ impl TryFrom<uwb_uci_packets::AndroidNotificationPacket> for UciNotification { if let AndroidNotificationChild::AndroidRangeDiagnosticsNtf(ntf) = evt.specialize() { debug!("Received diagnostic packet: {:?}", parse_diagnostics_ntf(ntf)); } else { - error!("Received unknown AndroidNotificationPacket: {:?}", evt); + error!("Received unknown AndroidNotification: {:?}", evt); } Err(Error::Unknown) } } -fn vendor_notification(evt: uwb_uci_packets::UciNotificationPacket) -> Result<UciNotification> { +fn vendor_notification(evt: uwb_uci_packets::UciNotification) -> Result<UciNotification> { Ok(UciNotification::Vendor(RawUciMessage { gid: evt.get_group_id().to_u32().ok_or_else(|| { error!("Failed to get gid from packet: {:?}", evt); @@ -413,7 +405,7 @@ fn vendor_notification(evt: uwb_uci_packets::UciNotificationPacket) -> Result<Uc })) } -fn get_vendor_uci_payload(evt: uwb_uci_packets::UciNotificationPacket) -> Result<Vec<u8>> { +fn get_vendor_uci_payload(evt: uwb_uci_packets::UciNotification) -> Result<Vec<u8>> { match evt.specialize() { uwb_uci_packets::UciNotificationChild::UciVendor_9_Notification(evt) => { match evt.specialize() { @@ -504,7 +496,7 @@ mod tests { } .build(); let core_notification = - uwb_uci_packets::CoreNotificationPacket::try_from(generic_error_packet).unwrap(); + uwb_uci_packets::CoreNotification::try_from(generic_error_packet).unwrap(); let core_notification = CoreNotification::try_from(core_notification).unwrap(); let uci_notification_from_generic_error = UciNotification::Core(core_notification); assert_eq!( @@ -521,7 +513,7 @@ mod tests { } .build(); let core_notification = - uwb_uci_packets::CoreNotificationPacket::try_from(device_status_ntf_packet).unwrap(); + uwb_uci_packets::CoreNotification::try_from(device_status_ntf_packet).unwrap(); let uci_notification = CoreNotification::try_from(core_notification).unwrap(); let uci_notification_from_device_status_ntf = UciNotification::Core(uci_notification); assert_eq!( @@ -557,12 +549,13 @@ mod tests { rcr_indicator: 0x12, current_ranging_interval: 0x13, two_way_ranging_measurements: vec![extended_measurement.clone()], + vendor_data: vec![], } .build(); - let raw_ranging_data = extended_two_way_session_info_ntf.clone().to_vec(); + let raw_ranging_data = + extended_two_way_session_info_ntf.clone().to_bytes()[UCI_PACKET_HEADER_LEN..].to_vec(); let range_notification = - uwb_uci_packets::SessionInfoNtfPacket::try_from(extended_two_way_session_info_ntf) - .unwrap(); + uwb_uci_packets::SessionInfoNtf::try_from(extended_two_way_session_info_ntf).unwrap(); let session_notification = SessionNotification::try_from(range_notification).unwrap(); let uci_notification_from_extended_two_way_session_info_ntf = UciNotification::Session(session_notification); @@ -606,12 +599,13 @@ mod tests { rcr_indicator: 0x12, current_ranging_interval: 0x13, two_way_ranging_measurements: vec![short_measurement.clone()], + vendor_data: vec![0x02, 0x01], } .build(); - let raw_ranging_data = short_two_way_session_info_ntf.clone().to_vec(); + let raw_ranging_data = + short_two_way_session_info_ntf.clone().to_bytes()[UCI_PACKET_HEADER_LEN..].to_vec(); let range_notification = - uwb_uci_packets::SessionInfoNtfPacket::try_from(short_two_way_session_info_ntf) - .unwrap(); + uwb_uci_packets::SessionInfoNtf::try_from(short_two_way_session_info_ntf).unwrap(); let session_notification = SessionNotification::try_from(range_notification).unwrap(); let uci_notification_from_short_two_way_session_info_ntf = UciNotification::Session(session_notification); @@ -651,12 +645,13 @@ mod tests { rcr_indicator: 0x12, current_ranging_interval: 0x13, owr_aoa_ranging_measurements: vec![extended_measurement.clone()], + vendor_data: vec![], } .build(); - let raw_ranging_data = extended_owr_aoa_session_info_ntf.clone().to_vec(); + let raw_ranging_data = + extended_owr_aoa_session_info_ntf.clone().to_bytes()[UCI_PACKET_HEADER_LEN..].to_vec(); let range_notification = - uwb_uci_packets::SessionInfoNtfPacket::try_from(extended_owr_aoa_session_info_ntf) - .unwrap(); + uwb_uci_packets::SessionInfoNtf::try_from(extended_owr_aoa_session_info_ntf).unwrap(); let session_notification = SessionNotification::try_from(range_notification).unwrap(); let uci_notification_from_extended_owr_aoa_session_info_ntf = UciNotification::Session(session_notification); @@ -695,12 +690,13 @@ mod tests { rcr_indicator: 0x12, current_ranging_interval: 0x13, owr_aoa_ranging_measurements: vec![short_measurement.clone()], + vendor_data: vec![], } .build(); - let raw_ranging_data = short_owr_aoa_session_info_ntf.clone().to_vec(); + let raw_ranging_data = + short_owr_aoa_session_info_ntf.clone().to_bytes()[UCI_PACKET_HEADER_LEN..].to_vec(); let range_notification = - uwb_uci_packets::SessionInfoNtfPacket::try_from(short_owr_aoa_session_info_ntf) - .unwrap(); + uwb_uci_packets::SessionInfoNtf::try_from(short_owr_aoa_session_info_ntf).unwrap(); let session_notification = SessionNotification::try_from(range_notification).unwrap(); let uci_notification_from_short_owr_aoa_session_info_ntf = UciNotification::Session(session_notification); @@ -723,11 +719,13 @@ mod tests { let session_status_ntf = uwb_uci_packets::SessionStatusNtfBuilder { session_id: 0x20, session_state: uwb_uci_packets::SessionState::SessionStateActive, - reason_code: uwb_uci_packets::ReasonCode::StateChangeWithSessionManagementCommands, + reason_code: uwb_uci_packets::ReasonCode::StateChangeWithSessionManagementCommands + .to_u8() + .unwrap(), } .build(); let session_notification_packet = - uwb_uci_packets::SessionConfigNotificationPacket::try_from(session_status_ntf).unwrap(); + uwb_uci_packets::SessionConfigNotification::try_from(session_status_ntf).unwrap(); let session_notification = SessionNotification::try_from(session_notification_packet).unwrap(); let uci_notification_from_session_status_ntf = @@ -737,7 +735,9 @@ mod tests { UciNotification::Session(SessionNotification::Status { session_id: 0x20, session_state: uwb_uci_packets::SessionState::SessionStateActive, - reason_code: uwb_uci_packets::ReasonCode::StateChangeWithSessionManagementCommands, + reason_code: uwb_uci_packets::ReasonCode::StateChangeWithSessionManagementCommands + .to_u8() + .unwrap(), }) ); } @@ -762,11 +762,10 @@ mod tests { controlee_status: vec![controlee_status.clone(), another_controlee_status.clone()], } .build(); - let session_notification_packet = - uwb_uci_packets::SessionConfigNotificationPacket::try_from( - session_update_controller_multicast_list_ntf, - ) - .unwrap(); + let session_notification_packet = uwb_uci_packets::SessionConfigNotification::try_from( + session_update_controller_multicast_list_ntf, + ) + .unwrap(); let session_notification = SessionNotification::try_from(session_notification_packet).unwrap(); let uci_notification_from_session_update_controller_multicast_list_ntf = @@ -784,11 +783,11 @@ mod tests { #[test] #[allow(non_snake_case)] //override snake case for vendor_A fn test_vendor_notification_casting() { - let vendor_9_empty_notification: uwb_uci_packets::UciNotificationPacket = + let vendor_9_empty_notification: uwb_uci_packets::UciNotification = uwb_uci_packets::UciVendor_9_NotificationBuilder { opcode: 0x40, payload: None } .build() .into(); - let vendor_A_nonempty_notification: uwb_uci_packets::UciNotificationPacket = + let vendor_A_nonempty_notification: uwb_uci_packets::UciNotification = uwb_uci_packets::UciVendor_A_NotificationBuilder { opcode: 0x41, payload: Some(bytes::Bytes::from_static(b"Placeholder notification.")), diff --git a/src/rust/uwb_core/src/uci/pcapng_block.rs b/src/rust/uwb_core/src/uci/pcapng_block.rs index c94ddac..6fcc670 100644 --- a/src/rust/uwb_core/src/uci/pcapng_block.rs +++ b/src/rust/uwb_core/src/uci/pcapng_block.rs @@ -143,7 +143,7 @@ pub struct InterfaceDescriptionBlockBuilder { impl Default for InterfaceDescriptionBlockBuilder { fn default() -> Self { Self { - link_type: 293, // USB 2.0 Low Speed + link_type: 299, // FiRa UCI snap_len: 0, // unlimited block_options: vec![], } @@ -422,7 +422,7 @@ mod tests { #[test] fn test_interface_description_block_with_options_build() { let comment_opt = BlockOption::new(0x1, "ABCDEF".to_owned().into_bytes()); - let link_type: u16 = 293; // 0x125 + let link_type: u16 = 299; // 0x12b let snap_len: u32 = 0; let interface_description_block = InterfaceDescriptionBlockBuilder::new() .link_type(link_type) @@ -433,7 +433,7 @@ mod tests { let expected_block: Vec<u8> = vec![ 0x01, 0x00, 0x00, 0x00, // block type 0x24, 0x00, 0x00, 0x00, // block length - 0x25, 0x01, 0x00, 0x00, // link type, reserved + 0x2b, 0x01, 0x00, 0x00, // link type, reserved 0x00, 0x00, 0x00, 0x00, // SnapLen 0x01, 0x00, 0x06, 0x00, // option code, padded length 0x41, 0x42, 0x43, 0x44, // option (ABCD) diff --git a/src/rust/uwb_core/src/uci/pcapng_uci_logger_factory.rs b/src/rust/uwb_core/src/uci/pcapng_uci_logger_factory.rs index 9844c05..04e1ef4 100644 --- a/src/rust/uwb_core/src/uci/pcapng_uci_logger_factory.rs +++ b/src/rust/uwb_core/src/uci/pcapng_uci_logger_factory.rs @@ -331,7 +331,7 @@ impl FileFactory { fn build_empty_file(&mut self) -> Option<BufferedFile> { self.rotate_file()?; let file_path = self.get_file_path(0); - BufferedFile::new(&file_path, self.buffer_size) + BufferedFile::new(&self.log_directory, &file_path, self.buffer_size) } /// get file path for log files of given index. @@ -376,12 +376,21 @@ struct BufferedFile { impl BufferedFile { /// Constructor. - pub fn new(file_path: &Path, buffer_size: usize) -> Option<Self> { + pub fn new(log_dir: &Path, file_path: &Path, buffer_size: usize) -> Option<Self> { if file_path.is_file() { if let Err(e) = fs::remove_file(file_path) { error!("UCI Log: failed to remove {}: {:?}", file_path.display(), e); }; } + if !log_dir.is_dir() { + if let Err(e) = fs::create_dir_all(log_dir) { + error!( + "UCI Log: failed to create log directory {}. Error: {:?}", + log_dir.display(), + e + ); + } + } let file = match fs::OpenOptions::new().write(true).create_new(true).open(file_path) { Ok(f) => f, Err(e) => { @@ -490,6 +499,34 @@ mod tests { } #[test] + fn test_no_preexisting_dir_created() { + let dir_root = Path::new("./uwb_test_dir_123"); + let dir = dir_root.join("this/path/doesnt/exist"); + { + let runtime = Builder::new_multi_thread().enable_all().build().unwrap(); + let mut file_manager = PcapngUciLoggerFactoryBuilder::new() + .buffer_size(1024) + .filename_prefix("log".to_owned()) + .log_path(dir.clone()) + .runtime_handle(runtime.handle().to_owned()) + .build() + .unwrap(); + let mut logger_0 = file_manager.build_logger("logger 0").unwrap(); + let packet_0 = UciVendor_A_NotificationBuilder { opcode: 0, payload: None }.build(); + logger_0.log_uci_control_packet(packet_0.into()); + // Sleep needed to guarantee handling pending logs before runtime goes out of scope. + thread::sleep(time::Duration::from_millis(10)); + } + // Expect the dir was created. + assert!(dir.is_dir()); + // Expect the log file exists. + let log_path = dir.join("log.pcapng"); + assert!(log_path.is_file()); + // Clear test dir + let _ = fs::remove_dir_all(dir_root); + } + + #[test] fn test_single_file_write() { let dir = tempdir().unwrap(); { diff --git a/src/rust/uwb_core/src/uci/response.rs b/src/rust/uwb_core/src/uci/response.rs index 546dc3e..6c1afab 100644 --- a/src/rust/uwb_core/src/uci/response.rs +++ b/src/rust/uwb_core/src/uci/response.rs @@ -20,7 +20,7 @@ use crate::error::{Error, Result}; use crate::params::uci_packets::{ AppConfigTlv, CapTlv, CoreSetConfigResponse, DeviceConfigTlv, GetDeviceInfoResponse, PowerStats, RawUciMessage, SessionState, SessionUpdateActiveRoundsDtTagResponse, - SetAppConfigResponse, StatusCode, UciControlPacketPacket, + SetAppConfigResponse, StatusCode, UciControlPacket, }; use crate::uci::error::status_code_to_result; @@ -88,9 +88,9 @@ impl UciResponse { } } -impl TryFrom<uwb_uci_packets::UciResponsePacket> for UciResponse { +impl TryFrom<uwb_uci_packets::UciResponse> for UciResponse { type Error = Error; - fn try_from(evt: uwb_uci_packets::UciResponsePacket) -> std::result::Result<Self, Self::Error> { + fn try_from(evt: uwb_uci_packets::UciResponse) -> std::result::Result<Self, Self::Error> { use uwb_uci_packets::UciResponseChild; match evt.specialize() { UciResponseChild::CoreResponse(evt) => evt.try_into(), @@ -107,11 +107,9 @@ impl TryFrom<uwb_uci_packets::UciResponsePacket> for UciResponse { } } -impl TryFrom<uwb_uci_packets::CoreResponsePacket> for UciResponse { +impl TryFrom<uwb_uci_packets::CoreResponse> for UciResponse { type Error = Error; - fn try_from( - evt: uwb_uci_packets::CoreResponsePacket, - ) -> std::result::Result<Self, Self::Error> { + fn try_from(evt: uwb_uci_packets::CoreResponse) -> std::result::Result<Self, Self::Error> { use uwb_uci_packets::CoreResponseChild; match evt.specialize() { CoreResponseChild::GetDeviceInfoRsp(evt) => Ok(UciResponse::CoreGetDeviceInfo( @@ -144,10 +142,10 @@ impl TryFrom<uwb_uci_packets::CoreResponsePacket> for UciResponse { } } -impl TryFrom<uwb_uci_packets::SessionConfigResponsePacket> for UciResponse { +impl TryFrom<uwb_uci_packets::SessionConfigResponse> for UciResponse { type Error = Error; fn try_from( - evt: uwb_uci_packets::SessionConfigResponsePacket, + evt: uwb_uci_packets::SessionConfigResponse, ) -> std::result::Result<Self, Self::Error> { use uwb_uci_packets::SessionConfigResponseChild; match evt.specialize() { @@ -198,10 +196,10 @@ impl TryFrom<uwb_uci_packets::SessionConfigResponsePacket> for UciResponse { } } -impl TryFrom<uwb_uci_packets::SessionControlResponsePacket> for UciResponse { +impl TryFrom<uwb_uci_packets::SessionControlResponse> for UciResponse { type Error = Error; fn try_from( - evt: uwb_uci_packets::SessionControlResponsePacket, + evt: uwb_uci_packets::SessionControlResponse, ) -> std::result::Result<Self, Self::Error> { use uwb_uci_packets::SessionControlResponseChild; match evt.specialize() { @@ -221,11 +219,9 @@ impl TryFrom<uwb_uci_packets::SessionControlResponsePacket> for UciResponse { } } -impl TryFrom<uwb_uci_packets::AndroidResponsePacket> for UciResponse { +impl TryFrom<uwb_uci_packets::AndroidResponse> for UciResponse { type Error = Error; - fn try_from( - evt: uwb_uci_packets::AndroidResponsePacket, - ) -> std::result::Result<Self, Self::Error> { + fn try_from(evt: uwb_uci_packets::AndroidResponse) -> std::result::Result<Self, Self::Error> { use uwb_uci_packets::AndroidResponseChild; match evt.specialize() { AndroidResponseChild::AndroidSetCountryCodeRsp(evt) => { @@ -241,9 +237,9 @@ impl TryFrom<uwb_uci_packets::AndroidResponsePacket> for UciResponse { } } -fn raw_response(evt: uwb_uci_packets::UciResponsePacket) -> Result<UciResponse> { +fn raw_response(evt: uwb_uci_packets::UciResponse) -> Result<UciResponse> { let gid = evt.get_group_id().to_u32().ok_or(Error::Unknown)?; let oid = evt.get_opcode().to_u32().ok_or(Error::Unknown)?; - let packet: UciControlPacketPacket = evt.into(); + let packet: UciControlPacket = evt.into(); Ok(UciResponse::RawUciCmd(Ok(RawUciMessage { gid, oid, payload: packet.to_raw_payload() }))) } diff --git a/src/rust/uwb_core/src/uci/uci_hal.rs b/src/rust/uwb_core/src/uci/uci_hal.rs index 27c593d..1153872 100644 --- a/src/rust/uwb_core/src/uci/uci_hal.rs +++ b/src/rust/uwb_core/src/uci/uci_hal.rs @@ -18,7 +18,7 @@ use std::convert::TryInto; use async_trait::async_trait; use tokio::sync::mpsc; -use uwb_uci_packets::{Packet, UciControlPacketHalPacket, UciControlPacketPacket}; +use uwb_uci_packets::{Packet, UciControlPacket, UciControlPacketHal}; use crate::error::Result; use crate::params::uci_packets::SessionId; @@ -50,15 +50,12 @@ pub trait UciHal: 'static + Send { /// /// The caller should call this method after the response of the previous send_command() is /// received. - /// - /// TODO(b/261886903): For the Data Packet Tx flow, we need to add a similar send_data() - /// API which implements fragmentation on the Data packet and calls send_packet(). async fn send_command(&mut self, cmd: UciCommand) -> Result<()> { // A UCI command message may consist of multiple UCI packets when the payload is over the // maximum packet size. We convert the command into list of UciHalPacket, then send the // packets via send_packet(). - let packet: UciControlPacketPacket = cmd.try_into()?; - let fragmented_packets: Vec<UciControlPacketHalPacket> = packet.into(); + let packet: UciControlPacket = cmd.try_into()?; + let fragmented_packets: Vec<UciControlPacketHal> = packet.into(); for packet in fragmented_packets.into_iter() { self.send_packet(packet.to_vec()).await?; } diff --git a/src/rust/uwb_core/src/uci/uci_logger.rs b/src/rust/uwb_core/src/uci/uci_logger.rs index 07fd701..5023d7a 100644 --- a/src/rust/uwb_core/src/uci/uci_logger.rs +++ b/src/rust/uwb_core/src/uci/uci_logger.rs @@ -18,8 +18,8 @@ use std::convert::TryFrom; use uwb_uci_packets::{ AppConfigTlv, AppConfigTlvType, Packet, SessionConfigCommandChild, SessionConfigResponseChild, SessionGetAppConfigRspBuilder, SessionSetAppConfigCmdBuilder, UciCommandChild, - UciControlPacketChild, UciControlPacketPacket, UciDataPacketPacket, UciResponseChild, - UciResponsePacket, UCI_PACKET_HAL_HEADER_LEN, + UciControlPacket, UciControlPacketChild, UciDataPacket, UciResponse, UciResponseChild, + UCI_PACKET_HAL_HEADER_LEN, }; use crate::error::{Error, Result}; @@ -52,10 +52,10 @@ impl TryFrom<String> for UciLoggerMode { /// Trait definition for the thread-safe uci logger pub trait UciLogger: 'static + Send + Sync { /// Logs Uci Control Packet. - fn log_uci_control_packet(&mut self, packet: UciControlPacketPacket); + fn log_uci_control_packet(&mut self, packet: UciControlPacket); /// Logs Uci Data Packet. This is being passed as a reference since most of the time logging is /// disabled, and so this will avoid copying the data payload. - fn log_uci_data_packet(&mut self, packet: &UciDataPacketPacket); + fn log_uci_data_packet(&mut self, packet: &UciDataPacket); /// Logs hal open event. fn log_hal_open(&mut self, result: Result<()>); /// Logs hal close event. @@ -69,7 +69,7 @@ fn filter_tlv(mut tlv: AppConfigTlv) -> AppConfigTlv { tlv } -fn filter_uci_command(cmd: UciControlPacketPacket) -> UciControlPacketPacket { +fn filter_uci_command(cmd: UciControlPacket) -> UciControlPacket { match cmd.specialize() { UciControlPacketChild::UciCommand(control_cmd) => match control_cmd.specialize() { UciCommandChild::SessionConfigCommand(session_cmd) => match session_cmd.specialize() { @@ -87,7 +87,7 @@ fn filter_uci_command(cmd: UciControlPacketPacket) -> UciControlPacketPacket { } } -fn filter_uci_response(rsp: UciResponsePacket) -> UciResponsePacket { +fn filter_uci_response(rsp: UciResponse) -> UciResponse { match rsp.specialize() { UciResponseChild::SessionConfigResponse(session_rsp) => match session_rsp.specialize() { SessionConfigResponseChild::SessionGetAppConfigRsp(rsp) => { @@ -104,8 +104,8 @@ fn filter_uci_response(rsp: UciResponsePacket) -> UciResponsePacket { // Log only the Data Packet header bytes, so that we don't log any PII (payload bytes). fn filter_uci_data( - packet: &UciDataPacketPacket, -) -> std::result::Result<UciDataPacketPacket, uwb_uci_packets::Error> { + packet: &UciDataPacket, +) -> std::result::Result<UciDataPacket, uwb_uci_packets::Error> { // Initialize a (zeroed out) Vec to the same length as the data packet, and then copy over // only the Data Packet header bytes into it. This masks out all the payload bytes to 0. let data_packet_bytes: Vec<u8> = packet.clone().to_vec(); @@ -113,7 +113,7 @@ fn filter_uci_data( for (i, &b) in data_packet_bytes[..UCI_PACKET_HAL_HEADER_LEN].iter().enumerate() { filtered_data_packet_bytes[i] = b; } - UciDataPacketPacket::parse(&filtered_data_packet_bytes) + UciDataPacket::parse(&filtered_data_packet_bytes) } /// Wrapper struct that filters messages feeded to UciLogger. @@ -148,19 +148,19 @@ impl<T: UciLogger> UciLoggerWrapper<T> { match self.mode { UciLoggerMode::Disabled => (), UciLoggerMode::Unfiltered => { - if let Ok(packet) = UciControlPacketPacket::try_from(cmd.clone()) { + if let Ok(packet) = UciControlPacket::try_from(cmd.clone()) { self.logger.log_uci_control_packet(packet); }; } UciLoggerMode::Filtered => { - if let Ok(packet) = UciControlPacketPacket::try_from(cmd.clone()) { + if let Ok(packet) = UciControlPacket::try_from(cmd.clone()) { self.logger.log_uci_control_packet(filter_uci_command(packet)); }; } } } - pub fn log_uci_response_or_notification(&mut self, packet: &UciControlPacketPacket) { + pub fn log_uci_response_or_notification(&mut self, packet: &UciControlPacket) { match self.mode { UciLoggerMode::Disabled => (), UciLoggerMode::Unfiltered => self.logger.log_uci_control_packet(packet.clone()), @@ -176,7 +176,7 @@ impl<T: UciLogger> UciLoggerWrapper<T> { } } - pub fn log_uci_data(&mut self, packet: &UciDataPacketPacket) { + pub fn log_uci_data(&mut self, packet: &UciDataPacket) { if self.mode == UciLoggerMode::Disabled { return; } @@ -191,9 +191,9 @@ impl<T: UciLogger> UciLoggerWrapper<T> { pub struct NopUciLogger {} impl UciLogger for NopUciLogger { - fn log_uci_control_packet(&mut self, _packet: UciControlPacketPacket) {} + fn log_uci_control_packet(&mut self, _packet: UciControlPacket) {} - fn log_uci_data_packet(&mut self, _packet: &UciDataPacketPacket) {} + fn log_uci_data_packet(&mut self, _packet: &UciDataPacket) {} fn log_hal_open(&mut self, _result: Result<()>) {} @@ -239,7 +239,7 @@ mod tests { #[test] fn test_log_response_filter() -> Result<()> { - let unfiltered_rsp: UciControlPacketPacket = SessionGetAppConfigRspBuilder { + let unfiltered_rsp: UciControlPacket = SessionGetAppConfigRspBuilder { status: StatusCode::UciStatusOk, tlvs: vec![ AppConfigTlv { cfg_id: AppConfigTlvType::StaticStsIv, v: vec![0, 1, 2] }, diff --git a/src/rust/uwb_core/src/uci/uci_logger_pcapng.rs b/src/rust/uwb_core/src/uci/uci_logger_pcapng.rs index c148d62..279713b 100644 --- a/src/rust/uwb_core/src/uci/uci_logger_pcapng.rs +++ b/src/rust/uwb_core/src/uci/uci_logger_pcapng.rs @@ -15,7 +15,7 @@ //! Implements UciLoggerPcapng, a UciLogger with PCAPNG format log. use log::warn; -use uwb_uci_packets::{UciControlPacketPacket, UciDataPacketPacket}; +use uwb_uci_packets::{UciControlPacket, UciDataPacket}; use crate::uci::pcapng_block::{BlockBuilder, BlockOption, EnhancedPacketBlockBuilder}; use crate::uci::pcapng_uci_logger_factory::LogWriter; @@ -42,7 +42,7 @@ impl UciLoggerPcapng { } impl UciLogger for UciLoggerPcapng { - fn log_uci_control_packet(&mut self, packet: UciControlPacketPacket) { + fn log_uci_control_packet(&mut self, packet: UciControlPacket) { let block_bytes = match EnhancedPacketBlockBuilder::new() .interface_id(self.interface_id) .packet(packet.into()) @@ -54,7 +54,7 @@ impl UciLogger for UciLoggerPcapng { self.send_block_bytes(block_bytes); } - fn log_uci_data_packet(&mut self, packet: &UciDataPacketPacket) { + fn log_uci_data_packet(&mut self, packet: &UciDataPacket) { let packet_header_bytes = match EnhancedPacketBlockBuilder::new() .interface_id(self.interface_id) .packet(packet.clone().into()) diff --git a/src/rust/uwb_core/src/uci/uci_manager.rs b/src/rust/uwb_core/src/uci/uci_manager.rs index 709df2f..c158d20 100644 --- a/src/rust/uwb_core/src/uci/uci_manager.rs +++ b/src/rust/uwb_core/src/uci/uci_manager.rs @@ -28,8 +28,8 @@ use crate::params::uci_packets::{ CreditAvailability, DataTransferNtfStatusCode, DeviceConfigId, DeviceConfigTlv, DeviceState, FiraComponent, GetDeviceInfoResponse, GroupId, MessageType, PowerStats, RawUciMessage, ResetConfig, SessionId, SessionState, SessionType, SessionUpdateActiveRoundsDtTagResponse, - SetAppConfigResponse, UciControlPacketPacket, UciDataPacketHalPacket, UciDataPacketPacket, - UciDataSndPacket, UpdateMulticastListAction, + SetAppConfigResponse, UciControlPacket, UciDataPacket, UciDataPacketHal, UciDataSnd, + UpdateMulticastListAction, }; use crate::params::utils::bytes_to_u64; use crate::uci::message::UciMessage; @@ -150,7 +150,7 @@ pub trait UciManager: 'static + Send + Sync + Clone { pub struct UciManagerImpl { cmd_sender: mpsc::UnboundedSender<(UciManagerCmd, oneshot::Sender<Result<UciResponse>>)>, data_packet_sender: - mpsc::UnboundedSender<(UciDataSndPacket, oneshot::Sender<DataTransferNtfStatusCode>)>, + mpsc::UnboundedSender<(UciDataSnd, oneshot::Sender<DataTransferNtfStatusCode>)>, } impl UciManagerImpl { @@ -500,7 +500,7 @@ struct RawCmdSignature { } impl RawCmdSignature { - pub fn is_same_signature(&self, packet: &UciControlPacketPacket) -> bool { + pub fn is_same_signature(&self, packet: &UciControlPacket) -> bool { packet.get_group_id() == self.gid && packet.get_opcode() == self.oid } } @@ -516,7 +516,7 @@ struct UciManagerActor<T: UciHal, U: UciLogger> { // Receive Data packets (to be sent to UWBS) and the corresponding status sender from // UciManager. data_packet_receiver: - mpsc::UnboundedReceiver<(UciDataSndPacket, oneshot::Sender<DataTransferNtfStatusCode>)>, + mpsc::UnboundedReceiver<(UciDataSnd, oneshot::Sender<DataTransferNtfStatusCode>)>, // Set to true when |hal| is opened successfully. is_hal_opened: bool, @@ -565,7 +565,7 @@ impl<T: UciHal, U: UciLogger> UciManagerActor<T, U> { oneshot::Sender<Result<UciResponse>>, )>, data_packet_receiver: mpsc::UnboundedReceiver<( - UciDataSndPacket, + UciDataSnd, oneshot::Sender<DataTransferNtfStatusCode>, )>, ) -> Self { @@ -747,7 +747,7 @@ impl<T: UciHal, U: UciLogger> UciManagerActor<T, U> { } } - async fn handle_data_packet_send(&mut self, data_packet: UciDataSndPacket) { + async fn handle_data_packet_send(&mut self, data_packet: UciDataSnd) { // We expect data Credit should be available when we start here, for all UWB Sessions as: // - it's available by default for a UWB Session when it becomes active, and, // - Data packet send completed for earlier packets only after the host received both @@ -758,7 +758,7 @@ impl<T: UciHal, U: UciLogger> UciManagerActor<T, U> { // credit availability here (before sending any data packet fragment). The map should also // be updated (in handle_notification()), when UWBS unilaterally sends a DATA_CREDIT_NTF. let data_packet_session_id = data_packet.get_session_id(); - let fragmented_packets: Vec<UciDataPacketHalPacket> = data_packet.into(); + let fragmented_packets: Vec<UciDataPacketHal> = data_packet.into(); for packet in fragmented_packets.into_iter() { let (data_credit_ntf_sender, data_credit_ntf_receiver) = oneshot::channel(); self.data_credit_ntf_sender = Some(data_credit_ntf_sender); @@ -947,7 +947,7 @@ impl<T: UciHal, U: UciLogger> UciManagerActor<T, U> { } } - fn handle_data_rcv(&mut self, packet: UciDataPacketPacket) { + fn handle_data_rcv(&mut self, packet: UciDataPacket) { match packet.try_into() { Ok(data_rcv) => { let _ = self.data_rcv_notf_sender.send(data_rcv); @@ -1050,10 +1050,10 @@ mod tests { // TODO(b/261886903): Check if this should be in a common library file as same function // is defined in uci_hal_android.rs also. - fn into_uci_hal_packets<T: Into<uwb_uci_packets::UciControlPacketPacket>>( + fn into_uci_hal_packets<T: Into<uwb_uci_packets::UciControlPacket>>( builder: T, ) -> Vec<UciHalPacket> { - let packets: Vec<uwb_uci_packets::UciControlPacketHalPacket> = builder.into().into(); + let packets: Vec<uwb_uci_packets::UciControlPacketHal> = builder.into().into(); packets.into_iter().map(|packet| packet.into()).collect() } @@ -1317,7 +1317,9 @@ mod tests { session_id, session_state: uwb_uci_packets::SessionState::SessionStateInit, reason_code: - uwb_uci_packets::ReasonCode::StateChangeWithSessionManagementCommands, + uwb_uci_packets::ReasonCode::StateChangeWithSessionManagementCommands + .to_u8() + .unwrap(), }); resp.append(&mut notf); diff --git a/src/rust/uwb_core/src/uci/uci_manager_sync.rs b/src/rust/uwb_core/src/uci/uci_manager_sync.rs index 02e4c85..dd41d2c 100644 --- a/src/rust/uwb_core/src/uci/uci_manager_sync.rs +++ b/src/rust/uwb_core/src/uci/uci_manager_sync.rs @@ -149,7 +149,6 @@ impl<U: UciManager> UciManagerSync<U> { mpsc::unbounded_channel::<RawUciMessage>(); let (data_rcv_notification_sender, data_rcv_notification_receiver) = mpsc::unbounded_channel::<DataRcvNotification>(); - // TODO(b/261762781):Add a similar channel for Data Packet Rx self.runtime_handle.to_owned().block_on(async { self.uci_manager.set_core_notification_sender(core_notification_sender).await; self.uci_manager.set_session_notification_sender(session_notification_sender).await; diff --git a/src/rust/uwb_uci_packets/build.rs b/src/rust/uwb_uci_packets/build.rs index 10ea8f1..f001de5 100644 --- a/src/rust/uwb_uci_packets/build.rs +++ b/src/rust/uwb_uci_packets/build.rs @@ -18,26 +18,27 @@ use std::process::Command; fn main() { let out_dir = std::env::var_os("OUT_DIR").unwrap(); let generated_file = "uci_packets.rs"; + let dst_path = Path::new(&out_dir).join(generated_file); if Path::new(generated_file).exists() { // Copy the rust code directly if the file exists. - let dst_path = Path::new(&out_dir).join(generated_file); let result = std::fs::copy(generated_file, &dst_path); eprintln!("{} exists, copy to {:?}: {:?}", generated_file, dst_path, result); return; } - // Generate the rust code by bluetooth_packetgen. - // The binary should be compiled by `m bluetooth_packetgen -j32` before calling cargo. + // The binary should be compiled by `m pdl` before calling cargo. let output = Command::new("env") - .arg("bluetooth_packetgen") - .arg("--out=".to_owned() + out_dir.to_str().unwrap()) - .arg("--include=.") - .arg("--rust") + .arg("pdl") + .arg("--output-format") + .arg("rust") .arg("uci_packets.pdl") .output() .unwrap(); + std::fs::write(&dst_path, &output.stdout) + .expect(&format!("Could not write {}", dst_path.display())); + eprintln!( "Status: {}, stdout: {}, stderr: {}", output.status, diff --git a/src/rust/uwb_uci_packets/src/lib.rs b/src/rust/uwb_uci_packets/src/lib.rs index 7b3aee0..bc95bc3 100644 --- a/src/rust/uwb_uci_packets/src/lib.rs +++ b/src/rust/uwb_uci_packets/src/lib.rs @@ -32,7 +32,7 @@ const MAX_PAYLOAD_LEN: usize = 255; // Real UCI packet header len. pub const UCI_PACKET_HAL_HEADER_LEN: usize = 4; // Unfragmented UCI packet header len. -const UCI_PACKET_HEADER_LEN: usize = 7; +pub const UCI_PACKET_HEADER_LEN: usize = 7; // Unfragmented UCI DATA_MESSAGE_SND packet header len. const UCI_DATA_SND_PACKET_HEADER_LEN: usize = 6; @@ -295,8 +295,8 @@ impl UciControlPacketHeader { // This function parses the packet bytes to return the Control Packet Opcode (OID) field. The // caller should check that the packet bytes represent a UCI control packet. The code will not -// panic because UciPacketHalPacket::to_bytes() should always be larger then the place we access. -fn get_opcode_from_uci_control_packet(packet: &UciPacketHalPacket) -> u8 { +// panic because UciPacketHal::to_bytes() should always be larger then the place we access. +fn get_opcode_from_uci_control_packet(packet: &UciPacketHal) -> u8 { packet.clone().to_bytes()[UCI_CONTROL_PACKET_HEADER_OPCODE_BYTE_POSITION] & UCI_CONTROL_PACKET_HEADER_OPCODE_MASK } @@ -317,35 +317,35 @@ pub fn build_uci_control_packet( group_id: GroupId, opcode: u8, payload: Option<Bytes>, -) -> Option<UciControlPacketPacket> { +) -> Option<UciControlPacket> { if !is_uci_control_packet(message_type) { - error!("Only control packets are allowed, MessageType: {}", message_type); + error!("Only control packets are allowed, MessageType: {message_type:?}"); return None; } Some(UciControlPacketBuilder { group_id, message_type, opcode, payload }.build()) } // Ensure that the new packet fragment belong to the same packet. -fn is_same_control_packet(header: &UciControlPacketHeader, packet: &UciPacketHalPacket) -> bool { +fn is_same_control_packet(header: &UciControlPacketHeader, packet: &UciPacketHal) -> bool { is_uci_control_packet(header.message_type) && header.message_type == packet.get_message_type() && header.group_id == packet.get_group_id_or_data_packet_format().into() && header.opcode == get_opcode_from_uci_control_packet(packet) } -impl UciControlPacketPacket { +impl UciControlPacket { // For some usage, we need to get the raw payload. pub fn to_raw_payload(self) -> Vec<u8> { self.to_bytes().slice(UCI_PACKET_HEADER_LEN..).to_vec() } } -// Helper to convert from vector of |UciPacketHalPacket| to |UciControlPacketPacket|. An example +// Helper to convert from vector of |UciPacketHal| to |UciControlPacket|. An example // usage is to convert a list UciPacketHAL fragments to one UciPacket, during de-fragmentation. -impl TryFrom<Vec<UciPacketHalPacket>> for UciControlPacketPacket { +impl TryFrom<Vec<UciPacketHal>> for UciControlPacket { type Error = Error; - fn try_from(packets: Vec<UciPacketHalPacket>) -> Result<Self> { + fn try_from(packets: Vec<UciPacketHal>) -> Result<Self> { if packets.is_empty() { return Err(Error::InvalidPacketError); } @@ -369,9 +369,9 @@ impl TryFrom<Vec<UciPacketHalPacket>> for UciControlPacketPacket { payload_buf.extend_from_slice(&packet.to_bytes().slice(UCI_PACKET_HAL_HEADER_LEN..)) } - // Create assembled |UciControlPacketPacket| and convert to bytes again since we need to + // Create assembled |UciControlPacket| and convert to bytes again since we need to // reparse the packet after defragmentation to get the appropriate message. - UciControlPacketPacket::parse( + UciControlPacket::parse( &UciControlPacketBuilder { message_type: header.message_type, group_id: header.group_id, @@ -389,7 +389,7 @@ fn is_uci_data_rcv_packet(message_type: MessageType, data_packet_format: DataPac message_type == MessageType::Data && data_packet_format == DataPacketFormat::DataRcv } -fn try_into_data_payload(packet: UciPacketHalPacket) -> Result<Bytes> { +fn try_into_data_payload(packet: UciPacketHal) -> Result<Bytes> { if is_uci_data_rcv_packet( packet.get_message_type(), packet.get_group_id_or_data_packet_format().try_into()?, @@ -401,12 +401,12 @@ fn try_into_data_payload(packet: UciPacketHalPacket) -> Result<Bytes> { } } -// Helper to convert from vector of |UciPacketHalPacket| to |UciDataPacketPacket|. An example +// Helper to convert from vector of |UciPacketHal| to |UciDataPacket|. An example // usage is to convert a list UciPacketHAL fragments to one UciPacket, during de-fragmentation. -impl TryFrom<Vec<UciPacketHalPacket>> for UciDataPacketPacket { +impl TryFrom<Vec<UciPacketHal>> for UciDataPacket { type Error = Error; - fn try_from(packets: Vec<UciPacketHalPacket>) -> Result<Self> { + fn try_from(packets: Vec<UciPacketHal>) -> Result<Self> { if packets.is_empty() { return Err(Error::InvalidPacketError); } @@ -419,9 +419,9 @@ impl TryFrom<Vec<UciPacketHalPacket>> for UciDataPacketPacket { payload_buf = [payload_buf, try_into_data_payload(packet)?].concat().into(); } - // Create assembled |UciDataPacketPacket| and convert to bytes again since we need to + // Create assembled |UciDataPacket| and convert to bytes again since we need to // reparse the packet after defragmentation to get the appropriate message. - UciDataPacketPacket::parse( + UciDataPacket::parse( &UciDataPacketBuilder { message_type: MessageType::Data, data_packet_format: DataPacketFormat::DataRcv, @@ -433,10 +433,10 @@ impl TryFrom<Vec<UciPacketHalPacket>> for UciDataPacketPacket { } } -// Helper to convert from |UciControlPacketPacket| to vector of |UciControlPacketHalPacket|s. An +// Helper to convert from |UciControlPacket| to vector of |UciControlPacketHal|s. An // example usage is to do this conversion for fragmentation (from Host to UWBS). -impl From<UciControlPacketPacket> for Vec<UciControlPacketHalPacket> { - fn from(packet: UciControlPacketPacket) -> Self { +impl From<UciControlPacket> for Vec<UciControlPacketHal> { + fn from(packet: UciControlPacket) -> Self { // Store header info. let header = match UciControlPacketHeader::new( packet.get_message_type(), @@ -446,7 +446,7 @@ impl From<UciControlPacketPacket> for Vec<UciControlPacketHalPacket> { Ok(hdr) => hdr, _ => { error!( - "Unable to parse UciControlPacketHeader from UciControlPacketPacket: {:?}", + "Unable to parse UciControlPacketHeader from UciControlPacket: {:?}", packet ); return Vec::new(); @@ -492,10 +492,10 @@ impl From<UciControlPacketPacket> for Vec<UciControlPacketHalPacket> { } } -// Helper to convert From<UciDataSndPacket> into Vec<UciDataPacketHalPacket>. An +// Helper to convert From<UciDataSnd> into Vec<UciDataPacketHal>. An // example usage is for fragmentation in the Data Packet Tx flow. -impl From<UciDataSndPacket> for Vec<UciDataPacketHalPacket> { - fn from(packet: UciDataSndPacket) -> Self { +impl From<UciDataSnd> for Vec<UciDataPacketHal> { + fn from(packet: UciDataSnd) -> Self { let mut fragments = Vec::new(); let dpf = packet.get_data_packet_format().into(); @@ -537,20 +537,20 @@ impl From<UciDataSndPacket> for Vec<UciDataPacketHalPacket> { pub struct PacketDefrager { // Cache to store incoming fragmented packets in the middle of reassembly. // Will be empty if there is no reassembly in progress. - // TODO(b/261762781): Prefer this to be UciControlPacketHalPacket - control_fragment_cache: Vec<UciPacketHalPacket>, - // TODO(b/261762781): Prefer this to be UciDataPacketHalPacket - data_fragment_cache: Vec<UciPacketHalPacket>, + // TODO(b/261762781): Prefer this to be UciControlPacketHal + control_fragment_cache: Vec<UciPacketHal>, + // TODO(b/261762781): Prefer this to be UciDataPacketHal + data_fragment_cache: Vec<UciPacketHal>, } pub enum UciDefragPacket { - Control(UciControlPacketPacket), - Data(UciDataPacketPacket), + Control(UciControlPacket), + Data(UciDataPacket), } impl PacketDefrager { pub fn defragment_packet(&mut self, msg: &[u8]) -> Option<UciDefragPacket> { - let packet = UciPacketHalPacket::parse(msg) + let packet = UciPacketHal::parse(msg) .or_else(|e| { error!("Failed to parse packet: {:?}", e); Err(e) @@ -617,9 +617,7 @@ pub struct ParsedFrameReport { cir: Vec<CirValue>, } -pub fn parse_diagnostics_ntf( - evt: AndroidRangeDiagnosticsNtfPacket, -) -> Result<ParsedDiagnosticNtfPacket> { +pub fn parse_diagnostics_ntf(evt: AndroidRangeDiagnosticsNtf) -> Result<ParsedDiagnosticNtfPacket> { let session_id = evt.get_session_id(); let sequence_number = evt.get_sequence_number(); let mut parsed_frame_reports = Vec::new(); @@ -628,7 +626,7 @@ pub fn parse_diagnostics_ntf( let mut aoa_vec = Vec::new(); let mut cir_vec = Vec::new(); for tlv in &report.frame_report_tlvs { - match FrameReportTlvPacketPacket::parse( + match FrameReportTlvPacket::parse( &[vec![tlv.t as u8, tlv.v.len() as u8, (tlv.v.len() >> 8) as u8], tlv.v.clone()] .concat(), ) { @@ -711,7 +709,7 @@ pub fn build_session_update_controller_multicast_list_cmd( session_id: u32, action: UpdateMulticastListAction, controlees: Controlees, -) -> Result<SessionUpdateControllerMulticastListCmdPacket> { +) -> Result<SessionUpdateControllerMulticastListCmd> { let mut controlees_buf = BytesMut::new(); match controlees { Controlees::NoSessionKey(controlee_v1) @@ -812,14 +810,14 @@ mod tests { #[test] fn test_build_multicast_update_packet() { let controlee = Controlee { short_address: 0x1234, subsession_id: 0x1324_3546 }; - let packet: UciControlPacketPacket = build_session_update_controller_multicast_list_cmd( + let packet: UciControlPacket = build_session_update_controller_multicast_list_cmd( 0x1425_3647, UpdateMulticastListAction::AddControlee, Controlees::NoSessionKey(vec![controlee; 1]), ) .unwrap() .into(); - let packet_fragments: Vec<UciControlPacketHalPacket> = packet.into(); + let packet_fragments: Vec<UciControlPacketHal> = packet.into(); let uci_packet: Vec<u8> = packet_fragments[0].clone().into(); assert_eq!( uci_packet, diff --git a/src/rust/uwb_uci_packets/uci_packets.pdl b/src/rust/uwb_uci_packets/uci_packets.pdl index da388f8..dcf7daa 100644 --- a/src/rust/uwb_uci_packets/uci_packets.pdl +++ b/src/rust/uwb_uci_packets/uci_packets.pdl @@ -135,6 +135,7 @@ enum StatusCode : 8 { // Vendor Specific Status Codes UCI_STATUS_ERROR_CCC_SE_BUSY = 0x50, UCI_STATUS_ERROR_CCC_LIFECYCLE = 0x51, + UCI_STATUS_ERROR_STOPPED_DUE_TO_OTHER_SESSION_CONFLICT = 0x52, } // This needs a separate type as the Status code values in an OWR for AOA @@ -294,6 +295,8 @@ enum CapTlvType : 8 { SUPPORTED_RANGE_DATA_NTF_CONFIG = 0xE5, SUPPORTED_RSSI_REPORTING = 0xE6, SUPPORTED_DIAGNOSTICS = 0xE7, + SUPPORTED_MIN_SLOT_DURATION_RSTU = 0xE8, + SUPPORTED_MAX_RANGING_SESSION_NUMBER = 0xE9, // CCC specific CCC_SUPPORTED_CHAPS_PER_SLOT = 0xA0, @@ -304,6 +307,7 @@ enum CapTlvType : 8 { CCC_SUPPORTED_UWB_CONFIGS = 0xA5, CCC_SUPPORTED_PULSE_SHAPE_COMBOS = 0xA6, CCC_SUPPORTED_RAN_MULTIPLIER = 0xA7, + CCC_SUPPORTED_MAX_RANGING_SESSION_NUMBER = 0xA8, SUPPORTED_POWER_STATS = 0xC0, } @@ -336,13 +340,48 @@ enum ReasonCode : 8 { STATE_CHANGE_WITH_SESSION_MANAGEMENT_COMMANDS = 0x00, MAX_RANGING_ROUND_RETRY_COUNT_REACHED = 0x01, MAX_NUMBER_OF_MEASUREMENTS_REACHED = 0x02, + SESSION_SUSPENDED_DUE_TO_INBAND_SIGNAL = 0x03, + SESSION_RESUMED_DUE_TO_INBAND_SIGNAL = 0x04, + SESSION_STOPPED_DUE_TO_INBAND_SIGNAL = 0x05, ERROR_INVALID_UL_TDOA_RANDOM_WINDOW = 0x1D, + ERROR_MIN_RFRAMES_PER_RR_NOT_SUPPORTED = 0x1E, + ERROR_TX_DELAY_NOT_SUPPORTED = 0x1F, ERROR_SLOT_LENGTH_NOT_SUPPORTED = 0x20, ERROR_INSUFFICIENT_SLOTS_PER_RR = 0x21, ERROR_MAC_ADDRESS_MODE_NOT_SUPPORTED = 0x22, - ERROR_INVALID_RANGING_INTERVAL = 0x23, + ERROR_INVALID_RANGING_DURATION = 0x23, ERROR_INVALID_STS_CONFIG = 0x24, ERROR_INVALID_RFRAME_CONFIG = 0x25, + ERROR_HUS_NOT_ENOUGH_SLOTS = 0x26, + ERROR_HUS_CFP_PHASE_TOO_SHORT = 0x27, + ERROR_HUS_CAP_PHASE_TOO_SHORT = 0x28, + ERROR_HUS_OTHERS = 0x29, + ERROR_STATUS_SESSION_KEY_NOT_FOUND = 0x2A, + ERROR_STATUS_SUB_SESSION_KEY_NOT_FOUND = 0x2B, + ERROR_INVALID_PREAMBLE_CODE_INDEX = 0x2C, + ERROR_INVALID_SFD_ID = 0x2D, + ERROR_INVALID_PSDU_DATA_RATE = 0x2E, + ERROR_INVALID_PHR_DATA_RATE = 0x2F, + ERROR_INVALID_PREAMBLE_DURATION = 0x30, + ERROR_INVALID_STS_LENGTH = 0x31, + ERROR_INVALID_NUM_OF_STS_SEGMENTS = 0x32, + ERROR_INVALID_NUM_OF_CONTROLEES = 0x33, + ERROR_MAX_RANGING_REPLY_TIME_EXCEEDED = 0x34, + ERROR_INVALID_DST_ADDRESS_LIST = 0x35, + ERROR_INVALID_OR_NOT_FOUND_SUB_SESSION_ID = 0x36, + ERROR_INVALID_RESULT_REPORT_CONFIG = 0x37, + ERROR_INVALID_RANGING_ROUND_CONTROL_CONFIG = 0x38, + ERROR_INVALID_RANGING_ROUND_USAGE = 0x39, + ERROR_INVALID_MULTI_NODE_MODE = 0x3A, + ERROR_RDS_FETCH_FAILURE = 0x3B, + ERROR_REF_UWB_SESSION_DOES_NOT_EXIST = 0x3C, + ERROR_REF_UWB_SESSION_RANGING_DURATION_MISMATCH = 0x3D, + ERROR_REF_UWB_SESSION_INVALID_OFFSET_TIME = 0x3E, + ERROR_REF_UWB_SESSION_LOST = 0x3F, + // TODO(b/272775225): Add a range for the vendor specific space, after PDL supports + // this feature (requested in b/267339120). + ERROR_INVALID_CHANNEL_WITH_AOA = 0x80, + ERROR_STOPPED_DUE_TO_OTHER_SESSION_CONFLICT = 0x81, } enum MulticastUpdateStatusCode : 8 { @@ -685,11 +724,14 @@ test SessionDeinitRsp { packet SessionStatusNtf : SessionConfigNotification (opcode = 0x2) { //SESSION_STATUS_NTF session_id: 32, session_state: SessionState, - reason_code: ReasonCode, + // TODO(b/272775225): Switch back to the enum type ReasonCode, once PDL supports defining a + // range inside an enum (for the vendor-specific space), in b/267339120. + reason_code: 8, } test SessionStatusNtf { "\x61\x02\x00\x06\x00\x00\x00\x01\x02\x03\x04\x02\x21", + "\x61\x02\x00\x06\x00\x00\x00\x01\x02\x03\x04\x01\x82", // Vendor Specific Reason Code } struct AppConfigTlv { @@ -917,7 +959,11 @@ struct ShortAddressTwoWayRangingMeasurement { aoa_destination_elevation_fom: 8, slot_index: 8, rssi: 8, - _reserved_: 88, + // b/272301550: The pdl compiler cannot handle individual fields + // larger than 64 bit. The work around is to split the 88 bit + // field into two. + _reserved_: 64, + _reserved_: 24, } struct ExtendedAddressTwoWayRangingMeasurement { @@ -984,6 +1030,7 @@ packet SessionInfoNtf : SessionControlNotification (opcode = 0x0) { // SESSION_I packet ShortMacTwoWaySessionInfoNtf : SessionInfoNtf (ranging_measurement_type = TWO_WAY, mac_address_indicator = SHORT_ADDRESS) { _count_(two_way_ranging_measurements) : 8, two_way_ranging_measurements : ShortAddressTwoWayRangingMeasurement[], + vendor_data: 8[], } test ShortMacTwoWaySessionInfoNtf { @@ -993,6 +1040,7 @@ test ShortMacTwoWaySessionInfoNtf { packet ExtendedMacTwoWaySessionInfoNtf : SessionInfoNtf (ranging_measurement_type = TWO_WAY, mac_address_indicator = EXTENDED_ADDRESS) { _count_(two_way_ranging_measurements) : 8, two_way_ranging_measurements : ExtendedAddressTwoWayRangingMeasurement[], + vendor_data: 8[], } test ExtendedMacTwoWaySessionInfoNtf { @@ -1020,6 +1068,7 @@ test ExtendedMacDlTDoASessionInfoNtf { packet ShortMacOwrAoaSessionInfoNtf : SessionInfoNtf (ranging_measurement_type = OWR_AOA, mac_address_indicator = SHORT_ADDRESS) { _count_(owr_aoa_ranging_measurements) : 8, owr_aoa_ranging_measurements : ShortAddressOwrAoaRangingMeasurement[], + vendor_data: 8[], } test ShortMacOwrAoaSessionInfoNtf { @@ -1030,6 +1079,7 @@ test ShortMacOwrAoaSessionInfoNtf { packet ExtendedMacOwrAoaSessionInfoNtf : SessionInfoNtf (ranging_measurement_type = OWR_AOA, mac_address_indicator = EXTENDED_ADDRESS) { _count_(owr_aoa_ranging_measurements) : 8, owr_aoa_ranging_measurements : ExtendedAddressOwrAoaRangingMeasurement[], + vendor_data: 8[], } test ExtendedMacOwrAoaSessionInfoNtf { |