summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAyush Jain <ayushjain@google.com>2024-03-07 00:31:18 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2024-03-07 00:31:18 +0000
commitb48caec4723ebfcf4f9d7b6549711e92e41e9f60 (patch)
tree6c54926a39ac16e34955f10e9dadd50e9e240f35
parent762a0c37dc1eacf3d43d4494709519780e337715 (diff)
parent8f786f4f789fa91eacbd753960b33973956bfdab (diff)
downloaduwb-b48caec4723ebfcf4f9d7b6549711e92e41e9f60.tar.gz
Merge "CR1045 Controller/Controlee specific HUS config command updates" into main
-rw-r--r--src/rust/uwb_core/protos/uwb_service.proto6
-rw-r--r--src/rust/uwb_core/src/params/uci_packets.rs13
-rw-r--r--src/rust/uwb_core/src/proto/mappings.rs21
-rw-r--r--src/rust/uwb_core/src/uci/command.rs34
-rw-r--r--src/rust/uwb_core/src/uci/mock_uci_manager.rs98
-rw-r--r--src/rust/uwb_core/src/uci/response.rs18
-rw-r--r--src/rust/uwb_core/src/uci/uci_manager.rs247
-rw-r--r--src/rust/uwb_core/src/uci/uci_manager_sync.rs23
-rw-r--r--src/rust/uwb_uci_packets/src/lib.rs77
-rw-r--r--src/rust/uwb_uci_packets/uci_packets.pdl78
10 files changed, 486 insertions, 129 deletions
diff --git a/src/rust/uwb_core/protos/uwb_service.proto b/src/rust/uwb_core/protos/uwb_service.proto
index f9fdca3..aaf6d18 100644
--- a/src/rust/uwb_core/protos/uwb_service.proto
+++ b/src/rust/uwb_core/protos/uwb_service.proto
@@ -208,6 +208,12 @@ enum UpdateMulticastListAction {
ADD_CONTROLEE_WITH_LONG_SUB_SESSION_KEY = 3;
}
+// Represent uwb_uci_packets::MacAddressIndicator.
+enum MacAddressIndicator {
+ SHORT_ADDRESS = 0x00;
+ EXTENDED_ADDRESS = 0x01;
+}
+
// Represent uwb_core::params::fira_app_config_params::DeviceType.
enum DeviceType {
CONTROLEE = 0;
diff --git a/src/rust/uwb_core/src/params/uci_packets.rs b/src/rust/uwb_core/src/params/uci_packets.rs
index b54680d..6f42e3b 100644
--- a/src/rust/uwb_core/src/params/uci_packets.rs
+++ b/src/rust/uwb_core/src/params/uci_packets.rs
@@ -21,15 +21,16 @@ use std::iter::FromIterator;
// Re-export enums and structs from uwb_uci_packets.
pub use uwb_uci_packets::{
AppConfigStatus, AppConfigTlv as RawAppConfigTlv, AppConfigTlvType, BitsPerSample, CapTlv,
- CapTlvType, Controlee, ControleeStatus, Controlees, CreditAvailability, DataRcvStatusCode,
- DataTransferNtfStatusCode, DataTransferPhaseConfigUpdateStatusCode, DeviceConfigId,
- DeviceConfigStatus, DeviceConfigTlv, DeviceState, ExtendedAddressDlTdoaRangingMeasurement,
- ExtendedAddressOwrAoaRangingMeasurement, ExtendedAddressTwoWayRangingMeasurement, GroupId,
+ CapTlvType, Controlee, ControleePhaseList, ControleeStatus, Controlees, CreditAvailability,
+ DataRcvStatusCode, DataTransferNtfStatusCode, DataTransferPhaseConfigUpdateStatusCode,
+ DeviceConfigId, DeviceConfigStatus, DeviceConfigTlv, DeviceState,
+ ExtendedAddressDlTdoaRangingMeasurement, ExtendedAddressOwrAoaRangingMeasurement,
+ ExtendedAddressTwoWayRangingMeasurement, GroupId, MacAddressIndicator,
MessageType, MulticastUpdateStatusCode, PhaseList, PowerStats, RadarConfigStatus,
RadarConfigTlv, RadarConfigTlvType, RadarDataType, RangingMeasurementType, ReasonCode,
ResetConfig, SessionState, SessionType, ShortAddressDlTdoaRangingMeasurement,
- ShortAddressOwrAoaRangingMeasurement, ShortAddressTwoWayRangingMeasurement, StatusCode,
- UpdateMulticastListAction,
+ ShortAddressOwrAoaRangingMeasurement, ShortAddressTwoWayRangingMeasurement,
+ StatusCode, UpdateMulticastListAction,
};
pub(crate) use uwb_uci_packets::{UciControlPacket, UciDataPacket, UciDataPacketHal};
diff --git a/src/rust/uwb_core/src/proto/mappings.rs b/src/rust/uwb_core/src/proto/mappings.rs
index fa9a7a8..089af2f 100644
--- a/src/rust/uwb_core/src/proto/mappings.rs
+++ b/src/rust/uwb_core/src/proto/mappings.rs
@@ -28,8 +28,8 @@ use crate::params::fira_app_config_params::{
};
use crate::params::uci_packets::{
Controlee, DeviceState, ExtendedAddressDlTdoaRangingMeasurement,
- ExtendedAddressOwrAoaRangingMeasurement, ExtendedAddressTwoWayRangingMeasurement, PowerStats,
- RangingMeasurementType, ReasonCode, SessionState, SessionType,
+ ExtendedAddressOwrAoaRangingMeasurement, ExtendedAddressTwoWayRangingMeasurement,
+ MacAddressIndicator, PowerStats, RangingMeasurementType, ReasonCode, SessionState, SessionType,
ShortAddressDlTdoaRangingMeasurement, ShortAddressOwrAoaRangingMeasurement,
ShortAddressTwoWayRangingMeasurement, StatusCode, UpdateMulticastListAction,
};
@@ -39,11 +39,12 @@ use crate::proto::bindings::{
Controlee as ProtoControlee, DeviceRole as ProtoDeviceRole, DeviceState as ProtoDeviceState,
DeviceType as ProtoDeviceType, DlTDoARangingMeasurement as ProtoDlTDoARangingMeasurement,
FiraAppConfigParams as ProtoFiraAppConfigParams, HoppingMode as ProtoHoppingMode,
- KeyRotation as ProtoKeyRotation, MacAddressMode as ProtoMacAddressMode,
- MacFcsType as ProtoMacFcsType, MultiNodeMode as ProtoMultiNodeMode,
- OwrAoaRangingMeasurement as ProtoOwrAoaRangingMeasurement, PowerStats as ProtoPowerStats,
- PreambleDuration as ProtoPreambleDuration, PrfMode as ProtoPrfMode,
- PsduDataRate as ProtoPsduDataRate, RangeDataNtfConfig as ProtoRangeDataNtfConfig,
+ KeyRotation as ProtoKeyRotation, MacAddressIndicator as ProtoMacAddressIndicator,
+ MacAddressMode as ProtoMacAddressMode, MacFcsType as ProtoMacFcsType,
+ MultiNodeMode as ProtoMultiNodeMode, OwrAoaRangingMeasurement as ProtoOwrAoaRangingMeasurement,
+ PowerStats as ProtoPowerStats, PreambleDuration as ProtoPreambleDuration,
+ PrfMode as ProtoPrfMode, PsduDataRate as ProtoPsduDataRate,
+ RangeDataNtfConfig as ProtoRangeDataNtfConfig,
RangingMeasurementType as ProtoRangingMeasurementType,
RangingRoundControl as ProtoRangingRoundControl, RangingRoundUsage as ProtoRangingRoundUsage,
RangingTimeStruct as ProtoRangingTimeStruct, ReasonCode as ProtoReasonCode,
@@ -697,6 +698,12 @@ enum_mapping! {
ADD_CONTROLEE_WITH_LONG_SUB_SESSION_KEY => AddControleeWithLongSubSessionKey,
}
+enum_mapping! {
+ ProtoMacAddressIndicator => MacAddressIndicator,
+ SHORT_ADDRESS => ShortAddress,
+ EXTENDED_ADDRESS => ExtendedAddress,
+}
+
pub enum ProtoRangingMeasurements {
TwoWay(Vec<ProtoTwoWayRangingMeasurement>),
OwrAoa(ProtoOwrAoaRangingMeasurement),
diff --git a/src/rust/uwb_core/src/uci/command.rs b/src/rust/uwb_core/src/uci/command.rs
index fa71b2d..9f0a70e 100644
--- a/src/rust/uwb_core/src/uci/command.rs
+++ b/src/rust/uwb_core/src/uci/command.rs
@@ -24,8 +24,9 @@ use crate::params::uci_packets::{
UpdateMulticastListAction, UpdateTime,
};
use uwb_uci_packets::{
- build_data_transfer_phase_config_cmd, build_session_update_controller_multicast_list_cmd,
- GroupId, MessageType, PhaseList,
+ build_data_transfer_phase_config_cmd, build_session_set_hybrid_controller_config_cmd,
+ build_session_update_controller_multicast_list_cmd, ControleePhaseList, GroupId, MessageType,
+ PhaseList,
};
/// The enum to represent the UCI commands. The definition of each field should follow UCI spec.
@@ -84,11 +85,16 @@ pub enum UciCommand {
SessionGetRangingCount {
session_token: SessionToken,
},
- SessionSetHybridConfig {
+ SessionSetHybridControllerConfig {
session_token: SessionToken,
+ message_control: u8,
number_of_phases: u8,
update_time: UpdateTime,
- phase_list: Vec<PhaseList>,
+ phase_list: PhaseList,
+ },
+ SessionSetHybridControleeConfig {
+ session_token: SessionToken,
+ controlee_phase_list: Vec<ControleePhaseList>,
},
SessionDataTransferPhaseConfig {
session_token: SessionToken,
@@ -231,19 +237,29 @@ impl TryFrom<UciCommand> for uwb_uci_packets::UciControlPacket {
UciCommand::SessionQueryMaxDataSize { session_token } => {
uwb_uci_packets::SessionQueryMaxDataSizeCmdBuilder { session_token }.build().into()
}
- UciCommand::SessionSetHybridConfig {
+ UciCommand::SessionSetHybridControllerConfig {
session_token,
+ message_control,
number_of_phases,
update_time,
phase_list,
- } => uwb_uci_packets::SessionSetHybridConfigCmdBuilder {
+ } => build_session_set_hybrid_controller_config_cmd(
session_token,
+ message_control,
number_of_phases,
- update_time: update_time.into(),
+ update_time.into(),
phase_list,
- }
- .build()
+ )
+ .map_err(|_| Error::BadParameters)?
.into(),
+ UciCommand::SessionSetHybridControleeConfig { session_token, controlee_phase_list } => {
+ uwb_uci_packets::SessionSetHybridControleeConfigCmdBuilder {
+ session_token,
+ controlee_phase_list,
+ }
+ .build()
+ .into()
+ }
UciCommand::SessionDataTransferPhaseConfig {
session_token,
dtpcm_repetition,
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 7805d19..6dd222f 100644
--- a/src/rust/uwb_core/src/uci/mock_uci_manager.rs
+++ b/src/rust/uwb_core/src/uci/mock_uci_manager.rs
@@ -28,10 +28,10 @@ use tokio::time::timeout;
use crate::error::{Error, Result};
use crate::params::uci_packets::{
app_config_tlvs_eq, device_config_tlvs_eq, radar_config_tlvs_eq, AndroidRadarConfigResponse,
- AppConfigTlv, AppConfigTlvType, CapTlv, Controlees, CoreSetConfigResponse, CountryCode,
- DeviceConfigId, DeviceConfigTlv, GetDeviceInfoResponse, PhaseList, PowerStats, RadarConfigTlv,
- RadarConfigTlvType, RawUciMessage, ResetConfig, SessionId, SessionState, SessionToken,
- SessionType, SessionUpdateDtTagRangingRoundsResponse, SetAppConfigResponse,
+ AppConfigTlv, AppConfigTlvType, CapTlv, ControleePhaseList, Controlees, CoreSetConfigResponse,
+ CountryCode, DeviceConfigId, DeviceConfigTlv, GetDeviceInfoResponse, PhaseList, PowerStats,
+ RadarConfigTlv, RadarConfigTlvType, RawUciMessage, ResetConfig, SessionId, SessionState,
+ SessionToken, SessionType, SessionUpdateDtTagRangingRoundsResponse, SetAppConfigResponse,
UpdateMulticastListAction, UpdateTime,
};
use crate::uci::notification::{
@@ -452,24 +452,46 @@ impl MockUciManager {
});
}
- /// Prepare Mock to expect session_set_hybrid_config.
+ /// Prepare Mock to expect session_set_hybrid_controller_config.
///
/// MockUciManager expects call with parameters, returns out as response
- pub fn expect_session_set_hybrid_config(
+ pub fn expect_session_set_hybrid_controller_config(
&mut self,
expected_session_id: SessionId,
+ expected_message_control: u8,
expected_number_of_phases: u8,
expected_update_time: UpdateTime,
- expected_phase_list: Vec<PhaseList>,
+ expected_phase_list: PhaseList,
out: Result<()>,
) {
- self.expected_calls.lock().unwrap().push_back(ExpectedCall::SessionSetHybridConfig {
- expected_session_id,
- expected_number_of_phases,
- expected_update_time,
- expected_phase_list,
- out,
- });
+ self.expected_calls.lock().unwrap().push_back(
+ ExpectedCall::SessionSetHybridControllerConfig {
+ expected_session_id,
+ expected_message_control,
+ expected_number_of_phases,
+ expected_update_time,
+ expected_phase_list,
+ out,
+ },
+ );
+ }
+
+ /// Prepare Mock to expect session_set_hybrid_controlee_config.
+ ///
+ /// MockUciManager expects call with parameters, returns out as response
+ pub fn expect_session_set_hybrid_controlee_config(
+ &mut self,
+ expected_session_id: SessionId,
+ expected_controlee_phase_list: Vec<ControleePhaseList>,
+ out: Result<()>,
+ ) {
+ self.expected_calls.lock().unwrap().push_back(
+ ExpectedCall::SessionSetHybridControleeConfig {
+ expected_session_id,
+ expected_controlee_phase_list,
+ out,
+ },
+ );
}
/// Prepare Mock to expect session_data_transfer_phase_config
@@ -1125,26 +1147,54 @@ impl UciManager for MockUciManager {
Ok(1) // No uci call here, no mock required.
}
- async fn session_set_hybrid_config(
+ async fn session_set_hybrid_controller_config(
&self,
session_id: SessionId,
+ message_control: u8,
number_of_phases: u8,
update_time: UpdateTime,
- phase_list: Vec<PhaseList>,
+ phase_lists: PhaseList,
) -> Result<()> {
let mut expected_calls = self.expected_calls.lock().unwrap();
match expected_calls.pop_front() {
- Some(ExpectedCall::SessionSetHybridConfig {
+ Some(ExpectedCall::SessionSetHybridControllerConfig {
expected_session_id,
+ expected_message_control,
expected_number_of_phases,
expected_update_time,
expected_phase_list,
out,
}) if expected_session_id == session_id
+ && expected_message_control == message_control
&& expected_number_of_phases == number_of_phases
&& expected_update_time == update_time
- && expected_phase_list.len() == phase_list.len()
- && expected_phase_list == phase_list =>
+ && expected_phase_list == phase_lists =>
+ {
+ self.expect_call_consumed.notify_one();
+ out
+ }
+ Some(call) => {
+ expected_calls.push_front(call);
+ Err(Error::MockUndefined)
+ }
+ None => Err(Error::MockUndefined),
+ }
+ }
+
+ async fn session_set_hybrid_controlee_config(
+ &self,
+ session_id: SessionId,
+ controlee_phase_list: Vec<ControleePhaseList>,
+ ) -> Result<()> {
+ let mut expected_calls = self.expected_calls.lock().unwrap();
+ match expected_calls.pop_front() {
+ Some(ExpectedCall::SessionSetHybridControleeConfig {
+ expected_session_id,
+ expected_controlee_phase_list,
+ out,
+ }) if expected_session_id == session_id
+ && expected_controlee_phase_list.len() == controlee_phase_list.len()
+ && expected_controlee_phase_list == controlee_phase_list =>
{
self.expect_call_consumed.notify_one();
out
@@ -1280,11 +1330,17 @@ enum ExpectedCall {
expected_app_payload_data: Vec<u8>,
out: Result<()>,
},
- SessionSetHybridConfig {
+ SessionSetHybridControllerConfig {
expected_session_id: SessionId,
+ expected_message_control: u8,
expected_number_of_phases: u8,
expected_update_time: UpdateTime,
- expected_phase_list: Vec<PhaseList>,
+ expected_phase_list: PhaseList,
+ out: Result<()>,
+ },
+ SessionSetHybridControleeConfig {
+ expected_session_id: SessionId,
+ expected_controlee_phase_list: Vec<ControleePhaseList>,
out: Result<()>,
},
SessionDataTransferPhaseConfig {
diff --git a/src/rust/uwb_core/src/uci/response.rs b/src/rust/uwb_core/src/uci/response.rs
index 68994a6..48313aa 100644
--- a/src/rust/uwb_core/src/uci/response.rs
+++ b/src/rust/uwb_core/src/uci/response.rs
@@ -52,7 +52,8 @@ pub(super) enum UciResponse {
AndroidGetRadarConfig(Result<Vec<RadarConfigTlv>>),
RawUciCmd(Result<RawUciMessage>),
SendUciData(Result<()>),
- SessionSetHybridConfig(Result<()>),
+ SessionSetHybridControllerConfig(Result<()>),
+ SessionSetHybridControleeConfig(Result<()>),
SessionDataTransferPhaseConfig(Result<()>),
}
@@ -82,9 +83,9 @@ impl UciResponse {
Self::AndroidGetRadarConfig(result) => Self::matches_result_retry(result),
Self::AndroidSetRadarConfig(resp) => Self::matches_status_retry(&resp.status),
Self::RawUciCmd(result) => Self::matches_result_retry(result),
- Self::SessionSetHybridConfig(result) => Self::matches_result_retry(result),
+ Self::SessionSetHybridControllerConfig(result) => Self::matches_result_retry(result),
+ Self::SessionSetHybridControleeConfig(result) => Self::matches_result_retry(result),
Self::SessionDataTransferPhaseConfig(result) => Self::matches_result_retry(result),
-
Self::CoreSetConfig(resp) => Self::matches_status_retry(&resp.status),
Self::SessionSetAppConfig(resp) => Self::matches_status_retry(&resp.status),
@@ -217,8 +218,15 @@ impl TryFrom<uwb_uci_packets::SessionConfigResponse> for UciResponse {
status_code_to_result(evt.get_status()).map(|_| evt.get_max_data_size()),
))
}
- SessionConfigResponseChild::SessionSetHybridConfigRsp(evt) => {
- Ok(UciResponse::SessionSetHybridConfig(status_code_to_result(evt.get_status())))
+ SessionConfigResponseChild::SessionSetHybridControllerConfigRsp(evt) => {
+ Ok(UciResponse::SessionSetHybridControllerConfig(status_code_to_result(
+ evt.get_status(),
+ )))
+ }
+ SessionConfigResponseChild::SessionSetHybridControleeConfigRsp(evt) => {
+ Ok(UciResponse::SessionSetHybridControleeConfig(status_code_to_result(
+ evt.get_status(),
+ )))
}
SessionConfigResponseChild::SessionDataTransferPhaseConfigRsp(evt) => {
Ok(UciResponse::SessionDataTransferPhaseConfig(status_code_to_result(
diff --git a/src/rust/uwb_core/src/uci/uci_manager.rs b/src/rust/uwb_core/src/uci/uci_manager.rs
index 8548278..f030015 100644
--- a/src/rust/uwb_core/src/uci/uci_manager.rs
+++ b/src/rust/uwb_core/src/uci/uci_manager.rs
@@ -44,7 +44,8 @@ use crate::utils::{clean_mpsc_receiver, PinSleep};
use pdl_runtime::Packet;
use std::collections::{HashMap, VecDeque};
use uwb_uci_packets::{
- fragment_data_msg_send, PhaseList, RawUciControlPacket, UciDataSnd, UciDefragPacket,
+ fragment_data_msg_send, ControleePhaseList, PhaseList, RawUciControlPacket, UciDataSnd,
+ UciDefragPacket,
};
// Conditional compilation: In production code, use the "prod" variant of the Aconfig flags
@@ -190,13 +191,22 @@ pub trait UciManager: 'static + Send + Sync + Clone {
&self,
session_id: SessionId,
) -> Result<SessionToken>;
- /// Send UCI command for setting hybrid config
- async fn session_set_hybrid_config(
+
+ /// Send UCI command for setting hybrid controller config
+ async fn session_set_hybrid_controller_config(
&self,
session_id: SessionId,
+ message_control: u8,
number_of_phases: u8,
update_time: UpdateTime,
- phase_list: Vec<PhaseList>,
+ phase_list: PhaseList,
+ ) -> Result<()>;
+
+ /// Send UCI command for setting hybrid controlee config
+ async fn session_set_hybrid_controlee_config(
+ &self,
+ session_id: SessionId,
+ controlee_phase_list: Vec<ControleePhaseList>,
) -> Result<()>;
}
@@ -674,22 +684,41 @@ impl UciManager for UciManagerImpl {
Ok(self.get_session_token(&session_id).await?)
}
- /// Send UCI command for setting hybrid config
- async fn session_set_hybrid_config(
+ /// Send UCI command for setting hybrid controller config
+ async fn session_set_hybrid_controller_config(
&self,
session_id: SessionId,
+ message_control: u8,
number_of_phases: u8,
update_time: UpdateTime,
- phase_list: Vec<PhaseList>,
+ phase_list: PhaseList,
) -> Result<()> {
- let cmd = UciCommand::SessionSetHybridConfig {
+ let cmd = UciCommand::SessionSetHybridControllerConfig {
session_token: self.get_session_token(&session_id).await?,
+ message_control,
number_of_phases,
update_time,
phase_list,
};
match self.send_cmd(UciManagerCmd::SendUciCommand { cmd }).await {
- Ok(UciResponse::SessionSetHybridConfig(resp)) => resp,
+ Ok(UciResponse::SessionSetHybridControllerConfig(resp)) => resp,
+ Ok(_) => Err(Error::Unknown),
+ Err(e) => Err(e),
+ }
+ }
+
+ /// Send UCI command for setting hybrid controlee config
+ async fn session_set_hybrid_controlee_config(
+ &self,
+ session_id: SessionId,
+ controlee_phase_list: Vec<ControleePhaseList>,
+ ) -> Result<()> {
+ let cmd = UciCommand::SessionSetHybridControleeConfig {
+ session_token: self.get_session_token(&session_id).await?,
+ controlee_phase_list,
+ };
+ match self.send_cmd(UciManagerCmd::SendUciCommand { cmd }).await {
+ Ok(UciResponse::SessionSetHybridControleeConfig(resp)) => resp,
Ok(_) => Err(Error::Unknown),
Err(e) => Err(e),
}
@@ -2201,29 +2230,94 @@ mod tests {
}
#[tokio::test]
- async fn test_session_set_hybrid_config_ok() {
+ async fn test_session_get_app_config_ok() {
let session_id = 0x123;
let session_token = 0x123;
+ let config_id = AppConfigTlvType::DeviceType;
+ let tlv = AppConfigTlv::new(AppConfigTlvType::DeviceType, vec![0x12, 0x34, 0x56]);
+ let tlv_clone = tlv.clone();
+
+ let (uci_manager, mut mock_hal) = setup_uci_manager_with_session_initialized(
+ |mut hal| async move {
+ let cmd =
+ UciCommand::SessionGetAppConfig { session_token, app_cfg: vec![config_id] };
+ let resp = into_uci_hal_packets(uwb_uci_packets::SessionGetAppConfigRspBuilder {
+ status: uwb_uci_packets::StatusCode::UciStatusOk,
+ tlvs: vec![tlv_clone.into_inner()],
+ });
+
+ hal.expected_send_command(cmd, resp, Ok(()));
+ },
+ UciLoggerMode::Disabled,
+ mpsc::unbounded_channel::<UciLogEvent>().0,
+ session_id,
+ session_token,
+ )
+ .await;
+
+ let expected_result = vec![tlv];
+ let result = uci_manager.session_get_app_config(session_id, vec![config_id]).await.unwrap();
+ assert_eq!(result, expected_result);
+ assert!(mock_hal.wait_expected_calls_done().await);
+ }
+
+ #[tokio::test]
+ async fn test_session_set_hybrid_controller_config_ok() {
+ let session_id = 0x123;
+ let message_control = 0x00;
+ let message_control_extended = 0x01;
+ let session_token = 0x123;
let number_of_phases = 0x02;
let update_time = UpdateTime::new(&[0x0; 8]).unwrap();
- let phase_list = vec![
- PhaseList { session_token: 0x12, start_slot_index: 0x13, end_slot_index: 0x01 },
- PhaseList { session_token: 0x14, start_slot_index: 0x13, end_slot_index: 0x01 },
- ];
- let phase_list_clone = phase_list.clone();
+ let phase_list_short_mac_address = PhaseList::ShortMacAddress(vec![
+ uwb_uci_packets::PhaseListShortMacAddress {
+ session_token: 0x11,
+ start_slot_index: 0x12,
+ end_slot_index: 0x13,
+ phase_participation: 0x01,
+ mac_address: [0x11, 0x22],
+ },
+ uwb_uci_packets::PhaseListShortMacAddress {
+ session_token: 0x21,
+ start_slot_index: 0x22,
+ end_slot_index: 0x23,
+ phase_participation: 0x01,
+ mac_address: [0x11, 0x33],
+ },
+ ]);
+ let phase_list_extended_mac_address = PhaseList::ExtendedMacAddress(vec![
+ uwb_uci_packets::PhaseListExtendedMacAddress {
+ session_token: 0x11,
+ start_slot_index: 0x12,
+ end_slot_index: 0x13,
+ phase_participation: 0x01,
+ mac_address: [0x11, 0x22, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38],
+ },
+ uwb_uci_packets::PhaseListExtendedMacAddress {
+ session_token: 0x21,
+ start_slot_index: 0x22,
+ end_slot_index: 0x23,
+ phase_participation: 0x01,
+ mac_address: [0x11, 0x22, 0x33, 0x34, 0x35, 0x36, 0x37, 0x39],
+ },
+ ]);
+ let mut phase_list_clone = phase_list_short_mac_address.clone();
+ // short mac address
let (uci_manager, mut mock_hal) = setup_uci_manager_with_session_active(
|mut hal| async move {
- let cmd = UciCommand::SessionSetHybridConfig {
+ let cmd = UciCommand::SessionSetHybridControllerConfig {
session_token,
+ message_control,
number_of_phases,
update_time,
phase_list: phase_list_clone,
};
- let resp =
- into_uci_hal_packets(uwb_uci_packets::SessionSetHybridConfigRspBuilder {
+ let resp = into_uci_hal_packets(
+ uwb_uci_packets::SessionSetHybridControllerConfigRspBuilder {
status: uwb_uci_packets::StatusCode::UciStatusOk,
- });
+ },
+ );
hal.expected_send_command(cmd, resp, Ok(()));
},
@@ -2235,12 +2329,93 @@ mod tests {
.await;
let result = uci_manager
- .session_set_hybrid_config(session_token, number_of_phases, update_time, phase_list)
+ .session_set_hybrid_controller_config(
+ session_token,
+ message_control,
+ number_of_phases,
+ update_time,
+ phase_list_short_mac_address,
+ )
+ .await;
+ assert!(result.is_ok());
+ assert!(mock_hal.wait_expected_calls_done().await);
+
+ // extended mac address
+ phase_list_clone = phase_list_extended_mac_address.clone();
+ let (uci_manager, mut mock_hal) = setup_uci_manager_with_session_active(
+ |mut hal| async move {
+ let cmd = UciCommand::SessionSetHybridControllerConfig {
+ session_token,
+ message_control: message_control_extended,
+ number_of_phases,
+ update_time,
+ phase_list: phase_list_clone,
+ };
+ let resp = into_uci_hal_packets(
+ uwb_uci_packets::SessionSetHybridControllerConfigRspBuilder {
+ status: uwb_uci_packets::StatusCode::UciStatusOk,
+ },
+ );
+
+ hal.expected_send_command(cmd, resp, Ok(()));
+ },
+ UciLoggerMode::Disabled,
+ mpsc::unbounded_channel::<UciLogEvent>().0,
+ session_id,
+ session_token,
+ )
+ .await;
+
+ let result = uci_manager
+ .session_set_hybrid_controller_config(
+ session_token,
+ message_control_extended,
+ number_of_phases,
+ update_time,
+ phase_list_extended_mac_address,
+ )
.await;
assert!(result.is_ok());
assert!(mock_hal.wait_expected_calls_done().await);
}
+ #[tokio::test]
+ async fn test_session_set_hybrid_controlee_config_ok() {
+ let session_id = 0x123;
+ let session_token = 0x123;
+ let phase_list = vec![
+ ControleePhaseList { session_token: 0x12, phase_participation: 0x01 },
+ ControleePhaseList { session_token: 0x14, phase_participation: 0x01 },
+ ];
+ let phase_list_clone = phase_list.clone();
+
+ let (uci_manager, mut mock_hal) = setup_uci_manager_with_session_active(
+ |mut hal| async move {
+ let cmd = UciCommand::SessionSetHybridControleeConfig {
+ session_token,
+ controlee_phase_list: phase_list_clone,
+ };
+ let resp = into_uci_hal_packets(
+ uwb_uci_packets::SessionSetHybridControleeConfigRspBuilder {
+ status: uwb_uci_packets::StatusCode::UciStatusOk,
+ },
+ );
+
+ hal.expected_send_command(cmd, resp, Ok(()));
+ },
+ UciLoggerMode::Disabled,
+ mpsc::unbounded_channel::<UciLogEvent>().0,
+ session_id,
+ session_token,
+ )
+ .await;
+
+ let result =
+ uci_manager.session_set_hybrid_controlee_config(session_token, phase_list).await;
+ assert!(result.is_ok());
+ assert!(mock_hal.wait_expected_calls_done().await);
+ }
+
#[tokio::test]
async fn test_session_data_transfer_phase_config_ok() {
let session_id = 0x123;
@@ -2293,38 +2468,6 @@ mod tests {
}
#[tokio::test]
- async fn test_session_get_app_config_ok() {
- let session_id = 0x123;
- let session_token = 0x123;
- let config_id = AppConfigTlvType::DeviceType;
- let tlv = AppConfigTlv::new(AppConfigTlvType::DeviceType, vec![0x12, 0x34, 0x56]);
- let tlv_clone = tlv.clone();
-
- let (uci_manager, mut mock_hal) = setup_uci_manager_with_session_initialized(
- |mut hal| async move {
- let cmd =
- UciCommand::SessionGetAppConfig { session_token, app_cfg: vec![config_id] };
- let resp = into_uci_hal_packets(uwb_uci_packets::SessionGetAppConfigRspBuilder {
- status: uwb_uci_packets::StatusCode::UciStatusOk,
- tlvs: vec![tlv_clone.into_inner()],
- });
-
- hal.expected_send_command(cmd, resp, Ok(()));
- },
- UciLoggerMode::Disabled,
- mpsc::unbounded_channel::<UciLogEvent>().0,
- session_id,
- session_token,
- )
- .await;
-
- let expected_result = vec![tlv];
- let result = uci_manager.session_get_app_config(session_id, vec![config_id]).await.unwrap();
- assert_eq!(result, expected_result);
- assert!(mock_hal.wait_expected_calls_done().await);
- }
-
- #[tokio::test]
async fn test_session_get_count_ok() {
let session_count = 5;
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 3231956..0375f97 100644
--- a/src/rust/uwb_core/src/uci/uci_manager_sync.rs
+++ b/src/rust/uwb_core/src/uci/uci_manager_sync.rs
@@ -40,7 +40,7 @@ use crate::uci::notification::{
use crate::uci::uci_hal::UciHal;
use crate::uci::uci_logger::{UciLogger, UciLoggerMode};
use crate::uci::uci_manager::{UciManager, UciManagerImpl};
-use uwb_uci_packets::{Controlees, PhaseList};
+use uwb_uci_packets::{ControleePhaseList, Controlees, PhaseList};
/// The NotificationManager processes UciNotification relayed from UciManagerSync in a sync fashion.
/// The UciManagerSync assumes the NotificationManager takes the responsibility to properly handle
@@ -417,22 +417,35 @@ impl<U: UciManager> UciManagerSync<U> {
self.runtime_handle.block_on(self.uci_manager.get_session_token_from_session_id(session_id))
}
- /// Send UCI command for setting hybrid configuration
- pub fn session_set_hybrid_config(
+ /// Send UCI command for setting hybrid controller configuration
+ pub fn session_set_hybrid_controller_config(
&self,
session_id: SessionId,
+ message_control: u8,
number_of_phases: u8,
update_time: UpdateTime,
- phase_list: Vec<PhaseList>,
+ phase_list: PhaseList,
) -> Result<()> {
- self.runtime_handle.block_on(self.uci_manager.session_set_hybrid_config(
+ self.runtime_handle.block_on(self.uci_manager.session_set_hybrid_controller_config(
session_id,
+ message_control,
number_of_phases,
update_time,
phase_list,
))
}
+ /// Send UCI command for setting hybrid controlee configuration
+ pub fn session_set_hybrid_controlee_config(
+ &self,
+ session_id: SessionId,
+ controlee_phase_list: Vec<ControleePhaseList>,
+ ) -> Result<()> {
+ self.runtime_handle.block_on(
+ self.uci_manager.session_set_hybrid_controlee_config(session_id, controlee_phase_list),
+ )
+ }
+
/// Send UCI command for session data transfer phase config
pub fn session_data_transfer_phase_config(
&self,
diff --git a/src/rust/uwb_uci_packets/src/lib.rs b/src/rust/uwb_uci_packets/src/lib.rs
index eed65a8..336aed4 100644
--- a/src/rust/uwb_uci_packets/src/lib.rs
+++ b/src/rust/uwb_uci_packets/src/lib.rs
@@ -368,10 +368,11 @@ fn is_same_control_packet(header: &UciControlPacketHeader, packet: &UciPacketHal
}
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] == DeviceState::DeviceStateError.into()
+ 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]
+ == DeviceState::DeviceStateError.into()
}
impl UciControlPacket {
@@ -406,8 +407,8 @@ impl TryFrom<Vec<UciPacketHal>> for UciControlPacket {
// if DEVICE_STATE_ERROR notification is received while waiting for remaining fragments,
// process it and send to upper layer for device recovery
if is_device_state_err_control_packet(&packet) {
- error!("Received device reset error: {:?}", packet);
- return UciControlPacket::parse(
+ error!("Received device reset error: {:?}", packet);
+ return UciControlPacket::parse(
&UciControlPacketBuilder {
message_type: packet.get_message_type(),
group_id: packet.get_group_id_or_data_packet_format().into(),
@@ -416,7 +417,7 @@ impl TryFrom<Vec<UciPacketHal>> for UciControlPacket {
}
.build()
.to_bytes(),
- );
+ );
}
error!("Received unexpected fragment: {:?}", packet);
return Err(Error::InvalidPacketError);
@@ -953,6 +954,68 @@ impl Drop for AppConfigTlv {
}
}
+#[derive(Debug, Clone, PartialEq)]
+pub enum PhaseList {
+ ShortMacAddress(Vec<PhaseListShortMacAddress>),
+ ExtendedMacAddress(Vec<PhaseListExtendedMacAddress>),
+}
+
+/// Generate the SessionSetHybridControllerConfig packet.
+pub fn build_session_set_hybrid_controller_config_cmd(
+ session_token: u32,
+ message_control: u8,
+ number_of_phases: u8,
+ update_time: [u8; 8],
+ phase_list: PhaseList,
+) -> Result<SessionSetHybridControllerConfigCmd> {
+ let mut phase_list_buffer = BytesMut::new();
+ match phase_list {
+ PhaseList::ShortMacAddress(phaseListShortMacAddressVec) => {
+ for phaseListShortMacAddress in phaseListShortMacAddressVec {
+ phase_list_buffer.extend_from_slice(
+ &(phaseListShortMacAddress.session_token.to_le_bytes()[0..4]),
+ );
+ phase_list_buffer.extend_from_slice(
+ &(phaseListShortMacAddress.start_slot_index.to_le_bytes()[0..2]),
+ );
+ phase_list_buffer.extend_from_slice(
+ &(phaseListShortMacAddress.end_slot_index.to_le_bytes()[0..2]),
+ );
+ phase_list_buffer.extend_from_slice(std::slice::from_ref(
+ &phaseListShortMacAddress.phase_participation,
+ ));
+ phase_list_buffer.extend_from_slice(&phaseListShortMacAddress.mac_address);
+ }
+ }
+ PhaseList::ExtendedMacAddress(phaseListExtendedMacAddressVec) => {
+ for phaseListExtendedMacAddress in phaseListExtendedMacAddressVec {
+ phase_list_buffer.extend_from_slice(
+ &(phaseListExtendedMacAddress.session_token.to_le_bytes()[0..4]),
+ );
+ phase_list_buffer.extend_from_slice(
+ &(phaseListExtendedMacAddress.start_slot_index.to_le_bytes()[0..2]),
+ );
+ phase_list_buffer.extend_from_slice(
+ &(phaseListExtendedMacAddress.end_slot_index.to_le_bytes()[0..2]),
+ );
+ phase_list_buffer.extend_from_slice(std::slice::from_ref(
+ &phaseListExtendedMacAddress.phase_participation,
+ ));
+ phase_list_buffer.extend_from_slice(&phaseListExtendedMacAddress.mac_address);
+ }
+ }
+ _ => return Err(Error::InvalidPacketError),
+ }
+ Ok(SessionSetHybridControllerConfigCmdBuilder {
+ session_token,
+ message_control,
+ number_of_phases,
+ update_time,
+ payload: Some(phase_list_buffer.freeze()),
+ }
+ .build())
+}
+
// Radar data 'bits per sample' field isn't a raw value, instead it's an enum
// that maps to the raw value. We need this mapping to get the max sample size
// length.
diff --git a/src/rust/uwb_uci_packets/uci_packets.pdl b/src/rust/uwb_uci_packets/uci_packets.pdl
index 3c80f87..7b3e174 100644
--- a/src/rust/uwb_uci_packets/uci_packets.pdl
+++ b/src/rust/uwb_uci_packets/uci_packets.pdl
@@ -66,7 +66,8 @@ enum SessionConfigOpCode : 6 {
SESSION_UPDATE_ACTIVE_ROUNDS_DT_TAG = 0x09,
SESSION_SET_INITIATOR_DT_ANCHOR_RR_RDM_LIST = 0x0a,
SESSION_QUERY_DATA_SIZE_IN_RANGING = 0x0b,
- SESSION_SET_HUS_CONFIG = 0x0c,
+ SESSION_SET_HUS_CONTROLLER_CONFIG = 0x0c,
+ SESSION_SET_HUS_CONTROLEE_CONFIG = 0x0d,
SESSION_DATA_TRANSFER_PHASE_CONFIGURATION = 0x0e,
}
@@ -972,22 +973,6 @@ packet SessionUpdateControllerMulticastListCmd : SessionConfigCommand (opcode =
_payload_,
}
-struct PhaseList {
- session_token: 32,
- start_slot_index: 16,
- end_slot_index: 16,
-}
-
-packet SessionSetHybridConfigCmd : SessionConfigCommand (opcode = 0x0c) { //SESSION_SET_HUS_CONFIG
- session_token: 32,
- number_of_phases: 8,
- update_time: 8[8],
- phase_list: PhaseList[],
-}
-
-packet SessionSetHybridConfigRsp : SessionConfigResponse (opcode = 0x0c) { //SESSION_SET_HUS_CONFIG
- status: StatusCode,
-}
struct SessionUpdateControllerMulticastListCmdPayload {
_count_(controlees): 8,
@@ -1088,6 +1073,65 @@ test SessionDataTransferPhaseConfigNtf {
"\x61\x0E\x00\x05\x00\x00\x00\x00\x00"
}
+struct PhaseListShortMacAddress {
+ session_token: 32,
+ start_slot_index: 16,
+ end_slot_index: 16,
+ phase_participation: 8,
+ mac_address: 8[2],
+}
+
+struct PhaseListExtendedMacAddress {
+ session_token: 32,
+ start_slot_index: 16,
+ end_slot_index: 16,
+ phase_participation: 8,
+ mac_address: 8[8],
+}
+
+packet SessionSetHybridControllerConfigCmd : SessionConfigCommand (opcode = 0x0C) { //SESSION_SET_HUS_CONTROLLER_CONFIG
+ session_token: 32,
+ message_control: 8,
+ number_of_phases: 8,
+ update_time: 8[8],
+ _payload_,
+}
+
+test SessionSetHybridControllerConfigCmd {
+"\x21\x0C\x00\x23\x03\x00\x00\x01\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x05\x01\x00\x19\x00\x00\x30\x00\x02\x00\x00\x03\x1A\x00\x32\x00\x00\x30\x00",
+}
+
+packet SessionSetHybridControllerConfigRsp : SessionConfigResponse (opcode = 0x0C) { //SESSION_SET_HUS_CONTROLLER_CONFIG
+ status: StatusCode,
+}
+
+test SessionSetHybridControllerConfigRsp {
+ "\x41\x0C\x00\x01\x00"
+}
+
+struct ControleePhaseList {
+ session_token: 32,
+ phase_participation: 8,
+}
+
+packet SessionSetHybridControleeConfigCmd : SessionConfigCommand (opcode = 0x0D) { //SESSION_SET_HUS_CONTROLEE_CONFIG
+ session_token: 32,
+ _count_(controlee_phase_list): 8,
+ controlee_phase_list: ControleePhaseList[],
+}
+
+test SessionSetHybridControleeConfigCmd {
+ "\x21\x0D\x00\x0F\x03\x00\x00\x01\x02\x01\x00\x00\x05\x02\x02\x00\x00\x03\x02",
+}
+
+packet SessionSetHybridControleeConfigRsp : SessionConfigResponse (opcode = 0x0D) { //SESSION_SET_HUS_CONTROLEE_CONFIG
+ status: StatusCode,
+}
+
+test SessionSetHybridControleeConfigRsp {
+ "\x41\x0D\x00\x01\x00"
+}
+
packet SessionStartCmd : SessionControlCommand (opcode = 0x0) { //RANGE_START
session_token: 32, // Session ID or Session Handle (based on UWBS version)
}