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<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,
> = 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<CoapOption<'_>, { 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:?}");
}
}
}
}