capsules_extra/net/udp/
udp_recv.rs
1use crate::net::ipv6::ip_utils::IPAddr;
16use crate::net::ipv6::ipv6_recv::IP6RecvClient;
17use crate::net::ipv6::IP6Header;
18use crate::net::udp::driver::UDPDriver;
19use crate::net::udp::udp_port_table::{PortQuery, UdpPortBindingRx};
20use crate::net::udp::UDPHeader;
21
22use kernel::collections::list::{List, ListLink, ListNode};
23use kernel::debug;
24use kernel::utilities::cells::{MapCell, OptionalCell};
25
26pub struct MuxUdpReceiver<'a> {
27 rcvr_list: List<'a, UDPReceiver<'a>>,
28 driver: OptionalCell<&'static UDPDriver<'static>>,
29}
30
31impl<'a> MuxUdpReceiver<'a> {
32 pub fn new() -> MuxUdpReceiver<'a> {
33 MuxUdpReceiver {
34 rcvr_list: List::new(),
35 driver: OptionalCell::empty(),
36 }
37 }
38
39 pub fn add_client(&self, rcvr: &'a UDPReceiver<'a>) {
40 self.rcvr_list.push_tail(rcvr);
41 }
42
43 pub fn set_driver(&self, driver_ref: &'static UDPDriver) {
44 self.driver.replace(driver_ref);
45 }
46}
47
48impl IP6RecvClient for MuxUdpReceiver<'_> {
49 fn receive(&self, ip_header: IP6Header, payload: &[u8]) {
50 if let Some((offset, udp_header)) = UDPHeader::decode(payload).done() {
51 let len = udp_header.get_len() as usize;
52 let dst_port = udp_header.get_dst_port();
53 if len > payload.len() {
54 debug!("[UDP_RECV] Error: Received UDP length too long");
55 return;
56 }
57 for rcvr in self.rcvr_list.iter() {
58 match rcvr.binding.take() {
59 Some(binding) => {
60 if binding.get_port() == dst_port {
61 rcvr.client.map(|client| {
62 client.receive(
63 ip_header.get_src_addr(),
64 ip_header.get_dst_addr(),
65 udp_header.get_src_port(),
66 udp_header.get_dst_port(),
67 &payload[offset..],
68 );
69 });
70 rcvr.binding.replace(binding);
71 break;
72 }
73 rcvr.binding.replace(binding);
74 }
75 None => {
77 if let Some(driver) = self.driver.take() {
78 if driver.is_bound(dst_port) {
79 driver.receive(
80 ip_header.get_src_addr(),
81 ip_header.get_dst_addr(),
82 udp_header.get_src_port(),
83 udp_header.get_dst_port(),
84 &payload[offset..],
85 );
86 self.driver.replace(driver);
87 break;
88 }
89 self.driver.replace(driver);
90 }
91 }
92 }
93 }
94 }
95 }
96}
97
98pub trait UDPRecvClient {
105 fn receive(
106 &self,
107 src_addr: IPAddr,
108 dst_addr: IPAddr,
109 src_port: u16,
110 dst_port: u16,
111 payload: &[u8],
112 );
113}
114
115pub struct UDPReceiver<'a> {
119 client: OptionalCell<&'a dyn UDPRecvClient>,
120 binding: MapCell<UdpPortBindingRx>,
121 next: ListLink<'a, UDPReceiver<'a>>,
122}
123
124impl<'a> ListNode<'a, UDPReceiver<'a>> for UDPReceiver<'a> {
125 fn next(&'a self) -> &'a ListLink<'a, UDPReceiver<'a>> {
126 &self.next
127 }
128}
129
130impl<'a> UDPReceiver<'a> {
131 pub fn new() -> UDPReceiver<'a> {
132 UDPReceiver {
133 client: OptionalCell::empty(),
134 binding: MapCell::empty(),
135 next: ListLink::empty(),
136 }
137 }
138
139 pub fn set_client(&self, client: &'a dyn UDPRecvClient) {
140 self.client.set(client);
141 }
142
143 pub fn get_binding(&self) -> Option<UdpPortBindingRx> {
144 self.binding.take()
145 }
146
147 pub fn is_bound(&self) -> bool {
148 self.binding.is_some()
149 }
150
151 pub fn set_binding(&self, binding: UdpPortBindingRx) -> Option<UdpPortBindingRx> {
152 self.binding.replace(binding)
153 }
154}