nrf_softdevice/ble/
replies.rs1#[cfg(any(feature = "ble-sec", feature = "ble-gatt-server"))]
2use core::mem::ManuallyDrop;
3
4#[cfg(any(feature = "ble-sec", feature = "ble-gatt-server"))]
5use super::Connection;
6#[cfg(any(feature = "ble-sec", feature = "ble-gatt-server"))]
7use crate::{raw, RawError};
8
9#[cfg(feature = "ble-sec")]
10pub struct PasskeyReply {
11 conn: ManuallyDrop<Connection>,
12}
13
14#[cfg(feature = "ble-sec")]
15impl Drop for PasskeyReply {
16 fn drop(&mut self) {
17 if let Err(_err) = unsafe { self.finalize(None) } {
18 warn!("sd_ble_gap_auth_key_reply err {:?}", _err);
19 }
20 }
21}
22
23#[cfg(feature = "ble-sec")]
24impl PasskeyReply {
25 pub(crate) fn new(conn: Connection) -> Self {
26 Self {
27 conn: ManuallyDrop::new(conn),
28 }
29 }
30
31 pub fn reply(mut self, passkey: Option<&[u8; 6]>) -> Result<(), RawError> {
32 let res = unsafe { self.finalize(passkey) };
33 core::mem::forget(self); res
35 }
36
37 unsafe fn finalize(&mut self, passkey: Option<&[u8; 6]>) -> Result<(), RawError> {
41 let res = if let Some(conn_handle) = self.conn.handle() {
42 let ptr = passkey.map(|x| x.as_ptr()).unwrap_or(core::ptr::null());
43 let ret = raw::sd_ble_gap_auth_key_reply(conn_handle, raw::BLE_GAP_AUTH_KEY_TYPE_PASSKEY as u8, ptr);
44 RawError::convert(ret)
45 } else {
46 Err(RawError::InvalidState)
47 };
48
49 ManuallyDrop::drop(&mut self.conn);
51 res
52 }
53}
54
55#[cfg(feature = "ble-sec")]
56pub struct OutOfBandReply {
57 conn: ManuallyDrop<Connection>,
58}
59
60#[cfg(feature = "ble-sec")]
61impl Drop for OutOfBandReply {
62 fn drop(&mut self) {
63 if let Err(_err) = unsafe { self.finalize(None) } {
64 warn!("sd_ble_gap_auth_key_reply err {:?}", _err);
65 }
66 }
67}
68
69#[cfg(feature = "ble-sec")]
70impl OutOfBandReply {
71 pub(crate) fn new(conn: Connection) -> Self {
72 Self {
73 conn: ManuallyDrop::new(conn),
74 }
75 }
76
77 pub fn reply(mut self, oob: Option<&[u8; 16]>) -> Result<(), RawError> {
78 let res = unsafe { self.finalize(oob) };
79 core::mem::forget(self); res
81 }
82
83 unsafe fn finalize(&mut self, oob: Option<&[u8; 16]>) -> Result<(), RawError> {
87 let res = if let Some(conn_handle) = self.conn.handle() {
88 let ptr = oob.map(|x| x.as_ptr()).unwrap_or(core::ptr::null());
89 let ret = raw::sd_ble_gap_auth_key_reply(conn_handle, raw::BLE_GAP_AUTH_KEY_TYPE_OOB as u8, ptr);
90 RawError::convert(ret)
91 } else {
92 Err(RawError::InvalidState)
93 };
94
95 ManuallyDrop::drop(&mut self.conn);
97 res
98 }
99}
100
101#[cfg(feature = "ble-gatt-server")]
102const DEFERRED_TYPE_READ: u8 = raw::BLE_GATTS_AUTHORIZE_TYPE_READ as u8;
103#[cfg(feature = "ble-gatt-server")]
104const DEFERRED_TYPE_WRITE: u8 = raw::BLE_GATTS_AUTHORIZE_TYPE_WRITE as u8;
105
106#[cfg(feature = "ble-gatt-server")]
107struct DeferredReply<const DEFERRED_TYPE: u8> {
108 conn: ManuallyDrop<Connection>,
109}
110
111#[cfg(feature = "ble-gatt-server")]
112impl<const DEFERRED_TYPE: u8> Drop for DeferredReply<DEFERRED_TYPE> {
113 fn drop(&mut self) {
114 warn!("DeferredReply<{}> dropped without reply", DEFERRED_TYPE);
115 let res = unsafe { self.finalize(DEFERRED_TYPE, Err(super::GattError::ATTERR_ATTRIBUTE_NOT_FOUND)) };
116
117 if let Err(_err) = res {
118 warn!("sd_ble_gatts_rw_authorize_reply err {:?}", _err);
119 }
120 }
121}
122
123#[cfg(feature = "ble-gatt-server")]
124impl<const DEFERRED_TYPE: u8> DeferredReply<DEFERRED_TYPE> {
125 fn reply(mut self, res: Result<Option<&[u8]>, super::GattError>) -> Result<(), RawError> {
126 let res = unsafe { self.finalize(DEFERRED_TYPE, res) };
127 core::mem::forget(self);
128 res
129 }
130
131 unsafe fn finalize(
135 &mut self,
136 deferred_type: u8,
137 res: Result<Option<&[u8]>, super::GattError>,
138 ) -> Result<(), RawError> {
139 let (gatt_status, update, p_data, len) = match res {
140 Ok(Some(data)) => (super::GattStatus::SUCCESS, true, data.as_ptr(), data.len()),
141 Ok(None) => (super::GattStatus::SUCCESS, false, core::ptr::null(), 0),
142 Err(err) => (err.to_status(), false, core::ptr::null(), 0),
143 };
144
145 let res = if let Some(handle) = self.conn.handle() {
146 let params = raw::ble_gatts_authorize_params_t {
147 gatt_status: gatt_status.into(),
148 _bitfield_1: raw::ble_gatts_authorize_params_t::new_bitfield_1(u8::from(update)),
149 offset: 0,
150 len: len as u16,
151 p_data,
152 };
153
154 let reply_params = raw::ble_gatts_rw_authorize_reply_params_t {
155 type_: deferred_type,
156 params: raw::ble_gatts_rw_authorize_reply_params_t__bindgen_ty_1 { read: params },
157 };
158
159 let ret = raw::sd_ble_gatts_rw_authorize_reply(handle, &reply_params);
160 RawError::convert(ret)
161 } else {
162 Err(RawError::BleInvalidConnHandle)
163 };
164
165 ManuallyDrop::drop(&mut self.conn);
167 res
168 }
169}
170
171#[cfg(feature = "ble-gatt-server")]
172pub struct DeferredWriteReply(DeferredReply<DEFERRED_TYPE_WRITE>);
173
174#[cfg(feature = "ble-gatt-server")]
175impl DeferredWriteReply {
177 pub(crate) fn new(conn: Connection) -> Self {
178 DeferredWriteReply(DeferredReply {
179 conn: ManuallyDrop::new(conn),
180 })
181 }
182
183 pub fn conn(&self) -> &Connection {
184 &self.0.conn
185 }
186
187 pub fn reply(self, res: Result<&[u8], super::GattError>) -> Result<(), RawError> {
188 self.0.reply(res.map(Some))
189 }
190}
191
192#[cfg(feature = "ble-gatt-server")]
193pub struct DeferredReadReply(DeferredReply<DEFERRED_TYPE_READ>);
194
195#[cfg(feature = "ble-gatt-server")]
196impl DeferredReadReply {
198 pub(crate) fn new(conn: Connection) -> Self {
199 DeferredReadReply(DeferredReply {
200 conn: ManuallyDrop::new(conn),
201 })
202 }
203
204 pub fn conn(&self) -> &Connection {
205 &self.0.conn
206 }
207
208 pub fn reply(self, res: Result<Option<&[u8]>, super::GattError>) -> Result<(), RawError> {
212 self.0.reply(res)
213 }
214}