1use capsules_core::virtualizers::virtual_aes_ccm::MuxAES128CCM;
30use capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm;
31use capsules_extra::net::ipv6::ipv6_send::IP6SendStruct;
32use capsules_extra::net::network_capabilities::{
33 AddrRange, NetworkCapability, PortRange, UdpVisibilityCapability,
34};
35use kernel::hil::symmetric_encryption::{self, AES128Ctr, AES128, AES128CBC, AES128CCM, AES128ECB};
36
37use capsules_core::virtualizers::virtual_alarm::MuxAlarm;
38use capsules_extra::net::thread::thread_utils::THREAD_PORT_NUMBER;
39use capsules_extra::net::udp::udp_port_table::UdpPortManager;
40use capsules_extra::net::udp::udp_recv::MuxUdpReceiver;
41use capsules_extra::net::udp::udp_recv::UDPReceiver;
42use capsules_extra::net::udp::udp_send::{MuxUdpSender, UDPSendStruct, UDPSender};
43use core::mem::MaybeUninit;
44use kernel::capabilities;
45use kernel::capabilities::NetworkCapabilityCreationCapability;
46use kernel::component::Component;
47use kernel::create_capability;
48use kernel::hil::radio;
49use kernel::hil::time::Alarm;
50
51const MAX_PAYLOAD_LEN: usize = super::udp_mux::MAX_PAYLOAD_LEN;
52pub const CRYPT_SIZE: usize = 3 * symmetric_encryption::AES128_BLOCK_SIZE + radio::MAX_BUF_SIZE;
53
54#[macro_export]
56macro_rules! thread_network_component_static {
57 ($A:ty, $B:ty $(,)?) => {{
58 use components::udp_mux::MAX_PAYLOAD_LEN;
59
60 let udp_send = kernel::static_buf!(
61 capsules_extra::net::udp::udp_send::UDPSendStruct<
62 'static,
63 capsules_extra::net::ipv6::ipv6_send::IP6SendStruct<
64 'static,
65 capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm<'static, $A>,
66 >,
67 >
68 );
69 let udp_vis_cap =
70 kernel::static_buf!(capsules_extra::net::network_capabilities::UdpVisibilityCapability);
71 let net_cap =
72 kernel::static_buf!(capsules_extra::net::network_capabilities::NetworkCapability);
73 let thread_network_driver = kernel::static_buf!(
74 capsules_extra::net::thread::driver::ThreadNetworkDriver<
75 'static,
76 VirtualMuxAlarm<'static, $A>,
77 >
78 );
79 let send_buffer = kernel::static_buf!([u8; MAX_PAYLOAD_LEN]);
80 let recv_buffer = kernel::static_buf!([u8; MAX_PAYLOAD_LEN]);
81 let udp_recv =
82 kernel::static_buf!(capsules_extra::net::udp::udp_recv::UDPReceiver<'static>);
83 let crypt_buf = kernel::static_buf!([u8; components::ieee802154::CRYPT_SIZE]);
84 let crypt = kernel::static_buf!(
85 capsules_core::virtualizers::virtual_aes_ccm::VirtualAES128CCM<'static, $B>,
86 );
87 let alarm = kernel::static_buf!(VirtualMuxAlarm<'static, $A>);
88
89 (
90 udp_send,
91 udp_vis_cap,
92 net_cap,
93 thread_network_driver,
94 send_buffer,
95 recv_buffer,
96 udp_recv,
97 crypt_buf,
98 crypt,
99 alarm,
100 )
101 };};
102}
103pub struct ThreadNetworkComponent<
104 A: Alarm<'static> + 'static,
105 B: AES128<'static> + AES128Ctr + AES128CBC + AES128ECB + 'static,
106> {
107 board_kernel: &'static kernel::Kernel,
108 driver_num: usize,
109 udp_send_mux:
110 &'static MuxUdpSender<'static, IP6SendStruct<'static, VirtualMuxAlarm<'static, A>>>,
111 udp_recv_mux: &'static MuxUdpReceiver<'static>,
112 port_table: &'static UdpPortManager,
113 aes_mux: &'static MuxAES128CCM<'static, B>,
114 serial_num: [u8; 8],
115 alarm_mux: &'static MuxAlarm<'static, A>,
116}
117
118impl<
119 A: Alarm<'static> + 'static,
120 B: AES128<'static> + AES128Ctr + AES128CBC + AES128ECB + 'static,
121 > ThreadNetworkComponent<A, B>
122{
123 pub fn new(
124 board_kernel: &'static kernel::Kernel,
125 driver_num: usize,
126 udp_send_mux: &'static MuxUdpSender<
127 'static,
128 IP6SendStruct<'static, VirtualMuxAlarm<'static, A>>,
129 >,
130 udp_recv_mux: &'static MuxUdpReceiver<'static>,
131 port_table: &'static UdpPortManager,
132 aes_mux: &'static MuxAES128CCM<'static, B>,
133 serial_num: [u8; 8],
134 alarm_mux: &'static MuxAlarm<'static, A>,
135 ) -> Self {
136 Self {
137 board_kernel,
138 driver_num,
139 udp_send_mux,
140 udp_recv_mux,
141 port_table,
142 aes_mux,
143 serial_num,
144 alarm_mux,
145 }
146 }
147}
148
149impl<
150 A: Alarm<'static> + 'static,
151 B: AES128<'static> + AES128Ctr + AES128CBC + AES128ECB + 'static,
152 > Component for ThreadNetworkComponent<A, B>
153{
154 type StaticInput = (
155 &'static mut MaybeUninit<
156 UDPSendStruct<
157 'static,
158 capsules_extra::net::ipv6::ipv6_send::IP6SendStruct<
159 'static,
160 VirtualMuxAlarm<'static, A>,
161 >,
162 >,
163 >,
164 &'static mut MaybeUninit<
165 capsules_extra::net::network_capabilities::UdpVisibilityCapability,
166 >,
167 &'static mut MaybeUninit<capsules_extra::net::network_capabilities::NetworkCapability>,
168 &'static mut MaybeUninit<
169 capsules_extra::net::thread::driver::ThreadNetworkDriver<
170 'static,
171 VirtualMuxAlarm<'static, A>,
172 >,
173 >,
174 &'static mut MaybeUninit<[u8; MAX_PAYLOAD_LEN]>,
175 &'static mut MaybeUninit<[u8; MAX_PAYLOAD_LEN]>,
176 &'static mut MaybeUninit<UDPReceiver<'static>>,
177 &'static mut MaybeUninit<[u8; CRYPT_SIZE]>,
178 &'static mut MaybeUninit<
179 capsules_core::virtualizers::virtual_aes_ccm::VirtualAES128CCM<'static, B>,
180 >,
181 &'static mut MaybeUninit<VirtualMuxAlarm<'static, A>>,
182 );
183 type Output = &'static capsules_extra::net::thread::driver::ThreadNetworkDriver<
184 'static,
185 VirtualMuxAlarm<'static, A>,
186 >;
187
188 fn finalize(self, s: Self::StaticInput) -> Self::Output {
189 let thread_virtual_alarm: &mut VirtualMuxAlarm<'_, A> =
190 s.9.write(VirtualMuxAlarm::new(self.alarm_mux));
191 thread_virtual_alarm.setup();
192
193 let grant_cap = create_capability!(capabilities::MemoryAllocationCapability);
194
195 let crypt_buf = s.7.write([0; CRYPT_SIZE]);
197 let aes_ccm = s.8.write(
198 capsules_core::virtualizers::virtual_aes_ccm::VirtualAES128CCM::new(
199 self.aes_mux,
200 crypt_buf,
201 ),
202 );
203 aes_ccm.setup();
204
205 let create_cap = create_capability!(NetworkCapabilityCreationCapability);
206 let udp_vis = s.1.write(UdpVisibilityCapability::new(&create_cap));
207 let udp_send = s.0.write(UDPSendStruct::new(self.udp_send_mux, udp_vis));
208
209 struct DriverCap;
212 unsafe impl capabilities::UdpDriverCapability for DriverCap {}
213 static DRIVER_CAP: DriverCap = DriverCap;
214
215 let net_cap = s.2.write(NetworkCapability::new(
216 AddrRange::Any,
217 PortRange::Any,
218 PortRange::Any,
219 &create_cap,
220 ));
221
222 let send_buffer = s.4.write([0; MAX_PAYLOAD_LEN]);
223 let recv_buffer = s.5.write([0; MAX_PAYLOAD_LEN]);
224
225 let thread_network_driver = s.3.write(
226 capsules_extra::net::thread::driver::ThreadNetworkDriver::new(
227 udp_send,
228 aes_ccm,
229 thread_virtual_alarm,
230 self.board_kernel.create_grant(self.driver_num, &grant_cap),
231 self.serial_num,
232 MAX_PAYLOAD_LEN,
233 self.port_table,
234 kernel::utilities::leasable_buffer::SubSliceMut::new(send_buffer),
235 kernel::utilities::leasable_buffer::SubSliceMut::new(recv_buffer),
236 &DRIVER_CAP,
237 net_cap,
238 ),
239 );
240
241 thread_virtual_alarm.set_alarm_client(thread_network_driver);
242
243 udp_send.set_client(thread_network_driver);
244 AES128CCM::set_client(aes_ccm, thread_network_driver);
245
246 let udp_driver_rcvr = s.6.write(UDPReceiver::new());
247 udp_driver_rcvr.set_client(thread_network_driver);
248
249 self.port_table
257 .create_socket()
258 .map(|socket| {
259 self.port_table
260 .bind(socket, THREAD_PORT_NUMBER, net_cap)
261 .map_or_else(
262 |_| (),
263 |(tx_bind, rx_bind)| {
264 udp_driver_rcvr.set_binding(rx_bind);
265 udp_send.set_binding(tx_bind);
266 },
267 )
268 })
269 .unwrap();
270
271 self.udp_recv_mux.add_client(udp_driver_rcvr);
272
273 thread_network_driver
274 }
275}