• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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