libcoap_rs/session/
server.rs1use std::cell::{Ref, RefMut};
11
12use libcoap_sys::{
13 coap_session_get_app_data, coap_session_get_type, coap_session_reference, coap_session_release,
14 coap_session_set_app_data, coap_session_t, coap_session_type_t,
15};
16
17use crate::mem::CoapFfiRcCell;
18use crate::mem::DropInnerExclusively;
19
20use super::{CoapSessionCommon, CoapSessionInner, CoapSessionInnerProvider};
21
22impl DropInnerExclusively for CoapServerSession<'_> {
23 fn drop_exclusively(self) {
24 let sess_ref = self.inner.clone();
25 std::mem::drop(self);
26 sess_ref.drop_exclusively();
27 }
28}
29
30#[derive(Debug, Clone)]
32pub struct CoapServerSession<'a> {
33 inner: CoapFfiRcCell<CoapServerSessionInner<'a>>,
37}
38
39#[derive(Debug)]
40struct CoapServerSessionInner<'a> {
42 inner: CoapSessionInner<'a>,
43}
44
45impl CoapServerSession<'_> {
46 pub(crate) unsafe fn initialize_raw<'a>(raw_session: *mut coap_session_t) -> CoapServerSession<'a> {
66 assert!(!raw_session.is_null(), "provided raw session was null");
67 let raw_session_type = coap_session_get_type(raw_session);
68 let inner = CoapSessionInner::new(raw_session);
69 let session_inner = match raw_session_type {
70 coap_session_type_t::COAP_SESSION_TYPE_NONE => panic!("provided session has no type"),
71 coap_session_type_t::COAP_SESSION_TYPE_CLIENT => {
72 panic!("attempted to create server session from raw client session")
73 },
74 coap_session_type_t::COAP_SESSION_TYPE_SERVER => CoapServerSessionInner { inner },
75 coap_session_type_t::COAP_SESSION_TYPE_HELLO => CoapServerSessionInner { inner },
76 _ => unreachable!("unknown session type"),
77 };
78 let session_ref = CoapFfiRcCell::new(session_inner);
79 coap_session_set_app_data(raw_session, session_ref.create_raw_weak());
80 coap_session_reference(raw_session);
83 CoapServerSession { inner: session_ref }
84 }
85
86 pub(crate) unsafe fn from_raw<'a>(raw_session: *mut coap_session_t) -> CoapServerSession<'a> {
102 assert!(!raw_session.is_null(), "provided raw session was null");
103 let raw_session_type = coap_session_get_type(raw_session);
104 match raw_session_type {
105 coap_session_type_t::COAP_SESSION_TYPE_NONE => panic!("provided session has no type"),
106 coap_session_type_t::COAP_SESSION_TYPE_SERVER | coap_session_type_t::COAP_SESSION_TYPE_HELLO => {
107 let raw_app_data_ptr = coap_session_get_app_data(raw_session);
108 assert!(!raw_app_data_ptr.is_null(), "provided raw session has no app data");
109 coap_session_reference(raw_session);
112 CoapServerSession {
113 inner: CoapFfiRcCell::clone_raw_rc(raw_app_data_ptr),
114 }
115 },
116 coap_session_type_t::COAP_SESSION_TYPE_CLIENT => {
117 panic!("attempted to create CoapServerSession from raw client session")
118 },
119 _ => unreachable!("unknown session type"),
120 }
121 }
122}
123
124impl<'a> Drop for CoapServerSession<'a> {
125 fn drop(&mut self) {
126 let raw_session = self.inner.borrow_mut().inner.raw_session;
127 unsafe {
129 coap_session_release(raw_session);
130 }
131 }
132}
133
134impl<'a> CoapSessionInnerProvider<'a> for CoapServerSession<'a> {
135 fn inner_ref<'b>(&'b self) -> Ref<'b, CoapSessionInner<'a>> {
136 Ref::map(self.inner.borrow(), |v| &v.inner)
137 }
138 fn inner_mut<'b>(&'b self) -> RefMut<'b, CoapSessionInner<'a>> {
139 RefMut::map(self.inner.borrow_mut(), |v| &mut v.inner)
140 }
141}
142
143impl<'a, T: CoapSessionCommon<'a>> PartialEq<T> for CoapServerSession<'_> {
144 fn eq(&self, other: &T) -> bool {
145 self.if_index() == other.if_index()
147 && unsafe { self.raw_session() == other.raw_session() }
148 && self.addr_local() == other.addr_local()
149 && self.addr_remote() == other.addr_remote()
150 }
151}
152
153impl Eq for CoapServerSession<'_> {}
154
155impl Drop for CoapServerSessionInner<'_> {
156 fn drop(&mut self) {
157 unsafe {
158 let app_data = coap_session_get_app_data(self.inner.raw_session);
159 assert!(!app_data.is_null());
160 std::mem::drop(CoapFfiRcCell::<CoapServerSessionInner>::raw_ptr_to_weak(app_data));
161 }
162 }
163}