#coap #communication #no-alloc #no-std #lwm2m

no-std coap-zero

无alloc环境下的CoAP协议实现

1 个不稳定版本

0.3.0 2024年2月16日

#876嵌入式开发

OLFL-1.3

240KB
4.5K SLoC

coap-zero

此crate提供CoAP协议的无heap和无alloc实现。

它旨在尽可能实现零拷贝,同时不牺牲太多可用性。实现的CoAP端点实现了可靠消息传输的自动重传(对于可确认消息)和消息去重。端点自动响应特定消息,例如,在适当的时候发送重置消息,或者在检测到重复请求时重传最后响应。

实现固定为NSTART=1,即同时只能处理一个传入请求和一个传出请求。

目前,仅实现了基本CoAP规范。未来计划也支持CoAP Observe,这是LwM2M所必需的,以及PATCH、FETCH和iPATCH方法,这些方法显著提高了LwM2M的能力,以及LwM2M固件升级所需的分块传输。

资源

用法

主要结构是coap_zero::endpoint::CoapEndpoint类型。它通过一个embedded_nal::UdpClientStack(非所有者)管理与其他CoAP端点的连接。它包含两个独立的类型,OutgoingCommunicationIncomingCommunication,以分别处理两个通信路径。

所有操作都由内部状态机驱动。因此,所有调用都是非阻塞的,用户必须重复调用CoapEndpoint::process方法以发送/接收CoAP消息。每当状态机取得进展时,就会返回相应的事件。一些事件必须由用户处理,以避免陷入特定的等待状态。例如,必须由用户响应传入的请求,尽管这个决定可能被推迟或涉及发送重置消息。

如果只需要消息解析,可以使用消息子模块。

用法示例

有关更详细的示例,请参阅示例文件夹中的示例。

static CLOCK: SystemClock = SystemClock;

let mut stack = Stack;
let mut receive_buffer = [0_u8; coap_zero::DEFAULT_COAP_MESSAGE_SIZE];

let mut endpoint: CoapEndpoint<'_, Stack, Rng, SystemClock> = CoapEndpoint::try_new(
    TransmissionParameters::default(),
    Rng,
    &CLOCK,
    &mut receive_buffer,
)
.unwrap();

endpoint
    .connect_to_url(&mut stack, "coap://coap.me:5683")
    .unwrap();

let outgoing = endpoint.outgoing();
outgoing
    .schedule_con(
        RequestCode::Get,
        outgoing
            .parse_options("coap://coap.me:5683/hello", Vec::new())
            .unwrap(),
        None,
        Duration::from_secs(5),
    )
    .unwrap();

loop {
    let (incoming_event, outgoing_event, endpoint_event) =
        endpoint.process(&mut stack).unwrap();

    match incoming_event.unwrap() {
        IncomingEvent::Nothing => {
            // Whenever nothing else happens, the Nothing event is generated. Ignore it
            // silently.
        }
        IncomingEvent::Request(_confirmable, _message) => {
            // Handle request
        }
        event => println!("Other incoming event: {event:?}"),
    }

    match outgoing_event.unwrap() {
        OutgoingEvent::Nothing => {}
        OutgoingEvent::Success(response) => println!("Request succeeded: {response:?}"),
        OutgoingEvent::Timeout
        | OutgoingEvent::PiggybackedWrongToken
        | OutgoingEvent::ResetReceived => {
            println!("Request failed");
        }
        event => println!("Other outgoing event: {event:?}"),
    }

    match endpoint_event {
        EndpointEvent::Nothing => {}
        EndpointEvent::MsgFormatErr(_err) => {
            // A message format error was detected. This is reported as an event instead of
            // an error because it is caused by the other endpoint.
            println!("endpoint event MsgFormatErr");
        }
        EndpointEvent::Ping => {
            println!("A ping has been received and a response has been sent");
        }
        EndpointEvent::Unhandled(message) => {
            println!("Unhandled message received: {message:?}");
        }
    }

}

示例

提供了多个示例。它们使用coap.me作为coap测试服务器。lwm2m示例展示了在轻量级m2m环境中使用Leshan公共测试服务器的用法。

  • ping - 发送ping并在接收到预期重置时终止
  • simple_get - 发送CON Get并接收附带响应
  • get_separate_response - 发送CON Get并接收单独响应
  • lwm2m - 注册到Leshan服务器并提供当前时间资源对象。注册不会更新,将在120秒后静默关闭。

许可证

开放物流基金会许可证
版本1.3,2023年1月

请参阅顶级目录中的LICENSE文件。

联系

弗劳恩霍夫IML嵌入式Rust小组 - [email protected]

依赖关系

~3MB
~62K SLoC