coap-zero 0.3.0

CoAP protocol implementation for no_std without alloc
Documentation
// Copyright Open Logistics Foundation
//
// Licensed under the Open Logistics Foundation License 1.3.
// For details on the licensing terms, see the LICENSE file.
// SPDX-License-Identifier: OLFL-1.3

//! Sends a ping (empty confirmable) requests to "coap://coap.me:5683/hello"
//! and decodes/prints the answer.

use std::{
    fs::File,
    io::Read,
    time::{Duration, SystemTime},
};

use embedded_timers::clock::{Clock, ClockError, Instant};

use coap_zero::endpoint::{outgoing::OutgoingEvent, CoapEndpoint, TransmissionParameters};
use std_embedded_nal::Stack;

#[derive(Debug)]
pub struct Random;

impl embedded_hal::blocking::rng::Read for Random {
    type Error = std::io::Error;

    fn read(&mut self, buf: &mut [u8]) -> Result<(), Self::Error> {
        File::open("/dev/urandom")?.read_exact(buf)
    }
}

#[derive(Debug)]
struct SystemClock;

impl Clock for SystemClock {
    fn try_now(&self) -> Result<Instant, ClockError> {
        Ok(SystemTime::now()
            .duration_since(SystemTime::UNIX_EPOCH)
            .unwrap())
    }
}

static CLOCK: SystemClock = SystemClock;

pub fn main() {
    simple_logger::SimpleLogger::new().env().init().unwrap();

    let mut stack = Stack::default();
    let mut receive_buffer = [0_u8; coap_zero::DEFAULT_COAP_MESSAGE_SIZE];

    let mut endpoint: CoapEndpoint<
        '_,
        Stack,
        Random,
        SystemClock,
        8,
        32,
        128,
        //{ coap_zero::DEFAULT_COAP_MESSAGE_SIZE },
    > = CoapEndpoint::try_new(
        TransmissionParameters::default(),
        Random {},
        &CLOCK,
        &mut receive_buffer,
    )
    .unwrap();

    endpoint
        .connect_to_url(&mut stack, "coap://coap.me:5683")
        .unwrap();

    println!();
    println!("Send Ping");
    println!();

    endpoint
        .outgoing()
        .schedule_ping(Duration::from_secs(5))
        .unwrap();

    loop {
        std::thread::sleep(Duration::from_millis(25));

        let (_incoming, outgoing, _endpoint) = endpoint.process(&mut stack).unwrap();

        use OutgoingEvent::*;
        match outgoing {
            Ok(Success(response)) => {
                assert!(response.is_rst().unwrap());
                println!("Successfully pinged");
                break;
            }
            Ok(Timeout) => {
                eprintln!("Server not reachable");
                break;
            }
            Ok(ev) => {
                println!("Other event: {ev:?}");
            }
            Err(e) => {
                println!("Warn: {e:?}");
                break;
            }
        }
    }
}