1 use crate::packets::uci; 2 use crate::MacAddress; 3 4 /// [UCI] 8.3 Application Configuration Parameters. 5 /// Sub-session Key provided for Provisioned STS for Responder specific Key mode 6 /// (STS_CONFIG equal to 0x04). 7 #[derive(Clone, PartialEq, Eq)] 8 pub enum SubSessionKey { 9 None, 10 Short([u8; 16]), 11 Extended([u8; 32]), 12 } 13 14 /// [UCI] 8.3 Application Configuration Parameters. 15 /// The configuration is initially filled with default values from the 16 /// specification. 17 /// See [UCI] Table 45: APP Configuration Parameters IDs 18 /// for the format of each parameter and the default value. 19 /// Mandatory APP configuration parameters are declared as optional, 20 /// and must be set before moving the session from SESSION_STATE_INIT to 21 /// SESSION_STATE_IDLE. 22 #[derive(Clone, PartialEq, Eq)] 23 pub struct AppConfig { 24 pub device_type: Option<uci::DeviceType>, 25 pub ranging_round_usage: Option<uci::RangingRoundUsage>, 26 pub sts_config: uci::StsConfig, 27 pub multi_node_mode: Option<uci::MultiNodeMode>, 28 channel_number: uci::ChannelNumber, 29 /// Number of Controlees(N) 1<=N<=8 (Default is 1) 30 pub number_of_controlees: u8, 31 /// MAC Address of the UWBS itself participating in UWB session. 32 /// The short address (2 bytes) or extended MAC address (8 bytes) 33 /// shall be indicated via MAC_ADDRESS_MODE config. 34 pub device_mac_address: Option<MacAddress>, 35 /// MAC Address list(N) for NUMBER_OF_CONTROLEES 36 /// devices participating in UWB Session. 37 /// 38 /// The size of this list shall be: 39 /// - equal to 1 when MULTI_NODE_MODE is set 0x00 (O2O). 40 /// - ranging from 1 to 8 when MULTI_NODE_MODE is set to 0x01 (O2M). 41 pub dst_mac_address: Vec<MacAddress>, 42 slot_duration: u16, 43 pub ranging_duration: u32, 44 sts_index: u32, 45 mac_fcs_type: uci::MacFcsType, 46 ranging_round_control: u8, 47 aoa_result_req: uci::AoaResultReq, 48 pub session_info_ntf_config: uci::SessionInfoNtfConfig, 49 near_proximity_config: u16, 50 far_proximity_config: u16, 51 pub device_role: Option<uci::DeviceRole>, 52 rframe_config: uci::RframeConfig, 53 rssi_reporting: uci::RssiReporting, 54 preamble_code_index: u8, 55 sfd_id: u8, 56 psdu_data_rate: uci::PsduDataRate, 57 preamble_duration: uci::PreambleDuration, 58 link_layer_mode: uci::LinkLayerMode, 59 data_repetition_count: u8, 60 ranging_time_struct: uci::RangingTimeStruct, 61 slots_per_rr: u8, 62 aoa_bound_config: [u16; 4], 63 prf_mode: uci::PrfMode, 64 cap_size_range: [u8; 2], 65 tx_jitter_window_size: u8, 66 pub schedule_mode: Option<uci::ScheduleMode>, 67 key_rotation: uci::KeyRotation, 68 key_rotation_rate: u8, 69 session_priority: u8, 70 pub mac_address_mode: uci::MacAddressMode, 71 vendor_id: u16, 72 static_sts_iv: [u8; 6], 73 number_of_sts_segments: u8, 74 max_rr_retry: u16, 75 uwb_initiation_time: u64, 76 hopping_mode: uci::HoppingMode, 77 block_stride_length: u8, 78 result_report_config: u8, 79 pub in_band_termination_attempt_count: u8, 80 sub_session_id: u32, 81 bprf_phr_data_rate: uci::BprfPhrDataRate, 82 max_number_of_measurements: u16, 83 sts_length: uci::StsLength, 84 min_frames_per_rr: u8, 85 mtu_size: u16, 86 inter_frame_interval: u8, 87 session_key: Vec<u8>, 88 sub_session_key: SubSessionKey, 89 pub session_data_transfer_status_ntf_config: uci::SessionDataTransferStatusNtfConfig, 90 session_time_base: [u8; 9], 91 application_data_endpoint: u8, 92 } 93 94 impl Default for AppConfig { default() -> Self95 fn default() -> Self { 96 AppConfig { 97 device_type: None, 98 ranging_round_usage: None, 99 sts_config: uci::StsConfig::Static, 100 multi_node_mode: None, 101 channel_number: uci::ChannelNumber::ChannelNumber9, 102 number_of_controlees: 1, 103 device_mac_address: None, 104 dst_mac_address: vec![], 105 slot_duration: 2400, 106 ranging_duration: 200, 107 sts_index: 0, 108 mac_fcs_type: uci::MacFcsType::Crc16, 109 // The default is 0x03 when Time Scheduled Ranging is used, 110 // 0x06 when Contention-based Ranging is used. 111 ranging_round_control: 0x06, 112 aoa_result_req: uci::AoaResultReq::AoaEnabled, 113 session_info_ntf_config: uci::SessionInfoNtfConfig::Enable, 114 near_proximity_config: 0, 115 far_proximity_config: 20000, 116 device_role: None, 117 rframe_config: uci::RframeConfig::Sp3, 118 rssi_reporting: uci::RssiReporting::Disable, 119 preamble_code_index: 10, 120 sfd_id: 2, 121 psdu_data_rate: uci::PsduDataRate::DataRate6m81, 122 preamble_duration: uci::PreambleDuration::Duration64Symbols, 123 link_layer_mode: uci::LinkLayerMode::BypassMode, 124 data_repetition_count: 0, 125 ranging_time_struct: uci::RangingTimeStruct::BlockBasedScheduling, 126 slots_per_rr: 25, 127 aoa_bound_config: [0; 4], 128 prf_mode: uci::PrfMode::BprfMode, 129 // Default for Octet[0] is SLOTS_PER_RR - 1 130 cap_size_range: [24, 5], 131 tx_jitter_window_size: 0, 132 schedule_mode: None, 133 key_rotation: uci::KeyRotation::Disable, 134 key_rotation_rate: 0, 135 session_priority: 50, 136 mac_address_mode: uci::MacAddressMode::Mode0, 137 vendor_id: 0, 138 static_sts_iv: [0; 6], 139 number_of_sts_segments: 1, 140 max_rr_retry: 0, 141 uwb_initiation_time: 0, 142 hopping_mode: uci::HoppingMode::Disable, 143 block_stride_length: 0, 144 result_report_config: 0x01, 145 in_band_termination_attempt_count: 1, 146 sub_session_id: 0, // XX 147 bprf_phr_data_rate: uci::BprfPhrDataRate::DataRate850k, 148 max_number_of_measurements: 0, 149 sts_length: uci::StsLength::Length64Symbols, 150 min_frames_per_rr: 4, 151 mtu_size: 0, // XX 152 inter_frame_interval: 1, 153 session_key: vec![], 154 sub_session_key: SubSessionKey::None, 155 session_data_transfer_status_ntf_config: 156 uci::SessionDataTransferStatusNtfConfig::Disable, 157 session_time_base: [0; 9], 158 application_data_endpoint: 0, 159 } 160 } 161 } 162 163 impl AppConfig { 164 /// Set the APP configuration value with the selected identifier 165 /// and value. Returns `Ok` if the identifier is known and the value 166 /// well formatted, `Err` otherwise. set(&mut self, id: uci::AppConfigTlvType, value: &[u8]) -> anyhow::Result<()>167 pub fn set(&mut self, id: uci::AppConfigTlvType, value: &[u8]) -> anyhow::Result<()> { 168 fn try_parse<T: TryFrom<u8, Error = u8>>(value: &[u8]) -> anyhow::Result<T> { 169 T::try_from(u8::from_le_bytes(value.try_into()?)).map_err(anyhow::Error::msg) 170 } 171 172 fn try_parse_u8(value: &[u8]) -> anyhow::Result<u8> { 173 Ok(u8::from_le_bytes(value.try_into()?)) 174 } 175 176 fn try_parse_u16(value: &[u8]) -> anyhow::Result<u16> { 177 Ok(u16::from_le_bytes(value.try_into()?)) 178 } 179 180 fn try_parse_u32(value: &[u8]) -> anyhow::Result<u32> { 181 Ok(u32::from_le_bytes(value.try_into()?)) 182 } 183 184 fn try_parse_u64(value: &[u8]) -> anyhow::Result<u64> { 185 Ok(u64::from_le_bytes(value.try_into()?)) 186 } 187 188 match id { 189 uci::AppConfigTlvType::DeviceType => self.device_type = Some(try_parse(value)?), 190 uci::AppConfigTlvType::RangingRoundUsage => { 191 self.ranging_round_usage = Some(try_parse(value)?) 192 } 193 uci::AppConfigTlvType::StsConfig => self.sts_config = try_parse(value)?, 194 uci::AppConfigTlvType::MultiNodeMode => self.multi_node_mode = Some(try_parse(value)?), 195 uci::AppConfigTlvType::ChannelNumber => self.channel_number = try_parse(value)?, 196 uci::AppConfigTlvType::NumberOfControlees => { 197 self.number_of_controlees = try_parse_u8(value)? 198 } 199 uci::AppConfigTlvType::DeviceMacAddress => { 200 self.device_mac_address = Some(match self.mac_address_mode { 201 uci::MacAddressMode::Mode0 => MacAddress::Short(value.try_into()?), 202 uci::MacAddressMode::Mode1 => unimplemented!(), 203 uci::MacAddressMode::Mode2 => MacAddress::Extended(value.try_into()?), 204 }) 205 } 206 uci::AppConfigTlvType::DstMacAddress => { 207 let mac_address_size = match self.mac_address_mode { 208 uci::MacAddressMode::Mode0 => 2, 209 uci::MacAddressMode::Mode1 => unimplemented!(), 210 uci::MacAddressMode::Mode2 => 8, 211 }; 212 if value.len() != self.number_of_controlees as usize * mac_address_size { 213 log::error!( 214 "invalid dst_mac_address len: expected {}x{}, got {}", 215 self.number_of_controlees, 216 mac_address_size, 217 value.len() 218 ); 219 anyhow::bail!("invalid dst_mac_address len") 220 } 221 self.dst_mac_address = value 222 .chunks(mac_address_size) 223 .map(|value| match self.mac_address_mode { 224 uci::MacAddressMode::Mode0 => MacAddress::Short(value.try_into().unwrap()), 225 uci::MacAddressMode::Mode1 => unimplemented!(), 226 uci::MacAddressMode::Mode2 => { 227 MacAddress::Extended(value.try_into().unwrap()) 228 } 229 }) 230 .collect(); 231 } 232 uci::AppConfigTlvType::SlotDuration => self.slot_duration = try_parse_u16(value)?, 233 uci::AppConfigTlvType::RangingDuration => self.ranging_duration = try_parse_u32(value)?, 234 uci::AppConfigTlvType::StsIndex => self.sts_index = try_parse_u32(value)?, 235 uci::AppConfigTlvType::MacFcsType => self.mac_fcs_type = try_parse(value)?, 236 uci::AppConfigTlvType::RangingRoundControl => { 237 self.ranging_round_control = try_parse_u8(value)? 238 } 239 uci::AppConfigTlvType::AoaResultReq => self.aoa_result_req = try_parse(value)?, 240 uci::AppConfigTlvType::SessionInfoNtfConfig => { 241 self.session_info_ntf_config = try_parse(value)? 242 } 243 uci::AppConfigTlvType::NearProximityConfig => { 244 self.near_proximity_config = try_parse_u16(value)? 245 } 246 uci::AppConfigTlvType::FarProximityConfig => { 247 self.far_proximity_config = try_parse_u16(value)? 248 } 249 uci::AppConfigTlvType::DeviceRole => self.device_role = Some(try_parse(value)?), 250 uci::AppConfigTlvType::RframeConfig => self.rframe_config = try_parse(value)?, 251 uci::AppConfigTlvType::RssiReporting => self.rssi_reporting = try_parse(value)?, 252 uci::AppConfigTlvType::PreambleCodeIndex => { 253 self.preamble_code_index = try_parse_u8(value)? 254 } 255 uci::AppConfigTlvType::SfdId => self.sfd_id = try_parse_u8(value)?, 256 uci::AppConfigTlvType::PsduDataRate => self.psdu_data_rate = try_parse(value)?, 257 uci::AppConfigTlvType::PreambleDuration => self.preamble_duration = try_parse(value)?, 258 uci::AppConfigTlvType::LinkLayerMode => self.link_layer_mode = try_parse(value)?, 259 uci::AppConfigTlvType::DataRepetitionCount => { 260 self.data_repetition_count = try_parse_u8(value)? 261 } 262 uci::AppConfigTlvType::RangingTimeStruct => { 263 self.ranging_time_struct = try_parse(value)? 264 } 265 uci::AppConfigTlvType::SlotsPerRr => self.slots_per_rr = try_parse_u8(value)?, 266 uci::AppConfigTlvType::AoaBoundConfig => { 267 if value.len() != 8 { 268 log::error!( 269 "invalid aoa_bound_config len: expected 8, got {}", 270 value.len() 271 ); 272 anyhow::bail!("invalid aoa_bound_config len") 273 } 274 self.aoa_bound_config = [ 275 u16::from_le_bytes([value[0], value[1]]), 276 u16::from_le_bytes([value[2], value[3]]), 277 u16::from_le_bytes([value[4], value[5]]), 278 u16::from_le_bytes([value[6], value[7]]), 279 ] 280 } 281 uci::AppConfigTlvType::PrfMode => self.prf_mode = try_parse(value)?, 282 uci::AppConfigTlvType::CapSizeRange => self.cap_size_range = value.try_into()?, 283 uci::AppConfigTlvType::TxJitterWindowSize => { 284 self.tx_jitter_window_size = try_parse_u8(value)? 285 } 286 uci::AppConfigTlvType::ScheduleMode => self.schedule_mode = Some(try_parse(value)?), 287 uci::AppConfigTlvType::KeyRotation => self.key_rotation = try_parse(value)?, 288 uci::AppConfigTlvType::KeyRotationRate => self.key_rotation_rate = try_parse_u8(value)?, 289 uci::AppConfigTlvType::SessionPriority => self.session_priority = try_parse_u8(value)?, 290 uci::AppConfigTlvType::MacAddressMode => self.mac_address_mode = try_parse(value)?, 291 uci::AppConfigTlvType::VendorId => self.vendor_id = try_parse_u16(value)?, 292 uci::AppConfigTlvType::StaticStsIv => self.static_sts_iv = value.try_into()?, 293 uci::AppConfigTlvType::NumberOfStsSegments => { 294 self.number_of_sts_segments = try_parse_u8(value)? 295 } 296 uci::AppConfigTlvType::MaxRrRetry => self.max_rr_retry = try_parse_u16(value)?, 297 uci::AppConfigTlvType::UwbInitiationTime => { 298 // Implement backward compatiblity for UCI 1.0 299 // where the value is 4 bytes instead of 8. 300 self.uwb_initiation_time = match value.len() { 301 4 => try_parse_u32(value)? as u64, 302 _ => try_parse_u64(value)?, 303 } 304 } 305 uci::AppConfigTlvType::HoppingMode => self.hopping_mode = try_parse(value)?, 306 uci::AppConfigTlvType::BlockStrideLength => { 307 self.block_stride_length = try_parse_u8(value)? 308 } 309 uci::AppConfigTlvType::ResultReportConfig => { 310 self.result_report_config = try_parse_u8(value)? 311 } 312 uci::AppConfigTlvType::InBandTerminationAttemptCount => { 313 self.in_band_termination_attempt_count = try_parse_u8(value)? 314 } 315 uci::AppConfigTlvType::SubSessionId => self.sub_session_id = try_parse_u32(value)?, 316 uci::AppConfigTlvType::BprfPhrDataRate => self.bprf_phr_data_rate = try_parse(value)?, 317 uci::AppConfigTlvType::MaxNumberOfMeasurements => { 318 self.max_number_of_measurements = try_parse_u16(value)? 319 } 320 uci::AppConfigTlvType::StsLength => self.sts_length = try_parse(value)?, 321 uci::AppConfigTlvType::MinFramesPerRr => self.min_frames_per_rr = try_parse_u8(value)?, 322 uci::AppConfigTlvType::MtuSize => self.mtu_size = try_parse_u16(value)?, 323 uci::AppConfigTlvType::InterFrameInterval => { 324 self.inter_frame_interval = try_parse_u8(value)? 325 } 326 uci::AppConfigTlvType::SessionKey => self.session_key = value.to_vec(), 327 uci::AppConfigTlvType::SubSessionKey => { 328 self.sub_session_key = match value.len() { 329 16 => SubSessionKey::Short(value.try_into().unwrap()), 330 32 => SubSessionKey::Extended(value.try_into().unwrap()), 331 _ => anyhow::bail!("invalid sub-session key size {}", value.len()), 332 } 333 } 334 uci::AppConfigTlvType::SessionDataTransferStatusNtfConfig => { 335 self.session_data_transfer_status_ntf_config = try_parse(value)? 336 } 337 uci::AppConfigTlvType::SessionTimeBase => self.session_time_base = value.try_into()?, 338 uci::AppConfigTlvType::ApplicationDataEndpoint => { 339 self.application_data_endpoint = try_parse_u8(value)? 340 } 341 342 uci::AppConfigTlvType::CccHopModeKey 343 | uci::AppConfigTlvType::CccUwbTime0 344 | uci::AppConfigTlvType::CccRangingProtocolVer 345 | uci::AppConfigTlvType::CccUwbConfigId 346 | uci::AppConfigTlvType::CccPulseshapeCombo 347 | uci::AppConfigTlvType::CccUrskTtl 348 | uci::AppConfigTlvType::CccLastIndexUsed 349 | uci::AppConfigTlvType::NbOfRangeMeasurements 350 | uci::AppConfigTlvType::NbOfAzimuthMeasurements 351 | uci::AppConfigTlvType::NbOfElevationMeasurements 352 | uci::AppConfigTlvType::EnableDiagnostics 353 | uci::AppConfigTlvType::DiagramsFrameReportsFields => { 354 log::error!("unsupported vendor config type {:?}", id); 355 anyhow::bail!("unsupported vendor config type {:?}", id) 356 } 357 _ => { 358 log::error!("unsupported app config type {:?}", id); 359 anyhow::bail!("unsupported app config type {:?}", id) 360 } 361 } 362 Ok(()) 363 } 364 365 /// Retrieve the APP configuration value with the selected identifier 366 /// Returns `Ok` if the identifier is known, `Err` otherwise. get(&self, id: uci::AppConfigTlvType) -> anyhow::Result<Vec<u8>>367 pub fn get(&self, id: uci::AppConfigTlvType) -> anyhow::Result<Vec<u8>> { 368 match id { 369 uci::AppConfigTlvType::DeviceType => Ok(vec![self 370 .device_type 371 .ok_or(anyhow::anyhow!("optional app config not set"))? 372 .into()]), 373 uci::AppConfigTlvType::RangingRoundUsage => Ok(vec![self 374 .ranging_round_usage 375 .ok_or(anyhow::anyhow!("optional app config not set"))? 376 .into()]), 377 uci::AppConfigTlvType::StsConfig => Ok(vec![self.sts_config.into()]), 378 uci::AppConfigTlvType::MultiNodeMode => Ok(vec![self 379 .multi_node_mode 380 .ok_or(anyhow::anyhow!("optional app config not set"))? 381 .into()]), 382 uci::AppConfigTlvType::ChannelNumber => Ok(vec![self.channel_number.into()]), 383 uci::AppConfigTlvType::NumberOfControlees => Ok(vec![self.number_of_controlees]), 384 uci::AppConfigTlvType::DeviceMacAddress => Ok(self 385 .device_mac_address 386 .ok_or(anyhow::anyhow!("optional app config not set"))? 387 .into()), 388 uci::AppConfigTlvType::DstMacAddress => Ok(self 389 .dst_mac_address 390 .iter() 391 .flat_map(Vec::<u8>::from) 392 .collect()), 393 uci::AppConfigTlvType::SlotDuration => Ok(self.slot_duration.to_le_bytes().to_vec()), 394 uci::AppConfigTlvType::RangingDuration => { 395 Ok(self.ranging_duration.to_le_bytes().to_vec()) 396 } 397 uci::AppConfigTlvType::StsIndex => Ok(self.sts_index.to_le_bytes().to_vec()), 398 uci::AppConfigTlvType::MacFcsType => Ok(vec![self.mac_fcs_type.into()]), 399 uci::AppConfigTlvType::RangingRoundControl => Ok(vec![self.ranging_round_control]), 400 uci::AppConfigTlvType::AoaResultReq => Ok(vec![self.aoa_result_req.into()]), 401 uci::AppConfigTlvType::SessionInfoNtfConfig => { 402 Ok(vec![self.session_info_ntf_config.into()]) 403 } 404 uci::AppConfigTlvType::NearProximityConfig => { 405 Ok(self.near_proximity_config.to_le_bytes().to_vec()) 406 } 407 uci::AppConfigTlvType::FarProximityConfig => { 408 Ok(self.far_proximity_config.to_le_bytes().to_vec()) 409 } 410 uci::AppConfigTlvType::DeviceRole => Ok(vec![self 411 .device_role 412 .ok_or(anyhow::anyhow!("optional app config not set"))? 413 .into()]), 414 uci::AppConfigTlvType::RframeConfig => Ok(vec![self.rframe_config.into()]), 415 uci::AppConfigTlvType::RssiReporting => Ok(vec![self.rssi_reporting.into()]), 416 uci::AppConfigTlvType::PreambleCodeIndex => Ok(vec![self.preamble_code_index]), 417 uci::AppConfigTlvType::SfdId => Ok(vec![self.sfd_id]), 418 uci::AppConfigTlvType::PsduDataRate => Ok(vec![self.psdu_data_rate.into()]), 419 uci::AppConfigTlvType::PreambleDuration => Ok(vec![self.preamble_duration.into()]), 420 uci::AppConfigTlvType::LinkLayerMode => Ok(vec![self.link_layer_mode.into()]), 421 uci::AppConfigTlvType::DataRepetitionCount => Ok(vec![self.data_repetition_count]), 422 uci::AppConfigTlvType::RangingTimeStruct => Ok(vec![self.ranging_time_struct.into()]), 423 uci::AppConfigTlvType::SlotsPerRr => Ok(vec![self.slots_per_rr]), 424 uci::AppConfigTlvType::AoaBoundConfig => Ok(self 425 .aoa_bound_config 426 .iter() 427 .copied() 428 .flat_map(u16::to_le_bytes) 429 .collect()), 430 uci::AppConfigTlvType::PrfMode => Ok(vec![self.prf_mode.into()]), 431 uci::AppConfigTlvType::CapSizeRange => Ok(self.cap_size_range.to_vec()), 432 uci::AppConfigTlvType::TxJitterWindowSize => Ok(vec![self.tx_jitter_window_size]), 433 uci::AppConfigTlvType::ScheduleMode => Ok(vec![self 434 .schedule_mode 435 .ok_or(anyhow::anyhow!("optional app config not set"))? 436 .into()]), 437 uci::AppConfigTlvType::KeyRotation => Ok(vec![self.key_rotation.into()]), 438 uci::AppConfigTlvType::KeyRotationRate => Ok(vec![self.key_rotation_rate]), 439 uci::AppConfigTlvType::SessionPriority => Ok(vec![self.session_priority]), 440 uci::AppConfigTlvType::MacAddressMode => Ok(vec![self.mac_address_mode.into()]), 441 uci::AppConfigTlvType::VendorId => Ok(self.vendor_id.to_le_bytes().to_vec()), 442 uci::AppConfigTlvType::StaticStsIv => Ok(self.static_sts_iv.to_vec()), 443 uci::AppConfigTlvType::NumberOfStsSegments => Ok(vec![self.number_of_sts_segments]), 444 uci::AppConfigTlvType::MaxRrRetry => Ok(self.max_rr_retry.to_le_bytes().to_vec()), 445 uci::AppConfigTlvType::UwbInitiationTime => { 446 Ok(self.uwb_initiation_time.to_le_bytes().to_vec()) 447 } 448 uci::AppConfigTlvType::HoppingMode => Ok(vec![self.hopping_mode.into()]), 449 uci::AppConfigTlvType::BlockStrideLength => Ok(vec![self.block_stride_length]), 450 uci::AppConfigTlvType::ResultReportConfig => Ok(vec![self.result_report_config]), 451 uci::AppConfigTlvType::InBandTerminationAttemptCount => { 452 Ok(vec![self.in_band_termination_attempt_count]) 453 } 454 uci::AppConfigTlvType::SubSessionId => Ok(self.sub_session_id.to_le_bytes().to_vec()), 455 uci::AppConfigTlvType::BprfPhrDataRate => Ok(vec![self.bprf_phr_data_rate.into()]), 456 uci::AppConfigTlvType::MaxNumberOfMeasurements => { 457 Ok(self.max_number_of_measurements.to_le_bytes().to_vec()) 458 } 459 uci::AppConfigTlvType::StsLength => Ok(vec![self.sts_length.into()]), 460 uci::AppConfigTlvType::MinFramesPerRr => Ok(vec![self.min_frames_per_rr]), 461 uci::AppConfigTlvType::MtuSize => Ok(self.mtu_size.to_le_bytes().to_vec()), 462 uci::AppConfigTlvType::InterFrameInterval => Ok(vec![self.inter_frame_interval]), 463 uci::AppConfigTlvType::SessionKey => Ok(self.session_key.clone()), 464 uci::AppConfigTlvType::SubSessionKey => Ok(match self.sub_session_key { 465 SubSessionKey::None => vec![], 466 SubSessionKey::Short(key) => key.to_vec(), 467 SubSessionKey::Extended(key) => key.to_vec(), 468 }), 469 uci::AppConfigTlvType::SessionDataTransferStatusNtfConfig => { 470 Ok(vec![self.session_data_transfer_status_ntf_config.into()]) 471 } 472 uci::AppConfigTlvType::SessionTimeBase => Ok(self.session_time_base.to_vec()), 473 uci::AppConfigTlvType::ApplicationDataEndpoint => { 474 Ok(vec![self.application_data_endpoint]) 475 } 476 477 uci::AppConfigTlvType::CccHopModeKey 478 | uci::AppConfigTlvType::CccUwbTime0 479 | uci::AppConfigTlvType::CccRangingProtocolVer 480 | uci::AppConfigTlvType::CccUwbConfigId 481 | uci::AppConfigTlvType::CccPulseshapeCombo 482 | uci::AppConfigTlvType::CccUrskTtl 483 | uci::AppConfigTlvType::CccLastIndexUsed 484 | uci::AppConfigTlvType::NbOfRangeMeasurements 485 | uci::AppConfigTlvType::NbOfAzimuthMeasurements 486 | uci::AppConfigTlvType::NbOfElevationMeasurements 487 | uci::AppConfigTlvType::EnableDiagnostics 488 | uci::AppConfigTlvType::DiagramsFrameReportsFields => { 489 log::error!("unsupported vendor config type {:?}", id); 490 anyhow::bail!("unsupported vendor config type {:?}", id) 491 } 492 _ => { 493 log::error!("unsupported app config type {:?}", id); 494 anyhow::bail!("unsupported app config type {:?}", id) 495 } 496 } 497 } 498 is_compatible_for_ranging(&self, peer_config: &Self) -> bool499 pub fn is_compatible_for_ranging(&self, peer_config: &Self) -> bool { 500 self.device_role != peer_config.device_role 501 && self.device_type != peer_config.device_type 502 && peer_config 503 .dst_mac_address 504 .contains(&self.device_mac_address.unwrap()) 505 && self 506 .dst_mac_address 507 .contains(&peer_config.device_mac_address.unwrap()) 508 } 509 can_start_data_transfer(&self) -> bool510 pub fn can_start_data_transfer(&self) -> bool { 511 self.device_role == Some(uci::DeviceRole::Initiator) 512 } 513 can_receive_data_transfer(&self) -> bool514 pub fn can_receive_data_transfer(&self) -> bool { 515 self.device_role == Some(uci::DeviceRole::Responder) 516 } 517 } 518