summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlbert Skog <mail@albertskog.se>2021-09-30 15:07:45 +0200
committerAlbert Skog <mail@albertskog.se>2021-09-30 15:12:05 +0200
commit3b869f8e25ace92d4444a4ae3351c9cb10691060 (patch)
tree1a87a33f24aacfdb61c357b39559b314aef8a37b
parent71b9e4b3c20ac4fab0d14c4541b365ed48aab58b (diff)
downloadnrf-softdevice-3b869f8e25ace92d4444a4ae3351c9cb10691060.zip
add support for indications
-rw-r--r--nrf-softdevice-macro/src/lib.rs30
-rw-r--r--nrf-softdevice/src/ble/gatt_server.rs36
2 files changed, 66 insertions, 0 deletions
diff --git a/nrf-softdevice-macro/src/lib.rs b/nrf-softdevice-macro/src/lib.rs
index d2e4789..fad3e93 100644
--- a/nrf-softdevice-macro/src/lib.rs
+++ b/nrf-softdevice-macro/src/lib.rs
@@ -122,6 +122,7 @@ pub fn gatt_server(args: TokenStream, item: TokenStream) -> TokenStream {
let get_fn = format_ident!("{}_get", ch.name);
let set_fn = format_ident!("{}_set", ch.name);
let notify_fn = format_ident!("{}_notify", ch.name);
+ let indicate_fn = format_ident!("{}_indicate", ch.name);
let uuid = ch.args.uuid;
let read = ch.args.read;
@@ -226,6 +227,35 @@ pub fn gatt_server(args: TokenStream, item: TokenStream) -> TokenStream {
}
));
}
+ if indicate {
+ let case_enabled = format_ident!("{}IndicationsEnabled", name_pascal);
+ let case_disabled = format_ident!("{}IndicationsDisabled", name_pascal);
+
+ code_impl.extend(quote_spanned!(ch.span=>
+ fn #indicate_fn(
+ &self,
+ conn: &#ble::Connection,
+ val: #ty,
+ ) -> Result<(), #ble::gatt_server::IndicateValueError> {
+ let buf = #ty_as_val::to_gatt(&val);
+ #ble::gatt_server::indicate_value(conn, self.#value_handle, buf)
+ }
+ ));
+
+ code_event_enum.extend(quote_spanned!(ch.span=>
+ #case_enabled,
+ #case_disabled,
+ ));
+ code_on_write.extend(quote_spanned!(ch.span=>
+ if handle == self.#cccd_handle {
+ if data.len() != 0 && data[0] & 0x01 != 0 {
+ return Some(#event_enum_name::#case_enabled);
+ } else {
+ return Some(#event_enum_name::#case_disabled);
+ }
+ }
+ ));
+ }
}
let uuid = args.uuid;
diff --git a/nrf-softdevice/src/ble/gatt_server.rs b/nrf-softdevice/src/ble/gatt_server.rs
index 58663cc..d6d7f13 100644
--- a/nrf-softdevice/src/ble/gatt_server.rs
+++ b/nrf-softdevice/src/ble/gatt_server.rs
@@ -266,6 +266,42 @@ pub fn notify_value(conn: &Connection, handle: u16, val: &[u8]) -> Result<(), No
Ok(())
}
+#[derive(Debug, PartialEq, Eq, Clone, Copy)]
+#[cfg_attr(feature = "defmt", derive(defmt::Format))]
+pub enum IndicateValueError {
+ Disconnected,
+ Raw(RawError),
+}
+
+impl From<RawError> for IndicateValueError {
+ fn from(err: RawError) -> Self {
+ Self::Raw(err)
+ }
+}
+
+impl From<DisconnectedError> for IndicateValueError {
+ fn from(_: DisconnectedError) -> Self {
+ Self::Disconnected
+ }
+}
+
+pub fn indicate_value(conn: &Connection, handle: u16, val: &[u8]) -> Result<(), IndicateValueError> {
+ let conn_handle = conn.with_state(|state| state.check_connected())?;
+
+ let mut len: u16 = val.len() as _;
+ let params = raw::ble_gatts_hvx_params_t {
+ handle,
+ type_: raw::BLE_GATT_HVX_INDICATION as u8,
+ offset: 0,
+ p_data: val.as_ptr() as _,
+ p_len: &mut len,
+ };
+ let ret = unsafe { raw::sd_ble_gatts_hvx(conn_handle, &params) };
+ RawError::convert(ret)?;
+
+ Ok(())
+}
+
pub(crate) unsafe fn on_evt(ble_evt: *const raw::ble_evt_t) {
let gatts_evt = get_union_field(ble_evt, &(*ble_evt).evt.gatts_evt);
match (*ble_evt).header.evt_id as u32 {