Loading tools/rootcanal/lmp/src/ffi.rs +6 −2 Original line number Diff line number Diff line Loading @@ -19,10 +19,14 @@ pub struct LinkManagerOps { } impl LinkManagerOps { pub(crate) fn get_address(&self, handle: u16) -> hci::Address { pub(crate) fn get_address(&self, handle: u16) -> Option<hci::Address> { let mut result = hci::EMPTY_ADDRESS; unsafe { (self.get_address)(self.user_pointer, handle, &mut result.bytes as *mut _) }; result if result == hci::EMPTY_ADDRESS { None } else { Some(result) } } pub(crate) fn get_handle(&self, addr: hci::Address) -> u16 { Loading tools/rootcanal/lmp/src/manager.rs +143 −10 Original line number Diff line number Diff line Loading @@ -117,19 +117,152 @@ impl LinkManager { Ok(()) } /// Send a command complete or command status event /// with the specified error code. fn send_command_complete_event( &self, command: &hci::CommandPacket, status: hci::ErrorCode, ) -> Result<(), LinkManagerError> { use hci::ConnectionManagementCommandChild::*; use hci::SecurityCommandChild::*; #[allow(unused_imports)] use Option::None; // Overwrite `None` variant of `Child` enum let event: hci::EventPacket = match command.specialize() { hci::CommandChild::SecurityCommand(command) => match command.specialize() { LinkKeyRequestReply(packet) => hci::LinkKeyRequestReplyCompleteBuilder { status, bd_addr: packet.get_bd_addr(), num_hci_command_packets, } .into(), LinkKeyRequestNegativeReply(packet) => { hci::LinkKeyRequestNegativeReplyCompleteBuilder { status, bd_addr: packet.get_bd_addr(), num_hci_command_packets, } .into() } PinCodeRequestReply(packet) => hci::PinCodeRequestReplyCompleteBuilder { status, bd_addr: packet.get_bd_addr(), num_hci_command_packets, } .into(), PinCodeRequestNegativeReply(packet) => { hci::PinCodeRequestNegativeReplyCompleteBuilder { status, bd_addr: packet.get_bd_addr(), num_hci_command_packets, } .into() } IoCapabilityRequestReply(packet) => hci::IoCapabilityRequestReplyCompleteBuilder { status, bd_addr: packet.get_bd_addr(), num_hci_command_packets, } .into(), IoCapabilityRequestNegativeReply(packet) => { hci::IoCapabilityRequestNegativeReplyCompleteBuilder { status, bd_addr: packet.get_bd_addr(), num_hci_command_packets, } .into() } UserConfirmationRequestReply(packet) => { hci::UserConfirmationRequestReplyCompleteBuilder { status, bd_addr: packet.get_bd_addr(), num_hci_command_packets, } .into() } UserConfirmationRequestNegativeReply(packet) => { hci::UserConfirmationRequestNegativeReplyCompleteBuilder { status, bd_addr: packet.get_bd_addr(), num_hci_command_packets, } .into() } UserPasskeyRequestReply(packet) => hci::UserPasskeyRequestReplyCompleteBuilder { status, bd_addr: packet.get_bd_addr(), num_hci_command_packets, } .into(), UserPasskeyRequestNegativeReply(packet) => { hci::UserPasskeyRequestNegativeReplyCompleteBuilder { status, bd_addr: packet.get_bd_addr(), num_hci_command_packets, } .into() } RemoteOobDataRequestReply(packet) => { hci::RemoteOobDataRequestReplyCompleteBuilder { status, bd_addr: packet.get_bd_addr(), num_hci_command_packets, } .into() } RemoteOobDataRequestNegativeReply(packet) => { hci::RemoteOobDataRequestNegativeReplyCompleteBuilder { status, bd_addr: packet.get_bd_addr(), num_hci_command_packets, } .into() } SendKeypressNotification(packet) => hci::SendKeypressNotificationCompleteBuilder { status, bd_addr: packet.get_bd_addr(), num_hci_command_packets, } .into(), _ => return Err(LinkManagerError::UnhandledHciPacket), }, hci::CommandChild::AclCommand(command) => match command.specialize() { hci::AclCommandChild::ConnectionManagementCommand(command) => { match command.specialize() { AuthenticationRequested(_) => hci::AuthenticationRequestedStatusBuilder { status, num_hci_command_packets, } .into(), SetConnectionEncryption(_) => hci::SetConnectionEncryptionStatusBuilder { status, num_hci_command_packets, } .into(), _ => return Err(LinkManagerError::UnhandledHciPacket), } } _ => return Err(LinkManagerError::UnhandledHciPacket), }, _ => return Err(LinkManagerError::UnhandledHciPacket), }; self.ops.send_hci_event(&event.to_vec()); Ok(()) } pub fn ingest_hci(&self, command: hci::CommandPacket) -> Result<(), LinkManagerError> { // Try to find the peer address from the command arguments let peer = hci::command_connection_handle(&command) .map(|handle| self.ops.get_address(handle)) .or_else(|| hci::command_remote_device_address(&command)); // Try to find the matching link from the command arguments let link = hci::command_connection_handle(&command) .and_then(|handle| self.ops.get_address(handle)) .or_else(|| hci::command_remote_device_address(&command)) .and_then(|peer| self.get_link(peer)); if let Some(peer) = peer { if let Some(link) = self.get_link(peer) { if let Some(link) = link { link.ingest_hci(command); }; Ok(()) } else { Err(LinkManagerError::UnhandledHciPacket) self.send_command_complete_event(&command, hci::ErrorCode::InvalidHciCommandParameters) } } Loading tools/rootcanal/model/controller/acl_connection_handler.cc +6 −0 Original line number Diff line number Diff line Loading @@ -200,6 +200,12 @@ AddressWithType AclConnectionHandler::GetAddress(uint16_t handle) const { return acl_connections_.at(handle).GetAddress(); } std::optional<AddressWithType> AclConnectionHandler::GetAddressSafe( uint16_t handle) const { return HasHandle(handle) ? acl_connections_.at(handle).GetAddress() : std::optional<AddressWithType>(); } Address AclConnectionHandler::GetScoAddress(uint16_t handle) const { ASSERT_LOG(HasScoHandle(handle), "Unknown SCO handle %hd", handle); return sco_connections_.at(handle).GetAddress(); Loading tools/rootcanal/model/controller/acl_connection_handler.h +1 −0 Original line number Diff line number Diff line Loading @@ -85,6 +85,7 @@ class AclConnectionHandler { uint16_t GetHandle(bluetooth::hci::AddressWithType addr) const; uint16_t GetHandleOnlyAddress(bluetooth::hci::Address addr) const; bluetooth::hci::AddressWithType GetAddress(uint16_t handle) const; std::optional<AddressWithType> GetAddressSafe(uint16_t handle) const; bluetooth::hci::Address GetScoAddress(uint16_t handle) const; bluetooth::hci::AddressWithType GetOwnAddress(uint16_t handle) const; bluetooth::hci::AddressWithType GetResolvedAddress(uint16_t handle) const; Loading tools/rootcanal/model/controller/link_layer_controller.cc +4 −2 Original line number Diff line number Diff line Loading @@ -1365,8 +1365,10 @@ LinkLayerController::LinkLayerController(const Address& address, [](void* user, uint16_t handle, uint8_t(*result)[6]) { auto controller = static_cast<LinkLayerController*>(user); auto address = controller->connections_.GetAddress(handle).GetAddress(); auto address_opt = controller->connections_.GetAddressSafe(handle); Address address = address_opt.has_value() ? address_opt.value().GetAddress() : Address::kEmpty; std::copy(address.data(), address.data() + 6, reinterpret_cast<uint8_t*>(result)); }, Loading Loading
tools/rootcanal/lmp/src/ffi.rs +6 −2 Original line number Diff line number Diff line Loading @@ -19,10 +19,14 @@ pub struct LinkManagerOps { } impl LinkManagerOps { pub(crate) fn get_address(&self, handle: u16) -> hci::Address { pub(crate) fn get_address(&self, handle: u16) -> Option<hci::Address> { let mut result = hci::EMPTY_ADDRESS; unsafe { (self.get_address)(self.user_pointer, handle, &mut result.bytes as *mut _) }; result if result == hci::EMPTY_ADDRESS { None } else { Some(result) } } pub(crate) fn get_handle(&self, addr: hci::Address) -> u16 { Loading
tools/rootcanal/lmp/src/manager.rs +143 −10 Original line number Diff line number Diff line Loading @@ -117,19 +117,152 @@ impl LinkManager { Ok(()) } /// Send a command complete or command status event /// with the specified error code. fn send_command_complete_event( &self, command: &hci::CommandPacket, status: hci::ErrorCode, ) -> Result<(), LinkManagerError> { use hci::ConnectionManagementCommandChild::*; use hci::SecurityCommandChild::*; #[allow(unused_imports)] use Option::None; // Overwrite `None` variant of `Child` enum let event: hci::EventPacket = match command.specialize() { hci::CommandChild::SecurityCommand(command) => match command.specialize() { LinkKeyRequestReply(packet) => hci::LinkKeyRequestReplyCompleteBuilder { status, bd_addr: packet.get_bd_addr(), num_hci_command_packets, } .into(), LinkKeyRequestNegativeReply(packet) => { hci::LinkKeyRequestNegativeReplyCompleteBuilder { status, bd_addr: packet.get_bd_addr(), num_hci_command_packets, } .into() } PinCodeRequestReply(packet) => hci::PinCodeRequestReplyCompleteBuilder { status, bd_addr: packet.get_bd_addr(), num_hci_command_packets, } .into(), PinCodeRequestNegativeReply(packet) => { hci::PinCodeRequestNegativeReplyCompleteBuilder { status, bd_addr: packet.get_bd_addr(), num_hci_command_packets, } .into() } IoCapabilityRequestReply(packet) => hci::IoCapabilityRequestReplyCompleteBuilder { status, bd_addr: packet.get_bd_addr(), num_hci_command_packets, } .into(), IoCapabilityRequestNegativeReply(packet) => { hci::IoCapabilityRequestNegativeReplyCompleteBuilder { status, bd_addr: packet.get_bd_addr(), num_hci_command_packets, } .into() } UserConfirmationRequestReply(packet) => { hci::UserConfirmationRequestReplyCompleteBuilder { status, bd_addr: packet.get_bd_addr(), num_hci_command_packets, } .into() } UserConfirmationRequestNegativeReply(packet) => { hci::UserConfirmationRequestNegativeReplyCompleteBuilder { status, bd_addr: packet.get_bd_addr(), num_hci_command_packets, } .into() } UserPasskeyRequestReply(packet) => hci::UserPasskeyRequestReplyCompleteBuilder { status, bd_addr: packet.get_bd_addr(), num_hci_command_packets, } .into(), UserPasskeyRequestNegativeReply(packet) => { hci::UserPasskeyRequestNegativeReplyCompleteBuilder { status, bd_addr: packet.get_bd_addr(), num_hci_command_packets, } .into() } RemoteOobDataRequestReply(packet) => { hci::RemoteOobDataRequestReplyCompleteBuilder { status, bd_addr: packet.get_bd_addr(), num_hci_command_packets, } .into() } RemoteOobDataRequestNegativeReply(packet) => { hci::RemoteOobDataRequestNegativeReplyCompleteBuilder { status, bd_addr: packet.get_bd_addr(), num_hci_command_packets, } .into() } SendKeypressNotification(packet) => hci::SendKeypressNotificationCompleteBuilder { status, bd_addr: packet.get_bd_addr(), num_hci_command_packets, } .into(), _ => return Err(LinkManagerError::UnhandledHciPacket), }, hci::CommandChild::AclCommand(command) => match command.specialize() { hci::AclCommandChild::ConnectionManagementCommand(command) => { match command.specialize() { AuthenticationRequested(_) => hci::AuthenticationRequestedStatusBuilder { status, num_hci_command_packets, } .into(), SetConnectionEncryption(_) => hci::SetConnectionEncryptionStatusBuilder { status, num_hci_command_packets, } .into(), _ => return Err(LinkManagerError::UnhandledHciPacket), } } _ => return Err(LinkManagerError::UnhandledHciPacket), }, _ => return Err(LinkManagerError::UnhandledHciPacket), }; self.ops.send_hci_event(&event.to_vec()); Ok(()) } pub fn ingest_hci(&self, command: hci::CommandPacket) -> Result<(), LinkManagerError> { // Try to find the peer address from the command arguments let peer = hci::command_connection_handle(&command) .map(|handle| self.ops.get_address(handle)) .or_else(|| hci::command_remote_device_address(&command)); // Try to find the matching link from the command arguments let link = hci::command_connection_handle(&command) .and_then(|handle| self.ops.get_address(handle)) .or_else(|| hci::command_remote_device_address(&command)) .and_then(|peer| self.get_link(peer)); if let Some(peer) = peer { if let Some(link) = self.get_link(peer) { if let Some(link) = link { link.ingest_hci(command); }; Ok(()) } else { Err(LinkManagerError::UnhandledHciPacket) self.send_command_complete_event(&command, hci::ErrorCode::InvalidHciCommandParameters) } } Loading
tools/rootcanal/model/controller/acl_connection_handler.cc +6 −0 Original line number Diff line number Diff line Loading @@ -200,6 +200,12 @@ AddressWithType AclConnectionHandler::GetAddress(uint16_t handle) const { return acl_connections_.at(handle).GetAddress(); } std::optional<AddressWithType> AclConnectionHandler::GetAddressSafe( uint16_t handle) const { return HasHandle(handle) ? acl_connections_.at(handle).GetAddress() : std::optional<AddressWithType>(); } Address AclConnectionHandler::GetScoAddress(uint16_t handle) const { ASSERT_LOG(HasScoHandle(handle), "Unknown SCO handle %hd", handle); return sco_connections_.at(handle).GetAddress(); Loading
tools/rootcanal/model/controller/acl_connection_handler.h +1 −0 Original line number Diff line number Diff line Loading @@ -85,6 +85,7 @@ class AclConnectionHandler { uint16_t GetHandle(bluetooth::hci::AddressWithType addr) const; uint16_t GetHandleOnlyAddress(bluetooth::hci::Address addr) const; bluetooth::hci::AddressWithType GetAddress(uint16_t handle) const; std::optional<AddressWithType> GetAddressSafe(uint16_t handle) const; bluetooth::hci::Address GetScoAddress(uint16_t handle) const; bluetooth::hci::AddressWithType GetOwnAddress(uint16_t handle) const; bluetooth::hci::AddressWithType GetResolvedAddress(uint16_t handle) const; Loading
tools/rootcanal/model/controller/link_layer_controller.cc +4 −2 Original line number Diff line number Diff line Loading @@ -1365,8 +1365,10 @@ LinkLayerController::LinkLayerController(const Address& address, [](void* user, uint16_t handle, uint8_t(*result)[6]) { auto controller = static_cast<LinkLayerController*>(user); auto address = controller->connections_.GetAddress(handle).GetAddress(); auto address_opt = controller->connections_.GetAddressSafe(handle); Address address = address_opt.has_value() ? address_opt.value().GetAddress() : Address::kEmpty; std::copy(address.data(), address.data() + 6, reinterpret_cast<uint8_t*>(result)); }, Loading