xref: /aosp_15_r20/external/uwb/src/rust/uwb_core/src/params/app_config_params.rs (revision e0df40009cb5d71e642272d38ba1bb7ffccfce41)
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::aliro_app_config_params::AliroAppConfigParams;
20 use crate::params::ccc_app_config_params::CccAppConfigParams;
21 use crate::params::ccc_started_app_config_params::CccStartedAppConfigParams;
22 use crate::params::fira_app_config_params::FiraAppConfigParams;
23 use crate::params::uci_packets::{AppConfigTlv, AppConfigTlvType, SessionState, SessionType};
24 
25 pub(super) type AppConfigTlvMap = HashMap<AppConfigTlvType, Vec<u8>>;
26 
27 /// The application configuration parameters of the UWB session. It is used to generate the
28 /// parameters for the SESSION_SET_APP_CONFIG_CMD, or converted from the result of the
29 /// SESSION_GET_APP_CONFIG_CMD.
30 #[derive(Debug, Clone, PartialEq, Eq)]
31 pub enum AppConfigParams {
32     Fira(FiraAppConfigParams),
33     Ccc(CccAppConfigParams),
34     CccStarted(CccStartedAppConfigParams),
35     Aliro(AliroAppConfigParams),
36 }
37 
38 impl AppConfigParams {
39     /// Generate the TLV list from the params.
generate_tlvs(&self) -> Vec<AppConfigTlv>40     pub fn generate_tlvs(&self) -> Vec<AppConfigTlv> {
41         Self::config_map_to_tlvs(self.generate_config_map())
42     }
43 
44     /// 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>>45     pub fn generate_updated_tlvs(
46         &self,
47         prev_params: &Self,
48         session_state: SessionState,
49     ) -> Option<Vec<AppConfigTlv>> {
50         Some(Self::config_map_to_tlvs(
51             self.generate_updated_config_map(prev_params, session_state)?,
52         ))
53     }
54 
config_map_to_tlvs(config_map: AppConfigTlvMap) -> Vec<AppConfigTlv>55     fn config_map_to_tlvs(config_map: AppConfigTlvMap) -> Vec<AppConfigTlv> {
56         config_map.into_iter().map(|(cfg_id, v)| AppConfigTlv::new(cfg_id, v)).collect()
57     }
58 
generate_config_map(&self) -> AppConfigTlvMap59     pub(super) fn generate_config_map(&self) -> AppConfigTlvMap {
60         match self {
61             Self::Fira(params) => params.generate_config_map(),
62             Self::Ccc(params) => params.generate_config_map(),
63             Self::Aliro(params) => params.generate_config_map(),
64             _ => HashMap::new(),
65         }
66     }
67 
generate_updated_config_map( &self, prev_params: &Self, session_state: SessionState, ) -> Option<AppConfigTlvMap>68     pub(super) fn generate_updated_config_map(
69         &self,
70         prev_params: &Self,
71         session_state: SessionState,
72     ) -> Option<AppConfigTlvMap> {
73         let config_map = self.generate_config_map();
74         let prev_config_map = prev_params.generate_config_map();
75 
76         match (self, prev_params) {
77             (Self::Fira(_), Self::Fira(_)) => {
78                 let updated_config_map = Self::diff_config_map(config_map, prev_config_map);
79                 if FiraAppConfigParams::is_config_updatable(&updated_config_map, session_state) {
80                     Some(updated_config_map)
81                 } else {
82                     None
83                 }
84             }
85             (Self::Ccc(_), Self::Ccc(_)) => {
86                 let updated_config_map = Self::diff_config_map(config_map, prev_config_map);
87                 if CccAppConfigParams::is_config_updatable(&updated_config_map, session_state) {
88                     Some(updated_config_map)
89                 } else {
90                     None
91                 }
92             }
93             (Self::Aliro(_), Self::Aliro(_)) => {
94                 let updated_config_map = Self::diff_config_map(config_map, prev_config_map);
95                 if AliroAppConfigParams::is_config_updatable(&updated_config_map, session_state) {
96                     Some(updated_config_map)
97                 } else {
98                     None
99                 }
100             }
101             _ => None,
102         }
103     }
104 
is_type_matched(&self, session_type: SessionType) -> bool105     pub fn is_type_matched(&self, session_type: SessionType) -> bool {
106         match self {
107             Self::Fira(_) => {
108                 session_type == SessionType::FiraDataTransferSession
109                     || session_type == SessionType::FiraRangingSession
110                     || session_type == SessionType::FiraRangingAndInBandDataSession
111                     || session_type == SessionType::FiraRangingOnlyPhase
112                     || session_type == SessionType::FiraInBandDataPhase
113                     || session_type == SessionType::FiraRangingWithDataPhase
114             }
115             Self::Ccc(_) | Self::CccStarted(_) => session_type == SessionType::Ccc,
116             Self::Aliro(_) => session_type == SessionType::Aliro,
117         }
118     }
119 
diff_config_map( config_map: AppConfigTlvMap, prev_config_map: AppConfigTlvMap, ) -> AppConfigTlvMap120     fn diff_config_map(
121         config_map: AppConfigTlvMap,
122         prev_config_map: AppConfigTlvMap,
123     ) -> AppConfigTlvMap {
124         // The key sets of both map should be the same.
125         debug_assert!(
126             config_map.len() == prev_config_map.len()
127                 && config_map.keys().all(|key| prev_config_map.contains_key(key))
128         );
129 
130         let mut updated_config_map = HashMap::new();
131         for (key, value) in config_map.into_iter() {
132             if !matches!(prev_config_map.get(&key), Some(prev_value) if prev_value == &value) {
133                 updated_config_map.insert(key, value);
134             }
135         }
136         updated_config_map
137     }
138 }
139