imix/imix_components/test/
mock_udp.rs

1// Licensed under the Apache License, Version 2.0 or the MIT License.
2// SPDX-License-Identifier: Apache-2.0 OR MIT
3// Copyright Tock Contributors 2022.
4
5//! Component to test in kernel udp
6
7// Author: Hudson Ayers <hayers@stanford.edu>
8
9#![allow(dead_code)] // Components are intended to be conditionally included
10
11use capsules_core::virtualizers::virtual_alarm::{MuxAlarm, VirtualMuxAlarm};
12use capsules_extra::net::ipv6::ipv6_send::IP6SendStruct;
13use capsules_extra::net::network_capabilities::{NetworkCapability, UdpVisibilityCapability};
14use capsules_extra::net::udp::udp_port_table::UdpPortManager;
15use capsules_extra::net::udp::udp_recv::{MuxUdpReceiver, UDPReceiver};
16use capsules_extra::net::udp::udp_send::{MuxUdpSender, UDPSendStruct, UDPSender};
17use core::mem::MaybeUninit;
18use kernel::component::Component;
19use kernel::hil::time::Alarm;
20use kernel::utilities::cells::TakeCell;
21
22#[macro_export]
23/// Macro for constructing a mock UDP capsule for tests.
24macro_rules! mock_udp_component_static {
25    () => {{
26        use capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm;
27        use capsules_extra::net::udp::udp_recv::UDPReceiver;
28        use capsules_extra::net::udp::udp_send::UDPSendStruct;
29        let udp_send = kernel::static_buf!(
30            UDPSendStruct<
31                'static,
32                capsules_extra::net::ipv6::ipv6_send::IP6SendStruct<
33                    'static,
34                    VirtualMuxAlarm<'static, sam4l::ast::Ast<'static>>,
35                >,
36            >
37        );
38
39        let udp_recv = kernel::static_buf!(UDPReceiver<'static>);
40        let udp_alarm = kernel::static_buf!(VirtualMuxAlarm<'static, sam4l::ast::Ast>,);
41
42        let mock_udp = kernel::static_buf!(
43            capsules_extra::test::udp::MockUdp<'static, VirtualMuxAlarm<'static, sam4l::ast::Ast>>,
44        );
45        (udp_send, udp_recv, udp_alarm, mock_udp)
46    }};
47}
48
49pub struct MockUDPComponent {
50    udp_send_mux: &'static MuxUdpSender<
51        'static,
52        IP6SendStruct<'static, VirtualMuxAlarm<'static, sam4l::ast::Ast<'static>>>,
53    >,
54    udp_recv_mux: &'static MuxUdpReceiver<'static>,
55    bound_port_table: &'static UdpPortManager,
56    alarm_mux: &'static MuxAlarm<'static, sam4l::ast::Ast<'static>>,
57    udp_payload: TakeCell<'static, [u8]>,
58    id: u16,
59    dst_port: u16,
60    net_cap: &'static NetworkCapability,
61    udp_vis: &'static UdpVisibilityCapability,
62}
63
64impl MockUDPComponent {
65    pub fn new(
66        udp_send_mux: &'static MuxUdpSender<
67            'static,
68            IP6SendStruct<'static, VirtualMuxAlarm<'static, sam4l::ast::Ast<'static>>>,
69        >,
70        udp_recv_mux: &'static MuxUdpReceiver<'static>,
71        bound_port_table: &'static UdpPortManager,
72        alarm: &'static MuxAlarm<'static, sam4l::ast::Ast<'static>>,
73        udp_payload: &'static mut [u8],
74        id: u16,
75        dst_port: u16,
76        net_cap: &'static NetworkCapability,
77        udp_vis: &'static UdpVisibilityCapability,
78    ) -> MockUDPComponent {
79        MockUDPComponent {
80            udp_send_mux,
81            udp_recv_mux,
82            bound_port_table,
83            alarm_mux: alarm,
84            udp_payload: TakeCell::new(udp_payload),
85            id,
86            dst_port,
87            net_cap,
88            udp_vis,
89        }
90    }
91}
92
93impl Component for MockUDPComponent {
94    type StaticInput = (
95        &'static mut MaybeUninit<
96            UDPSendStruct<
97                'static,
98                capsules_extra::net::ipv6::ipv6_send::IP6SendStruct<
99                    'static,
100                    VirtualMuxAlarm<'static, sam4l::ast::Ast<'static>>,
101                >,
102            >,
103        >,
104        &'static mut MaybeUninit<UDPReceiver<'static>>,
105        &'static mut MaybeUninit<VirtualMuxAlarm<'static, sam4l::ast::Ast<'static>>>,
106        &'static mut MaybeUninit<
107            capsules_extra::test::udp::MockUdp<
108                'static,
109                VirtualMuxAlarm<'static, sam4l::ast::Ast<'static>>,
110            >,
111        >,
112    );
113    type Output = &'static capsules_extra::test::udp::MockUdp<
114        'static,
115        VirtualMuxAlarm<'static, sam4l::ast::Ast<'static>>,
116    >;
117
118    fn finalize(self, s: Self::StaticInput) -> Self::Output {
119        let udp_send =
120            s.0.write(UDPSendStruct::new(self.udp_send_mux, self.udp_vis));
121
122        let udp_recv = s.1.write(UDPReceiver::new());
123        self.udp_recv_mux.add_client(udp_recv);
124
125        let udp_alarm = s.2.write(VirtualMuxAlarm::new(self.alarm_mux));
126        udp_alarm.setup();
127
128        let mock_udp = s.3.write(capsules_extra::test::udp::MockUdp::new(
129            self.id,
130            udp_alarm,
131            udp_send,
132            udp_recv,
133            self.bound_port_table,
134            kernel::utilities::leasable_buffer::SubSliceMut::new(
135                self.udp_payload.take().expect("missing payload"),
136            ),
137            self.dst_port,
138            self.net_cap,
139        ));
140        udp_send.set_client(mock_udp);
141        udp_recv.set_client(mock_udp);
142        udp_alarm.set_alarm_client(mock_udp);
143        mock_udp
144    }
145}