//! [embedded_graphics] targets made available via CoAP
//!
//! TBD:
//!
//! * There is nothing RIOT specific about this; maybe there should be embedded-coap-demos?
//! * Anything but primitive ASCII uploads
use coap_message::{Code, MinimalWritableMessage, MutableWritableMessage, ReadableMessage};
use coap_message_utils::Error;
use embedded_graphics::pixelcolor::BinaryColor;
use embedded_graphics::prelude::*;
struct TargetWrapper<T: DrawTarget<BinaryColor>> {
target: T,
// if we could make this generic over color types (currenlty can't b/c how do we get from input
// to concrete values otherwise?), this'd need
// _phantom: core::marker::PhantomData<C>,
}
impl<T: DrawTarget<BinaryColor>> coap_handler::Handler for TargetWrapper<T> {
type RequestData = ();
type ExtractRequestError = Error;
type BuildResponseError<M: MinimalWritableMessage> = M::UnionError;
fn extract_request_data<M: ReadableMessage>(
&mut self,
request: &M,
) -> Result<Self::RequestData, Self::ExtractRequestError> {
// FIXME check code; error handling
let p = request.payload();
if p.len() == 25 {
for (line, linedata) in p.chunks_exact(5).enumerate() {
for (row, c) in linedata.iter().enumerate() {
Pixel(
Point::new(row as _, line as _),
match c {
0x20 => BinaryColor::Off,
_ => BinaryColor::On,
},
)
.draw(&mut self.target)
// FIXME do we get anythign better?
.map_err(|_| Error::internal_server_error())?;
}
}
Ok(())
} else {
// FIXME: Express "Not exactly 25 characters found" using problem details or diagnostic
// payload
Err(Error::internal_server_error())
}
}
fn estimate_length(&mut self, _request: &Self::RequestData) -> usize {
100 // worst case
}
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<T: DrawTarget<BinaryColor>>(target: T) -> impl coap_handler::Handler {
TargetWrapper { target }
}