1use crate::net::ipv6::ip_utils::IPAddr;
13use crate::net::network_capabilities::NetworkCapability;
14use crate::net::udp::udp_port_table::UdpPortManager;
15use crate::net::udp::udp_recv::{UDPReceiver, UDPRecvClient};
16use crate::net::udp::udp_send::{UDPSendClient, UDPSender};
17use core::cell::Cell;
18
19use kernel::debug;
20use kernel::hil::time::{self, Alarm, Frequency};
21use kernel::utilities::cells::MapCell;
22use kernel::utilities::leasable_buffer::SubSliceMut;
23use kernel::ErrorCode;
24
25pub const DST_ADDR: IPAddr = IPAddr([
26 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e,
27 0x1f,
28 ]);
31pub const PAYLOAD_LEN: usize = 192;
32pub const SEND_INTERVAL_SECONDS: u32 = 5;
33
34pub struct MockUdp<'a, A: Alarm<'a>> {
35 id: u16,
36 pub alarm: &'a A,
37 udp_sender: &'a dyn UDPSender<'a>,
38 udp_receiver: &'a UDPReceiver<'a>,
39 port_table: &'static UdpPortManager,
40 udp_dgram: MapCell<SubSliceMut<'static, u8>>,
41 src_port: Cell<u16>,
42 dst_port: Cell<u16>,
43 send_loop: Cell<bool>,
44 net_cap: Cell<&'static NetworkCapability>,
45}
46
47impl<'a, A: Alarm<'a>> MockUdp<'a, A> {
48 pub fn new(
49 id: u16,
50 alarm: &'a A,
51 udp_sender: &'a dyn UDPSender<'a>,
52 udp_receiver: &'a UDPReceiver<'a>,
53 port_table: &'static UdpPortManager,
54 udp_dgram: SubSliceMut<'static, u8>,
55 dst_port: u16,
56 net_cap: &'static NetworkCapability,
57 ) -> MockUdp<'a, A> {
58 MockUdp {
59 id,
60 alarm,
61 udp_sender,
62 udp_receiver,
63 port_table,
64 udp_dgram: MapCell::new(udp_dgram),
65 src_port: Cell::new(0), dst_port: Cell::new(dst_port),
67 send_loop: Cell::new(false),
68 net_cap: Cell::new(net_cap),
69 }
70 }
71
72 pub fn start_sending(&self) {
74 self.send_loop.set(true);
76 let delay = <A::Frequency>::frequency() * SEND_INTERVAL_SECONDS;
77 self.alarm
78 .set_alarm(self.alarm.now(), A::Ticks::from(delay));
79 }
80
81 pub fn update_capability(&self, new_cap: &'static NetworkCapability) {
82 self.net_cap.set(new_cap);
83 }
84
85 pub fn stop_sending(&self) {
86 let _ = self.alarm.disarm();
87 }
88
89 pub fn bind(&self, src_port: u16) {
92 self.src_port.set(src_port);
93 if self.udp_sender.is_bound() != self.udp_receiver.is_bound() {
94 debug!(
95 "Error: bindings should match. sender bound: {} rcvr bound: {}",
96 self.udp_sender.is_bound(),
97 self.udp_receiver.is_bound()
98 );
99 }
100 match self.udp_sender.is_bound() {
101 true => {
102 match self.port_table.unbind(
103 self.udp_sender.get_binding().expect("missing1"),
104 self.udp_receiver.get_binding().expect("missing2"),
105 ) {
106 Ok(sock) => {
107 match self
108 .port_table
109 .bind(sock, self.src_port.get(), self.net_cap.get())
110 {
111 Ok((send_bind, rcv_bind)) => {
112 debug!("Resetting binding"); self.udp_sender.set_binding(send_bind);
114 self.udp_receiver.set_binding(rcv_bind);
115 }
116 Err(_sock) => {
117 debug!("Binding error in mock_udp");
118 }
120 }
121 }
122 Err((_send_bind, _rcv_bind)) => {
123 debug!("TEST FAIL: attempted to unbind with mismatched bindings.");
124 }
125 }
126 }
127 false => {
128 let socket = self.port_table.create_socket();
130 match socket {
131 Ok(sock) => {
132 match self
133 .port_table
134 .bind(sock, self.src_port.get(), self.net_cap.get())
135 {
136 Ok((send_bind, rcv_bind)) => {
137 self.udp_sender.set_binding(send_bind);
138 self.udp_receiver.set_binding(rcv_bind);
139 }
140 Err(_sock) => {
141 debug!("Binding error in mock_udp (passed 0 as src_port?)");
142 }
144 }
145 }
146 Err(_return_code) => {
147 debug!("Socket error in mock_udp");
148 }
149 }
150 }
151 }
152 }
153
154 pub fn set_dst(&self, dst_port: u16) {
155 self.dst_port.set(dst_port);
156 }
157
158 pub fn send(&self, value: u16) -> Result<(), ErrorCode> {
160 match self.udp_dgram.take() {
161 Some(mut dgram) => {
162 dgram[0] = (value >> 8) as u8;
163 dgram[1] = (value & 0x00ff) as u8;
164 dgram.slice(0..2);
165 match self.udp_sender.send_to(
166 DST_ADDR,
167 self.dst_port.get(),
168 dgram,
169 self.net_cap.get(),
170 ) {
171 Ok(()) => Ok(()),
172 Err(mut buf) => {
173 buf.reset();
174 self.udp_dgram.replace(buf);
175 Err(ErrorCode::RESERVE)
176 }
177 }
178 }
179 None => {
180 debug!("ERROR: udp_dgram not present.");
181 Err(ErrorCode::FAIL)
182 }
183 }
184 }
185}
186
187impl<'a, A: Alarm<'a>> time::AlarmClient for MockUdp<'a, A> {
188 fn alarm(&self) {
189 if self.send_loop.get() {
190 let _ = self.send(self.id);
191 }
192 }
193}
194
195impl<'a, A: Alarm<'a>> UDPSendClient for MockUdp<'a, A> {
196 fn send_done(&self, result: Result<(), ErrorCode>, mut dgram: SubSliceMut<'static, u8>) {
197 debug!("Mock UDP done sending. Result: {:?}", result);
198 dgram.reset();
199 self.udp_dgram.replace(dgram);
200 debug!("");
201 let delay = <A::Frequency>::frequency() * SEND_INTERVAL_SECONDS;
202 self.alarm
203 .set_alarm(self.alarm.now(), A::Ticks::from(delay));
204 }
205}
206
207impl<'a, A: Alarm<'a>> UDPRecvClient for MockUdp<'a, A> {
208 fn receive(
209 &self,
210 src_addr: IPAddr,
211 _dst_addr: IPAddr,
212 src_port: u16,
213 _dst_port: u16,
214 payload: &[u8],
215 ) {
216 debug!(
217 "[MOCK_UDP {:?}] Received packet from {:?}:{:?}, contents: {:?}\n",
218 self.id, src_addr, src_port, payload
219 );
220 }
221}