libcoap_rs/
event.rs

1// SPDX-License-Identifier: BSD-2-Clause
2/*
3 * Copyright © The libcoap-rs Contributors, all rights reserved.
4 * This file is part of the libcoap-rs project, see the README file for
5 * general information on this project and the NOTICE.md and LICENSE files
6 * for information regarding copyright ownership and terms of use.
7 *
8 * event.rs - Event handling traits and logic for the libcoap Rust wrapper.
9 */
10
11//! Event handling-related code
12
13use std::fmt::Debug;
14
15use libcoap_sys::{
16    coap_event_t, coap_event_t_COAP_EVENT_SERVER_SESSION_NEW, coap_event_t_COAP_EVENT_TCP_CONNECTED,
17    coap_session_get_context, coap_session_get_type, coap_session_t, coap_session_type_t_COAP_SESSION_TYPE_SERVER,
18};
19
20use crate::{
21    context::CoapContext,
22    session::{CoapServerSession, CoapSession},
23};
24
25/// Trait for CoAP event handlers.
26///
27/// Implementations of this trait can be provided to a [CoapContext] to handle various events relating
28/// to sessions.
29///
30/// This is the equivalent to the [libcoap `coap_event_handler_t` type](https://libcoap.net/doc/reference/develop/group__events.html#ga5d57fba7df54eae6f8cb3a47a4cb3569).
31pub trait CoapEventHandler: Debug {
32    /// Handle a DTLS connected event.
33    ///
34    /// This event is triggered when a DTLS session switches to the connected state.
35    #[allow(unused_variables)]
36    fn handle_dtls_connected(&mut self, session: &mut CoapSession) {}
37
38    /// Handle a DTLS closed event.
39    ///
40    /// This event is triggered when a DTLS session is closed.
41    #[allow(unused_variables)]
42    fn handle_dtls_closed(&mut self, session: &mut CoapSession) {}
43
44    /// Handle a DTLS renegotiation event.
45    ///
46    /// This event is triggered when a DTLS renegotiation occurs.
47    #[allow(unused_variables)]
48    fn handle_dtls_renegotiate(&mut self, session: &mut CoapSession) {}
49
50    /// Handle a DTLS error event.
51    ///
52    /// This event is triggered when a DTLS error occurs.
53    #[allow(unused_variables)]
54    fn handle_dtls_error(&mut self, session: &mut CoapSession) {}
55
56    /// Handle a TCP connected event.
57    ///
58    /// This event is triggered when a new TCP connection is established.
59    #[allow(unused_variables)]
60    fn handle_tcp_connected(&mut self, session: &mut CoapSession) {}
61
62    /// Handle a TCP closed event.
63    ///
64    /// This event is triggered when a new TCP connection is closed.
65    #[allow(unused_variables)]
66    fn handle_tcp_closed(&mut self, session: &mut CoapSession) {}
67
68    /// Handle a TCP failed event.
69    #[allow(unused_variables)]
70    fn handle_tcp_failed(&mut self, session: &mut CoapSession) {}
71
72    /// Handle a session connected event.
73    ///
74    /// This event is triggered by CSM exchanges only when reliable protocols are used.
75    #[allow(unused_variables)]
76    fn handle_session_connected(&mut self, session: &mut CoapSession) {}
77
78    /// Handle a session closed event.
79    ///
80    /// This event is triggered by CSM exchanges only when reliable protocols are used.
81    #[allow(unused_variables)]
82    fn handle_session_closed(&mut self, session: &mut CoapSession) {}
83
84    /// Handle a session failed event.
85    ///
86    /// This event is triggered by CSM exchanges only when reliable protocols are used.
87    #[allow(unused_variables)]
88    fn handle_session_failed(&mut self, session: &mut CoapSession) {}
89
90    /// Handle a partially received message.
91    #[allow(unused_variables)]
92    fn handle_partial_block(&mut self, session: &mut CoapSession) {}
93
94    /// Handle a failure to transmit a block.
95    #[allow(unused_variables)]
96    fn handle_xmit_block_fail(&mut self, session: &mut CoapSession) {}
97
98    /// Handle the creation of a new server-side session.
99    ///
100    /// This event is called inside the IO loop when a new server-side session is created.
101    #[allow(unused_variables)]
102    fn handle_server_session_new(&mut self, session: &mut CoapServerSession) {}
103
104    /// Handle the deletion of a server-side session.
105    ///
106    /// This event is called inside of the IO loop when a server-side session is deleted.
107    /// This can happen for a number of reasons:
108    /// - The session has been idle for too long (see [CoapContext::session_timeout()] and
109    ///   [CoapContext::set_session_timeout()])
110    /// - The maximum number of handshaking sessions is exceeded (see
111    ///   [CoapContext::max_handshake_sessions()] and [CoapContext::set_max_handshake_sessions()])
112    /// - The maximum number of idle sessions is exceeded (see
113    ///   [CoapContext::max_idle_sessions()] and [CoapContext::set_max_idle_sessions()])
114    #[allow(unused_variables)]
115    fn handle_server_session_del(&mut self, session: &mut CoapServerSession) {}
116
117    /// Handle the receival of a badly formatted packet.
118    ///
119    /// Note that this only refers to packets that can't be parsed by libcoap, i.e. valid packets
120    /// that have some semantic issues and therefore can't be parsed into a request or response
121    /// object do not trigger this event.
122    #[allow(unused_variables)]
123    fn handle_bad_packet(&mut self, session: &mut CoapSession) {}
124
125    /// Handle a retransmission event.
126    #[allow(unused_variables)]
127    fn handle_msg_retransmitted(&mut self, session: &mut CoapSession) {}
128
129    /// Handle an OSCORE decryption failure event.
130    #[allow(unused_variables)]
131    fn handle_oscore_decryption_failure(&mut self, session: &mut CoapSession) {}
132
133    /// Handle an OSCORE not enabled event.
134    #[allow(unused_variables)]
135    fn handle_oscore_not_enabled(&mut self, session: &mut CoapSession) {}
136
137    /// Handle an OSCORE no protected payload provided event.
138    #[allow(unused_variables)]
139    fn handle_oscore_no_protected_payload(&mut self, session: &mut CoapSession) {}
140
141    /// Handle an OSCORE no security definition found event.
142    #[allow(unused_variables)]
143    fn handle_oscore_no_security(&mut self, session: &mut CoapSession) {}
144
145    /// Handle an OSCORE internal error.
146    #[allow(unused_variables)]
147    fn handle_oscore_internal_error(&mut self, session: &mut CoapSession) {}
148
149    /// Handle a decoding error when parsing OSCORE options.
150    #[allow(unused_variables)]
151    fn handle_oscore_decode_error(&mut self, session: &mut CoapSession) {}
152
153    /// Handle an oversized WebSocket packet event.
154    #[allow(unused_variables)]
155    fn handle_ws_packet_size(&mut self, session: &mut CoapSession) {}
156
157    /// Handle a WebSocket layer up event.
158    #[allow(unused_variables)]
159    fn handle_ws_connected(&mut self, session: &mut CoapSession) {}
160
161    /// Handle a WebSocket layer closed event.
162
163    #[allow(unused_variables)]
164    fn handle_ws_closed(&mut self, session: &mut CoapSession) {}
165
166    /// Handle a failure to perform a keepalive (no response to keepalive packet)
167    #[allow(unused_variables)]
168    fn handle_keepalive_failure(&mut self, session: &mut CoapSession) {}
169}
170
171// This should be fine as we don't provide this type to an FFI function, we only read from it.
172#[allow(improper_ctypes_definitions)]
173pub(crate) unsafe extern "C" fn event_handler_callback(raw_session: *mut coap_session_t, event: coap_event_t) -> i32 {
174    let raw_session_type = coap_session_get_type(raw_session);
175
176    let session: CoapSession = if event == coap_event_t_COAP_EVENT_SERVER_SESSION_NEW
177        || (event == coap_event_t_COAP_EVENT_TCP_CONNECTED
178            && raw_session_type == coap_session_type_t_COAP_SESSION_TYPE_SERVER)
179    {
180        CoapServerSession::initialize_raw(raw_session).into()
181    } else {
182        CoapSession::from_raw(raw_session)
183    };
184
185    // SAFETY: Pointer is always valid as long as there is no bug in libcoap.
186    let context = CoapContext::from_raw(coap_session_get_context(raw_session));
187    context.handle_event(session, event);
188    0
189}