1 // Copyright 2022, The Android Open Source Project 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #![allow(missing_docs)] 16 17 use std::collections::HashMap; 18 19 use crate::params::ccc_app_config_params::CccAppConfigParams; 20 use crate::params::ccc_started_app_config_params::CccStartedAppConfigParams; 21 use crate::params::fira_app_config_params::FiraAppConfigParams; 22 use crate::params::uci_packets::{AppConfigTlv, AppConfigTlvType, SessionState, SessionType}; 23 24 pub(super) type AppConfigTlvMap = HashMap<AppConfigTlvType, Vec<u8>>; 25 26 /// The application configuration parameters of the UWB session. It is used to generate the 27 /// parameters for the SESSION_SET_APP_CONFIG_CMD, or converted from the result of the 28 /// SESSION_GET_APP_CONFIG_CMD. 29 #[derive(Debug, Clone, PartialEq, Eq)] 30 pub enum AppConfigParams { 31 Fira(FiraAppConfigParams), 32 Ccc(CccAppConfigParams), 33 CccStarted(CccStartedAppConfigParams), 34 } 35 36 impl AppConfigParams { 37 /// Generate the TLV list from the params. generate_tlvs(&self) -> Vec<AppConfigTlv>38 pub fn generate_tlvs(&self) -> Vec<AppConfigTlv> { 39 Self::config_map_to_tlvs(self.generate_config_map()) 40 } 41 42 /// Generate the updated TLV list from the difference between this and the previous params. generate_updated_tlvs( &self, prev_params: &Self, session_state: SessionState, ) -> Option<Vec<AppConfigTlv>>43 pub fn generate_updated_tlvs( 44 &self, 45 prev_params: &Self, 46 session_state: SessionState, 47 ) -> Option<Vec<AppConfigTlv>> { 48 Some(Self::config_map_to_tlvs( 49 self.generate_updated_config_map(prev_params, session_state)?, 50 )) 51 } 52 config_map_to_tlvs(config_map: AppConfigTlvMap) -> Vec<AppConfigTlv>53 fn config_map_to_tlvs(config_map: AppConfigTlvMap) -> Vec<AppConfigTlv> { 54 config_map.into_iter().map(|(cfg_id, v)| AppConfigTlv::new(cfg_id, v)).collect() 55 } 56 generate_config_map(&self) -> AppConfigTlvMap57 pub(super) fn generate_config_map(&self) -> AppConfigTlvMap { 58 match self { 59 Self::Fira(params) => params.generate_config_map(), 60 Self::Ccc(params) => params.generate_config_map(), 61 _ => HashMap::new(), 62 } 63 } 64 generate_updated_config_map( &self, prev_params: &Self, session_state: SessionState, ) -> Option<AppConfigTlvMap>65 pub(super) fn generate_updated_config_map( 66 &self, 67 prev_params: &Self, 68 session_state: SessionState, 69 ) -> Option<AppConfigTlvMap> { 70 let config_map = self.generate_config_map(); 71 let prev_config_map = prev_params.generate_config_map(); 72 73 match (self, prev_params) { 74 (Self::Fira(_), Self::Fira(_)) => { 75 let updated_config_map = Self::diff_config_map(config_map, prev_config_map); 76 if FiraAppConfigParams::is_config_updatable(&updated_config_map, session_state) { 77 Some(updated_config_map) 78 } else { 79 None 80 } 81 } 82 (Self::Ccc(_), Self::Ccc(_)) => { 83 let updated_config_map = Self::diff_config_map(config_map, prev_config_map); 84 if CccAppConfigParams::is_config_updatable(&updated_config_map, session_state) { 85 Some(updated_config_map) 86 } else { 87 None 88 } 89 } 90 _ => None, 91 } 92 } 93 is_type_matched(&self, session_type: SessionType) -> bool94 pub fn is_type_matched(&self, session_type: SessionType) -> bool { 95 match self { 96 Self::Fira(_) => { 97 session_type == SessionType::FiraDataTransfer 98 || session_type == SessionType::FiraRangingSession 99 } 100 Self::Ccc(_) | Self::CccStarted(_) => session_type == SessionType::Ccc, 101 } 102 } 103 diff_config_map( config_map: AppConfigTlvMap, prev_config_map: AppConfigTlvMap, ) -> AppConfigTlvMap104 fn diff_config_map( 105 config_map: AppConfigTlvMap, 106 prev_config_map: AppConfigTlvMap, 107 ) -> AppConfigTlvMap { 108 // The key sets of both map should be the same. 109 debug_assert!( 110 config_map.len() == prev_config_map.len() 111 && config_map.keys().all(|key| prev_config_map.contains_key(key)) 112 ); 113 114 let mut updated_config_map = HashMap::new(); 115 for (key, value) in config_map.into_iter() { 116 if !matches!(prev_config_map.get(&key), Some(prev_value) if prev_value == &value) { 117 updated_config_map.insert(key, value); 118 } 119 } 120 updated_config_map 121 } 122 } 123