riot_coap_handler_demos/
gpio.rsuse coap_message::{
Code, MinimalWritableMessage, MutableWritableMessage, OptionNumber, ReadableMessage,
};
use embedded_hal::digital::{InputPin, OutputPin};
use crate::common::ErrorDetail;
struct OutputWrapper<P: OutputPin>(P);
struct InputWrapper<P: InputPin>(P);
impl<P: InputPin> coap_handler::Handler for InputWrapper<P> {
type RequestData = ();
type ExtractRequestError = core::convert::Infallible;
type BuildResponseError<M: MinimalWritableMessage> = M::UnionError;
fn extract_request_data<M: ReadableMessage>(
&mut self,
_request: &M,
) -> Result<Self::RequestData, Self::ExtractRequestError> {
Ok(())
}
fn estimate_length(&mut self, _request: &Self::RequestData) -> usize {
3
}
fn build_response<M: MutableWritableMessage>(
&mut self,
response: &mut M,
_request: Self::RequestData,
) -> Result<(), M::UnionError> {
if let Ok(high) = self.0.is_high() {
response.set_code(Code::new(coap_numbers::code::CONTENT)?);
response.add_option_uint(
OptionNumber::new(coap_numbers::option::CONTENT_FORMAT)?,
60u8, )?;
response.set_payload(if high {
b"\xf5" } else {
b"\xf4" })?;
} else {
response.set_code(Code::new(coap_numbers::code::INTERNAL_SERVER_ERROR)?);
response.set_payload(b"GPIO read error")?;
}
Ok(())
}
}
impl<P: OutputPin> coap_handler::Handler for OutputWrapper<P> {
type RequestData = ();
type ExtractRequestError = ErrorDetail;
type BuildResponseError<M: MinimalWritableMessage> = M::UnionError;
fn extract_request_data<M: ReadableMessage>(&mut self, request: &M) -> Result<(), ErrorDetail> {
match request.payload() {
b"\xf5" => self.0.set_high().map_err(|_| ErrorDetail("Failure setting pin")),
b"\xf4" => self.0.set_low().map_err(|_| ErrorDetail("Failure setting pin")),
_ => Err(ErrorDetail("PUT value must be CBOR true or false")),
}
}
fn estimate_length(&mut self, _request: &Self::RequestData) -> usize {
4
}
fn build_response<M: MutableWritableMessage>(
&mut self,
response: &mut M,
_request: Self::RequestData,
) -> Result<(), M::UnionError> {
response.set_code(Code::new(coap_numbers::code::CHANGED)?);
Ok(())
}
}
pub fn handler_for_input<P: InputPin>(
pin: P,
) -> impl coap_handler::Handler + coap_handler::Reporting {
coap_handler_implementations::wkc::ConstantSingleRecordReport::new(
InputWrapper(pin),
&[coap_handler::Attribute::ResourceType(
"tag:chrysn@fsfe.org,2024-08-26:gpio",
)],
)
}
pub fn handler_for_output<P: OutputPin>(
pin: P,
) -> impl coap_handler::Handler + coap_handler::Reporting {
coap_handler_implementations::wkc::ConstantSingleRecordReport::new(
OutputWrapper(pin),
&[coap_handler::Attribute::ResourceType(
"tag:chrysn@fsfe.org,2024-08-26:gpio",
)],
)
}