libcoap_rs/
transport.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
// SPDX-License-Identifier: BSD-2-Clause
/*
 * Copyright © The libcoap-rs Contributors, all rights reserved.
 * This file is part of the libcoap-rs project, see the README file for
 * general information on this project and the NOTICE.md and LICENSE files
 * for information regarding copyright ownership and terms of use.
 *
 * transport.rs - CoAP transports.
 */

use std::{net::SocketAddr, os::raw::c_uint};

use libcoap_sys::{
    coap_endpoint_set_default_mtu, coap_endpoint_t, coap_free_endpoint, coap_new_endpoint, coap_proto_t,
};

use crate::{error::EndpointCreationError, types::CoapAddress, CoapContext};

pub type EndpointMtu = c_uint;

#[derive(Debug)]
pub struct CoapEndpoint {
    raw_endpoint: *mut coap_endpoint_t,
}

/// Trait for functions common between all types of endpoints.
impl CoapEndpoint {
    /// Sets the default MTU value of the endpoint.
    pub fn set_default_mtu(&mut self, mtu: EndpointMtu) {
        // SAFETY: as_mut_raw_endpoint cannot fail and will always return a valid reference.
        // Modifying the state of the endpoint is also fine, because we have a mutable reference
        // of the whole endpoint.
        unsafe {
            coap_endpoint_set_default_mtu(&mut *self.raw_endpoint, mtu);
        }
    }

    /// Method utilized by transport protocol specific constructors to actually create the endpoint in libcoap
    pub(crate) fn new_endpoint(
        context: &mut CoapContext,
        addr: SocketAddr,
        proto: coap_proto_t,
    ) -> Result<Self, EndpointCreationError> {
        let endpoint = unsafe {
            // SAFETY: coap_new_endpoint will return null if it is unable to add new endpoint.
            // These states are processed further in the code
            coap_new_endpoint(
                context.as_mut_raw_context(),
                CoapAddress::from(addr).as_raw_address(),
                proto,
            )
        };

        if endpoint.is_null() {
            Err(EndpointCreationError::Unknown)
        } else {
            Ok(Self { raw_endpoint: endpoint })
        }
    }
}

impl Drop for CoapEndpoint {
    fn drop(&mut self) {
        // SAFETY: Raw endpoint is guaranteed to exist for as long as the container exists.
        unsafe { coap_free_endpoint(self.raw_endpoint) }
    }
}