1use capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm;
25use capsules_extra::net::ipv6::ip_utils::IPAddr;
26use capsules_extra::net::ipv6::ipv6_send::IP6SendStruct;
27use capsules_extra::net::network_capabilities::{
28 AddrRange, NetworkCapability, PortRange, UdpVisibilityCapability,
29};
30use capsules_extra::net::udp::udp_port_table::UdpPortManager;
31use capsules_extra::net::udp::udp_recv::MuxUdpReceiver;
32use capsules_extra::net::udp::udp_recv::UDPReceiver;
33use capsules_extra::net::udp::udp_send::{MuxUdpSender, UDPSendStruct, UDPSender};
34use core::mem::MaybeUninit;
35use kernel::capabilities;
36use kernel::capabilities::NetworkCapabilityCreationCapability;
37use kernel::component::Component;
38use kernel::create_capability;
39use kernel::hil::time::Alarm;
40
41const MAX_PAYLOAD_LEN: usize = super::udp_mux::MAX_PAYLOAD_LEN;
42
43#[macro_export]
45macro_rules! udp_driver_component_static {
46 ($A:ty $(,)?) => {{
47 use components::udp_mux::MAX_PAYLOAD_LEN;
48
49 let udp_send = kernel::static_buf!(
50 capsules_extra::net::udp::udp_send::UDPSendStruct<
51 'static,
52 capsules_extra::net::ipv6::ipv6_send::IP6SendStruct<
53 'static,
54 capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm<'static, $A>,
55 >,
56 >
57 );
58 let udp_vis_cap =
59 kernel::static_buf!(capsules_extra::net::network_capabilities::UdpVisibilityCapability);
60 let net_cap =
61 kernel::static_buf!(capsules_extra::net::network_capabilities::NetworkCapability);
62 let udp_driver = kernel::static_buf!(capsules_extra::net::udp::UDPDriver<'static>);
63 let buffer = kernel::static_buf!([u8; MAX_PAYLOAD_LEN]);
64 let udp_recv =
65 kernel::static_buf!(capsules_extra::net::udp::udp_recv::UDPReceiver<'static>);
66
67 (udp_send, udp_vis_cap, net_cap, udp_driver, buffer, udp_recv)
68 };};
69}
70
71pub struct UDPDriverComponent<A: Alarm<'static> + 'static> {
72 board_kernel: &'static kernel::Kernel,
73 driver_num: usize,
74 udp_send_mux:
75 &'static MuxUdpSender<'static, IP6SendStruct<'static, VirtualMuxAlarm<'static, A>>>,
76 udp_recv_mux: &'static MuxUdpReceiver<'static>,
77 port_table: &'static UdpPortManager,
78 interface_list: &'static [IPAddr],
79}
80
81impl<A: Alarm<'static>> UDPDriverComponent<A> {
82 pub fn new(
83 board_kernel: &'static kernel::Kernel,
84 driver_num: usize,
85 udp_send_mux: &'static MuxUdpSender<
86 'static,
87 IP6SendStruct<'static, VirtualMuxAlarm<'static, A>>,
88 >,
89 udp_recv_mux: &'static MuxUdpReceiver<'static>,
90 port_table: &'static UdpPortManager,
91 interface_list: &'static [IPAddr],
92 ) -> Self {
93 Self {
94 board_kernel,
95 driver_num,
96 udp_send_mux,
97 udp_recv_mux,
98 port_table,
99 interface_list,
100 }
101 }
102}
103
104impl<A: Alarm<'static>> Component for UDPDriverComponent<A> {
105 type StaticInput = (
106 &'static mut MaybeUninit<
107 UDPSendStruct<
108 'static,
109 capsules_extra::net::ipv6::ipv6_send::IP6SendStruct<
110 'static,
111 VirtualMuxAlarm<'static, A>,
112 >,
113 >,
114 >,
115 &'static mut MaybeUninit<
116 capsules_extra::net::network_capabilities::UdpVisibilityCapability,
117 >,
118 &'static mut MaybeUninit<capsules_extra::net::network_capabilities::NetworkCapability>,
119 &'static mut MaybeUninit<capsules_extra::net::udp::UDPDriver<'static>>,
120 &'static mut MaybeUninit<[u8; MAX_PAYLOAD_LEN]>,
121 &'static mut MaybeUninit<UDPReceiver<'static>>,
122 );
123 type Output = &'static capsules_extra::net::udp::UDPDriver<'static>;
124
125 fn finalize(self, s: Self::StaticInput) -> Self::Output {
126 let grant_cap = create_capability!(capabilities::MemoryAllocationCapability);
127 let create_cap = create_capability!(NetworkCapabilityCreationCapability);
129 let udp_vis = s.1.write(UdpVisibilityCapability::new(&create_cap));
130 let udp_send = s.0.write(UDPSendStruct::new(self.udp_send_mux, udp_vis));
131
132 struct DriverCap;
135 unsafe impl capabilities::UdpDriverCapability for DriverCap {}
136 static DRIVER_CAP: DriverCap = DriverCap;
137
138 let net_cap = s.2.write(NetworkCapability::new(
139 AddrRange::Any,
140 PortRange::Any,
141 PortRange::Any,
142 &create_cap,
143 ));
144
145 let buffer = s.4.write([0; MAX_PAYLOAD_LEN]);
146
147 let udp_driver = s.3.write(capsules_extra::net::udp::UDPDriver::new(
148 udp_send,
149 self.board_kernel.create_grant(self.driver_num, &grant_cap),
150 self.interface_list,
151 MAX_PAYLOAD_LEN,
152 self.port_table,
153 kernel::utilities::leasable_buffer::SubSliceMut::new(buffer),
154 &DRIVER_CAP,
155 net_cap,
156 ));
157 udp_send.set_client(udp_driver);
158 self.port_table.set_user_ports(udp_driver, &DRIVER_CAP);
159
160 let udp_driver_rcvr = s.5.write(UDPReceiver::new());
161 self.udp_recv_mux.set_driver(udp_driver);
162 self.udp_recv_mux.add_client(udp_driver_rcvr);
163 udp_driver
164 }
165}