diff options
-rwxr-xr-x | src/Android.bp | 5 | ||||
-rw-r--r-- | src/rust/uci_hal_android/uci_hal_android.rs | 3 | ||||
-rw-r--r-- | src/rust/uwb_core/src/params/uci_packets.rs | 13 | ||||
-rw-r--r-- | src/rust/uwb_core/src/session/session_manager.rs | 14 | ||||
-rw-r--r-- | src/rust/uwb_core/src/session/uwb_session.rs | 1 | ||||
-rw-r--r-- | src/rust/uwb_core/src/uci/command.rs | 2 | ||||
-rw-r--r-- | src/rust/uwb_core/src/uci/message.rs | 11 | ||||
-rw-r--r-- | src/rust/uwb_core/src/uci/mock_uci_logger.rs | 5 | ||||
-rw-r--r-- | src/rust/uwb_core/src/uci/mock_uci_manager.rs | 12 | ||||
-rw-r--r-- | src/rust/uwb_core/src/uci/notification.rs | 29 | ||||
-rw-r--r-- | src/rust/uwb_core/src/uci/response.rs | 116 | ||||
-rw-r--r-- | src/rust/uwb_core/src/uci/uci_hal.rs | 2 | ||||
-rw-r--r-- | src/rust/uwb_core/src/uci/uci_logger.rs | 4 | ||||
-rw-r--r-- | src/rust/uwb_core/src/uci/uci_logger_pcapng.rs | 5 | ||||
-rw-r--r-- | src/rust/uwb_core/src/uci/uci_manager.rs | 93 | ||||
-rw-r--r-- | src/rust/uwb_core/src/uci/uci_manager_sync.rs | 8 | ||||
-rw-r--r-- | src/rust/uwb_uci_packets/src/lib.rs | 132 | ||||
-rw-r--r-- | src/rust/uwb_uci_packets/uci_packets.pdl | 13 |
18 files changed, 339 insertions, 129 deletions
diff --git a/src/Android.bp b/src/Android.bp index 54b746e..78fec77 100755 --- a/src/Android.bp +++ b/src/Android.bp @@ -69,7 +69,7 @@ rust_library { genrule { name: "UwbGeneratedPackets_rust", - defaults: ["pdl_rust_generator_defaults"], + defaults: ["pdl_rust_legacy_generator_defaults"], srcs: [ "rust/uwb_uci_packets/uci_packets.pdl", ], @@ -248,8 +248,9 @@ rust_defaults { "libbinder_rs", "libbinder_tokio_rs", "libbytes", - "libjni", + "libjni_legacy", "liblog_rust", + "libpdl_runtime", "libthiserror", "libtokio", "libuwb_uci_packets", diff --git a/src/rust/uci_hal_android/uci_hal_android.rs b/src/rust/uci_hal_android/uci_hal_android.rs index aa41875..86c9c93 100644 --- a/src/rust/uci_hal_android/uci_hal_android.rs +++ b/src/rust/uci_hal_android/uci_hal_android.rs @@ -30,6 +30,7 @@ use android_hardware_uwb::binder::{ use async_trait::async_trait; use binder_tokio::{Tokio, TokioRuntime}; use log::error; +use pdl_runtime::Packet; use tokio::runtime::Handle; use tokio::sync::{mpsc, Mutex}; use uwb_core::error::{Error as UwbCoreError, Result as UwbCoreResult}; @@ -43,7 +44,7 @@ fn input_uci_hal_packet<T: Into<uwb_uci_packets::UciControlPacket>>( builder: T, ) -> Vec<UciHalPacket> { let packets: Vec<uwb_uci_packets::UciControlPacketHal> = builder.into().into(); - packets.into_iter().map(|packet| packet.into()).collect() + packets.into_iter().map(|packet| packet.encode_to_vec().unwrap()).collect() } /// Send device status notification with error state. diff --git a/src/rust/uwb_core/src/params/uci_packets.rs b/src/rust/uwb_core/src/params/uci_packets.rs index 8ccb0ce..c7062d4 100644 --- a/src/rust/uwb_core/src/params/uci_packets.rs +++ b/src/rust/uwb_core/src/params/uci_packets.rs @@ -31,7 +31,9 @@ pub use uwb_uci_packets::{ MulticastUpdateStatusCode, PhaseList, PowerStats, RadarConfigStatus, RadarConfigTlv, RadarConfigTlvType, RadarDataType, RangingMeasurementType, ReasonCode, ResetConfig, SessionState, SessionType, SessionUpdateControllerMulticastListNtfV1Payload, - SessionUpdateControllerMulticastListNtfV2Payload, ShortAddressDlTdoaRangingMeasurement, + SessionUpdateControllerMulticastListNtfV2Payload, + SessionUpdateControllerMulticastListRspV1Payload, + SessionUpdateControllerMulticastListRspV2Payload, ShortAddressDlTdoaRangingMeasurement, ShortAddressOwrAoaRangingMeasurement, ShortAddressTwoWayRangingMeasurement, StatusCode, UpdateMulticastListAction, }; @@ -188,6 +190,15 @@ pub struct AndroidRadarConfigResponse { pub config_status: Vec<RadarConfigStatus>, } +/// The response from UciManager::(session_update_controller_multicast_list() method. +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct SessionUpdateControllerMulticastResponse { + /// The status code of the response. + pub status: StatusCode, + /// Controlee Status + pub status_list: Vec<ControleeStatusV2>, +} + /// The response from UciManager::session_update_dt_tag_ranging_rounds() method. #[derive(Debug, Clone, PartialEq, Eq)] pub struct SessionUpdateDtTagRangingRoundsResponse { diff --git a/src/rust/uwb_core/src/session/session_manager.rs b/src/rust/uwb_core/src/session/session_manager.rs index 5436747..feb32b7 100644 --- a/src/rust/uwb_core/src/session/session_manager.rs +++ b/src/rust/uwb_core/src/session/session_manager.rs @@ -367,7 +367,7 @@ impl<T: UciManager> SessionManagerActor<T> { } }, UciSessionNotification::SessionInfo(range_data) => { - if self.active_sessions.get(&range_data.session_token).is_some() { + if self.active_sessions.contains_key(&range_data.session_token) { let _ = self.session_notf_sender.send(SessionNotification::RangeData { session_id: range_data.session_token, range_data, @@ -606,7 +606,7 @@ mod tests { use crate::params::ccc_started_app_config_params::CccStartedAppConfigParams; use crate::params::uci_packets::{ AppConfigTlv, AppConfigTlvType, ControleeStatusV1, Controlees, MulticastUpdateStatusCode, - ReasonCode, SetAppConfigResponse, StatusCode, + ReasonCode, SessionUpdateControllerMulticastResponse, SetAppConfigResponse, StatusCode, }; use crate::params::utils::{u32_to_bytes, u64_to_bytes, u8_to_bytes}; use crate::params::{FiraAppConfigParamsBuilder, KeyRotation}; @@ -861,7 +861,10 @@ mod tests { action, Controlees::NoSessionKey(controlees_clone), multicast_list_notf, - Ok(()), + Ok(SessionUpdateControllerMulticastResponse { + status: StatusCode::UciStatusOk, + status_list: vec![], + }), ); }) .await; @@ -948,7 +951,10 @@ mod tests { action, uwb_uci_packets::Controlees::NoSessionKey(controlees_clone), vec![], // Not sending notification. - Ok(()), + Ok(SessionUpdateControllerMulticastResponse { + status: StatusCode::UciStatusOk, + status_list: vec![], + }), ); }) .await; diff --git a/src/rust/uwb_core/src/session/uwb_session.rs b/src/rust/uwb_core/src/session/uwb_session.rs index 7e82e0a..6b1556e 100644 --- a/src/rust/uwb_core/src/session/uwb_session.rs +++ b/src/rust/uwb_core/src/session/uwb_session.rs @@ -313,6 +313,7 @@ impl<T: UciManager> UwbSessionActor<T> { action, Controlees::NoSessionKey(controlees), false, + false, ) .await?; diff --git a/src/rust/uwb_core/src/uci/command.rs b/src/rust/uwb_core/src/uci/command.rs index 51cbdcb..6c3a339 100644 --- a/src/rust/uwb_core/src/uci/command.rs +++ b/src/rust/uwb_core/src/uci/command.rs @@ -69,6 +69,7 @@ pub enum UciCommand { action: UpdateMulticastListAction, controlees: Controlees, is_multicast_list_ntf_v2_supported: bool, + is_multicast_list_rsp_v2_supported: bool, }, SessionUpdateDtTagRangingRounds { session_token: u32, @@ -409,6 +410,7 @@ mod tests { action: UpdateMulticastListAction::AddControlee, controlees: Controlees::NoSessionKey(vec![]), is_multicast_list_ntf_v2_supported: false, + is_multicast_list_rsp_v2_supported: false, }; packet = uwb_uci_packets::UciControlPacket::try_from(cmd.clone()).unwrap(); assert_eq!( diff --git a/src/rust/uwb_core/src/uci/message.rs b/src/rust/uwb_core/src/uci/message.rs index b0f4c22..a01febf 100644 --- a/src/rust/uwb_core/src/uci/message.rs +++ b/src/rust/uwb_core/src/uci/message.rs @@ -28,18 +28,19 @@ pub(super) enum UciMessage { Notification(UciNotification), } -impl TryFrom<(uwb_uci_packets::UciControlPacket, UCIMajorVersion, bool)> for UciMessage { +impl TryFrom<(uwb_uci_packets::UciControlPacket, UCIMajorVersion, bool, bool)> for UciMessage { type Error = Error; fn try_from( - pair: (uwb_uci_packets::UciControlPacket, UCIMajorVersion, bool), + pair: (uwb_uci_packets::UciControlPacket, UCIMajorVersion, bool, bool), ) -> Result<Self, Self::Error> { let packet = pair.0; let uci_fira_major_ver = pair.1; let is_multicast_list_ntf_v2_supported = pair.2; + let is_multicast_list_rsp_v2_supported = pair.3; match packet.specialize() { - uwb_uci_packets::UciControlPacketChild::UciResponse(evt) => { - Ok(UciMessage::Response(evt.try_into()?)) - } + uwb_uci_packets::UciControlPacketChild::UciResponse(evt) => Ok(UciMessage::Response( + (evt, uci_fira_major_ver, is_multicast_list_rsp_v2_supported).try_into()?, + )), uwb_uci_packets::UciControlPacketChild::UciNotification(evt) => { Ok(UciMessage::Notification( (evt, uci_fira_major_ver, is_multicast_list_ntf_v2_supported).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 e21fb71..52d6044 100644 --- a/src/rust/uwb_core/src/uci/mock_uci_logger.rs +++ b/src/rust/uwb_core/src/uci/mock_uci_logger.rs @@ -14,6 +14,7 @@ use std::convert::TryFrom; +use pdl_runtime::Packet; use tokio::sync::mpsc; use uwb_uci_packets::{UciControlPacket, UciDataPacket}; @@ -58,10 +59,10 @@ impl UciLogger for MockUciLogger { } fn log_uci_control_packet(&mut self, packet: UciControlPacket) { - let _ = self.log_sender.send(UciLogEvent::Packet(packet.into())); + let _ = self.log_sender.send(UciLogEvent::Packet(packet.encode_to_vec().unwrap())); } fn log_uci_data_packet(&mut self, packet: &UciDataPacket) { - let _ = self.log_sender.send(UciLogEvent::Packet(packet.clone().into())); + let _ = self.log_sender.send(UciLogEvent::Packet(packet.encode_to_vec().unwrap())); } } diff --git a/src/rust/uwb_core/src/uci/mock_uci_manager.rs b/src/rust/uwb_core/src/uci/mock_uci_manager.rs index 7ae33ab..608205d 100644 --- a/src/rust/uwb_core/src/uci/mock_uci_manager.rs +++ b/src/rust/uwb_core/src/uci/mock_uci_manager.rs @@ -31,8 +31,9 @@ use crate::params::uci_packets::{ AppConfigTlv, AppConfigTlvType, CapTlv, ControleePhaseList, Controlees, CoreSetConfigResponse, CountryCode, DeviceConfigId, DeviceConfigTlv, GetDeviceInfoResponse, PhaseList, PowerStats, RadarConfigTlv, RadarConfigTlvType, RawUciMessage, ResetConfig, SessionId, SessionState, - SessionToken, SessionType, SessionUpdateDtTagRangingRoundsResponse, SetAppConfigResponse, - UpdateMulticastListAction, UpdateTime, + SessionToken, SessionType, SessionUpdateControllerMulticastResponse, + SessionUpdateDtTagRangingRoundsResponse, SetAppConfigResponse, UpdateMulticastListAction, + UpdateTime, }; use crate::uci::notification::{ CoreNotification, DataRcvNotification, RadarDataRcvNotification, SessionNotification, @@ -263,7 +264,7 @@ impl MockUciManager { expected_action: UpdateMulticastListAction, expected_controlees: Controlees, notfs: Vec<UciNotification>, - out: Result<()>, + out: Result<SessionUpdateControllerMulticastResponse>, ) { self.expected_calls.lock().unwrap().push_back( ExpectedCall::SessionUpdateControllerMulticastList { @@ -840,7 +841,8 @@ impl UciManager for MockUciManager { action: UpdateMulticastListAction, controlees: Controlees, _is_multicast_list_ntf_v2_supported: bool, - ) -> Result<()> { + _is_multicast_list_rsp_v2_supported: bool, + ) -> Result<SessionUpdateControllerMulticastResponse> { let mut expected_calls = self.expected_calls.lock().unwrap(); match expected_calls.pop_front() { Some(ExpectedCall::SessionUpdateControllerMulticastList { @@ -1274,7 +1276,7 @@ enum ExpectedCall { expected_action: UpdateMulticastListAction, expected_controlees: Controlees, notfs: Vec<UciNotification>, - out: Result<()>, + out: Result<SessionUpdateControllerMulticastResponse>, }, SessionUpdateDtTagRangingRounds { expected_session_id: u32, diff --git a/src/rust/uwb_core/src/uci/notification.rs b/src/rust/uwb_core/src/uci/notification.rs index 58e68cd..688199e 100644 --- a/src/rust/uwb_core/src/uci/notification.rs +++ b/src/rust/uwb_core/src/uci/notification.rs @@ -498,7 +498,7 @@ impl TryFrom<uwb_uci_packets::SessionControlNotification> for SessionNotificatio impl TryFrom<uwb_uci_packets::SessionInfoNtf> for SessionNotification { type Error = Error; 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(); + let raw_ranging_data = evt.encode_to_bytes().unwrap()[UCI_PACKET_HEADER_LEN..].to_vec(); use uwb_uci_packets::SessionInfoNtfChild; let ranging_measurements = match evt.specialize() { SessionInfoNtfChild::ShortMacTwoWaySessionInfoNtf(evt) => { @@ -772,8 +772,9 @@ mod tests { vendor_data: vec![], } .build(); - let raw_ranging_data = - extended_two_way_session_info_ntf.clone().to_bytes()[UCI_PACKET_HEADER_LEN..].to_vec(); + let raw_ranging_data = extended_two_way_session_info_ntf.encode_to_bytes().unwrap() + [UCI_PACKET_HEADER_LEN..] + .to_vec(); let range_notification = uwb_uci_packets::SessionInfoNtf::try_from(extended_two_way_session_info_ntf).unwrap(); let session_notification = SessionNotification::try_from(range_notification).unwrap(); @@ -822,8 +823,9 @@ mod tests { vendor_data: vec![0x02, 0x01], } .build(); - let raw_ranging_data = - short_two_way_session_info_ntf.clone().to_bytes()[UCI_PACKET_HEADER_LEN..].to_vec(); + let raw_ranging_data = short_two_way_session_info_ntf.encode_to_bytes().unwrap() + [UCI_PACKET_HEADER_LEN..] + .to_vec(); let range_notification = uwb_uci_packets::SessionInfoNtf::try_from(short_two_way_session_info_ntf).unwrap(); let session_notification = SessionNotification::try_from(range_notification).unwrap(); @@ -868,8 +870,9 @@ mod tests { vendor_data: vec![], } .build(); - let raw_ranging_data = - extended_owr_aoa_session_info_ntf.clone().to_bytes()[UCI_PACKET_HEADER_LEN..].to_vec(); + let raw_ranging_data = extended_owr_aoa_session_info_ntf.encode_to_bytes().unwrap() + [UCI_PACKET_HEADER_LEN..] + .to_vec(); let range_notification = uwb_uci_packets::SessionInfoNtf::try_from(extended_owr_aoa_session_info_ntf).unwrap(); let session_notification = SessionNotification::try_from(range_notification).unwrap(); @@ -913,8 +916,9 @@ mod tests { vendor_data: vec![], } .build(); - let raw_ranging_data = - short_owr_aoa_session_info_ntf.clone().to_bytes()[UCI_PACKET_HEADER_LEN..].to_vec(); + let raw_ranging_data = short_owr_aoa_session_info_ntf.encode_to_bytes().unwrap() + [UCI_PACKET_HEADER_LEN..] + .to_vec(); let range_notification = uwb_uci_packets::SessionInfoNtf::try_from(short_owr_aoa_session_info_ntf).unwrap(); let session_notification = SessionNotification::try_from(range_notification).unwrap(); @@ -1226,8 +1230,9 @@ mod tests { session_token: 0x11, } .build(); - let raw_ranging_data = - short_mac_dl_tdoa_session_info_ntf.clone().to_bytes()[UCI_PACKET_HEADER_LEN..].to_vec(); + let raw_ranging_data = short_mac_dl_tdoa_session_info_ntf.encode_to_bytes().unwrap() + [UCI_PACKET_HEADER_LEN..] + .to_vec(); let short_measurement = ShortAddressDlTdoaRangingMeasurement::parse(&dl_tdoa_measurements, 1).unwrap(); let range_notification_packet = @@ -1279,7 +1284,7 @@ mod tests { session_token: 0x11, } .build(); - let raw_ranging_data = extended_mac_dl_tdoa_session_info_ntf.clone().to_bytes() + let raw_ranging_data = extended_mac_dl_tdoa_session_info_ntf.encode_to_bytes().unwrap() [UCI_PACKET_HEADER_LEN..] .to_vec(); let short_measurement = diff --git a/src/rust/uwb_core/src/uci/response.rs b/src/rust/uwb_core/src/uci/response.rs index 8f5925e..74e8328 100644 --- a/src/rust/uwb_core/src/uci/response.rs +++ b/src/rust/uwb_core/src/uci/response.rs @@ -14,11 +14,16 @@ use std::convert::{TryFrom, TryInto}; +use log::error; + use crate::error::{Error, Result}; use crate::params::uci_packets::{ AndroidRadarConfigResponse, AppConfigTlv, CapTlv, CoreSetConfigResponse, DeviceConfigTlv, GetDeviceInfoResponse, PowerStats, RadarConfigTlv, RawUciMessage, SessionHandle, SessionState, - SessionUpdateDtTagRangingRoundsResponse, SetAppConfigResponse, StatusCode, UciControlPacket, + SessionUpdateControllerMulticastListRspV1Payload, + SessionUpdateControllerMulticastListRspV2Payload, SessionUpdateControllerMulticastResponse, + SessionUpdateDtTagRangingRoundsResponse, SetAppConfigResponse, StatusCode, UCIMajorVersion, + UciControlPacket, }; use crate::uci::error::status_code_to_result; @@ -40,7 +45,7 @@ pub(super) enum UciResponse { SessionGetAppConfig(Result<Vec<AppConfigTlv>>), SessionGetCount(Result<u8>), SessionGetState(Result<SessionState>), - SessionUpdateControllerMulticastList(Result<()>), + SessionUpdateControllerMulticastList(Result<SessionUpdateControllerMulticastResponse>), SessionUpdateDtTagRangingRounds(Result<SessionUpdateDtTagRangingRoundsResponse>), SessionQueryMaxDataSize(Result<u16>), SessionStart(Result<()>), @@ -103,13 +108,20 @@ impl UciResponse { } } -impl TryFrom<uwb_uci_packets::UciResponse> for UciResponse { +impl TryFrom<(uwb_uci_packets::UciResponse, UCIMajorVersion, bool)> for UciResponse { type Error = Error; - fn try_from(evt: uwb_uci_packets::UciResponse) -> std::result::Result<Self, Self::Error> { + fn try_from( + pair: (uwb_uci_packets::UciResponse, UCIMajorVersion, bool), + ) -> std::result::Result<Self, Self::Error> { + let evt = pair.0; + let uci_fira_major_ver = pair.1; + let is_multicast_list_rsp_v2_supported = pair.2; use uwb_uci_packets::UciResponseChild; match evt.specialize() { UciResponseChild::CoreResponse(evt) => evt.try_into(), - UciResponseChild::SessionConfigResponse(evt) => evt.try_into(), + UciResponseChild::SessionConfigResponse(evt) => { + (evt, uci_fira_major_ver, is_multicast_list_rsp_v2_supported).try_into() + } UciResponseChild::SessionControlResponse(evt) => evt.try_into(), UciResponseChild::AndroidResponse(evt) => evt.try_into(), UciResponseChild::UciVendor_9_Response(evt) => raw_response(evt.into()), @@ -161,12 +173,15 @@ impl TryFrom<uwb_uci_packets::CoreResponse> for UciResponse { } } -impl TryFrom<uwb_uci_packets::SessionConfigResponse> for UciResponse { +impl TryFrom<(uwb_uci_packets::SessionConfigResponse, UCIMajorVersion, bool)> for UciResponse { type Error = Error; fn try_from( - evt: uwb_uci_packets::SessionConfigResponse, + pair: (uwb_uci_packets::SessionConfigResponse, UCIMajorVersion, bool), ) -> std::result::Result<Self, Self::Error> { use uwb_uci_packets::SessionConfigResponseChild; + let evt = pair.0; + let uci_fira_major_ver = pair.1; + let is_multicast_list_rsp_v2_supported = pair.2; match evt.specialize() { SessionConfigResponseChild::SessionInitRsp(evt) => { Ok(UciResponse::SessionInit(status_code_to_result(evt.get_status()).map(|_| None))) @@ -187,9 +202,54 @@ impl TryFrom<uwb_uci_packets::SessionConfigResponse> for UciResponse { status_code_to_result(evt.get_status()).map(|_| evt.get_session_state()), )) } - SessionConfigResponseChild::SessionUpdateControllerMulticastListRsp(evt) => { - Ok(UciResponse::SessionUpdateControllerMulticastList(status_code_to_result( - evt.get_status(), + SessionConfigResponseChild::SessionUpdateControllerMulticastListRsp(evt) + if uci_fira_major_ver == UCIMajorVersion::V1 + || !is_multicast_list_rsp_v2_supported => + { + error!( + "Tryfrom: SessionConfigResponse:: SessionUpdateControllerMulticastListRspV1 " + ); + let payload = evt.get_payload(); + let multicast_update_list_rsp_payload_v1 = + SessionUpdateControllerMulticastListRspV1Payload::parse(payload).map_err( + |e| { + error!( + "Failed to parse Multicast list ntf v1 {:?}, payload: {:?}", + e, &payload + ); + Error::BadParameters + }, + )?; + + Ok(UciResponse::SessionUpdateControllerMulticastList(Ok( + SessionUpdateControllerMulticastResponse { + status: multicast_update_list_rsp_payload_v1.status, + status_list: vec![], + }, + ))) + } + SessionConfigResponseChild::SessionUpdateControllerMulticastListRsp(evt) + if uci_fira_major_ver == UCIMajorVersion::V2 => + { + error!( + "Tryfrom: SessionConfigResponse:: SessionUpdateControllerMulticastListRspV2 " + ); + let payload = evt.get_payload(); + let multicast_update_list_rsp_payload_v2 = + SessionUpdateControllerMulticastListRspV2Payload::parse(payload).map_err( + |e| { + error!( + "Failed to parse Multicast list ntf v1 {:?}, payload: {:?}", + e, &payload + ); + Error::BadParameters + }, + )?; + Ok(UciResponse::SessionUpdateControllerMulticastList(Ok( + SessionUpdateControllerMulticastResponse { + status: multicast_update_list_rsp_payload_v2.status, + status_list: multicast_update_list_rsp_payload_v2.controlee_status, + }, ))) } SessionConfigResponseChild::SessionUpdateDtTagRangingRoundsRsp(evt) => { @@ -311,7 +371,13 @@ mod tests { .build(), ) .unwrap(); - let mut uci_response = UciResponse::try_from(uci_vendor_rsp_packet.clone()).unwrap(); + let uci_fira_major_version = UCIMajorVersion::V1; + let mut uci_response = UciResponse::try_from(( + uci_vendor_rsp_packet.clone(), + uci_fira_major_version.clone(), + false, + )) + .unwrap(); assert_eq!( uci_response, UciResponse::RawUciCmd(Ok(RawUciMessage { @@ -329,7 +395,12 @@ mod tests { .build(), ) .unwrap(); - uci_response = UciResponse::try_from(uci_vendor_rsp_packet.clone()).unwrap(); + uci_response = UciResponse::try_from(( + uci_vendor_rsp_packet.clone(), + uci_fira_major_version.clone(), + false, + )) + .unwrap(); assert_eq!( uci_response, UciResponse::RawUciCmd(Ok(RawUciMessage { @@ -347,7 +418,12 @@ mod tests { .build(), ) .unwrap(); - uci_response = UciResponse::try_from(uci_vendor_rsp_packet.clone()).unwrap(); + uci_response = UciResponse::try_from(( + uci_vendor_rsp_packet.clone(), + uci_fira_major_version.clone(), + false, + )) + .unwrap(); assert_eq!( uci_response, UciResponse::RawUciCmd(Ok(RawUciMessage { @@ -365,7 +441,12 @@ mod tests { .build(), ) .unwrap(); - uci_response = UciResponse::try_from(uci_vendor_rsp_packet.clone()).unwrap(); + uci_response = UciResponse::try_from(( + uci_vendor_rsp_packet.clone(), + uci_fira_major_version.clone(), + false, + )) + .unwrap(); assert_eq!( uci_response, UciResponse::RawUciCmd(Ok(RawUciMessage { @@ -383,7 +464,12 @@ mod tests { .build(), ) .unwrap(); - uci_response = UciResponse::try_from(uci_vendor_rsp_packet.clone()).unwrap(); + uci_response = UciResponse::try_from(( + uci_vendor_rsp_packet.clone(), + uci_fira_major_version.clone(), + false, + )) + .unwrap(); assert_eq!( uci_response, UciResponse::RawUciCmd(Ok(RawUciMessage { diff --git a/src/rust/uwb_core/src/uci/uci_hal.rs b/src/rust/uwb_core/src/uci/uci_hal.rs index 098840a..adc69b3 100644 --- a/src/rust/uwb_core/src/uci/uci_hal.rs +++ b/src/rust/uwb_core/src/uci/uci_hal.rs @@ -58,7 +58,7 @@ pub trait UciHal: 'static + Send + Sync { 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?; + self.send_packet(packet.encode_to_vec().unwrap()).await?; } Ok(()) } diff --git a/src/rust/uwb_core/src/uci/uci_logger.rs b/src/rust/uwb_core/src/uci/uci_logger.rs index 381351c..a6060d9 100644 --- a/src/rust/uwb_core/src/uci/uci_logger.rs +++ b/src/rust/uwb_core/src/uci/uci_logger.rs @@ -108,10 +108,10 @@ fn filter_uci_response(rsp: UciResponse) -> UciResponse { // Log only the Data Packet header bytes, so that we don't log any PII (payload bytes). fn filter_uci_data( packet: &UciDataPacket, -) -> std::result::Result<UciDataPacket, pdl_runtime::Error> { +) -> std::result::Result<UciDataPacket, pdl_runtime::DecodeError> { // 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(); + let data_packet_bytes: Vec<u8> = packet.encode_to_vec().unwrap(); let mut filtered_data_packet_bytes: Vec<u8> = vec![0; data_packet_bytes.len()]; for (i, &b) in data_packet_bytes[..UCI_PACKET_HAL_HEADER_LEN].iter().enumerate() { filtered_data_packet_bytes[i] = b; 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 5743913..ca67601 100644 --- a/src/rust/uwb_core/src/uci/uci_logger_pcapng.rs +++ b/src/rust/uwb_core/src/uci/uci_logger_pcapng.rs @@ -15,6 +15,7 @@ //! Implements UciLoggerPcapng, a UciLogger with PCAPNG format log. use log::warn; +use pdl_runtime::Packet; use tokio::sync::mpsc; use uwb_uci_packets::{UciControlPacket, UciDataPacket}; @@ -51,7 +52,7 @@ impl UciLogger for UciLoggerPcapng { fn log_uci_control_packet(&mut self, packet: UciControlPacket) { let block_bytes = match EnhancedPacketBlockBuilder::new() .interface_id(self.interface_id) - .packet(packet.into()) + .packet(packet.encode_to_vec().unwrap()) .into_le_bytes() { Some(b) => b, @@ -63,7 +64,7 @@ impl UciLogger for UciLoggerPcapng { 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()) + .packet(packet.encode_to_vec().unwrap()) .into_le_bytes() { Some(b) => b, diff --git a/src/rust/uwb_core/src/uci/uci_manager.rs b/src/rust/uwb_core/src/uci/uci_manager.rs index 065da83..ce2e103 100644 --- a/src/rust/uwb_core/src/uci/uci_manager.rs +++ b/src/rust/uwb_core/src/uci/uci_manager.rs @@ -27,8 +27,8 @@ use crate::params::uci_packets::{ CoreSetConfigResponse, CountryCode, CreditAvailability, DeviceConfigId, DeviceConfigTlv, DeviceState, GetDeviceInfoResponse, GroupId, MessageType, PowerStats, RadarConfigTlv, RadarConfigTlvType, RawUciMessage, ResetConfig, SessionId, SessionState, SessionToken, - SessionType, SessionUpdateDtTagRangingRoundsResponse, SetAppConfigResponse, UciDataPacket, - UciDataPacketHal, UpdateMulticastListAction, UpdateTime, + SessionType, SessionUpdateControllerMulticastResponse, SessionUpdateDtTagRangingRoundsResponse, + SetAppConfigResponse, UciDataPacket, UciDataPacketHal, UpdateMulticastListAction, UpdateTime, }; use crate::params::utils::{bytes_to_u16, bytes_to_u64}; use crate::params::UCIMajorVersion; @@ -122,7 +122,8 @@ pub trait UciManager: 'static + Send + Sync + Clone { action: UpdateMulticastListAction, controlees: Controlees, is_multicast_list_ntf_v2_supported: bool, - ) -> Result<()>; + is_multicast_list_rsp_v2_supported: bool, + ) -> Result<SessionUpdateControllerMulticastResponse>; // Update ranging rounds for DT Tag async fn session_update_dt_tag_ranging_rounds( @@ -472,7 +473,8 @@ impl UciManager for UciManagerImpl { action: UpdateMulticastListAction, controlees: Controlees, is_multicast_list_ntf_v2_supported: bool, - ) -> Result<()> { + is_multicast_list_rsp_v2_supported: bool, + ) -> Result<SessionUpdateControllerMulticastResponse> { let controlees_len = match controlees { Controlees::NoSessionKey(ref controlee_vec) => controlee_vec.len(), Controlees::ShortSessionKey(ref controlee_vec) => controlee_vec.len(), @@ -487,6 +489,7 @@ impl UciManager for UciManagerImpl { action, controlees, is_multicast_list_ntf_v2_supported, + is_multicast_list_rsp_v2_supported, }; match self.send_cmd(UciManagerCmd::SendUciCommand { cmd }).await { Ok(UciResponse::SessionUpdateControllerMulticastList(resp)) => resp, @@ -793,6 +796,9 @@ struct UciManagerActor<T: UciHal, U: UciLogger> { // The flag that indicate whether multicast list ntf v2 is supported. is_multicast_list_ntf_v2_supported: bool, + + // The flag that indicate whether multicast list rsp v2 is supported. + is_multicast_list_rsp_v2_supported: bool, } impl<T: UciHal, U: UciLogger> UciManagerActor<T, U> { @@ -831,6 +837,7 @@ impl<T: UciHal, U: UciLogger> UciManagerActor<T, U> { get_device_info_rsp: None, max_data_packet_payload_size: MAX_DATA_PACKET_PAYLOAD_SIZE, is_multicast_list_ntf_v2_supported: false, + is_multicast_list_rsp_v2_supported: false, } } @@ -1090,9 +1097,11 @@ impl<T: UciHal, U: UciLogger> UciManagerActor<T, U> { action: _, controlees: _, is_multicast_list_ntf_v2_supported, + is_multicast_list_rsp_v2_supported, } = cmd.clone() { self.is_multicast_list_ntf_v2_supported = is_multicast_list_ntf_v2_supported; + self.is_multicast_list_rsp_v2_supported = is_multicast_list_rsp_v2_supported; } self.uci_cmd_retryer = @@ -1144,7 +1153,11 @@ impl<T: UciHal, U: UciLogger> UciManagerActor<T, U> { return; } - match self.hal.send_packet(uci_data_snd_retryer.data_packet.clone().to_vec()).await { + match self + .hal + .send_packet(uci_data_snd_retryer.data_packet.encode_to_vec().unwrap()) + .await + { Ok(_) => { self.uci_data_snd_retryer = Some(uci_data_snd_retryer); } @@ -1257,7 +1270,7 @@ impl<T: UciHal, U: UciLogger> UciManagerActor<T, U> { retry_count: MAX_RETRY_COUNT, }); - let result = self.hal.send_packet(hal_data_packet_fragment.to_vec()).await; + let result = self.hal.send_packet(hal_data_packet_fragment.encode_to_vec().unwrap()).await; if result.is_err() { error!( "Result {:?} of sending data packet fragment SessionToken: {} to HAL", @@ -1299,6 +1312,7 @@ impl<T: UciHal, U: UciLogger> UciManagerActor<T, U> { UCIMajorVersion::from_u8(uci_fira_major_version) .map_or(UCIMajorVersion::V1, |v| v), self.is_multicast_list_ntf_v2_supported, + self.is_multicast_list_rsp_v2_supported, ) .try_into() { @@ -1689,6 +1703,7 @@ mod tests { use super::*; use bytes::Bytes; + use pdl_runtime::Packet; use tokio::macros::support::Future; use uwb_uci_packets::{ Controlee_V2_0_16_Byte_Version, Controlee_V2_0_32_Byte_Version, SessionGetCountCmdBuilder, @@ -1706,12 +1721,16 @@ mod tests { use crate::uci::notification::RadarSweepData; use crate::uci::uci_logger::NopUciLogger; use crate::utils::init_test_logging; + use bytes::{BufMut, BytesMut}; + use uwb_uci_packets::ControleeStatusV2; + use uwb_uci_packets::SessionUpdateControllerMulticastListRspV1Payload; + use uwb_uci_packets::SessionUpdateControllerMulticastListRspV2Payload; fn into_uci_hal_packets<T: Into<uwb_uci_packets::UciControlPacket>>( builder: T, ) -> Vec<UciHalPacket> { let packets: Vec<uwb_uci_packets::UciControlPacketHal> = builder.into().into(); - packets.into_iter().map(|packet| packet.into()).collect() + packets.into_iter().map(|packet| packet.encode_to_vec().unwrap()).collect() } // Construct a UCI packet, with the header fields and payload bytes. @@ -2610,6 +2629,31 @@ mod tests { assert!(mock_hal.wait_expected_calls_done().await); } + fn write_multicast_rsp_v1_payload( + payload: &SessionUpdateControllerMulticastListRspV1Payload, + buffer: &mut BytesMut, + ) { + buffer.put_u8(payload.status.into()); + } + + fn write_v2_controlee_status(status: &ControleeStatusV2, buffer: &mut BytesMut) { + for elem in &status.mac_address { + buffer.put_u8(*elem); + } + buffer.put_u8(u8::from(status.status)); + } + + fn write_multicast_rsp_v2_payload( + payload: &SessionUpdateControllerMulticastListRspV2Payload, + buffer: &mut BytesMut, + ) { + buffer.put_u8(payload.status.into()); + buffer.put_u8(payload.controlee_status.len() as u8); + for elem in &payload.controlee_status { + write_v2_controlee_status(elem, buffer); + } + } + #[tokio::test] async fn test_session_update_controller_multicast_list_v1_ok() { let session_id = 0x123; @@ -2626,10 +2670,16 @@ mod tests { action, controlees: Controlees::NoSessionKey(vec![controlee_clone]), is_multicast_list_ntf_v2_supported: false, + is_multicast_list_rsp_v2_supported: false, }; + let pload = SessionUpdateControllerMulticastListRspV1Payload { + status: StatusCode::UciStatusOk, + }; + let mut buf = BytesMut::new(); + write_multicast_rsp_v1_payload(&pload, &mut buf); let resp = into_uci_hal_packets( uwb_uci_packets::SessionUpdateControllerMulticastListRspBuilder { - status: uwb_uci_packets::StatusCode::UciStatusOk, + payload: Some(buf.freeze()), }, ); @@ -2648,6 +2698,7 @@ mod tests { action, uwb_uci_packets::Controlees::NoSessionKey(vec![controlee]), false, + false, ) .await; assert!(result.is_ok()); @@ -2677,13 +2728,19 @@ mod tests { action, controlees: Controlees::ShortSessionKey(vec![controlee_clone]), is_multicast_list_ntf_v2_supported: true, + is_multicast_list_rsp_v2_supported: true, }; + let pload = SessionUpdateControllerMulticastListRspV2Payload { + status: StatusCode::UciStatusOk, + controlee_status: vec![], + }; + let mut buf = BytesMut::new(); + write_multicast_rsp_v2_payload(&pload, &mut buf); let resp = into_uci_hal_packets( uwb_uci_packets::SessionUpdateControllerMulticastListRspBuilder { - status: uwb_uci_packets::StatusCode::UciStatusOk, + payload: Some(buf.freeze()), }, ); - hal.expected_send_command(cmd, resp, Ok(())); }, UciLoggerMode::Disabled, @@ -2698,6 +2755,7 @@ mod tests { action, uwb_uci_packets::Controlees::ShortSessionKey(vec![controlee]), true, + true, ) .await; assert!(result.is_ok()); @@ -2728,10 +2786,17 @@ mod tests { action, controlees: Controlees::LongSessionKey(vec![controlee_clone]), is_multicast_list_ntf_v2_supported: true, + is_multicast_list_rsp_v2_supported: true, + }; + let pload = SessionUpdateControllerMulticastListRspV2Payload { + status: StatusCode::UciStatusOk, + controlee_status: vec![], }; + let mut buf = BytesMut::new(); + write_multicast_rsp_v2_payload(&pload, &mut buf); let resp = into_uci_hal_packets( uwb_uci_packets::SessionUpdateControllerMulticastListRspBuilder { - status: uwb_uci_packets::StatusCode::UciStatusOk, + payload: Some(buf.freeze()), }, ); @@ -2750,6 +2815,7 @@ mod tests { action, uwb_uci_packets::Controlees::LongSessionKey(vec![controlee]), true, + true, ) .await; assert!(result.is_ok()); @@ -4280,13 +4346,14 @@ mod tests { uci_manager.set_logger_mode(UciLoggerMode::Filtered).await.unwrap(); uci_manager.session_get_count().await.unwrap(); let packet: Vec<u8> = log_receiver.recv().await.unwrap().try_into().unwrap(); - let cmd_packet: Vec<u8> = SessionGetCountCmdBuilder {}.build().into(); + let cmd_packet: Vec<u8> = SessionGetCountCmdBuilder {}.build().encode_to_vec().unwrap(); assert_eq!(&packet, &cmd_packet); let packet: Vec<u8> = log_receiver.recv().await.unwrap().try_into().unwrap(); let rsp_packet: Vec<u8> = SessionGetCountRspBuilder { status: StatusCode::UciStatusOk, session_count: 2 } .build() - .into(); + .encode_to_vec() + .unwrap(); assert_eq!(&packet, &rsp_packet); assert!(mock_hal.wait_expected_calls_done().await); 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 53e47d9..acb6af7 100644 --- a/src/rust/uwb_core/src/uci/uci_manager_sync.rs +++ b/src/rust/uwb_core/src/uci/uci_manager_sync.rs @@ -29,8 +29,8 @@ use crate::params::{ AndroidRadarConfigResponse, AppConfigTlv, AppConfigTlvType, CapTlv, CoreSetConfigResponse, CountryCode, DeviceConfigId, DeviceConfigTlv, GetDeviceInfoResponse, PowerStats, RadarConfigTlv, RadarConfigTlvType, RawUciMessage, ResetConfig, SessionId, SessionState, - SessionType, SessionUpdateDtTagRangingRoundsResponse, SetAppConfigResponse, - UpdateMulticastListAction, UpdateTime, + SessionType, SessionUpdateControllerMulticastResponse, SessionUpdateDtTagRangingRoundsResponse, + SetAppConfigResponse, UpdateMulticastListAction, UpdateTime, }; #[cfg(any(test, feature = "mock-utils"))] use crate::uci::mock_uci_manager::MockUciManager; @@ -317,12 +317,14 @@ impl<U: UciManager> UciManagerSync<U> { action: UpdateMulticastListAction, controlees: Controlees, is_multicast_list_ntf_v2_supported: bool, - ) -> Result<()> { + is_multicast_list_rsp_v2_supported: bool, + ) -> Result<SessionUpdateControllerMulticastResponse> { self.runtime_handle.block_on(self.uci_manager.session_update_controller_multicast_list( session_id, action, controlees, is_multicast_list_ntf_v2_supported, + is_multicast_list_rsp_v2_supported, )) } diff --git a/src/rust/uwb_uci_packets/src/lib.rs b/src/rust/uwb_uci_packets/src/lib.rs index 18c50c1..6ed8b62 100644 --- a/src/rust/uwb_uci_packets/src/lib.rs +++ b/src/rust/uwb_uci_packets/src/lib.rs @@ -283,10 +283,10 @@ impl From<DataPacketFormat> for GroupIdOrDataPacketFormat { // The GroupIdOrDataPacketFormat enum has more values defined (for the GroupId bits) than the // DataPacketFormat enum. Hence this is implemented as TryFrom() instead of From(). impl TryFrom<GroupIdOrDataPacketFormat> for DataPacketFormat { - type Error = Error; + type Error = DecodeError; - fn try_from(gid_or_dpf: GroupIdOrDataPacketFormat) -> Result<Self> { - DataPacketFormat::try_from(u8::from(gid_or_dpf)).or(Err(Error::InvalidPacketError)) + fn try_from(gid_or_dpf: GroupIdOrDataPacketFormat) -> Result<Self, DecodeError> { + DataPacketFormat::try_from(u8::from(gid_or_dpf)).or(Err(DecodeError::InvalidPacketError)) } } @@ -298,9 +298,9 @@ struct UciControlPacketHeader { } impl UciControlPacketHeader { - fn new(message_type: MessageType, group_id: GroupId, opcode: u8) -> Result<Self> { + fn new(message_type: MessageType, group_id: GroupId, opcode: u8) -> Result<Self, DecodeError> { if !is_uci_control_packet(message_type) { - return Err(Error::InvalidPacketError); + return Err(DecodeError::InvalidPacketError); } Ok(UciControlPacketHeader { @@ -330,9 +330,9 @@ fn get_oid_from_uci_control_packet(packet: &[u8]) -> u8 { // 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 UciPacketHal::to_bytes() should always be larger then the place we access. +// panic because UciPacketHal::encode_to_bytes() should always be larger then the place we access. fn get_opcode_from_uci_control_packet(packet: &UciPacketHal) -> u8 { - get_oid_from_uci_control_packet(&packet.clone().to_bytes()) + get_oid_from_uci_control_packet(&packet.encode_to_bytes().unwrap()) } fn is_uci_control_packet(message_type: MessageType) -> bool { @@ -371,25 +371,25 @@ fn is_device_state_err_control_packet(packet: &UciPacketHal) -> bool { packet.get_message_type() == MessageType::Notification.into() && packet.get_group_id_or_data_packet_format() == GroupIdOrDataPacketFormat::Core.into() && get_opcode_from_uci_control_packet(packet) == CoreOpCode::CoreDeviceStatusNtf.into() - && packet.clone().to_vec()[UCI_PACKET_HAL_HEADER_LEN] + && packet.encode_to_vec().unwrap()[UCI_PACKET_HAL_HEADER_LEN] == DeviceState::DeviceStateError.into() } 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() + self.encode_to_bytes().unwrap().slice(UCI_PACKET_HEADER_LEN..).to_vec() } } // 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<UciPacketHal>> for UciControlPacket { - type Error = Error; + type Error = DecodeError; - fn try_from(packets: Vec<UciPacketHal>) -> Result<Self> { + fn try_from(packets: Vec<UciPacketHal>) -> Result<Self, DecodeError> { if packets.is_empty() { - return Err(Error::InvalidPacketError); + return Err(DecodeError::InvalidPacketError); } // Store header info from the first packet. @@ -413,17 +413,25 @@ impl TryFrom<Vec<UciPacketHal>> for UciControlPacket { message_type: packet.get_message_type(), group_id: packet.get_group_id_or_data_packet_format().into(), opcode: get_opcode_from_uci_control_packet(&packet), - payload: Some(packet.to_bytes().slice(UCI_PACKET_HAL_HEADER_LEN..)), + payload: Some( + packet + .encode_to_bytes() + .unwrap() + .slice(UCI_PACKET_HAL_HEADER_LEN..), + ), } .build() - .to_bytes(), + .encode_to_bytes() + .unwrap(), ); } error!("Received unexpected fragment: {:?}", packet); - return Err(Error::InvalidPacketError); + return Err(DecodeError::InvalidPacketError); } // get payload by stripping the header. - payload_buf.extend_from_slice(&packet.to_bytes().slice(UCI_PACKET_HAL_HEADER_LEN..)) + payload_buf.extend_from_slice( + &packet.encode_to_bytes().unwrap().slice(UCI_PACKET_HAL_HEADER_LEN..), + ) } // Create assembled |UciControlPacket| and convert to bytes again since we need to @@ -436,7 +444,8 @@ impl TryFrom<Vec<UciPacketHal>> for UciControlPacket { payload: Some(payload_buf.into()), } .build() - .to_bytes(), + .encode_to_bytes() + .unwrap(), ) } } @@ -472,24 +481,24 @@ fn is_data_rcv_or_radar_format(data_packet_format: DataPacketFormat) -> bool { fn try_into_data_payload( packet: UciPacketHal, expected_data_packet_format: DataPacketFormat, -) -> Result<Bytes> { +) -> Result<Bytes, DecodeError> { let dpf: DataPacketFormat = packet.get_group_id_or_data_packet_format().try_into()?; if is_uci_data_packet(packet.get_message_type()) && dpf == expected_data_packet_format { - Ok(packet.to_bytes().slice(UCI_PACKET_HAL_HEADER_LEN..)) + Ok(packet.encode_to_bytes().unwrap().slice(UCI_PACKET_HAL_HEADER_LEN..)) } else { error!("Received unexpected data packet fragment: {:?}", packet); - Err(Error::InvalidPacketError) + Err(DecodeError::InvalidPacketError) } } // 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<UciPacketHal>> for UciDataPacket { - type Error = Error; + type Error = DecodeError; - fn try_from(packets: Vec<UciPacketHal>) -> Result<Self> { + fn try_from(packets: Vec<UciPacketHal>) -> Result<Self, DecodeError> { if packets.is_empty() { - return Err(Error::InvalidPacketError); + return Err(DecodeError::InvalidPacketError); } let dpf: DataPacketFormat = packets[0].get_group_id_or_data_packet_format().try_into()?; @@ -514,7 +523,8 @@ impl TryFrom<Vec<UciPacketHal>> for UciDataPacket { payload: Some(payload_buf.into()), } .build() - .to_bytes(), + .encode_to_bytes() + .unwrap(), ) } } @@ -541,7 +551,7 @@ impl From<UciControlPacket> for Vec<UciControlPacketHal> { let mut fragments = Vec::new(); // get payload by stripping the header. - let payload = packet.to_bytes().slice(UCI_PACKET_HEADER_LEN..); + let payload = packet.encode_to_bytes().unwrap().slice(UCI_PACKET_HEADER_LEN..); if payload.is_empty() { fragments.push( UciControlPacketHalBuilder { @@ -585,7 +595,7 @@ pub fn fragment_data_msg_send(packet: UciDataSnd, max_payload_len: usize) -> Vec let dpf = packet.get_data_packet_format().into(); // get payload by stripping the header. - let payload = packet.to_bytes().slice(UCI_DATA_SND_PACKET_HEADER_LEN..); + let payload = packet.encode_to_bytes().unwrap().slice(UCI_DATA_SND_PACKET_HEADER_LEN..); if payload.is_empty() { fragments.push( UciDataPacketHalBuilder { @@ -632,7 +642,7 @@ pub struct PacketDefrager { pub enum UciDefragPacket { Control(UciControlPacket), Data(UciDataPacket), - Raw(Result<()>, RawUciControlPacket), + Raw(Result<(), DecodeError>, RawUciControlPacket), } impl PacketDefrager { @@ -654,7 +664,7 @@ impl PacketDefrager { Err(_) => { error!("Rx packet from HAL has unrecognized MT={}", mt_u8); return Some(UciDefragPacket::Raw( - Err(Error::InvalidPacketError), + Err(DecodeError::InvalidPacketError), RawUciControlPacket { mt: mt_u8, gid: 0, oid: 0, payload: Vec::new() }, )); } @@ -742,7 +752,7 @@ impl PacketDefrager { mt_u8, pbf, gid, oid ); return Some(UciDefragPacket::Raw( - Err(Error::InvalidPacketError), + Err(DecodeError::InvalidPacketError), RawUciControlPacket { mt: mt_u8, gid, oid, payload: Vec::new() }, )); } @@ -769,7 +779,9 @@ pub struct ParsedFrameReport { segment_metrics: Vec<SegmentMetricsValue>, } -pub fn parse_diagnostics_ntf(evt: AndroidRangeDiagnosticsNtf) -> Result<ParsedDiagnosticNtfPacket> { +pub fn parse_diagnostics_ntf( + evt: AndroidRangeDiagnosticsNtf, +) -> Result<ParsedDiagnosticNtfPacket, DecodeError> { let session_token = evt.get_session_token(); let sequence_number = evt.get_sequence_number(); let mut parsed_frame_reports = Vec::new(); @@ -796,11 +808,11 @@ pub fn parse_diagnostics_ntf(evt: AndroidRangeDiagnosticsNtf) -> Result<ParsedDi FrameReportTlvPacketChild::SegmentMetrics(sm) => { segment_metrics_vec.append(&mut sm.get_segment_metrics().clone()) } - _ => return Err(Error::InvalidPacketError), + _ => return Err(DecodeError::InvalidPacketError), }, Err(e) => { error!("Failed to parse the packet {:?}", e); - return Err(Error::InvalidPacketError); + return Err(DecodeError::InvalidPacketError); } } } @@ -863,7 +875,7 @@ pub fn build_session_update_controller_multicast_list_cmd( session_token: u32, action: UpdateMulticastListAction, controlees: Controlees, -) -> Result<SessionUpdateControllerMulticastListCmd> { +) -> Result<SessionUpdateControllerMulticastListCmd, DecodeError> { let mut controlees_buf = BytesMut::new(); match controlees { Controlees::NoSessionKey(controlee_v1) => { @@ -888,7 +900,7 @@ pub fn build_session_update_controller_multicast_list_cmd( controlees_buf.extend_from_slice(&write_controlee_2_0_32byte(&controlee)); } } - _ => return Err(Error::InvalidPacketError), + _ => return Err(DecodeError::InvalidPacketError), } Ok(SessionUpdateControllerMulticastListCmdBuilder { session_token, @@ -906,7 +918,7 @@ pub fn build_data_transfer_phase_config_cmd( dtpml_size: u8, mac_address: Vec<u8>, slot_bitmap: Vec<u8>, -) -> Result<SessionDataTransferPhaseConfigCmd> { +) -> Result<SessionDataTransferPhaseConfigCmd, DecodeError> { let mut dtpml_buffer = BytesMut::new(); //calculate mac address mode from data transfer control @@ -916,7 +928,7 @@ pub fn build_data_transfer_phase_config_cmd( let mac_address_size = match mac_address_mode { SHORT_ADDRESS => 2, EXTENDED_ADDRESS => 8, - _ => return Err(Error::InvalidPacketError), + _ => return Err(DecodeError::InvalidPacketError), }; // Calculate slot bitmap size from data transfer control @@ -932,7 +944,7 @@ pub fn build_data_transfer_phase_config_cmd( // Validate sizes of mac_address and slot_bitmap if slot_bitmap_vec.len() != dtpml_size.into() || mac_address_vec.len() != dtpml_size.into() { - return Err(Error::InvalidPacketError); + return Err(DecodeError::InvalidPacketError); } // Combine segmented vectors into dtpml_buffer @@ -973,7 +985,7 @@ pub fn build_session_set_hybrid_controller_config_cmd( number_of_phases: u8, update_time: [u8; 8], phase_list: PhaseList, -) -> Result<SessionSetHybridControllerConfigCmd> { +) -> Result<SessionSetHybridControllerConfigCmd, DecodeError> { let mut phase_list_buffer = BytesMut::new(); match phase_list { PhaseList::ShortMacAddress(phaseListShortMacAddressVec) => { @@ -1010,7 +1022,7 @@ pub fn build_session_set_hybrid_controller_config_cmd( phase_list_buffer.extend_from_slice(&phaseListExtendedMacAddress.mac_address); } } - _ => return Err(Error::InvalidPacketError), + _ => return Err(DecodeError::InvalidPacketError), } Ok(SessionSetHybridControllerConfigCmdBuilder { session_token, @@ -1072,11 +1084,11 @@ mod tests { let mut frame_reports = Vec::new(); let tlvs = vec![ FrameReportTlv { t: rssi.get_t(), v: rssi.get_rssi().to_vec() }, - FrameReportTlv { t: aoa.get_t(), v: aoa.to_vec()[3..].to_vec() }, - FrameReportTlv { t: cir.get_t(), v: cir.to_vec()[3..].to_vec() }, + FrameReportTlv { t: aoa.get_t(), v: aoa.encode_to_vec().unwrap()[3..].to_vec() }, + FrameReportTlv { t: cir.get_t(), v: cir.encode_to_vec().unwrap()[3..].to_vec() }, FrameReportTlv { t: segment_metrics.get_t(), - v: segment_metrics.to_vec()[3..].to_vec(), + v: segment_metrics.encode_to_vec().unwrap()[3..].to_vec(), }, ]; let frame_report = @@ -1118,15 +1130,15 @@ mod tests { .unwrap() .into(); let packet_fragments: Vec<UciControlPacketHal> = packet.into(); - let uci_packet: Vec<u8> = packet_fragments[0].clone().into(); + let uci_packet = packet_fragments[0].encode_to_vec(); assert_eq!( uci_packet, - vec![ + Ok(vec![ 0x21, 0x07, 0x00, 0x0c, // 2(packet info), RFU, payload length(12) 0x47, 0x36, 0x25, 0x14, // 4(session id (LE)) 0x00, 0x01, 0x12, 0x34, // action, # controlee, 2(short address (LE)) 0x46, 0x35, 0x24, 0x13, // 4(subsession id (LE)) - ] + ]) ); } @@ -1149,17 +1161,17 @@ mod tests { .unwrap() .into(); let packet_fragments: Vec<UciControlPacketHal> = packet.into(); - let uci_packet: Vec<u8> = packet_fragments[0].clone().into(); + let uci_packet = packet_fragments[0].encode_to_vec(); assert_eq!( uci_packet, - vec![ + Ok(vec![ 0x21, 0x07, 0x00, 0x1c, // 2(packet info), RFU, payload length(28) 0x47, 0x36, 0x25, 0x14, // 4(session id (LE)) 0x02, 0x01, 0x12, 0x34, // action, # controlee, 2(short address (LE)) 0x46, 0x35, 0x24, 0x13, // 4(subsession id (LE)) 0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef, 0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef, // 16(subsession key(LE)) - ] + ]) ); } @@ -1183,10 +1195,10 @@ mod tests { .unwrap() .into(); let packet_fragments: Vec<UciControlPacketHal> = packet.into(); - let uci_packet: Vec<u8> = packet_fragments[0].clone().into(); + let uci_packet = packet_fragments[0].encode_to_vec(); assert_eq!( uci_packet, - vec![ + Ok(vec![ 0x21, 0x07, 0x00, 0x2c, // 2(packet info), RFU, payload length(44) 0x47, 0x36, 0x25, 0x14, // 4(session id (LE)) 0x03, 0x01, 0x12, 0x34, // action, # controlee, 2(short address (LE)) @@ -1194,7 +1206,7 @@ mod tests { 0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef, 0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef, 0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef, 0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef, // 32(subsession key(LE)) - ] + ]) ); } @@ -1414,15 +1426,15 @@ mod tests { .unwrap() .into(); let packet_fragments: Vec<UciControlPacketHal> = packet.into(); - let uci_packet: Vec<u8> = packet_fragments[0].clone().into(); + let uci_packet = packet_fragments[0].encode_to_vec(); assert_eq!( uci_packet, - vec![ + Ok(vec![ 0x21, 0x0e, 0x00, 0x0b, // 2(packet info), RFU, payload length(11) 0x78, 0x56, 0x34, 0x12, // 4(session id (LE)) 0x00, 0x02, 0x01, // dtpcm_repetition, data_transfer_control, dtpml_size 0x00, 0x01, 0x02, 0x03, // payload - ] + ]) ); } @@ -1445,10 +1457,10 @@ mod tests { .unwrap() .into(); let packet_fragments: Vec<UciControlPacketHal> = packet.into(); - let uci_packet: Vec<u8> = packet_fragments[0].clone().into(); + let uci_packet = packet_fragments[0].encode_to_vec(); assert_eq!( uci_packet, - vec![ + Ok(vec![ 0x21, 0x0c, 0x00, 0x19, // 2(packet info), RFU, payload length(25) 0x78, 0x56, 0x34, 0x12, // 4(session id (LE)) 0x00, 0x00, // message_control, number_of_phases @@ -1458,7 +1470,7 @@ mod tests { 0x21, 0x11, // end slot index (LE) 0x00, // phase_participation 0x01, 0x02, // mac address - ] + ]) ); } @@ -1481,10 +1493,10 @@ mod tests { .unwrap() .into(); let packet_fragments: Vec<UciControlPacketHal> = packet.into(); - let uci_packet: Vec<u8> = packet_fragments[0].clone().into(); + let uci_packet = packet_fragments[0].encode_to_vec(); assert_eq!( uci_packet, - vec![ + Ok(vec![ 0x21, 0x0c, 0x00, 0x1f, // 2(packet info), RFU, payload length(31) 0x78, 0x56, 0x34, 0x12, // 4(session id (LE)) 0x00, 0x00, // message_control, number_of_phases @@ -1494,7 +1506,7 @@ mod tests { 0x21, 0x11, // end slot index (LE) 0x00, // phase_participation 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 // mac address - ] + ]) ); } } diff --git a/src/rust/uwb_uci_packets/uci_packets.pdl b/src/rust/uwb_uci_packets/uci_packets.pdl index 0268145..60a36d8 100644 --- a/src/rust/uwb_uci_packets/uci_packets.pdl +++ b/src/rust/uwb_uci_packets/uci_packets.pdl @@ -299,6 +299,7 @@ enum AppConfigTlvType : 8 { NB_OF_ELEVATION_MEASUREMENTS = 0xE5, ENABLE_DIAGNOSTICS = 0xE8, DIAGRAMS_FRAME_REPORTS_FIELDS = 0xE9, + ANTENNA_MODE = 0xEA, }, } @@ -991,13 +992,23 @@ struct SessionUpdateControllerMulticastListCmd_2_0_32_Byte_Payload { } packet SessionUpdateControllerMulticastListRsp : SessionConfigResponse (opcode = 0x7) { //SESSION_UPDATE_CONTROLLER_MULTICAST_LIST - status: StatusCode, + _payload_, } test SessionUpdateControllerMulticastListRsp { "\x41\x07\x00\x01\x00\x00\x00\x00", } +struct SessionUpdateControllerMulticastListRspV1Payload { + status: StatusCode, +} + +struct SessionUpdateControllerMulticastListRspV2Payload { + status: StatusCode, + _count_(controlee_status): 8, + controlee_status: ControleeStatusV2[], +} + struct ControleeStatusV1 { mac_address: 8[2], subsession_id: 32, |