Loading system/rust/src/gatt/server.rs +1 −1 Original line number Diff line number Diff line Loading @@ -4,7 +4,7 @@ mod att_database; pub mod att_server_bearer; pub mod gatt_database; mod transaction_handler; mod request_handler; mod transactions; #[cfg(test)] Loading system/rust/src/gatt/server/att_server_bearer.rs +23 −16 Original line number Diff line number Diff line Loading @@ -17,20 +17,27 @@ use crate::{ utils::{owned_handle::OwnedHandle, packet::HACK_child_to_opcode}, }; use super::{att_database::AttDatabase, transaction_handler::AttTransactionHandler}; use super::{att_database::AttDatabase, request_handler::AttRequestHandler}; enum AttTransaction<T: AttDatabase> { Idle(AttTransactionHandler<T>), enum AttRequestState<T: AttDatabase> { Idle(AttRequestHandler<T>), Pending(Option<OwnedHandle<()>>), } const DEFAULT_ATT_MTU: usize = 23; /// The errors that can occur while trying to send a packet #[derive(Debug)] pub enum SendError { /// The packet failed to serialize SerializeError(SerializeError), } /// This represents a single ATT bearer (currently, always the unenhanced fixed /// channel on LE) The AttTransactionHandler ensures that only one transaction /// can take place at a time /// channel on LE) The AttRequestState ensures that only one transaction can /// take place at a time pub struct AttServerBearer<T: AttDatabase> { curr_operation: Cell<AttTransaction<T>>, curr_request: Cell<AttRequestState<T>>, send_packet: Box<dyn Fn(AttBuilder) -> Result<(), SerializeError>>, mtu: Cell<usize>, } Loading @@ -43,7 +50,7 @@ impl<T: AttDatabase + 'static> AttServerBearer<T> { send_packet: impl Fn(AttBuilder) -> Result<(), SerializeError> + 'static, ) -> Self { Self { curr_operation: AttTransaction::Idle(AttTransactionHandler::new(db)).into(), curr_request: AttRequestState::Idle(AttRequestHandler::new(db)).into(), send_packet: Box::new(send_packet), mtu: Cell::new(DEFAULT_ATT_MTU), } Loading @@ -54,9 +61,9 @@ impl<T: AttDatabase + 'static> WeakBoxRef<'_, AttServerBearer<T>> { /// Handle an incoming packet, and send outgoing packets as appropriate /// using the owned ATT channel. pub fn handle_packet(&self, packet: AttView<'_>) { let curr_operation = self.curr_operation.replace(AttTransaction::Pending(None)); self.curr_operation.replace(match curr_operation { AttTransaction::Idle(mut request_handler) => { let curr_request = self.curr_request.replace(AttRequestState::Pending(None)); self.curr_request.replace(match curr_request { AttRequestState::Idle(mut request_handler) => { // even if the MTU is updated afterwards, 5.3 3F 3.4.2.2 states that the // request-time MTU should be used let mtu = self.mtu.get(); Loading @@ -81,25 +88,25 @@ impl<T: AttDatabase + 'static> WeakBoxRef<'_, AttServerBearer<T>> { }).expect("packet should never fail to serialize"); } // ready for next transaction this.curr_operation.replace(AttTransaction::Idle(request_handler)); this.curr_request.replace(AttRequestState::Idle(request_handler)); } } }) }); AttTransaction::Pending(Some(task.into())) AttRequestState::Pending(Some(task.into())) } AttTransaction::Pending(_) => { AttRequestState::Pending(_) => { warn!("multiple ATT operations cannot simultaneously take place, dropping one"); // TODO(aryarahul) - disconnect connection here; curr_operation curr_request } }); } fn send_packet(&self, packet: impl Into<AttChild>) -> Result<(), SerializeError> { fn send_packet(&self, packet: impl Into<AttChild>) -> Result<(), SendError> { let child = packet.into(); let packet = AttBuilder { opcode: HACK_child_to_opcode(&child), _child_: child }; (self.send_packet)(packet) (self.send_packet)(packet).map_err(SendError::SerializeError) } } Loading system/rust/src/gatt/server/transaction_handler.rs→system/rust/src/gatt/server/request_handler.rs +5 −5 Original line number Diff line number Diff line Loading @@ -23,11 +23,11 @@ use super::{ /// This struct handles all requests needing ACKs. Only ONE should exist per /// bearer per database, to ensure serialization. pub struct AttTransactionHandler<Db: AttDatabase> { pub struct AttRequestHandler<Db: AttDatabase> { db: Db, } impl<Db: AttDatabase> AttTransactionHandler<Db> { impl<Db: AttDatabase> AttRequestHandler<Db> { pub fn new(db: Db) -> Self { Self { db } } Loading Loading @@ -106,8 +106,8 @@ mod test { core::uuid::Uuid, gatt::server::{ att_database::{AttAttribute, AttPermissions}, request_handler::AttRequestHandler, test::test_att_db::TestAttDatabase, transaction_handler::AttTransactionHandler, }, packets::{ AttAttributeDataChild, AttReadRequestBuilder, AttReadResponseBuilder, Loading @@ -127,7 +127,7 @@ mod test { }, vec![1, 2, 3], )]); let mut handler = AttTransactionHandler { db }; let mut handler = AttRequestHandler { db }; let att_view = build_att_view_or_crash(AttReadRequestBuilder { attribute_handle: AttHandle(3).into(), }); Loading Loading @@ -155,7 +155,7 @@ mod test { }, vec![1, 2, 3], )]); let mut handler = AttTransactionHandler { db }; let mut handler = AttRequestHandler { db }; let att_view = build_att_view_or_crash(AttWriteResponseBuilder {}); // act Loading Loading
system/rust/src/gatt/server.rs +1 −1 Original line number Diff line number Diff line Loading @@ -4,7 +4,7 @@ mod att_database; pub mod att_server_bearer; pub mod gatt_database; mod transaction_handler; mod request_handler; mod transactions; #[cfg(test)] Loading
system/rust/src/gatt/server/att_server_bearer.rs +23 −16 Original line number Diff line number Diff line Loading @@ -17,20 +17,27 @@ use crate::{ utils::{owned_handle::OwnedHandle, packet::HACK_child_to_opcode}, }; use super::{att_database::AttDatabase, transaction_handler::AttTransactionHandler}; use super::{att_database::AttDatabase, request_handler::AttRequestHandler}; enum AttTransaction<T: AttDatabase> { Idle(AttTransactionHandler<T>), enum AttRequestState<T: AttDatabase> { Idle(AttRequestHandler<T>), Pending(Option<OwnedHandle<()>>), } const DEFAULT_ATT_MTU: usize = 23; /// The errors that can occur while trying to send a packet #[derive(Debug)] pub enum SendError { /// The packet failed to serialize SerializeError(SerializeError), } /// This represents a single ATT bearer (currently, always the unenhanced fixed /// channel on LE) The AttTransactionHandler ensures that only one transaction /// can take place at a time /// channel on LE) The AttRequestState ensures that only one transaction can /// take place at a time pub struct AttServerBearer<T: AttDatabase> { curr_operation: Cell<AttTransaction<T>>, curr_request: Cell<AttRequestState<T>>, send_packet: Box<dyn Fn(AttBuilder) -> Result<(), SerializeError>>, mtu: Cell<usize>, } Loading @@ -43,7 +50,7 @@ impl<T: AttDatabase + 'static> AttServerBearer<T> { send_packet: impl Fn(AttBuilder) -> Result<(), SerializeError> + 'static, ) -> Self { Self { curr_operation: AttTransaction::Idle(AttTransactionHandler::new(db)).into(), curr_request: AttRequestState::Idle(AttRequestHandler::new(db)).into(), send_packet: Box::new(send_packet), mtu: Cell::new(DEFAULT_ATT_MTU), } Loading @@ -54,9 +61,9 @@ impl<T: AttDatabase + 'static> WeakBoxRef<'_, AttServerBearer<T>> { /// Handle an incoming packet, and send outgoing packets as appropriate /// using the owned ATT channel. pub fn handle_packet(&self, packet: AttView<'_>) { let curr_operation = self.curr_operation.replace(AttTransaction::Pending(None)); self.curr_operation.replace(match curr_operation { AttTransaction::Idle(mut request_handler) => { let curr_request = self.curr_request.replace(AttRequestState::Pending(None)); self.curr_request.replace(match curr_request { AttRequestState::Idle(mut request_handler) => { // even if the MTU is updated afterwards, 5.3 3F 3.4.2.2 states that the // request-time MTU should be used let mtu = self.mtu.get(); Loading @@ -81,25 +88,25 @@ impl<T: AttDatabase + 'static> WeakBoxRef<'_, AttServerBearer<T>> { }).expect("packet should never fail to serialize"); } // ready for next transaction this.curr_operation.replace(AttTransaction::Idle(request_handler)); this.curr_request.replace(AttRequestState::Idle(request_handler)); } } }) }); AttTransaction::Pending(Some(task.into())) AttRequestState::Pending(Some(task.into())) } AttTransaction::Pending(_) => { AttRequestState::Pending(_) => { warn!("multiple ATT operations cannot simultaneously take place, dropping one"); // TODO(aryarahul) - disconnect connection here; curr_operation curr_request } }); } fn send_packet(&self, packet: impl Into<AttChild>) -> Result<(), SerializeError> { fn send_packet(&self, packet: impl Into<AttChild>) -> Result<(), SendError> { let child = packet.into(); let packet = AttBuilder { opcode: HACK_child_to_opcode(&child), _child_: child }; (self.send_packet)(packet) (self.send_packet)(packet).map_err(SendError::SerializeError) } } Loading
system/rust/src/gatt/server/transaction_handler.rs→system/rust/src/gatt/server/request_handler.rs +5 −5 Original line number Diff line number Diff line Loading @@ -23,11 +23,11 @@ use super::{ /// This struct handles all requests needing ACKs. Only ONE should exist per /// bearer per database, to ensure serialization. pub struct AttTransactionHandler<Db: AttDatabase> { pub struct AttRequestHandler<Db: AttDatabase> { db: Db, } impl<Db: AttDatabase> AttTransactionHandler<Db> { impl<Db: AttDatabase> AttRequestHandler<Db> { pub fn new(db: Db) -> Self { Self { db } } Loading Loading @@ -106,8 +106,8 @@ mod test { core::uuid::Uuid, gatt::server::{ att_database::{AttAttribute, AttPermissions}, request_handler::AttRequestHandler, test::test_att_db::TestAttDatabase, transaction_handler::AttTransactionHandler, }, packets::{ AttAttributeDataChild, AttReadRequestBuilder, AttReadResponseBuilder, Loading @@ -127,7 +127,7 @@ mod test { }, vec![1, 2, 3], )]); let mut handler = AttTransactionHandler { db }; let mut handler = AttRequestHandler { db }; let att_view = build_att_view_or_crash(AttReadRequestBuilder { attribute_handle: AttHandle(3).into(), }); Loading Loading @@ -155,7 +155,7 @@ mod test { }, vec![1, 2, 3], )]); let mut handler = AttTransactionHandler { db }; let mut handler = AttRequestHandler { db }; let att_view = build_att_view_or_crash(AttWriteResponseBuilder {}); // act Loading