pub fn full_application_tree(
    main_log: Option<&'static Log>
) -> impl Handler + Reporting
Expand description

Build a handler that contains all the demo applications

Note that no log::Log is created because that needs to be global, created-only-once and available as early in the application start-up as possible as per the log crate’s design; you’d have to pass one in if you want to view the log through CoAP.

The resources /message/info and /message/warn for creating log messages will be available independently thereof as long as the with-log feature is active.

Examples found in repository?
examples/std_embedded_nal_minicoapserver.rs (line 19)
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
fn run<S>(stack: &mut S)
where
    S: UdpFullStack,
{
    let mut sock = stack.socket().expect("Can't create a socket");

    let log = Some(coap_message_demos::log::Log::start_once());

    let mut handler = coap_message_demos::full_application_tree(log);

    stack.bind(&mut sock, 5683).expect("Can't bind to port");
    info!("Server is ready.");

    loop {
        match embedded_nal_minimal_coapserver::poll(stack, &mut sock, &mut handler) {
            Err(embedded_nal::nb::Error::WouldBlock) => {
                // See <https://github.com/rust-embedded-community/embedded-nal/issues/47>
                std::thread::sleep(std::time::Duration::from_millis(50));
            }
            e => e.expect("UDP error during send/receive"),
        }
    }
}
More examples
Hide additional examples
examples/std_embedded_nal_minicoaptcpserver.rs (line 17)
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
fn run<S>(stack: &mut S)
where
    S: embedded_nal::TcpFullStack + embedded_nal_tcpextensions::TcpExactStack,
{
    let mut sock = stack.socket().expect("Can't create a socket");

    let log = Some(coap_message_demos::log::Log::start_once());

    let mut handler = coap_message_demos::full_application_tree(log);

    stack.bind(&mut sock, 5683).expect("Can't bind to port");
    info!("Server is ready.");

    let mut pool = embedded_nal_minimal_coaptcpserver::ServerPool::<S, 4, 1152>::new(sock);

    loop {
        pool.poll(stack, &mut handler)
            .expect("Actual error in polling (accepting?)");
        // See <https://github.com/rust-embedded-community/embedded-nal/issues/47>
        std::thread::sleep(std::time::Duration::from_millis(50));
    }
}
examples/std_embedded_nal_coap.rs (line 20)
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
async fn run<S>(stack: &mut S)
where
    S: embedded_nal_async::UdpStack,
{
    let mut sock = stack
        .bind_multiple(embedded_nal_async::SocketAddr::new(
            "::".parse().unwrap(),
            5683,
        ))
        .await
        .expect("Can't create a socket");

    let log = Some(coap_message_demos::log::Log::start_once());

    let mut handler = coap_message_demos::full_application_tree(log);

    info!("Server is ready.");

    let coap = embedded_nal_coap::CoAPShared::<3>::new();
    let (client, server) = coap.split();

    // going with an embassy_futures join instead of an async_std::task::spawn b/c CoAPShared is not
    // Sync, and async_std expects to work in multiple threads
    embassy_futures::join::join(
        async {
            use rand::SeedableRng;
            server
                .run(
                    &mut sock,
                    &mut handler,
                    &mut rand::rngs::StdRng::from_entropy(),
                )
                .await
                .expect("UDP error")
        },
        run_client_operations(client)
    )
    .await;
}
examples/coaplite.rs (line 10)
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
fn main() {
    let log = Some(coap_message_demos::log::Log::start_once());

    let mut handler = coap_message_demos::full_application_tree(log);

    let socket = UdpSocket::bind("localhost:5683").unwrap();
    let mut buf = [0; 1280];

    loop {
        let (size, src) = socket.recv_from(&mut buf).expect("Didn't receive data");

        let packet = Packet::from_bytes(&buf[..size]).unwrap();
        let request = CoapRequest::from_packet(packet, src);

        let extracted = handler.extract_request_data(&request.message);

        let mut response = request.response.unwrap();
        match extracted {
            Ok(extracted) => {
                if let Err(e2) =
                    handler.build_response(&mut response.message, extracted)
                {
                    response.message.payload = Default::default();
                    response.message.clear_all_options();
                    e2.render(&mut response.message).unwrap();
                }
            }
            Err(e) => {
                e.render(&mut response.message).unwrap();
            }
        }

        let packet = response.message.to_bytes().unwrap();
        socket
            .send_to(&packet[..], &src)
            .expect("Could not send the data");
    }
}
examples/coap_crate.rs (line 26)
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
fn main() {
    let addr = "localhost:5683";

    let log = coap_message_demos::log::Log::start_once();

    Runtime::new().unwrap().block_on(async move {
        let server = Server::new_udp(addr).unwrap();
        println!("Server up on {}", addr);
        info!("Server up on {}", addr);

        use coap_handler::Handler;

        // Unlike in coap 0.11, the run closure is now Fn, so we can't have an exclusive reference
        // to a handler but need to fan out. To avoid the need for a mutex, we just use a handler
        // factory.
        //
        // Note that this may have "funny" effects w/rt the CBOR editable items, which are shared
        // only across handlers spawned from a single full_application_tree call.
        let handler = || coap_message_demos::full_application_tree(Some(log));

        server
            .run(
                move |mut request: Box<coap_lite::CoapRequest<std::net::SocketAddr>>| {
                    let mut handler = handler();

                    // We can just unwrap because the tokio based surver unwinds crashing handlers.
                    // We could still choose to rather render the errors, because a) it'd provide
                    // concrete information to the client and b) it sends a response instead of
                    // leaving the client hanging -- see the coap-lite example for how that is
                    // done.

                    let extracted = handler.extract_request_data(&request.message).unwrap();

                    if let Some(r) = request.response.as_mut() {
                        handler.build_response(&mut r.message, extracted).unwrap();
                    }

                    async { request }
                },
            )
            .await
            .unwrap();
    });
}