imix/test/
udp_lowpan_test.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//! `udp_lowpan_test.rs`: Kernel test suite for the UDP/6LoWPAN stack
6//!
7//! This file tests port binding and sending and receiving messages from kernel space.
8//! It has several different test modes. Each test uses the same radio initialization code,
9//! but is started with a different function. A description of these tests and the expected output
10//! follows.
11//!
12//! To use this test suite, insert the below code into `boards/imix/src/main.rs` as follows:
13//!
14//!```rust
15//! let udp_lowpan_test = test::udp_lowpan_test::initialize_all(
16//!    udp_send_mux,
17//!     udp_recv_mux,
18//!     udp_port_table,
19//!     mux_alarm,
20//! );
21//! udp_lowpan_test.start();
22//!```
23//!
24//! Different Initialization functions (pick one):
25//!
26//! start(),
27//! instantiates two capsules that use the UDP stack, and tests various
28//! binding and sending orders to ensure that port binding and sending
29//! is enforced as expected.
30//! The messages sent are long enough to require multiple fragments. The payload of each message
31//! is all 0's.
32//!
33//! start_rx() runs a test where an app and a userspace capsule both verify correctness of port
34//! binding across userspace apps and capsules, and then both attempt UDP reception on
35//! different ports.
36//!
37//! start_with_app() tests port binding virtualization between both apps and capsules, and triggers
38//! simultaneous sends in apps and capsules to test queueing when both apps and capsules are used.
39//!
40//! start_dual_rx() tests multiple capsules attempting to bind to different ports and receive
41//! messages in quick succession, to test in-kernel distribution of received packets.
42//!
43//! Depending on the test you want to run, replace the call to start() with calls to
44//! start_rx(), start_dual_rx(), or start_with_app().
45//! Only one of these should be included at a time. Each is used for a different
46//! set of kernel tests, some of which require additional boards or that userland
47//! apps be flashed simultaneously.
48//!
49//! start() is an in-kernel only test. Its expected output follows:
50//!
51//! ```
52//! Running test 0:
53//! send_fail test passed
54//! Running test 1:
55//! port_table_test passed
56//! Running test 2:
57//! port_table_test2 passed
58//! Running test 3:
59//! send_test executed, look at printed results once callbacks arrive
60//! Mock UDP done sending. Result: Ok(())
61//!
62//! Mock UDP done sending. Result: Ok(())
63//!
64//! All UDP kernel tests complete.
65//! ```
66//!
67//! start_with_app() should be used alongside the userland app `examples/tests/udp/udp_virt_app_kernel`
68//!
69//! start_with_app() expected output:
70//!
71//! ```
72//! [UDP VIRT] Starting Kernel Coop UDP Test App.
73//! bind_test passed
74//! send_test executed, look at printed results once callbacks arrive
75//! Mock UDP done sending. Result: Ok(())
76//!
77//! Mock UDP done sending. Result: Ok(())
78//!
79//! App part of app/kernel test successful!
80//! ```
81//!
82//! start_rx() should be run alongside the userland app
83//! `examples/tests/udp/udp_virt_rx_tests/app1`. It also requires that a second board with the
84//! normal kernel (no tests) be running simultaneously with both userland apps in
85//! `examples/tests/udp/udp_virt_app_tests/` flashed on this second board. Press reset on the
86//! second board at least 2 seconds after running `tockloader listen` on the receiving board to run
87//! this test.
88//!
89//! start_rx() expected output:
90//!
91//! ```
92//! [UDP_RCV_APP1]: Rcvd UDP Packet from: 0001:0203:0405:0607:0809:0a0b:0c0d:0e0f : 26411
93//! Packet Payload: Hello World - App1
94//!
95//! [MOCK_UDP 1] Received packet from IPAddr([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]):22222, contents: [72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 32, 45, 32, 65, 112, 112, 50, 10]
96//!
97//! [UDP_RCV_APP1]: Rcvd UDP Packet from: 0001:0203:0405:0607:0809:0a0b:0c0d:0e0f : 20480
98//! Packet Payload: Hello World - App1
99//!
100//! [MOCK_UDP 1] Received packet from IPAddr([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]):81, contents: [72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 32, 45, 32, 65, 112, 112, 50, 10]
101//! ```
102//!
103//! start_dual_rx() has the same instructions as start_rx(), but it should be run with no userspace
104//! apps on the receiving board. This test also requires additional changes to main.rs --
105//! serial_num_bottom_16 must be replaced with 49138 for this to work. main.rs includes comments
106//! showing what should be included and excluded to run this final test. (Normally userspace apps
107//! would set the appropriate src mac address of the board under test, but for in-kernel only tests
108//! we do not currently expose this functionality to capsules).
109//!
110//! start_dual_rx() expected output:
111//!
112//! ```
113//![MOCK_UDP 1] Received packet from IPAddr([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]):11111, contents: [72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 32, 45, 32, 65, 112, 112, 49, 10]
114//!
115//! [MOCK_UDP 2] Received packet from IPAddr([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]):22222, contents: [72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 32, 45, 32, 65, 112, 112, 50, 10]
116//!
117//! [MOCK_UDP 1] Received packet from IPAddr([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]):80, contents: [72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 32, 45, 32, 65, 112, 112, 49, 10]
118//!
119//! [MOCK_UDP 2] Received packet from IPAddr([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]):81, contents: [72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 32, 45, 32, 65, 112, 112, 50, 10]
120//! ```
121
122use super::super::imix_components::test::mock_udp::MockUDPComponent;
123use crate::mock_udp_component_static;
124use capsules_core::virtualizers::virtual_alarm::{MuxAlarm, VirtualMuxAlarm};
125use capsules_extra::net::ipv6::ip_utils::IPAddr;
126use capsules_extra::net::ipv6::ipv6_send::IP6SendStruct;
127use capsules_extra::net::network_capabilities::{
128    AddrRange, NetworkCapability, PortRange, UdpVisibilityCapability,
129};
130use capsules_extra::net::udp::udp_port_table::UdpPortManager;
131use capsules_extra::net::udp::udp_recv::MuxUdpReceiver;
132use capsules_extra::net::udp::udp_send::MuxUdpSender;
133use capsules_extra::test::udp::MockUdp;
134use core::cell::Cell;
135use core::ptr::addr_of_mut;
136use kernel::capabilities::NetworkCapabilityCreationCapability;
137use kernel::component::Component;
138use kernel::create_capability;
139use kernel::debug;
140use kernel::hil::time::{self, Alarm, ConvertTicks};
141use kernel::static_init;
142use kernel::ErrorCode;
143
144pub const TEST_DELAY_MS: u32 = 2000;
145pub const TEST_LOOP: bool = false;
146static mut UDP_PAYLOAD: [u8; PAYLOAD_LEN] = [0; PAYLOAD_LEN]; //Becomes payload of UDP packet
147
148const UDP_HDR_SIZE: usize = 8;
149const PAYLOAD_LEN: usize = components::udp_mux::MAX_PAYLOAD_LEN;
150static mut UDP_PAYLOAD1: [u8; PAYLOAD_LEN - UDP_HDR_SIZE] = [0; PAYLOAD_LEN - UDP_HDR_SIZE];
151static mut UDP_PAYLOAD2: [u8; PAYLOAD_LEN - UDP_HDR_SIZE] = [0; PAYLOAD_LEN - UDP_HDR_SIZE];
152
153#[derive(Copy, Clone)]
154enum TestMode {
155    DefaultMode,
156    WithAppMode,
157    RxMode,
158    DualRxMode,
159}
160
161pub struct LowpanTest<'a, A: time::Alarm<'a>> {
162    alarm: &'a A,
163    test_counter: Cell<usize>,
164    port_table: &'static UdpPortManager,
165    mock_udp1: &'a MockUdp<'a, A>,
166    mock_udp2: &'a MockUdp<'a, A>,
167    test_mode: Cell<TestMode>,
168}
169
170pub unsafe fn initialize_all(
171    udp_send_mux: &'static MuxUdpSender<
172        'static,
173        IP6SendStruct<'static, VirtualMuxAlarm<'static, sam4l::ast::Ast<'static>>>,
174    >,
175    udp_recv_mux: &'static MuxUdpReceiver<'static>,
176    port_table: &'static UdpPortManager,
177    mux_alarm: &'static MuxAlarm<'static, sam4l::ast::Ast>,
178) -> &'static LowpanTest<
179    'static,
180    capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm<'static, sam4l::ast::Ast<'static>>,
181> {
182    let create_cap = create_capability!(NetworkCapabilityCreationCapability);
183    let net_cap = static_init!(
184        NetworkCapability,
185        NetworkCapability::new(AddrRange::Any, PortRange::Any, PortRange::Any, &create_cap)
186    );
187    let udp_vis = static_init!(
188        UdpVisibilityCapability,
189        UdpVisibilityCapability::new(&create_cap)
190    );
191    let mock_udp1 = MockUDPComponent::new(
192        udp_send_mux,
193        udp_recv_mux,
194        port_table,
195        mux_alarm,
196        &mut *addr_of_mut!(UDP_PAYLOAD1),
197        1, //id
198        3, //dst_port
199        net_cap,
200        udp_vis,
201    )
202    .finalize(mock_udp_component_static!());
203
204    let mock_udp2 = MockUDPComponent::new(
205        udp_send_mux,
206        udp_recv_mux,
207        port_table,
208        mux_alarm,
209        &mut *addr_of_mut!(UDP_PAYLOAD2),
210        2, //id
211        4, //dst_port
212        net_cap,
213        udp_vis,
214    )
215    .finalize(mock_udp_component_static!());
216
217    let alarm = static_init!(
218        VirtualMuxAlarm<'static, sam4l::ast::Ast>,
219        VirtualMuxAlarm::new(mux_alarm)
220    );
221    alarm.setup();
222
223    let udp_lowpan_test = static_init!(
224        LowpanTest<'static, VirtualMuxAlarm<'static, sam4l::ast::Ast>>,
225        LowpanTest::new(alarm, port_table, mock_udp1, mock_udp2,)
226    );
227
228    udp_lowpan_test.alarm.set_alarm_client(udp_lowpan_test);
229
230    udp_lowpan_test
231}
232
233impl<'a, A: time::Alarm<'a>> LowpanTest<'a, A> {
234    pub fn new(
235        alarm: &'a A,
236        port_table: &'static UdpPortManager,
237        mock_udp1: &'static MockUdp<'a, A>,
238        mock_udp2: &'static MockUdp<'a, A>,
239    ) -> LowpanTest<'a, A> {
240        LowpanTest {
241            alarm,
242            test_counter: Cell::new(0),
243            port_table,
244            mock_udp1,
245            mock_udp2,
246            test_mode: Cell::new(TestMode::DefaultMode),
247        }
248    }
249
250    pub fn start(&self) {
251        self.schedule_next();
252    }
253
254    pub fn start_with_app(&self) {
255        self.test_mode.set(TestMode::WithAppMode);
256        self.schedule_next();
257    }
258
259    pub fn start_rx(&self) {
260        self.test_mode.set(TestMode::RxMode);
261        self.schedule_next();
262    }
263
264    pub fn start_dual_rx(&self) {
265        self.test_mode.set(TestMode::DualRxMode);
266        self.schedule_next();
267    }
268
269    fn schedule_next(&self) {
270        let delta = self.alarm.ticks_from_ms(TEST_DELAY_MS);
271        let now = self.alarm.now();
272        self.alarm.set_alarm(now, delta);
273    }
274
275    fn run_test_and_increment(&self) {
276        let test_counter = self.test_counter.get();
277        self.run_test(test_counter);
278        match TEST_LOOP {
279            true => self.test_counter.set((test_counter + 1) % self.num_tests()),
280            false => self.test_counter.set(test_counter + 1),
281        }
282    }
283
284    fn num_tests(&self) -> usize {
285        10
286    }
287
288    fn run_test(&self, test_id: usize) {
289        match self.test_mode.get() {
290            TestMode::DefaultMode => {
291                if test_id < self.num_tests() {
292                    debug!("Running test {}:", test_id);
293                } else {
294                    debug!("All UDP kernel tests complete.");
295                }
296                match test_id {
297                    0 => self.capsule_send_fail(),
298                    1 => self.port_table_test(),
299                    2 => self.port_table_test2(),
300                    3 => self.capsule_send_test(),
301                    4 => self.addr_range_valid_test(),
302                    5 => self.port_range_valid_test(),
303                    6 => self.capsule_send_valid_net_cap_test(),
304                    7 => self.capsule_send_invalid_net_cap_port_test(),
305                    8 => self.capsule_send_invalid_net_cap_addr_test(),
306                    9 => self.capsule_send_invalid_net_cap_addr_port_test(),
307                    _ => return,
308                }
309            }
310            TestMode::RxMode => match test_id {
311                0 => self.capsule_receive_test(),
312                _ => return,
313            },
314            TestMode::DualRxMode => match test_id {
315                0 => self.capsule_dual_receive_test(),
316                _ => return,
317            },
318            TestMode::WithAppMode => match test_id {
319                0 => self.bind_test(),
320                1 => self.capsule_send_test(),
321                _ => return,
322            },
323        }
324        self.schedule_next();
325    }
326
327    // This test ensures that an app and capsule cant bind to the same port
328    // but can bind to different ports
329    fn bind_test(&self) {
330        let create_cap = create_capability!(NetworkCapabilityCreationCapability);
331        let net_cap = unsafe {
332            static_init!(
333                NetworkCapability,
334                NetworkCapability::new(AddrRange::Any, PortRange::Any, PortRange::Any, &create_cap)
335            )
336        };
337        let mut socket1 = self.port_table.create_socket().unwrap();
338        // Attempt to bind to a port that has already been bound by an app.
339        let result = self.port_table.bind(socket1, 1000, net_cap);
340        assert!(result.is_err());
341        socket1 = result.unwrap_err(); // Get the socket back
342
343        //now bind to an open port
344        let (_send_bind, _recv_bind) = self
345            .port_table
346            .bind(socket1, 1001, net_cap)
347            .expect("UDP Bind fail");
348        //dont unbind, so we can test if app will still be able to bind it
349
350        debug!("bind_test passed");
351    }
352
353    // A basic test of port table functionality without using any capsules at all,
354    // instead directly creating socket and calling bind/unbind.
355    // This test ensures that two capsules could not bind to the same port,
356    // that single bindings work correctly,
357    fn port_table_test(&self) {
358        let create_cap = create_capability!(NetworkCapabilityCreationCapability);
359        let net_cap = unsafe {
360            static_init!(
361                NetworkCapability,
362                NetworkCapability::new(AddrRange::Any, PortRange::Any, PortRange::Any, &create_cap)
363            )
364        };
365        // Initialize bindings.
366        let socket1 = self.port_table.create_socket().unwrap();
367        let mut socket2 = self.port_table.create_socket().unwrap();
368        let socket3 = self.port_table.create_socket().unwrap();
369        //debug!("Finished creating sockets");
370        // Attempt to bind to a port that has already been bound.
371        let (send_bind, recv_bind) = self
372            .port_table
373            .bind(socket1, 4000, net_cap)
374            .expect("UDP Bind fail1");
375        let result = self.port_table.bind(socket2, 4000, net_cap);
376        assert!(result.is_err());
377        socket2 = result.unwrap_err(); // This is how you get the socket back
378        let (send_bind2, recv_bind2) = self
379            .port_table
380            .bind(socket2, 4001, net_cap)
381            .expect("UDP Bind fail2");
382
383        // Ensure that only the first binding is able to send
384        assert_eq!(send_bind.get_port(), 4000);
385        assert_eq!(recv_bind.get_port(), 4000);
386        assert!(self.port_table.unbind(send_bind, recv_bind).is_ok());
387
388        // Show that you can bind to a port once another socket has unbound it
389        let (send_bind3, recv_bind3) = self
390            .port_table
391            .bind(socket3, 4000, net_cap)
392            .expect("UDP Bind fail3");
393
394        //clean up remaining bindings
395        assert!(self.port_table.unbind(send_bind3, recv_bind3).is_ok());
396        assert!(self.port_table.unbind(send_bind2, recv_bind2).is_ok());
397
398        debug!("port_table_test passed");
399    }
400
401    fn port_table_test2(&self) {
402        // Show that you can create up to 16 sockets before fail, but that destroying allows more
403        // (MAX_NUM_BOUND_PORTS is set to 16 in udp_port_table.rs)
404        {
405            let _socket1 = self.port_table.create_socket().unwrap();
406            let _socket2 = self.port_table.create_socket().unwrap();
407            let _socket3 = self.port_table.create_socket().unwrap();
408            let _socket4 = self.port_table.create_socket().unwrap();
409            let _socket5 = self.port_table.create_socket().unwrap();
410            let _socket6 = self.port_table.create_socket().unwrap();
411            let _socket7 = self.port_table.create_socket().unwrap();
412            let _socket8 = self.port_table.create_socket().unwrap();
413            let _socket9 = self.port_table.create_socket().unwrap();
414            let _socket10 = self.port_table.create_socket().unwrap();
415            let _socket11 = self.port_table.create_socket().unwrap();
416            let _socket12 = self.port_table.create_socket().unwrap();
417            let _socket13 = self.port_table.create_socket().unwrap();
418            let _socket14 = self.port_table.create_socket().unwrap();
419            let _socket15 = self.port_table.create_socket().unwrap();
420            let _socket16 = self.port_table.create_socket().unwrap();
421            let willfail = self.port_table.create_socket();
422            assert!(willfail.is_err());
423            // these sockets table slots are freed once they are dropped, so
424            // we can succeed again outside this block
425        }
426        let willsucceed = self.port_table.create_socket();
427        assert!(willsucceed.is_ok());
428
429        debug!("port_table_test2 passed");
430    }
431
432    fn capsule_send_fail(&self) {
433        let ret = self.mock_udp1.send(0);
434        assert!(ret != Ok(())); //trying to send while not bound should fail!
435
436        debug!("send_fail test passed")
437    }
438
439    fn capsule_send_test(&self) {
440        self.mock_udp1.bind(14000);
441        self.mock_udp1.set_dst(15000);
442        self.mock_udp2.bind(14001);
443        self.mock_udp2.set_dst(15001);
444        // Send from 2 different capsules in quick succession - second send should execute once
445        // first completes!
446        let _ = self.mock_udp1.send(22);
447        let _ = self.mock_udp2.send(23);
448
449        debug!("send_test executed, look at printed results once callbacks arrive");
450    }
451
452    fn capsule_app_send_test(&self) {
453        self.mock_udp1.bind(16124);
454        self.mock_udp1.set_dst(15000);
455        let _ = self.mock_udp1.send(22);
456
457        debug!("app/kernel send_test executed, look at printed results once callbacks arrive");
458    }
459
460    fn capsule_receive_test(&self) {
461        self.mock_udp1.bind(16124);
462    }
463
464    fn capsule_dual_receive_test(&self) {
465        self.mock_udp1.bind(16123);
466        self.mock_udp2.bind(16124);
467    }
468
469    // Test network capability enforcement for addrs
470    fn addr_range_valid_test(&self) {
471        let ip_addr1 = IPAddr([
472            0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
473            0x0e, 0x0f,
474        ]);
475        let ip_addr2 = IPAddr([
476            0x01, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
477            0x0e, 0x0f,
478        ]); // differs in first byte from ip_addr1
479        let ip_addr3 = IPAddr([
480            0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
481            0x0e, 0x00,
482        ]); // differs in last byte from ip_addr1
483            // Any
484        let any_addr = AddrRange::Any;
485        for ip_addr in [ip_addr1, ip_addr2, ip_addr3].iter() {
486            assert!(any_addr.is_addr_valid(*ip_addr))
487        }
488        // No addrs
489        let no_addrs = AddrRange::NoAddrs;
490        for ip_addr in [ip_addr1, ip_addr2, ip_addr3].iter() {
491            assert!(!no_addrs.is_addr_valid(*ip_addr))
492        }
493        let addr_set = AddrRange::AddrSet([
494            IPAddr::new(),
495            IPAddr::new(),
496            IPAddr::new(),
497            IPAddr::new(),
498            IPAddr::new(),
499            IPAddr::new(),
500            ip_addr3,
501            ip_addr1,
502        ]);
503        assert!(addr_set.is_addr_valid(ip_addr1));
504        assert!(!addr_set.is_addr_valid(ip_addr2));
505        assert!(addr_set.is_addr_valid(ip_addr3));
506        // Single addr
507        let single_addr = AddrRange::Addr(ip_addr1);
508        assert!(single_addr.is_addr_valid(ip_addr1));
509        assert!(!single_addr.is_addr_valid(ip_addr2));
510        // Subnet
511        let subnet = AddrRange::Subnet(ip_addr1, 120);
512        assert!(subnet.is_addr_valid(ip_addr1));
513        assert!(!subnet.is_addr_valid(ip_addr2));
514        assert!(subnet.is_addr_valid(ip_addr3));
515        debug!("AddrRange tests passed");
516    }
517
518    // Test enforcement for ports
519    fn port_range_valid_test(&self) {
520        // Any
521        let any_port = PortRange::Any;
522        assert!(any_port.is_port_valid(1000));
523        // No ports
524        let no_ports = PortRange::NoPorts;
525        assert!(!no_ports.is_port_valid(1000));
526        // Port set
527        let port_set = PortRange::PortSet([80, 22, 100, 200, 300, 400, 500, 8888]);
528        for port in [80, 22, 100, 200, 300, 400, 500, 8888].iter() {
529            assert!(port_set.is_port_valid(*port));
530        }
531        assert!(!port_set.is_port_valid(1000));
532        // Port range pair
533        let port_range = PortRange::Range(1000, 2000);
534        assert!(port_range.is_port_valid(1000));
535        assert!(port_range.is_port_valid(1500));
536        assert!(port_range.is_port_valid(2000));
537        assert!(!port_range.is_port_valid(2001));
538        assert!(!port_range.is_port_valid(900));
539        // Single port
540        let single_port = PortRange::Port(8888);
541        assert!(single_port.is_port_valid(8888));
542        assert!(!single_port.is_port_valid(8000));
543        debug!("PortRange tests passed");
544    }
545
546    fn capsule_send_net_cap_test(
547        &self,
548        net_cap1: &'static NetworkCapability,
549        net_cap2: &'static NetworkCapability,
550    ) -> (Result<(), ErrorCode>, Result<(), ErrorCode>) {
551        // from capsule send_test
552        self.mock_udp1.update_capability(net_cap1);
553        self.mock_udp1.bind(14000);
554        self.mock_udp1.set_dst(15000);
555        self.mock_udp2.update_capability(net_cap2);
556        self.mock_udp2.bind(14001);
557        self.mock_udp2.set_dst(15001);
558        // Send from 2 different capsules in quick succession - second send should execute once
559        // first completes, assuming valid capabilities for each.
560        let ret1 = self.mock_udp1.send(22);
561        let ret2 = self.mock_udp2.send(23);
562        debug!("send_test executed, look at printed results once callbacks arrive");
563        (ret1, ret2)
564    }
565
566    fn capsule_send_valid_net_cap_test(&self) {
567        let create_cap = create_capability!(NetworkCapabilityCreationCapability);
568        let net_cap1 = unsafe {
569            static_init!(
570                NetworkCapability,
571                NetworkCapability::new(
572                    AddrRange::Any,
573                    PortRange::Port(15000),
574                    PortRange::Any,
575                    &create_cap
576                )
577            )
578        };
579        let net_cap2 = unsafe {
580            static_init!(
581                NetworkCapability,
582                NetworkCapability::new(
583                    AddrRange::Any,
584                    PortRange::Port(15001),
585                    PortRange::Any,
586                    &create_cap
587                )
588            )
589        };
590        let (ret1, ret2) = self.capsule_send_net_cap_test(net_cap1, net_cap2);
591        assert_eq!(ret1, Ok(()));
592        assert_eq!(ret2, Ok(()));
593        debug!("send_valid_net_cap test executed, look at printed results once callbacks arrive");
594    }
595
596    // Invalid network capability (valid addr, invalid port)
597    fn capsule_send_invalid_net_cap_port_test(&self) {
598        let create_cap = create_capability!(NetworkCapabilityCreationCapability);
599        let net_cap1 = unsafe {
600            static_init!(
601                NetworkCapability,
602                NetworkCapability::new(
603                    AddrRange::Any,
604                    PortRange::Port(15000),
605                    PortRange::Any,
606                    &create_cap
607                )
608            )
609        };
610        // net_cap2 has an invalid dst port
611        let net_cap2 = unsafe {
612            static_init!(
613                NetworkCapability,
614                NetworkCapability::new(
615                    AddrRange::Any,
616                    PortRange::Port(15002),
617                    PortRange::Any,
618                    &create_cap
619                )
620            )
621        };
622        let (ret1, ret2) = self.capsule_send_net_cap_test(net_cap1, net_cap2);
623        assert_eq!(ret1, Ok(()));
624        assert_eq!(ret2, Err(ErrorCode::RESERVE));
625        debug!("send_invalid_net_cap_port test executed, expect one send with Result: Ok(())");
626    }
627
628    // Invalid network capability (invalid addr, valid port)
629    fn capsule_send_invalid_net_cap_addr_test(&self) {
630        let create_cap = create_capability!(NetworkCapabilityCreationCapability);
631        let net_cap1 = unsafe {
632            static_init!(
633                NetworkCapability,
634                NetworkCapability::new(AddrRange::Any, PortRange::Any, PortRange::Any, &create_cap)
635            )
636        };
637        // net_cap2 has an invalid address range
638        let net_cap2 = unsafe {
639            static_init!(
640                NetworkCapability,
641                NetworkCapability::new(
642                    AddrRange::NoAddrs,
643                    PortRange::Port(15000),
644                    PortRange::Any,
645                    &create_cap
646                )
647            )
648        };
649
650        let (ret1, ret2) = self.capsule_send_net_cap_test(net_cap1, net_cap2);
651        assert_eq!(ret1, Ok(()));
652        assert_eq!(ret2, Err(ErrorCode::RESERVE));
653        debug!("send_invalid_net_cap_addr executed, expect one send with Result: Ok(())");
654    }
655
656    // Invalid network capability (invalid addr, invalid port)
657    fn capsule_send_invalid_net_cap_addr_port_test(&self) {
658        let create_cap = create_capability!(NetworkCapabilityCreationCapability);
659        let net_cap1 = unsafe {
660            static_init!(
661                NetworkCapability,
662                NetworkCapability::new(
663                    AddrRange::Any,
664                    PortRange::Port(15000),
665                    PortRange::Any,
666                    &create_cap
667                )
668            )
669        };
670
671        // net_cap2 has an invalid address range and port
672        let net_cap2 = unsafe {
673            static_init!(
674                NetworkCapability,
675                NetworkCapability::new(
676                    AddrRange::NoAddrs,
677                    PortRange::Port(15002),
678                    PortRange::Any,
679                    &create_cap
680                )
681            )
682        };
683        let (ret1, ret2) = self.capsule_send_net_cap_test(net_cap1, net_cap2);
684        assert_eq!(ret1, Ok(()));
685        assert_eq!(ret2, Err(ErrorCode::RESERVE));
686        debug!("send_invalid_net_cap_addr_port test executed, expect one send with Result: Ok(())");
687    }
688}
689
690impl<'a, A: time::Alarm<'a>> time::AlarmClient for LowpanTest<'a, A> {
691    fn alarm(&self) {
692        self.run_test_and_increment();
693    }
694}