diff options
author | 2022-08-22 21:06:44 +0000 | |
---|---|---|
committer | 2022-08-22 21:06:44 +0000 | |
commit | 640e18c4d130e68abd36b972cd502906df9da7cc (patch) | |
tree | 67a3f61926708bbf0dff05ff9a3f8edf7aaf5362 | |
parent | 73b96272ba5f9b5b36789e1728dba6c669829713 (diff) | |
parent | 78e858b62a0cbb6760f67bad3f4a40bd63cc9e07 (diff) |
Merge "RootCanal: Implement support for enhanced synchronous link commands"
-rw-r--r-- | system/gd/hci/hci_packets.pdl | 78 | ||||
-rw-r--r-- | tools/rootcanal/model/controller/dual_mode_controller.cc | 317 | ||||
-rw-r--r-- | tools/rootcanal/model/controller/dual_mode_controller.h | 9 |
3 files changed, 371 insertions, 33 deletions
diff --git a/system/gd/hci/hci_packets.pdl b/system/gd/hci/hci_packets.pdl index 5cc475ae7e..cadc0c696c 100644 --- a/system/gd/hci/hci_packets.pdl +++ b/system/gd/hci/hci_packets.pdl @@ -1168,6 +1168,26 @@ packet ReadLmpHandleComplete : CommandComplete (command_op_code = READ_LMP_HANDL _reserved_ : 32, } +enum SynchronousPacketTypeBits : 16 { + HV1_ALLOWED = 0x0001, + HV2_ALLOWED = 0x0002, + HV3_ALLOWED = 0x0004, + EV3_ALLOWED = 0x0008, + EV4_ALLOWED = 0x0010, + EV5_ALLOWED = 0x0020, + NO_2_EV3_ALLOWED = 0x0040, + NO_3_EV3_ALLOWED = 0x0080, + NO_2_EV5_ALLOWED = 0x0100, + NO_3_EV5_ALLOWED = 0x0200, +} + +enum RetransmissionEffort : 8 { + NO_RETRANSMISSION = 0x00, + OPTIMIZED_FOR_POWER = 0x01, + OPTIMIZED_FOR_LINK_QUALITY = 0x02, + DO_NOT_CARE = 0xFF, +} + packet SetupSynchronousConnection : ScoConnectionCommand (op_code = SETUP_SYNCHRONOUS_CONNECTION) { connection_handle : 12, _reserved_ : 4, @@ -1176,8 +1196,8 @@ packet SetupSynchronousConnection : ScoConnectionCommand (op_code = SETUP_SYNCHR max_latency : 16, // 0-3 reserved, 0xFFFF = don't care voice_setting : 10, _reserved_ : 6, - retransmission_effort : 8, - packet_type : 16, + retransmission_effort : RetransmissionEffort, + packet_type : 16, // See SynchronousPacketTypeBits } packet SetupSynchronousConnectionStatus : CommandStatus (command_op_code = SETUP_SYNCHRONOUS_CONNECTION) { @@ -1190,8 +1210,8 @@ packet AcceptSynchronousConnection : ScoConnectionCommand (op_code = ACCEPT_SYNC max_latency : 16, // 0-3 reserved, 0xFFFF = don't care voice_setting : 10, _reserved_ : 6, - retransmission_effort : 8, - packet_type : 16, + retransmission_effort : RetransmissionEffort, + packet_type : 16, // See SynchronousPacketTypeBits } packet AcceptSynchronousConnectionStatus : CommandStatus (command_op_code = ACCEPT_SYNCHRONOUS_CONNECTION) { @@ -1342,34 +1362,14 @@ enum ScoDataPath : 8 { AUDIO_TEST_MODE = 0xFF, } -enum SynchronousPacketTypeBits : 16 { - HV1_ALLOWED = 0x0001, - HV2_ALLOWED = 0x0002, - HV3_ALLOWED = 0x0004, - EV3_ALLOWED = 0x0008, - EV4_ALLOWED = 0x0010, - EV5_ALLOWED = 0x0020, - NO_2_EV3_ALLOWED = 0x0040, - NO_3_EV3_ALLOWED = 0x0080, - NO_2_EV5_ALLOWED = 0x0100, - NO_3_EV5_ALLOWED = 0x0200, -} - -enum RetransmissionEffort : 8 { - NO_RETRANSMISSION = 0x00, - OPTIMIZED_FOR_POWER = 0x01, - OPTIMIZED_FOR_LINK_QUALITY = 0x02, - DO_NOT_CARE = 0xFF, -} - packet EnhancedSetupSynchronousConnection : ScoConnectionCommand (op_code = ENHANCED_SETUP_SYNCHRONOUS_CONNECTION) { connection_handle: 12, _reserved_ : 4, // Next two items // [0x00000000, 0xFFFFFFFE] Bandwidth in octets per second. // [0xFFFFFFFF]: Don't care - transmit_bandwidth_octets_per_second : 32, - receive_bandwidth_octets_per_second : 32, + transmit_bandwidth : 32, + receive_bandwidth : 32, transmit_coding_format : ScoCodingFormat, receive_coding_format : ScoCodingFormat, // Next two items @@ -1379,8 +1379,8 @@ packet EnhancedSetupSynchronousConnection : ScoConnectionCommand (op_code = ENHA receive_codec_frame_size : 16, // Next two items // Host to Controller nominal data rate in octets per second. - input_bandwidth_octets_per_second : 32, - output_bandwidth_octets_per_second : 32, + input_bandwidth : 32, + output_bandwidth : 32, input_coding_format : ScoCodingFormat, output_coding_format : ScoCodingFormat, // Next two items @@ -1407,11 +1407,15 @@ packet EnhancedSetupSynchronousConnection : ScoConnectionCommand (op_code = ENHA // of the eSCO window, where the eSCO window is reserved slots plus the // retransmission window // [0xFFFF]: don't care - max_latency_ms: 16, - packet_type : 16, // Or together SynchronousPacketTypeBits + max_latency: 16, + packet_type : 16, // See SynchronousPacketTypeBits retransmission_effort : RetransmissionEffort, } +test EnhancedSetupSynchronousConnection { + "\x3d\x04\x3b\x02\x00\x40\x1f\x00\x00\x40\x1f\x00\x00\x05\x00\x00\x00\x00\x05\x00\x00\x00\x00\x3c\x00\x3c\x00\x00\x7d\x00\x00\x00\x7d\x00\x00\x04\x00\x00\x00\x00\x04\x00\x00\x00\x00\x10\x00\x10\x00\x02\x02\x00\x00\x01\x01\x00\x00\x0d\x00\x88\x03\x02", +} + packet EnhancedSetupSynchronousConnectionStatus : CommandStatus (command_op_code = ENHANCED_SETUP_SYNCHRONOUS_CONNECTION) { } @@ -1460,7 +1464,7 @@ packet EnhancedAcceptSynchronousConnection : ScoConnectionCommand (op_code = ENH // retransmission window // [0xFFFF]: don't care max_latency : 16, - packet_type : 16, // Or together SynchronousPacketTypeBits + packet_type : 16, // See SynchronousPacketTypeBits retransmission_effort : RetransmissionEffort, } @@ -5342,6 +5346,10 @@ packet SynchronousConnectionComplete : Event (event_code = SYNCHRONOUS_CONNECTIO air_mode : ScoAirMode, } +test SynchronousConnectionComplete { + "\x2c\x11\x00\x03\x00\x1d\xdf\xed\x2b\x1a\xf8\x02\x0c\x04\x3c\x00\x3c\x00\x03", +} + packet SynchronousConnectionChanged : Event (event_code = SYNCHRONOUS_CONNECTION_CHANGED) { status : ErrorCode, connection_handle : 12, @@ -5435,6 +5443,10 @@ packet EnhancedFlush : Command (op_code = ENHANCED_FLUSH) { packet_type : FlushablePacketType, } +test EnhancedFlush { + "\x5f\x0c\x03\x02\x00\x00", +} + packet EnhancedFlushStatus : CommandStatus (command_op_code = ENHANCED_FLUSH) { } @@ -5443,6 +5455,10 @@ packet EnhancedFlushComplete : Event (event_code = ENHANCED_FLUSH_COMPLETE) { _reserved_ : 4, } +test EnhancedFlushComplete { + "\x39\x02\x02\x00", +} + packet UserPasskeyNotification : Event (event_code = USER_PASSKEY_NOTIFICATION) { bd_addr : Address, passkey : 20, // 0x00000-0xF423F (000000 - 999999) diff --git a/tools/rootcanal/model/controller/dual_mode_controller.cc b/tools/rootcanal/model/controller/dual_mode_controller.cc index f0df052ce7..4e67077879 100644 --- a/tools/rootcanal/model/controller/dual_mode_controller.cc +++ b/tools/rootcanal/model/controller/dual_mode_controller.cc @@ -126,6 +126,10 @@ DualModeController::DualModeController(const std::string& properties_filename, SET_SUPPORTED(SETUP_SYNCHRONOUS_CONNECTION, SetupSynchronousConnection); SET_SUPPORTED(ACCEPT_SYNCHRONOUS_CONNECTION, AcceptSynchronousConnection); SET_SUPPORTED(REJECT_SYNCHRONOUS_CONNECTION, RejectSynchronousConnection); + SET_SUPPORTED(ENHANCED_SETUP_SYNCHRONOUS_CONNECTION, + EnhancedSetupSynchronousConnection); + SET_SUPPORTED(ENHANCED_ACCEPT_SYNCHRONOUS_CONNECTION, + EnhancedAcceptSynchronousConnection); SET_SUPPORTED(IO_CAPABILITY_REQUEST_REPLY, IoCapabilityRequestReply); SET_SUPPORTED(USER_CONFIRMATION_REQUEST_REPLY, UserConfirmationRequestReply); SET_SUPPORTED(USER_CONFIRMATION_REQUEST_NEGATIVE_REPLY, @@ -145,6 +149,7 @@ DualModeController::DualModeController(const std::string& properties_filename, SET_SUPPORTED(READ_INQUIRY_RESPONSE_TRANSMIT_POWER_LEVEL, ReadInquiryResponseTransmitPowerLevel); SET_SUPPORTED(SEND_KEYPRESS_NOTIFICATION, SendKeypressNotification); + SET_SUPPORTED(ENHANCED_FLUSH, EnhancedFlush); SET_HANDLER(SET_EVENT_MASK_PAGE_2, SetEventMaskPage2); SET_SUPPORTED(READ_LOCAL_OOB_DATA, ReadLocalOobData); SET_SUPPORTED(READ_LOCAL_OOB_EXTENDED_DATA, ReadLocalOobExtendedData); @@ -684,7 +689,8 @@ void DualModeController::SetupSynchronousConnection(CommandView command) { auto status = link_layer_controller_.SetupSynchronousConnection( command_view.GetConnectionHandle(), command_view.GetTransmitBandwidth(), command_view.GetReceiveBandwidth(), command_view.GetMaxLatency(), - command_view.GetVoiceSetting(), command_view.GetRetransmissionEffort(), + command_view.GetVoiceSetting(), + static_cast<uint8_t>(command_view.GetRetransmissionEffort()), command_view.GetPacketType()); send_event_(bluetooth::hci::SetupSynchronousConnectionStatusBuilder::Create( @@ -700,13 +706,304 @@ void DualModeController::AcceptSynchronousConnection(CommandView command) { auto status = link_layer_controller_.AcceptSynchronousConnection( command_view.GetBdAddr(), command_view.GetTransmitBandwidth(), command_view.GetReceiveBandwidth(), command_view.GetMaxLatency(), - command_view.GetVoiceSetting(), command_view.GetRetransmissionEffort(), + command_view.GetVoiceSetting(), + static_cast<uint8_t>(command_view.GetRetransmissionEffort()), command_view.GetPacketType()); send_event_(bluetooth::hci::AcceptSynchronousConnectionStatusBuilder::Create( status, kNumCommandPackets)); } +void DualModeController::EnhancedSetupSynchronousConnection( + CommandView command) { + auto command_view = gd_hci::EnhancedSetupSynchronousConnectionView::Create( + gd_hci::ScoConnectionCommandView::Create( + gd_hci::AclCommandView::Create(command))); + auto status = ErrorCode::SUCCESS; + ASSERT(command_view.IsValid()); + + // The Host shall set the Transmit_Coding_Format and Receive_Coding_Formats + // to be equal. + auto transmit_coding_format = command_view.GetTransmitCodingFormat(); + auto receive_coding_format = command_view.GetReceiveCodingFormat(); + if (transmit_coding_format.coding_format_ != + receive_coding_format.coding_format_ || + transmit_coding_format.company_id_ != receive_coding_format.company_id_ || + transmit_coding_format.vendor_specific_codec_id_ != + receive_coding_format.vendor_specific_codec_id_) { + LOG_INFO( + "EnhancedSetupSynchronousConnection: rejected Transmit_Coding_Format " + "(%s)" + " and Receive_Coding_Format (%s) as they are not equal", + transmit_coding_format.ToString().c_str(), + receive_coding_format.ToString().c_str()); + status = ErrorCode::INVALID_HCI_COMMAND_PARAMETERS; + } + + // The Host shall either set the Input_Bandwidth and Output_Bandwidth + // to be equal, or shall set one of them to be zero and the other non-zero. + auto input_bandwidth = command_view.GetInputBandwidth(); + auto output_bandwidth = command_view.GetOutputBandwidth(); + if (input_bandwidth != output_bandwidth && input_bandwidth != 0 && + output_bandwidth != 0) { + LOG_INFO( + "EnhancedSetupSynchronousConnection: rejected Input_Bandwidth (%u)" + " and Output_Bandwidth (%u) as they are not equal and different from 0", + input_bandwidth, output_bandwidth); + status = ErrorCode::INVALID_HCI_COMMAND_PARAMETERS; + } + + // The Host shall set the Input_Coding_Format and Output_Coding_Format + // to be equal. + auto input_coding_format = command_view.GetInputCodingFormat(); + auto output_coding_format = command_view.GetOutputCodingFormat(); + if (input_coding_format.coding_format_ != + output_coding_format.coding_format_ || + input_coding_format.company_id_ != output_coding_format.company_id_ || + input_coding_format.vendor_specific_codec_id_ != + output_coding_format.vendor_specific_codec_id_) { + LOG_INFO( + "EnhancedSetupSynchronousConnection: rejected Input_Coding_Format (%s)" + " and Output_Coding_Format (%s) as they are not equal", + input_coding_format.ToString().c_str(), + output_coding_format.ToString().c_str()); + status = ErrorCode::INVALID_HCI_COMMAND_PARAMETERS; + } + + // Root-Canal does not implement audio data transport paths other than the + // default HCI transport. + if (command_view.GetInputDataPath() != bluetooth::hci::ScoDataPath::HCI || + command_view.GetOutputDataPath() != bluetooth::hci::ScoDataPath::HCI) { + LOG_INFO( + "EnhancedSetupSynchronousConnection: rejected Input_Data_Path (%u)" + " and/or Output_Data_Path (%u) as they are un-implemented", + static_cast<unsigned>(command_view.GetInputDataPath()), + static_cast<unsigned>(command_view.GetOutputDataPath())); + status = ErrorCode::INVALID_HCI_COMMAND_PARAMETERS; + } + + // Either both the Transmit_Coding_Format and Input_Coding_Format shall be + // “transparent” or neither shall be. If both are “transparent”, the + // Transmit_Bandwidth and the Input_Bandwidth shall be the same and the + // Controller shall not modify the data sent to the remote device. + auto transmit_bandwidth = command_view.GetTransmitBandwidth(); + auto receive_bandwidth = command_view.GetReceiveBandwidth(); + if (transmit_coding_format.coding_format_ == + bluetooth::hci::ScoCodingFormatValues::TRANSPARENT && + transmit_coding_format.coding_format_ == + bluetooth::hci::ScoCodingFormatValues::TRANSPARENT && + transmit_bandwidth != input_bandwidth) { + LOG_INFO( + "EnhancedSetupSynchronousConnection: rejected Transmit_Bandwidth (%u)" + " and Input_Bandwidth (%u) as they are not equal", + transmit_bandwidth, input_bandwidth); + LOG_INFO( + "EnhancedSetupSynchronousConnection: the Transmit_Bandwidth and " + "Input_Bandwidth shall be equal when both Transmit_Coding_Format " + "and Input_Coding_Format are 'transparent'"); + status = ErrorCode::INVALID_HCI_COMMAND_PARAMETERS; + } + if ((transmit_coding_format.coding_format_ == + bluetooth::hci::ScoCodingFormatValues::TRANSPARENT) != + (transmit_coding_format.coding_format_ == + bluetooth::hci::ScoCodingFormatValues::TRANSPARENT)) { + LOG_INFO( + "EnhancedSetupSynchronousConnection: rejected Transmit_Coding_Format " + "(%s) and Input_Coding_Format (%s) as they are incompatible", + transmit_coding_format.ToString().c_str(), + input_coding_format.ToString().c_str()); + status = ErrorCode::INVALID_HCI_COMMAND_PARAMETERS; + } + + // Either both the Receive_Coding_Format and Output_Coding_Format shall + // be “transparent” or neither shall be. If both are “transparent”, the + // Receive_Bandwidth and the Output_Bandwidth shall be the same and the + // Controller shall not modify the data sent to the Host. + if (receive_coding_format.coding_format_ == + bluetooth::hci::ScoCodingFormatValues::TRANSPARENT && + receive_coding_format.coding_format_ == + bluetooth::hci::ScoCodingFormatValues::TRANSPARENT && + receive_bandwidth != output_bandwidth) { + LOG_INFO( + "EnhancedSetupSynchronousConnection: rejected Receive_Bandwidth (%u)" + " and Output_Bandwidth (%u) as they are not equal", + receive_bandwidth, output_bandwidth); + LOG_INFO( + "EnhancedSetupSynchronousConnection: the Receive_Bandwidth and " + "Output_Bandwidth shall be equal when both Receive_Coding_Format " + "and Output_Coding_Format are 'transparent'"); + status = ErrorCode::INVALID_HCI_COMMAND_PARAMETERS; + } + if ((receive_coding_format.coding_format_ == + bluetooth::hci::ScoCodingFormatValues::TRANSPARENT) != + (receive_coding_format.coding_format_ == + bluetooth::hci::ScoCodingFormatValues::TRANSPARENT)) { + LOG_INFO( + "EnhancedSetupSynchronousConnection: rejected Receive_Coding_Format " + "(%s) and Output_Coding_Format (%s) as they are incompatible", + receive_coding_format.ToString().c_str(), + output_coding_format.ToString().c_str()); + status = ErrorCode::INVALID_HCI_COMMAND_PARAMETERS; + } + + if (status == ErrorCode::SUCCESS) { + status = link_layer_controller_.SetupSynchronousConnection( + command_view.GetConnectionHandle(), transmit_bandwidth, + receive_bandwidth, command_view.GetMaxLatency(), 0 /* Voice_Setting */, + static_cast<uint8_t>(command_view.GetRetransmissionEffort()), + command_view.GetPacketType()); + } + + send_event_( + bluetooth::hci::EnhancedSetupSynchronousConnectionStatusBuilder::Create( + status, kNumCommandPackets)); +} + +void DualModeController::EnhancedAcceptSynchronousConnection( + CommandView command) { + auto command_view = gd_hci::EnhancedAcceptSynchronousConnectionView::Create( + gd_hci::ScoConnectionCommandView::Create( + gd_hci::AclCommandView::Create(command))); + auto status = ErrorCode::SUCCESS; + ASSERT(command_view.IsValid()); + + // The Host shall set the Transmit_Coding_Format and Receive_Coding_Formats + // to be equal. + auto transmit_coding_format = command_view.GetTransmitCodingFormat(); + auto receive_coding_format = command_view.GetReceiveCodingFormat(); + if (transmit_coding_format.coding_format_ != + receive_coding_format.coding_format_ || + transmit_coding_format.company_id_ != receive_coding_format.company_id_ || + transmit_coding_format.vendor_specific_codec_id_ != + receive_coding_format.vendor_specific_codec_id_) { + LOG_INFO( + "EnhancedAcceptSynchronousConnection: rejected Transmit_Coding_Format " + "(%s)" + " and Receive_Coding_Format (%s) as they are not equal", + transmit_coding_format.ToString().c_str(), + receive_coding_format.ToString().c_str()); + status = ErrorCode::INVALID_HCI_COMMAND_PARAMETERS; + } + + // The Host shall either set the Input_Bandwidth and Output_Bandwidth + // to be equal, or shall set one of them to be zero and the other non-zero. + auto input_bandwidth = command_view.GetInputBandwidth(); + auto output_bandwidth = command_view.GetOutputBandwidth(); + if (input_bandwidth != output_bandwidth && input_bandwidth != 0 && + output_bandwidth != 0) { + LOG_INFO( + "EnhancedAcceptSynchronousConnection: rejected Input_Bandwidth (%u)" + " and Output_Bandwidth (%u) as they are not equal and different from 0", + input_bandwidth, output_bandwidth); + status = ErrorCode::INVALID_HCI_COMMAND_PARAMETERS; + } + + // The Host shall set the Input_Coding_Format and Output_Coding_Format + // to be equal. + auto input_coding_format = command_view.GetInputCodingFormat(); + auto output_coding_format = command_view.GetOutputCodingFormat(); + if (input_coding_format.coding_format_ != + output_coding_format.coding_format_ || + input_coding_format.company_id_ != output_coding_format.company_id_ || + input_coding_format.vendor_specific_codec_id_ != + output_coding_format.vendor_specific_codec_id_) { + LOG_INFO( + "EnhancedAcceptSynchronousConnection: rejected Input_Coding_Format (%s)" + " and Output_Coding_Format (%s) as they are not equal", + input_coding_format.ToString().c_str(), + output_coding_format.ToString().c_str()); + status = ErrorCode::INVALID_HCI_COMMAND_PARAMETERS; + } + + // Root-Canal does not implement audio data transport paths other than the + // default HCI transport. + if (command_view.GetInputDataPath() != bluetooth::hci::ScoDataPath::HCI || + command_view.GetOutputDataPath() != bluetooth::hci::ScoDataPath::HCI) { + LOG_INFO( + "EnhancedAcceptSynchronousConnection: rejected Input_Data_Path (%u)" + " and/or Output_Data_Path (%u) as they are un-implemented", + static_cast<unsigned>(command_view.GetInputDataPath()), + static_cast<unsigned>(command_view.GetOutputDataPath())); + status = ErrorCode::INVALID_HCI_COMMAND_PARAMETERS; + } + + // Either both the Transmit_Coding_Format and Input_Coding_Format shall be + // “transparent” or neither shall be. If both are “transparent”, the + // Transmit_Bandwidth and the Input_Bandwidth shall be the same and the + // Controller shall not modify the data sent to the remote device. + auto transmit_bandwidth = command_view.GetTransmitBandwidth(); + auto receive_bandwidth = command_view.GetReceiveBandwidth(); + if (transmit_coding_format.coding_format_ == + bluetooth::hci::ScoCodingFormatValues::TRANSPARENT && + transmit_coding_format.coding_format_ == + bluetooth::hci::ScoCodingFormatValues::TRANSPARENT && + transmit_bandwidth != input_bandwidth) { + LOG_INFO( + "EnhancedSetupSynchronousConnection: rejected Transmit_Bandwidth (%u)" + " and Input_Bandwidth (%u) as they are not equal", + transmit_bandwidth, input_bandwidth); + LOG_INFO( + "EnhancedSetupSynchronousConnection: the Transmit_Bandwidth and " + "Input_Bandwidth shall be equal when both Transmit_Coding_Format " + "and Input_Coding_Format are 'transparent'"); + status = ErrorCode::INVALID_HCI_COMMAND_PARAMETERS; + } + if ((transmit_coding_format.coding_format_ == + bluetooth::hci::ScoCodingFormatValues::TRANSPARENT) != + (transmit_coding_format.coding_format_ == + bluetooth::hci::ScoCodingFormatValues::TRANSPARENT)) { + LOG_INFO( + "EnhancedSetupSynchronousConnection: rejected Transmit_Coding_Format " + "(%s) and Input_Coding_Format (%s) as they are incompatible", + transmit_coding_format.ToString().c_str(), + input_coding_format.ToString().c_str()); + status = ErrorCode::INVALID_HCI_COMMAND_PARAMETERS; + } + + // Either both the Receive_Coding_Format and Output_Coding_Format shall + // be “transparent” or neither shall be. If both are “transparent”, the + // Receive_Bandwidth and the Output_Bandwidth shall be the same and the + // Controller shall not modify the data sent to the Host. + if (receive_coding_format.coding_format_ == + bluetooth::hci::ScoCodingFormatValues::TRANSPARENT && + receive_coding_format.coding_format_ == + bluetooth::hci::ScoCodingFormatValues::TRANSPARENT && + receive_bandwidth != output_bandwidth) { + LOG_INFO( + "EnhancedSetupSynchronousConnection: rejected Receive_Bandwidth (%u)" + " and Output_Bandwidth (%u) as they are not equal", + receive_bandwidth, output_bandwidth); + LOG_INFO( + "EnhancedSetupSynchronousConnection: the Receive_Bandwidth and " + "Output_Bandwidth shall be equal when both Receive_Coding_Format " + "and Output_Coding_Format are 'transparent'"); + status = ErrorCode::INVALID_HCI_COMMAND_PARAMETERS; + } + if ((receive_coding_format.coding_format_ == + bluetooth::hci::ScoCodingFormatValues::TRANSPARENT) != + (receive_coding_format.coding_format_ == + bluetooth::hci::ScoCodingFormatValues::TRANSPARENT)) { + LOG_INFO( + "EnhancedSetupSynchronousConnection: rejected Receive_Coding_Format " + "(%s) and Output_Coding_Format (%s) as they are incompatible", + receive_coding_format.ToString().c_str(), + output_coding_format.ToString().c_str()); + status = ErrorCode::INVALID_HCI_COMMAND_PARAMETERS; + } + + if (status == ErrorCode::SUCCESS) { + status = link_layer_controller_.AcceptSynchronousConnection( + command_view.GetBdAddr(), transmit_bandwidth, receive_bandwidth, + command_view.GetMaxLatency(), 0 /* Voice_Setting */, + static_cast<uint8_t>(command_view.GetRetransmissionEffort()), + command_view.GetPacketType()); + } + + send_event_( + bluetooth::hci::EnhancedAcceptSynchronousConnectionStatusBuilder::Create( + status, kNumCommandPackets)); +} + void DualModeController::RejectSynchronousConnection(CommandView command) { auto command_view = gd_hci::RejectSynchronousConnectionView::Create( gd_hci::ScoConnectionCommandView::Create( @@ -959,6 +1256,22 @@ void DualModeController::SendKeypressNotification(CommandView command) { #endif /* ROOTCANAL_LMP */ } +void DualModeController::EnhancedFlush(CommandView command) { + auto command_view = bluetooth::hci::EnhancedFlushView::Create(command); + ASSERT(command_view.IsValid()); + + auto handle = command_view.GetConnectionHandle(); + send_event_(bluetooth::hci::EnhancedFlushStatusBuilder::Create( + ErrorCode::SUCCESS, kNumCommandPackets)); + + // TODO: When adding a queue of ACL packets. + // Send the Enhanced Flush Complete event after discarding + // all L2CAP packets identified by the Packet Type. + if (properties_.IsUnmasked(EventCode::ENHANCED_FLUSH_COMPLETE)) { + send_event_(bluetooth::hci::EnhancedFlushCompleteBuilder::Create(handle)); + } +} + void DualModeController::SetEventMaskPage2(CommandView command) { auto payload = std::make_unique<bluetooth::packet::RawBuilder>(std::vector<uint8_t>( diff --git a/tools/rootcanal/model/controller/dual_mode_controller.h b/tools/rootcanal/model/controller/dual_mode_controller.h index 8b9dd6d6cc..45a5e36562 100644 --- a/tools/rootcanal/model/controller/dual_mode_controller.h +++ b/tools/rootcanal/model/controller/dual_mode_controller.h @@ -222,6 +222,12 @@ class DualModeController : public Device { // 7.1.36 void IoCapabilityRequestNegativeReply(CommandView args); + // 7.1.45 + void EnhancedSetupSynchronousConnection(CommandView args); + + // 7.1.46 + void EnhancedAcceptSynchronousConnection(CommandView args); + // 7.1.53 void RemoteOobExtendedDataRequestReply(CommandView args); @@ -372,6 +378,9 @@ class DualModeController : public Device { // 7.3.63 void SendKeypressNotification(CommandView args); + // 7.3.66 + void EnhancedFlush(CommandView args); + // 7.3.69 void SetEventMaskPage2(CommandView args); |