Loading system/rust/src/gatt/callbacks.rs +23 −1 Original line number Diff line number Diff line Loading @@ -8,7 +8,7 @@ pub use callback_transaction_manager::{CallbackResponseError, CallbackTransactio use async_trait::async_trait; use crate::packets::{AttAttributeDataChild, AttErrorCode}; use crate::packets::{AttAttributeDataChild, AttAttributeDataView, AttErrorCode}; use super::ids::{AttHandle, ConnectionId, TransactionId}; Loading @@ -25,6 +25,20 @@ pub trait GattCallbacks { offset: u32, is_long: bool, ); /// Invoked when a client tries to write a characteristic. Expects a /// response using bluetooth::gatt::send_response(); #[allow(clippy::too_many_arguments)] // needed to match the C++ interface fn on_server_write_characteristic( &self, conn_id: ConnectionId, trans_id: TransactionId, handle: AttHandle, offset: u32, need_response: bool, is_prepare: bool, value: AttAttributeDataView, ); } /// This interface is an "async" version of the above, and is passed directly Loading @@ -44,4 +58,12 @@ pub trait GattDatastore { conn_id: ConnectionId, handle: AttHandle, ) -> Result<AttAttributeDataChild, AttErrorCode>; /// Write data to a given characteristic on the specified connection. async fn write_characteristic( &self, conn_id: ConnectionId, handle: AttHandle, data: AttAttributeDataView<'_>, ) -> Result<(), AttErrorCode>; } system/rust/src/gatt/callbacks/callback_transaction_manager.rs +22 −1 Original line number Diff line number Diff line Loading @@ -9,7 +9,7 @@ use crate::{ ids::{AttHandle, ConnectionId, TransactionId}, GattCallbacks, }, packets::{AttAttributeDataChild, AttErrorCode}, packets::{AttAttributeDataChild, AttAttributeDataView, AttErrorCode}, }; use super::GattDatastore; Loading Loading @@ -138,4 +138,25 @@ impl GattDatastore for CallbackTransactionManager { Err(AttErrorCode::UNLIKELY_ERROR) } } async fn write_characteristic( &self, conn_id: ConnectionId, handle: AttHandle, data: AttAttributeDataView<'_>, ) -> Result<(), AttErrorCode> { let (trans_id, rx) = self.pending_transactions.borrow_mut().start_new_transaction(conn_id)?; self.callbacks .on_server_write_characteristic(conn_id, trans_id, handle, 0, true, false, data); if let Ok(value) = rx.await { value.map(|_| ()) // the data passed back is irrelevant for write // requests } else { warn!("sender side of {trans_id:?} dropped while handling request - most likely this response will not be sent over the air"); Err(AttErrorCode::UNLIKELY_ERROR) } } } system/rust/src/gatt/ffi.rs +39 −1 Original line number Diff line number Diff line Loading @@ -11,7 +11,10 @@ use log::{error, info, warn}; use crate::{ do_in_rust_thread, packets::{AttAttributeDataChild, AttBuilder, AttErrorCode, Serializable, SerializeError}, packets::{ AttAttributeDataChild, AttAttributeDataView, AttBuilder, AttErrorCode, Serializable, SerializeError, }, }; use super::{ Loading Loading @@ -54,6 +57,20 @@ mod inner { offset: u32, is_long: bool, ); /// This callback is invoked when writing a characteristic - the client /// must reply using SendResponse #[cxx_name = "OnServerWriteCharacteristic"] fn on_server_write_characteristic( self: &GattServerCallbacks, conn_id: u16, trans_id: u32, attr_handle: u16, offset: u32, need_response: bool, is_prepare: bool, value: &[u8], ); } /// What action the arbiter should take in response to an incoming packet Loading Loading @@ -143,6 +160,27 @@ impl GattCallbacks for GattCallbacksImpl { .unwrap() .on_server_read_characteristic(conn_id.0, trans_id.0, handle.0, offset, is_long); } fn on_server_write_characteristic( &self, conn_id: ConnectionId, trans_id: TransactionId, handle: AttHandle, offset: u32, need_response: bool, is_prepare: bool, value: AttAttributeDataView, ) { self.0.as_ref().unwrap().on_server_write_characteristic( conn_id.0, trans_id.0, handle.0, offset, need_response, is_prepare, &value.get_raw_payload().collect::<Vec<_>>(), ); } } /// Implementation of AttTransport wrapping the corresponding C++ method Loading system/rust/src/gatt/ffi/gatt_shim.cc +22 −0 Original line number Diff line number Diff line Loading @@ -69,5 +69,27 @@ void GattServerCallbacks::OnServerReadCharacteristic(uint16_t conn_id, addr.value(), attr_handle, offset, is_long)); } void GattServerCallbacks::OnServerWriteCharacteristic( uint16_t conn_id, uint32_t trans_id, uint16_t attr_handle, uint32_t offset, bool need_response, bool is_prepare, ::rust::Slice<const uint8_t> value) const { auto addr = AddressOfConnection(conn_id); if (!addr.has_value()) { LOG_WARN( "Dropping server write characteristic since connection %d not found", conn_id); return; } auto buf = new uint8_t[value.size()]; std::copy(value.begin(), value.end(), buf); do_in_jni_thread( FROM_HERE, base::Bind(callbacks.request_write_characteristic_cb, conn_id, trans_id, addr.value(), attr_handle, offset, need_response, is_prepare, base::Owned(buf), value.size())); } } // namespace gatt } // namespace bluetooth system/rust/src/gatt/ffi/gatt_shim.h +5 −0 Original line number Diff line number Diff line Loading @@ -34,6 +34,11 @@ class GattServerCallbacks { uint16_t attr_handle, uint32_t offset, bool is_long) const; void OnServerWriteCharacteristic(uint16_t conn_id, uint32_t trans_id, uint16_t attr_handle, uint32_t offset, bool need_response, bool is_prepare, ::rust::Slice<const uint8_t> value) const; private: const btgatt_server_callbacks_t& callbacks; }; Loading Loading
system/rust/src/gatt/callbacks.rs +23 −1 Original line number Diff line number Diff line Loading @@ -8,7 +8,7 @@ pub use callback_transaction_manager::{CallbackResponseError, CallbackTransactio use async_trait::async_trait; use crate::packets::{AttAttributeDataChild, AttErrorCode}; use crate::packets::{AttAttributeDataChild, AttAttributeDataView, AttErrorCode}; use super::ids::{AttHandle, ConnectionId, TransactionId}; Loading @@ -25,6 +25,20 @@ pub trait GattCallbacks { offset: u32, is_long: bool, ); /// Invoked when a client tries to write a characteristic. Expects a /// response using bluetooth::gatt::send_response(); #[allow(clippy::too_many_arguments)] // needed to match the C++ interface fn on_server_write_characteristic( &self, conn_id: ConnectionId, trans_id: TransactionId, handle: AttHandle, offset: u32, need_response: bool, is_prepare: bool, value: AttAttributeDataView, ); } /// This interface is an "async" version of the above, and is passed directly Loading @@ -44,4 +58,12 @@ pub trait GattDatastore { conn_id: ConnectionId, handle: AttHandle, ) -> Result<AttAttributeDataChild, AttErrorCode>; /// Write data to a given characteristic on the specified connection. async fn write_characteristic( &self, conn_id: ConnectionId, handle: AttHandle, data: AttAttributeDataView<'_>, ) -> Result<(), AttErrorCode>; }
system/rust/src/gatt/callbacks/callback_transaction_manager.rs +22 −1 Original line number Diff line number Diff line Loading @@ -9,7 +9,7 @@ use crate::{ ids::{AttHandle, ConnectionId, TransactionId}, GattCallbacks, }, packets::{AttAttributeDataChild, AttErrorCode}, packets::{AttAttributeDataChild, AttAttributeDataView, AttErrorCode}, }; use super::GattDatastore; Loading Loading @@ -138,4 +138,25 @@ impl GattDatastore for CallbackTransactionManager { Err(AttErrorCode::UNLIKELY_ERROR) } } async fn write_characteristic( &self, conn_id: ConnectionId, handle: AttHandle, data: AttAttributeDataView<'_>, ) -> Result<(), AttErrorCode> { let (trans_id, rx) = self.pending_transactions.borrow_mut().start_new_transaction(conn_id)?; self.callbacks .on_server_write_characteristic(conn_id, trans_id, handle, 0, true, false, data); if let Ok(value) = rx.await { value.map(|_| ()) // the data passed back is irrelevant for write // requests } else { warn!("sender side of {trans_id:?} dropped while handling request - most likely this response will not be sent over the air"); Err(AttErrorCode::UNLIKELY_ERROR) } } }
system/rust/src/gatt/ffi.rs +39 −1 Original line number Diff line number Diff line Loading @@ -11,7 +11,10 @@ use log::{error, info, warn}; use crate::{ do_in_rust_thread, packets::{AttAttributeDataChild, AttBuilder, AttErrorCode, Serializable, SerializeError}, packets::{ AttAttributeDataChild, AttAttributeDataView, AttBuilder, AttErrorCode, Serializable, SerializeError, }, }; use super::{ Loading Loading @@ -54,6 +57,20 @@ mod inner { offset: u32, is_long: bool, ); /// This callback is invoked when writing a characteristic - the client /// must reply using SendResponse #[cxx_name = "OnServerWriteCharacteristic"] fn on_server_write_characteristic( self: &GattServerCallbacks, conn_id: u16, trans_id: u32, attr_handle: u16, offset: u32, need_response: bool, is_prepare: bool, value: &[u8], ); } /// What action the arbiter should take in response to an incoming packet Loading Loading @@ -143,6 +160,27 @@ impl GattCallbacks for GattCallbacksImpl { .unwrap() .on_server_read_characteristic(conn_id.0, trans_id.0, handle.0, offset, is_long); } fn on_server_write_characteristic( &self, conn_id: ConnectionId, trans_id: TransactionId, handle: AttHandle, offset: u32, need_response: bool, is_prepare: bool, value: AttAttributeDataView, ) { self.0.as_ref().unwrap().on_server_write_characteristic( conn_id.0, trans_id.0, handle.0, offset, need_response, is_prepare, &value.get_raw_payload().collect::<Vec<_>>(), ); } } /// Implementation of AttTransport wrapping the corresponding C++ method Loading
system/rust/src/gatt/ffi/gatt_shim.cc +22 −0 Original line number Diff line number Diff line Loading @@ -69,5 +69,27 @@ void GattServerCallbacks::OnServerReadCharacteristic(uint16_t conn_id, addr.value(), attr_handle, offset, is_long)); } void GattServerCallbacks::OnServerWriteCharacteristic( uint16_t conn_id, uint32_t trans_id, uint16_t attr_handle, uint32_t offset, bool need_response, bool is_prepare, ::rust::Slice<const uint8_t> value) const { auto addr = AddressOfConnection(conn_id); if (!addr.has_value()) { LOG_WARN( "Dropping server write characteristic since connection %d not found", conn_id); return; } auto buf = new uint8_t[value.size()]; std::copy(value.begin(), value.end(), buf); do_in_jni_thread( FROM_HERE, base::Bind(callbacks.request_write_characteristic_cb, conn_id, trans_id, addr.value(), attr_handle, offset, need_response, is_prepare, base::Owned(buf), value.size())); } } // namespace gatt } // namespace bluetooth
system/rust/src/gatt/ffi/gatt_shim.h +5 −0 Original line number Diff line number Diff line Loading @@ -34,6 +34,11 @@ class GattServerCallbacks { uint16_t attr_handle, uint32_t offset, bool is_long) const; void OnServerWriteCharacteristic(uint16_t conn_id, uint32_t trans_id, uint16_t attr_handle, uint32_t offset, bool need_response, bool is_prepare, ::rust::Slice<const uint8_t> value) const; private: const btgatt_server_callbacks_t& callbacks; }; Loading