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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
use core::future::Future;
use crate::ember::aes::MmoHashContext;
use crate::ember::key::Data;
use crate::ember::{Eui64, NodeId};
use crate::error::Error;
use crate::frame::parameters::trust_center::{
aes_mmo_hash, broadcast_network_key_switch, broadcast_next_network_key, remove_device,
unicast_nwk_key_update,
};
use crate::transport::Transport;
use crate::types::ByteSizedVec;
/// The `TrustCenter` trait provides an interface for the Trust Center features.
pub trait TrustCenter {
/// This routine processes the passed chunk of data and updates the hash context based on it.
///
/// If the `finalize` parameter is not set, then the length of the data passed in must be a
/// multiple of 16.
///
/// If the `finalize` parameter is set then the length can be any value up 1-16,
/// and the final hash value will be calculated.
fn aes_mmo_hash(
&mut self,
context: MmoHashContext,
finalize: bool,
data: ByteSizedVec<u8>,
) -> impl Future<Output = Result<MmoHashContext, Error>> + Send;
/// This function broadcasts a switch key message to tell all nodes to change to the
/// sequence number of the previously sent Alternate Encryption Key.
fn broadcast_network_key_switch(&mut self) -> impl Future<Output = Result<(), Error>> + Send;
/// This function broadcasts a new encryption key,
/// but does not tell the nodes in the network to start using it.
///
/// To tell nodes to switch to the new key, use [`broadcast_network_key_switch()`](Self::broadcast_network_key_switch).
/// This is only valid for the Trust Center/Coordinator.
///
/// It is up to the application to determine how quickly
/// to send the Switch Key after sending the alternate encryption key.
fn broadcast_next_network_key(
&mut self,
key: Data,
) -> impl Future<Output = Result<(), Error>> + Send;
/// This command sends an APS remove device using APS encryption to the destination indicating
/// either to remove itself from the network, or one of its children.
fn remove_device(
&mut self,
dest_short: NodeId,
dest_long: Eui64,
target_long: Eui64,
) -> impl Future<Output = Result<(), Error>> + Send;
/// This command will send a unicast transport key message with a new NWK key
/// to the specified device.
///
/// APS encryption using the device's existing link key will be used.
fn unicast_nwk_key_update(
&mut self,
dest_short: NodeId,
dest_long: Eui64,
key: Data,
) -> impl Future<Output = Result<(), Error>> + Send;
}
impl<T> TrustCenter for T
where
T: Transport,
{
async fn aes_mmo_hash(
&mut self,
context: MmoHashContext,
finalize: bool,
data: ByteSizedVec<u8>,
) -> Result<MmoHashContext, Error> {
self.communicate(aes_mmo_hash::Command::new(context, finalize, data))
.await?
.try_into()
}
async fn broadcast_network_key_switch(&mut self) -> Result<(), Error> {
self.communicate(broadcast_network_key_switch::Command)
.await?
.try_into()
}
async fn broadcast_next_network_key(&mut self, key: Data) -> Result<(), Error> {
self.communicate(broadcast_next_network_key::Command::new(key))
.await?
.try_into()
}
async fn remove_device(
&mut self,
dest_short: NodeId,
dest_long: Eui64,
target_long: Eui64,
) -> Result<(), Error> {
self.communicate(remove_device::Command::new(
dest_short,
dest_long,
target_long,
))
.await?
.try_into()
}
async fn unicast_nwk_key_update(
&mut self,
dest_short: NodeId,
dest_long: Eui64,
key: Data,
) -> Result<(), Error> {
self.communicate(unicast_nwk_key_update::Command::new(
dest_short, dest_long, key,
))
.await?
.try_into()
}
}