// 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 two CONfirmable GET requests to "coap://coap.me:5683/separate" //! and decodes/prints the answer. use std::{ fs::File, io::Read, time::{Duration, SystemTime}, }; use embedded_timers::clock::{Clock, ClockError, Instant}; use try_ascii::try_ascii; use coap_zero::{ endpoint::CoapEndpoint, endpoint::{outgoing::OutgoingEvent, TransmissionParameters}, message::{ codes::RequestCode, options::{CoapOption, CoapOptionName}, Message, }, }; use heapless::Vec; 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 { 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(); let uri_path = CoapOption { name: CoapOptionName::UriPath, value: b"separate", }; let mut options_vec: heapless::Vec, { coap_zero::DEFAULT_MAX_OPTION_COUNT }> = heapless::Vec::new(); options_vec.push(uri_path).unwrap(); println!(); println!("Send Confirmable from constructed Message"); println!(); endpoint .outgoing() .schedule_con(RequestCode::Get, options_vec, None, Duration::from_secs(10)) .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)) => { let decoded_message: Message<'_, { coap_zero::DEFAULT_MAX_OPTION_COUNT }> = Message::try_from(response).unwrap(); println!("DecodedMessage: {decoded_message:?}"); if let Some(payload) = decoded_message.payload() { println!("Payload Length: {}", payload.len()); println!("Payload: \"{:?}\"", try_ascii(payload)); } break; } Ok(Nothing) => {} Ok(AckReceived) => { println!("ACK received"); } Ok(ev) => { println!("Other event: {ev:?}"); } Err(e) => { println!("Warn: {e:?}"); } } } println!(); println!("Send Confirmable from URI"); println!(); let outgoing = endpoint.outgoing(); outgoing .schedule_con( RequestCode::Get, outgoing .parse_options("coap://coap.me:5683/separate", Vec::new()) .unwrap(), None, Duration::from_secs(10), ) .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)) => { let decoded_message: Message<'_, { coap_zero::DEFAULT_MAX_OPTION_COUNT }> = Message::try_from(response).unwrap(); println!("DecodedMessage: {decoded_message:?}"); if let Some(payload) = decoded_message.payload() { println!("Payload Length: {}", payload.len()); println!("Payload: \"{:?}\"", try_ascii(payload)); } break; } Ok(Nothing) => {} Ok(AckReceived) => { println!("ACK received"); } Ok(ev) => { println!("Other event: {ev:?}"); } Err(e) => { println!("Warn: {e:?}"); } } } }