#coap

no-std coap-lite

A lightweight CoAP message manipulation crate, ideal for embedded environments

10 unstable releases (4 breaking)

new 0.5.0 Jul 19, 2021
0.4.1 Feb 25, 2021
0.3.5 Jan 19, 2021
0.3.2 Dec 6, 2020
0.1.0 Sep 8, 2019

#34 in Embedded development

Download history 24/week @ 2021-04-04 33/week @ 2021-04-11 28/week @ 2021-04-18 16/week @ 2021-04-25 12/week @ 2021-05-02 16/week @ 2021-05-09 20/week @ 2021-05-16 10/week @ 2021-05-23 12/week @ 2021-05-30 40/week @ 2021-06-06 23/week @ 2021-06-13 42/week @ 2021-06-20 41/week @ 2021-06-27 36/week @ 2021-07-04 89/week @ 2021-07-11 144/week @ 2021-07-18

126 downloads per month
Used in 2 crates

MIT/Apache

110KB
2.5K SLoC

coap-lite

Latest version Documentation License

A lightweight low-level CoAP message manipulation crate.

Its goal is to be compliant with the CoAP standards and to provide a building block for libraries (e.g. coap) and applications.

coap-lite supports #![no_std] and embedded environments.

It was originally based on the improved low-level message handling code from the coap crate as well as rust-async-coap, made to work in bare metal environments.

Supported RFCs

Usage

This crate provides several types that can be used to build, modify and encode/decode CoAP messages to/from their byte representation.

Note for no_std users: it does require allocation, so you might have to set a global allocator depending on your target.

Client

The following example uses std::net::UdpSocket to send the UDP packet but you can use anything, e.g. smoltcp for embedded.

use coap_lite::{
    CoapRequest, RequestType as Method
};
use std::net::{SocketAddr, UdpSocket};

fn main() {
    let mut request: CoapRequest<SocketAddr> = CoapRequest::new();

    request.set_method(Method::Get);
    request.set_path("/test");

    let socket = UdpSocket::bind("127.0.0.1:0").unwrap();

    let packet = request.message.to_bytes().unwrap();
    socket.send_to(&packet[..], "127.0.0.1:5683").expect("Could not send the data");
}

Server

use coap_lite::{CoapRequest, Packet};
use std::net::{UdpSocket};

fn main() {
    let socket = UdpSocket::bind("127.0.0.1:5683").unwrap();
    let mut buf = [0; 100];
    let (size, src) = socket.recv_from(&mut buf).expect("Didn't receive data");

    println!("Payload {:x?}", &buf[..size]);

    let packet = Packet::from_bytes(&buf[..size]).unwrap();
    let request = CoapRequest::from_packet(packet, src);

    let method = request.get_method().clone();
    let path = request.get_path();

    println!("Received CoAP request '{:?} {}' from {}", method, path, src);

    let mut response = request.response.unwrap();
    response.message.payload = b"OK".to_vec();

    let packet = response.message.to_bytes().unwrap();
    socket.send_to(&packet[..], &src).expect("Could not send the data");
}

Low-level binary conversion

use coap_lite::{
    CoapOption, MessageClass, MessageType,
    Packet, RequestType, ResponseType,
};

let mut request = Packet::new();
request.header.message_id = 23839;
request.header.code = MessageClass::Request(RequestType::Get);
request.set_token(vec![0, 0, 57, 116]);
request.add_option(CoapOption::UriHost, b"localhost".to_vec());
request.add_option(CoapOption::UriPath, b"tv1".to_vec());
assert_eq!(
    [
        0x44, 0x01, 0x5D, 0x1F, 0x00, 0x00, 0x39, 0x74, 0x39, 0x6C, 0x6F,
        0x63, 0x61, 0x6C, 0x68, 0x6F, 0x73, 0x74, 0x83, 0x74, 0x76, 0x31,
    ],
    request.to_bytes().unwrap()[..]
);

let response = Packet::from_bytes(&[
    0x64, 0x45, 0x5D, 0x1F, 0x00, 0x00, 0x39, 0x74, 0xFF, 0x48, 0x65,
    0x6C, 0x6C, 0x6F, 0x20, 0x57, 0x6F, 0x72, 0x6C, 0x64, 0x21,
])
.unwrap();
assert_eq!(23839, response.header.message_id);
assert_eq!(
    MessageClass::Response(ResponseType::Content),
    response.header.code
);
assert_eq!(MessageType::Acknowledgement, response.header.get_type());
assert_eq!([0, 0, 57, 116], response.get_token()[..]);
assert_eq!(b"Hello World!", &response.payload[..]);

License

Licensed under either of

at your option.

This is a modification of the coap and rust-async-coap crates, their licenses are in LICENSE-3RD-PARTY.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

Dependencies

~0–290KB