1use capsules_core::virtualizers::virtual_alarm::{MuxAlarm, VirtualMuxAlarm};
31use capsules_extra::ieee802154::device::MacDevice;
32use capsules_extra::net::ieee802154::MacAddress;
33use capsules_extra::net::ipv6::ip_utils::IPAddr;
34use capsules_extra::net::ipv6::ipv6_recv::IP6Receiver;
35use capsules_extra::net::ipv6::ipv6_recv::IP6RecvStruct;
36use capsules_extra::net::ipv6::ipv6_send::IP6SendStruct;
37use capsules_extra::net::ipv6::ipv6_send::IP6Sender;
38use capsules_extra::net::ipv6::{IP6Packet, IPPayload, TransportHeader};
39use capsules_extra::net::network_capabilities::{IpVisibilityCapability, UdpVisibilityCapability};
40use capsules_extra::net::sixlowpan::{sixlowpan_compression, sixlowpan_state};
41use capsules_extra::net::udp::udp_port_table::{
42 SocketBindingEntry, UdpPortManager, MAX_NUM_BOUND_PORTS,
43};
44use capsules_extra::net::udp::udp_recv::MuxUdpReceiver;
45use capsules_extra::net::udp::udp_send::MuxUdpSender;
46use capsules_extra::net::udp::UDPHeader;
47use core::mem::MaybeUninit;
48use kernel::capabilities;
49use kernel::component::Component;
50use kernel::create_capability;
51use kernel::hil::radio;
52use kernel::hil::time::Alarm;
53
54pub const MAX_PAYLOAD_LEN: usize = 200; #[macro_export]
67macro_rules! udp_mux_component_static {
68 ($A:ty, $M:ty $(,)?) => {{
69 use capsules_core;
70 use capsules_core::virtualizers::virtual_alarm::{MuxAlarm, VirtualMuxAlarm};
71 use capsules_extra::net::sixlowpan::{sixlowpan_compression, sixlowpan_state};
72 use capsules_extra::net::udp::udp_send::MuxUdpSender;
73 use components::udp_mux::MAX_PAYLOAD_LEN;
74 use core::mem::MaybeUninit;
75
76 let alarm = kernel::static_buf!(VirtualMuxAlarm<'static, $A>);
77 let mac_user =
78 kernel::static_buf!(capsules_extra::ieee802154::virtual_mac::MacUser<'static, $M>);
79 let sixlowpan = kernel::static_buf!(
80 sixlowpan_state::Sixlowpan<
81 'static,
82 VirtualMuxAlarm<'static, $A>,
83 sixlowpan_compression::Context,
84 >
85 );
86 let rx_state = kernel::static_buf!(sixlowpan_state::RxState<'static>);
87 let ip6_send = kernel::static_buf!(
88 capsules_extra::net::ipv6::ipv6_send::IP6SendStruct<
89 'static,
90 VirtualMuxAlarm<'static, $A>,
91 >
92 );
93 let mux_udp_send = kernel::static_buf!(
94 MuxUdpSender<
95 'static,
96 capsules_extra::net::ipv6::ipv6_send::IP6SendStruct<
97 'static,
98 VirtualMuxAlarm<'static, $A>,
99 >,
100 >
101 );
102 let mux_udp_recv =
103 kernel::static_buf!(capsules_extra::net::udp::udp_recv::MuxUdpReceiver<'static>);
104 let udp_port_manager =
105 kernel::static_buf!(capsules_extra::net::udp::udp_port_table::UdpPortManager);
106
107 let ip6_packet = kernel::static_buf!(capsules_extra::net::ipv6::IP6Packet<'static>);
108 let ip6_receive =
109 kernel::static_buf!(capsules_extra::net::ipv6::ipv6_recv::IP6RecvStruct<'static>);
110
111 let used_ports = kernel::static_buf!(
123 [Option<capsules_extra::net::udp::udp_port_table::SocketBindingEntry>;
124 capsules_extra::net::udp::udp_port_table::MAX_NUM_BOUND_PORTS]
125 );
126
127 let radio_buf = kernel::static_buf!([u8; kernel::hil::radio::MAX_BUF_SIZE]);
128 let sixlowpan_rx = kernel::static_buf!([u8; 1280]);
129 let udp_dgram = kernel::static_buf!([u8; MAX_PAYLOAD_LEN]);
130
131 let udp_vis_cap =
132 kernel::static_buf!(capsules_extra::net::network_capabilities::UdpVisibilityCapability);
133 let ip_vis_cap =
134 kernel::static_buf!(capsules_extra::net::network_capabilities::IpVisibilityCapability);
135
136 (
137 alarm,
138 mac_user,
139 sixlowpan,
140 rx_state,
141 ip6_send,
142 mux_udp_send,
143 mux_udp_recv,
144 udp_port_manager,
145 ip6_packet,
146 ip6_receive,
147 used_ports,
148 radio_buf,
149 sixlowpan_rx,
150 udp_dgram,
151 udp_vis_cap,
152 ip_vis_cap,
153 )
154 };};
155}
156
157pub struct UDPMuxComponent<A: Alarm<'static> + 'static, M: MacDevice<'static> + 'static> {
158 mux_mac: &'static capsules_extra::ieee802154::virtual_mac::MuxMac<'static, M>,
159 ctx_pfix_len: u8,
160 ctx_pfix: [u8; 16],
161 dst_mac_addr: MacAddress,
162 src_mac_addr: MacAddress,
163 interface_list: &'static [IPAddr],
164 alarm_mux: &'static MuxAlarm<'static, A>,
165}
166
167impl<A: Alarm<'static> + 'static, M: MacDevice<'static>> UDPMuxComponent<A, M> {
168 pub fn new(
169 mux_mac: &'static capsules_extra::ieee802154::virtual_mac::MuxMac<'static, M>,
170 ctx_pfix_len: u8,
171 ctx_pfix: [u8; 16],
172 dst_mac_addr: MacAddress,
173 src_mac_addr: MacAddress,
174 interface_list: &'static [IPAddr],
175 alarm_mux: &'static MuxAlarm<'static, A>,
176 ) -> Self {
177 Self {
178 mux_mac,
179 ctx_pfix_len,
180 ctx_pfix,
181 dst_mac_addr,
182 src_mac_addr,
183 interface_list,
184 alarm_mux,
185 }
186 }
187}
188
189impl<A: Alarm<'static> + 'static, M: MacDevice<'static>> Component for UDPMuxComponent<A, M> {
190 type StaticInput = (
191 &'static mut MaybeUninit<VirtualMuxAlarm<'static, A>>,
192 &'static mut MaybeUninit<capsules_extra::ieee802154::virtual_mac::MacUser<'static, M>>,
193 &'static mut MaybeUninit<
194 sixlowpan_state::Sixlowpan<
195 'static,
196 VirtualMuxAlarm<'static, A>,
197 sixlowpan_compression::Context,
198 >,
199 >,
200 &'static mut MaybeUninit<sixlowpan_state::RxState<'static>>,
201 &'static mut MaybeUninit<
202 capsules_extra::net::ipv6::ipv6_send::IP6SendStruct<
203 'static,
204 VirtualMuxAlarm<'static, A>,
205 >,
206 >,
207 &'static mut MaybeUninit<
208 MuxUdpSender<
209 'static,
210 capsules_extra::net::ipv6::ipv6_send::IP6SendStruct<
211 'static,
212 VirtualMuxAlarm<'static, A>,
213 >,
214 >,
215 >,
216 &'static mut MaybeUninit<MuxUdpReceiver<'static>>,
217 &'static mut MaybeUninit<UdpPortManager>,
218 &'static mut MaybeUninit<IP6Packet<'static>>,
219 &'static mut MaybeUninit<IP6RecvStruct<'static>>,
220 &'static mut MaybeUninit<[Option<SocketBindingEntry>; MAX_NUM_BOUND_PORTS]>,
221 &'static mut MaybeUninit<[u8; radio::MAX_BUF_SIZE]>,
222 &'static mut MaybeUninit<[u8; 1280]>,
223 &'static mut MaybeUninit<[u8; MAX_PAYLOAD_LEN]>,
224 &'static mut MaybeUninit<UdpVisibilityCapability>,
225 &'static mut MaybeUninit<IpVisibilityCapability>,
226 );
227 type Output = (
228 &'static MuxUdpSender<'static, IP6SendStruct<'static, VirtualMuxAlarm<'static, A>>>,
229 &'static MuxUdpReceiver<'static>,
230 &'static UdpPortManager,
231 );
232
233 fn finalize(self, s: Self::StaticInput) -> Self::Output {
234 let ipsender_virtual_alarm = s.0.write(VirtualMuxAlarm::new(self.alarm_mux));
235 ipsender_virtual_alarm.setup();
236
237 let udp_mac =
238 s.1.write(capsules_extra::ieee802154::virtual_mac::MacUser::new(
239 self.mux_mac,
240 ));
241 self.mux_mac.add_user(udp_mac);
242 let create_cap = create_capability!(capabilities::NetworkCapabilityCreationCapability);
243 let udp_vis = s.14.write(UdpVisibilityCapability::new(&create_cap));
244 let ip_vis = s.15.write(IpVisibilityCapability::new(&create_cap));
245
246 let sixlowpan = s.2.write(sixlowpan_state::Sixlowpan::new(
247 sixlowpan_compression::Context {
248 prefix: self.ctx_pfix,
249 prefix_len: self.ctx_pfix_len,
250 id: 0,
251 compress: false,
252 },
253 ipsender_virtual_alarm, ));
255
256 let sixlowpan_rx_buffer = s.12.write([0; 1280]);
257 let sixlowpan_state = sixlowpan as &dyn sixlowpan_state::SixlowpanState;
258 let sixlowpan_tx = sixlowpan_state::TxState::new(sixlowpan_state);
259 let default_rx_state =
260 s.3.write(sixlowpan_state::RxState::new(sixlowpan_rx_buffer));
261 sixlowpan_state.add_rx_state(default_rx_state);
262 udp_mac.set_receive_client(sixlowpan);
263
264 let udp_dgram_buffer = s.13.write([0; MAX_PAYLOAD_LEN]);
265 let tr_hdr = TransportHeader::UDP(UDPHeader::new());
266 let ip_pyld: IPPayload = IPPayload {
267 header: tr_hdr,
268 payload: udp_dgram_buffer,
269 };
270 let ip6_dg = s.8.write(IP6Packet::new(ip_pyld));
271
272 let radio_buf = s.11.write([0; radio::MAX_BUF_SIZE]);
273
274 let ip_send =
282 s.4.write(capsules_extra::net::ipv6::ipv6_send::IP6SendStruct::new(
283 ip6_dg,
284 ipsender_virtual_alarm,
285 radio_buf,
286 sixlowpan_tx,
287 udp_mac,
288 self.dst_mac_addr,
289 self.src_mac_addr,
290 ip_vis,
291 ));
292 ipsender_virtual_alarm.set_alarm_client(ip_send);
293
294 ip_send.set_addr(self.interface_list[0]);
299 udp_mac.set_transmit_client(ip_send);
300
301 let ip_receive =
302 s.9.write(capsules_extra::net::ipv6::ipv6_recv::IP6RecvStruct::new());
303 sixlowpan_state.set_rx_client(ip_receive);
304 let udp_recv_mux = s.6.write(MuxUdpReceiver::new());
305 ip_receive.set_client(udp_recv_mux);
306
307 let udp_send_mux = s.5.write(MuxUdpSender::new(ip_send));
308 ip_send.set_client(udp_send_mux);
309
310 let kernel_ports = s.10.write([None; MAX_NUM_BOUND_PORTS]);
311 let create_table_cap = create_capability!(capabilities::CreatePortTableCapability);
312 let udp_port_table = s.7.write(UdpPortManager::new(
313 &create_table_cap,
314 kernel_ports,
315 udp_vis,
316 ));
317
318 (udp_send_mux, udp_recv_mux, udp_port_table)
319 }
320}