1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
use crate::{
attributes::CommandCodeAttributes,
tss2_esys::{TPMA_CC, TPML_CCA},
Error, Result, WrapperErrorKind,
};
use log::error;
use std::{convert::TryFrom, iter::IntoIterator, ops::Deref};
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct CommandCodeAttributesList {
command_code_attributes: Vec<CommandCodeAttributes>,
}
impl CommandCodeAttributesList {
pub const MAX_SIZE: usize = Self::calculate_max_size();
pub fn find(&self, command_index: u16) -> Option<&CommandCodeAttributes> {
self.command_code_attributes
.iter()
.find(|cca| cca.command_index() == command_index)
}
const fn calculate_max_size() -> usize {
crate::structures::capability_data::max_cap_size::<TPMA_CC>()
}
}
impl Deref for CommandCodeAttributesList {
type Target = Vec<CommandCodeAttributes>;
fn deref(&self) -> &Self::Target {
&self.command_code_attributes
}
}
impl AsRef<[CommandCodeAttributes]> for CommandCodeAttributesList {
fn as_ref(&self) -> &[CommandCodeAttributes] {
self.command_code_attributes.as_slice()
}
}
impl TryFrom<Vec<CommandCodeAttributes>> for CommandCodeAttributesList {
type Error = Error;
fn try_from(command_code_attributes: Vec<CommandCodeAttributes>) -> Result<Self> {
if command_code_attributes.len() > Self::MAX_SIZE {
error!("Failed to convert Vec<CommandCodeAttributes> into CommandCodeAttributesList, to many items (> {})", Self::MAX_SIZE);
return Err(Error::local_error(WrapperErrorKind::InvalidParam));
}
Ok(CommandCodeAttributesList {
command_code_attributes,
})
}
}
impl IntoIterator for CommandCodeAttributesList {
type Item = CommandCodeAttributes;
type IntoIter = std::vec::IntoIter<Self::Item>;
fn into_iter(self) -> Self::IntoIter {
self.command_code_attributes.into_iter()
}
}
impl TryFrom<TPML_CCA> for CommandCodeAttributesList {
type Error = Error;
fn try_from(tpml_cca: TPML_CCA) -> Result<Self> {
let count = usize::try_from(tpml_cca.count).map_err(|e| {
error!("Failed to parse count in TPML_CCA as usize: {}", e);
Error::local_error(WrapperErrorKind::InvalidParam)
})?;
if count > Self::MAX_SIZE {
error!("Invalid size value in TPML_CCA (> {})", Self::MAX_SIZE,);
return Err(Error::local_error(WrapperErrorKind::InvalidParam));
}
tpml_cca.commandAttributes[..count]
.iter()
.map(|&tp| CommandCodeAttributes::try_from(tp))
.collect::<Result<Vec<CommandCodeAttributes>>>()
.map(|command_code_attributes| CommandCodeAttributesList {
command_code_attributes,
})
}
}
impl From<CommandCodeAttributesList> for TPML_CCA {
fn from(command_code_attributes_list: CommandCodeAttributesList) -> Self {
let mut tpml_cca: TPML_CCA = Default::default();
for command_code_attributes in command_code_attributes_list {
tpml_cca.commandAttributes[tpml_cca.count as usize] = command_code_attributes.into();
tpml_cca.count += 1;
}
tpml_cca
}
}