Loading system/gd/hci/hci_packets.pdl +47 −31 Original line number Original line Diff line number Diff line Loading @@ -1168,6 +1168,26 @@ packet ReadLmpHandleComplete : CommandComplete (command_op_code = READ_LMP_HANDL _reserved_ : 32, _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) { packet SetupSynchronousConnection : ScoConnectionCommand (op_code = SETUP_SYNCHRONOUS_CONNECTION) { connection_handle : 12, connection_handle : 12, _reserved_ : 4, _reserved_ : 4, Loading @@ -1176,8 +1196,8 @@ packet SetupSynchronousConnection : ScoConnectionCommand (op_code = SETUP_SYNCHR max_latency : 16, // 0-3 reserved, 0xFFFF = don't care max_latency : 16, // 0-3 reserved, 0xFFFF = don't care voice_setting : 10, voice_setting : 10, _reserved_ : 6, _reserved_ : 6, retransmission_effort : 8, retransmission_effort : RetransmissionEffort, packet_type : 16, packet_type : 16, // See SynchronousPacketTypeBits } } packet SetupSynchronousConnectionStatus : CommandStatus (command_op_code = SETUP_SYNCHRONOUS_CONNECTION) { packet SetupSynchronousConnectionStatus : CommandStatus (command_op_code = SETUP_SYNCHRONOUS_CONNECTION) { Loading @@ -1190,8 +1210,8 @@ packet AcceptSynchronousConnection : ScoConnectionCommand (op_code = ACCEPT_SYNC max_latency : 16, // 0-3 reserved, 0xFFFF = don't care max_latency : 16, // 0-3 reserved, 0xFFFF = don't care voice_setting : 10, voice_setting : 10, _reserved_ : 6, _reserved_ : 6, retransmission_effort : 8, retransmission_effort : RetransmissionEffort, packet_type : 16, packet_type : 16, // See SynchronousPacketTypeBits } } packet AcceptSynchronousConnectionStatus : CommandStatus (command_op_code = ACCEPT_SYNCHRONOUS_CONNECTION) { packet AcceptSynchronousConnectionStatus : CommandStatus (command_op_code = ACCEPT_SYNCHRONOUS_CONNECTION) { Loading Loading @@ -1342,34 +1362,14 @@ enum ScoDataPath : 8 { AUDIO_TEST_MODE = 0xFF, 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) { packet EnhancedSetupSynchronousConnection : ScoConnectionCommand (op_code = ENHANCED_SETUP_SYNCHRONOUS_CONNECTION) { connection_handle: 12, connection_handle: 12, _reserved_ : 4, _reserved_ : 4, // Next two items // Next two items // [0x00000000, 0xFFFFFFFE] Bandwidth in octets per second. // [0x00000000, 0xFFFFFFFE] Bandwidth in octets per second. // [0xFFFFFFFF]: Don't care // [0xFFFFFFFF]: Don't care transmit_bandwidth_octets_per_second : 32, transmit_bandwidth : 32, receive_bandwidth_octets_per_second : 32, receive_bandwidth : 32, transmit_coding_format : ScoCodingFormat, transmit_coding_format : ScoCodingFormat, receive_coding_format : ScoCodingFormat, receive_coding_format : ScoCodingFormat, // Next two items // Next two items Loading @@ -1379,8 +1379,8 @@ packet EnhancedSetupSynchronousConnection : ScoConnectionCommand (op_code = ENHA receive_codec_frame_size : 16, receive_codec_frame_size : 16, // Next two items // Next two items // Host to Controller nominal data rate in octets per second. // Host to Controller nominal data rate in octets per second. input_bandwidth_octets_per_second : 32, input_bandwidth : 32, output_bandwidth_octets_per_second : 32, output_bandwidth : 32, input_coding_format : ScoCodingFormat, input_coding_format : ScoCodingFormat, output_coding_format : ScoCodingFormat, output_coding_format : ScoCodingFormat, // Next two items // Next two items Loading @@ -1407,11 +1407,15 @@ packet EnhancedSetupSynchronousConnection : ScoConnectionCommand (op_code = ENHA // of the eSCO window, where the eSCO window is reserved slots plus the // of the eSCO window, where the eSCO window is reserved slots plus the // retransmission window // retransmission window // [0xFFFF]: don't care // [0xFFFF]: don't care max_latency_ms: 16, max_latency: 16, packet_type : 16, // Or together SynchronousPacketTypeBits packet_type : 16, // See SynchronousPacketTypeBits retransmission_effort : RetransmissionEffort, 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) { packet EnhancedSetupSynchronousConnectionStatus : CommandStatus (command_op_code = ENHANCED_SETUP_SYNCHRONOUS_CONNECTION) { } } Loading Loading @@ -1460,7 +1464,7 @@ packet EnhancedAcceptSynchronousConnection : ScoConnectionCommand (op_code = ENH // retransmission window // retransmission window // [0xFFFF]: don't care // [0xFFFF]: don't care max_latency : 16, max_latency : 16, packet_type : 16, // Or together SynchronousPacketTypeBits packet_type : 16, // See SynchronousPacketTypeBits retransmission_effort : RetransmissionEffort, retransmission_effort : RetransmissionEffort, } } Loading Loading @@ -5342,6 +5346,10 @@ packet SynchronousConnectionComplete : Event (event_code = SYNCHRONOUS_CONNECTIO air_mode : ScoAirMode, 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) { packet SynchronousConnectionChanged : Event (event_code = SYNCHRONOUS_CONNECTION_CHANGED) { status : ErrorCode, status : ErrorCode, connection_handle : 12, connection_handle : 12, Loading Loading @@ -5435,6 +5443,10 @@ packet EnhancedFlush : Command (op_code = ENHANCED_FLUSH) { packet_type : FlushablePacketType, packet_type : FlushablePacketType, } } test EnhancedFlush { "\x5f\x0c\x03\x02\x00\x00", } packet EnhancedFlushStatus : CommandStatus (command_op_code = ENHANCED_FLUSH) { packet EnhancedFlushStatus : CommandStatus (command_op_code = ENHANCED_FLUSH) { } } Loading @@ -5443,6 +5455,10 @@ packet EnhancedFlushComplete : Event (event_code = ENHANCED_FLUSH_COMPLETE) { _reserved_ : 4, _reserved_ : 4, } } test EnhancedFlushComplete { "\x39\x02\x02\x00", } packet UserPasskeyNotification : Event (event_code = USER_PASSKEY_NOTIFICATION) { packet UserPasskeyNotification : Event (event_code = USER_PASSKEY_NOTIFICATION) { bd_addr : Address, bd_addr : Address, passkey : 20, // 0x00000-0xF423F (000000 - 999999) passkey : 20, // 0x00000-0xF423F (000000 - 999999) Loading tools/rootcanal/model/controller/dual_mode_controller.cc +315 −2 Original line number Original line Diff line number Diff line Loading @@ -126,6 +126,10 @@ DualModeController::DualModeController(const std::string& properties_filename, SET_SUPPORTED(SETUP_SYNCHRONOUS_CONNECTION, SetupSynchronousConnection); SET_SUPPORTED(SETUP_SYNCHRONOUS_CONNECTION, SetupSynchronousConnection); SET_SUPPORTED(ACCEPT_SYNCHRONOUS_CONNECTION, AcceptSynchronousConnection); SET_SUPPORTED(ACCEPT_SYNCHRONOUS_CONNECTION, AcceptSynchronousConnection); SET_SUPPORTED(REJECT_SYNCHRONOUS_CONNECTION, RejectSynchronousConnection); 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(IO_CAPABILITY_REQUEST_REPLY, IoCapabilityRequestReply); SET_SUPPORTED(USER_CONFIRMATION_REQUEST_REPLY, UserConfirmationRequestReply); SET_SUPPORTED(USER_CONFIRMATION_REQUEST_REPLY, UserConfirmationRequestReply); SET_SUPPORTED(USER_CONFIRMATION_REQUEST_NEGATIVE_REPLY, SET_SUPPORTED(USER_CONFIRMATION_REQUEST_NEGATIVE_REPLY, Loading @@ -145,6 +149,7 @@ DualModeController::DualModeController(const std::string& properties_filename, SET_SUPPORTED(READ_INQUIRY_RESPONSE_TRANSMIT_POWER_LEVEL, SET_SUPPORTED(READ_INQUIRY_RESPONSE_TRANSMIT_POWER_LEVEL, ReadInquiryResponseTransmitPowerLevel); ReadInquiryResponseTransmitPowerLevel); SET_SUPPORTED(SEND_KEYPRESS_NOTIFICATION, SendKeypressNotification); SET_SUPPORTED(SEND_KEYPRESS_NOTIFICATION, SendKeypressNotification); SET_SUPPORTED(ENHANCED_FLUSH, EnhancedFlush); SET_HANDLER(SET_EVENT_MASK_PAGE_2, SetEventMaskPage2); SET_HANDLER(SET_EVENT_MASK_PAGE_2, SetEventMaskPage2); SET_SUPPORTED(READ_LOCAL_OOB_DATA, ReadLocalOobData); SET_SUPPORTED(READ_LOCAL_OOB_DATA, ReadLocalOobData); SET_SUPPORTED(READ_LOCAL_OOB_EXTENDED_DATA, ReadLocalOobExtendedData); SET_SUPPORTED(READ_LOCAL_OOB_EXTENDED_DATA, ReadLocalOobExtendedData); Loading Loading @@ -684,7 +689,8 @@ void DualModeController::SetupSynchronousConnection(CommandView command) { auto status = link_layer_controller_.SetupSynchronousConnection( auto status = link_layer_controller_.SetupSynchronousConnection( command_view.GetConnectionHandle(), command_view.GetTransmitBandwidth(), command_view.GetConnectionHandle(), command_view.GetTransmitBandwidth(), command_view.GetReceiveBandwidth(), command_view.GetMaxLatency(), 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()); command_view.GetPacketType()); send_event_(bluetooth::hci::SetupSynchronousConnectionStatusBuilder::Create( send_event_(bluetooth::hci::SetupSynchronousConnectionStatusBuilder::Create( Loading @@ -700,13 +706,304 @@ void DualModeController::AcceptSynchronousConnection(CommandView command) { auto status = link_layer_controller_.AcceptSynchronousConnection( auto status = link_layer_controller_.AcceptSynchronousConnection( command_view.GetBdAddr(), command_view.GetTransmitBandwidth(), command_view.GetBdAddr(), command_view.GetTransmitBandwidth(), command_view.GetReceiveBandwidth(), command_view.GetMaxLatency(), 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()); command_view.GetPacketType()); send_event_(bluetooth::hci::AcceptSynchronousConnectionStatusBuilder::Create( send_event_(bluetooth::hci::AcceptSynchronousConnectionStatusBuilder::Create( status, kNumCommandPackets)); 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) { void DualModeController::RejectSynchronousConnection(CommandView command) { auto command_view = gd_hci::RejectSynchronousConnectionView::Create( auto command_view = gd_hci::RejectSynchronousConnectionView::Create( gd_hci::ScoConnectionCommandView::Create( gd_hci::ScoConnectionCommandView::Create( Loading Loading @@ -959,6 +1256,22 @@ void DualModeController::SendKeypressNotification(CommandView command) { #endif /* ROOTCANAL_LMP */ #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) { void DualModeController::SetEventMaskPage2(CommandView command) { auto payload = auto payload = std::make_unique<bluetooth::packet::RawBuilder>(std::vector<uint8_t>( std::make_unique<bluetooth::packet::RawBuilder>(std::vector<uint8_t>( Loading tools/rootcanal/model/controller/dual_mode_controller.h +9 −0 Original line number Original line Diff line number Diff line Loading @@ -222,6 +222,12 @@ class DualModeController : public Device { // 7.1.36 // 7.1.36 void IoCapabilityRequestNegativeReply(CommandView args); void IoCapabilityRequestNegativeReply(CommandView args); // 7.1.45 void EnhancedSetupSynchronousConnection(CommandView args); // 7.1.46 void EnhancedAcceptSynchronousConnection(CommandView args); // 7.1.53 // 7.1.53 void RemoteOobExtendedDataRequestReply(CommandView args); void RemoteOobExtendedDataRequestReply(CommandView args); Loading Loading @@ -372,6 +378,9 @@ class DualModeController : public Device { // 7.3.63 // 7.3.63 void SendKeypressNotification(CommandView args); void SendKeypressNotification(CommandView args); // 7.3.66 void EnhancedFlush(CommandView args); // 7.3.69 // 7.3.69 void SetEventMaskPage2(CommandView args); void SetEventMaskPage2(CommandView args); Loading Loading
system/gd/hci/hci_packets.pdl +47 −31 Original line number Original line Diff line number Diff line Loading @@ -1168,6 +1168,26 @@ packet ReadLmpHandleComplete : CommandComplete (command_op_code = READ_LMP_HANDL _reserved_ : 32, _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) { packet SetupSynchronousConnection : ScoConnectionCommand (op_code = SETUP_SYNCHRONOUS_CONNECTION) { connection_handle : 12, connection_handle : 12, _reserved_ : 4, _reserved_ : 4, Loading @@ -1176,8 +1196,8 @@ packet SetupSynchronousConnection : ScoConnectionCommand (op_code = SETUP_SYNCHR max_latency : 16, // 0-3 reserved, 0xFFFF = don't care max_latency : 16, // 0-3 reserved, 0xFFFF = don't care voice_setting : 10, voice_setting : 10, _reserved_ : 6, _reserved_ : 6, retransmission_effort : 8, retransmission_effort : RetransmissionEffort, packet_type : 16, packet_type : 16, // See SynchronousPacketTypeBits } } packet SetupSynchronousConnectionStatus : CommandStatus (command_op_code = SETUP_SYNCHRONOUS_CONNECTION) { packet SetupSynchronousConnectionStatus : CommandStatus (command_op_code = SETUP_SYNCHRONOUS_CONNECTION) { Loading @@ -1190,8 +1210,8 @@ packet AcceptSynchronousConnection : ScoConnectionCommand (op_code = ACCEPT_SYNC max_latency : 16, // 0-3 reserved, 0xFFFF = don't care max_latency : 16, // 0-3 reserved, 0xFFFF = don't care voice_setting : 10, voice_setting : 10, _reserved_ : 6, _reserved_ : 6, retransmission_effort : 8, retransmission_effort : RetransmissionEffort, packet_type : 16, packet_type : 16, // See SynchronousPacketTypeBits } } packet AcceptSynchronousConnectionStatus : CommandStatus (command_op_code = ACCEPT_SYNCHRONOUS_CONNECTION) { packet AcceptSynchronousConnectionStatus : CommandStatus (command_op_code = ACCEPT_SYNCHRONOUS_CONNECTION) { Loading Loading @@ -1342,34 +1362,14 @@ enum ScoDataPath : 8 { AUDIO_TEST_MODE = 0xFF, 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) { packet EnhancedSetupSynchronousConnection : ScoConnectionCommand (op_code = ENHANCED_SETUP_SYNCHRONOUS_CONNECTION) { connection_handle: 12, connection_handle: 12, _reserved_ : 4, _reserved_ : 4, // Next two items // Next two items // [0x00000000, 0xFFFFFFFE] Bandwidth in octets per second. // [0x00000000, 0xFFFFFFFE] Bandwidth in octets per second. // [0xFFFFFFFF]: Don't care // [0xFFFFFFFF]: Don't care transmit_bandwidth_octets_per_second : 32, transmit_bandwidth : 32, receive_bandwidth_octets_per_second : 32, receive_bandwidth : 32, transmit_coding_format : ScoCodingFormat, transmit_coding_format : ScoCodingFormat, receive_coding_format : ScoCodingFormat, receive_coding_format : ScoCodingFormat, // Next two items // Next two items Loading @@ -1379,8 +1379,8 @@ packet EnhancedSetupSynchronousConnection : ScoConnectionCommand (op_code = ENHA receive_codec_frame_size : 16, receive_codec_frame_size : 16, // Next two items // Next two items // Host to Controller nominal data rate in octets per second. // Host to Controller nominal data rate in octets per second. input_bandwidth_octets_per_second : 32, input_bandwidth : 32, output_bandwidth_octets_per_second : 32, output_bandwidth : 32, input_coding_format : ScoCodingFormat, input_coding_format : ScoCodingFormat, output_coding_format : ScoCodingFormat, output_coding_format : ScoCodingFormat, // Next two items // Next two items Loading @@ -1407,11 +1407,15 @@ packet EnhancedSetupSynchronousConnection : ScoConnectionCommand (op_code = ENHA // of the eSCO window, where the eSCO window is reserved slots plus the // of the eSCO window, where the eSCO window is reserved slots plus the // retransmission window // retransmission window // [0xFFFF]: don't care // [0xFFFF]: don't care max_latency_ms: 16, max_latency: 16, packet_type : 16, // Or together SynchronousPacketTypeBits packet_type : 16, // See SynchronousPacketTypeBits retransmission_effort : RetransmissionEffort, 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) { packet EnhancedSetupSynchronousConnectionStatus : CommandStatus (command_op_code = ENHANCED_SETUP_SYNCHRONOUS_CONNECTION) { } } Loading Loading @@ -1460,7 +1464,7 @@ packet EnhancedAcceptSynchronousConnection : ScoConnectionCommand (op_code = ENH // retransmission window // retransmission window // [0xFFFF]: don't care // [0xFFFF]: don't care max_latency : 16, max_latency : 16, packet_type : 16, // Or together SynchronousPacketTypeBits packet_type : 16, // See SynchronousPacketTypeBits retransmission_effort : RetransmissionEffort, retransmission_effort : RetransmissionEffort, } } Loading Loading @@ -5342,6 +5346,10 @@ packet SynchronousConnectionComplete : Event (event_code = SYNCHRONOUS_CONNECTIO air_mode : ScoAirMode, 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) { packet SynchronousConnectionChanged : Event (event_code = SYNCHRONOUS_CONNECTION_CHANGED) { status : ErrorCode, status : ErrorCode, connection_handle : 12, connection_handle : 12, Loading Loading @@ -5435,6 +5443,10 @@ packet EnhancedFlush : Command (op_code = ENHANCED_FLUSH) { packet_type : FlushablePacketType, packet_type : FlushablePacketType, } } test EnhancedFlush { "\x5f\x0c\x03\x02\x00\x00", } packet EnhancedFlushStatus : CommandStatus (command_op_code = ENHANCED_FLUSH) { packet EnhancedFlushStatus : CommandStatus (command_op_code = ENHANCED_FLUSH) { } } Loading @@ -5443,6 +5455,10 @@ packet EnhancedFlushComplete : Event (event_code = ENHANCED_FLUSH_COMPLETE) { _reserved_ : 4, _reserved_ : 4, } } test EnhancedFlushComplete { "\x39\x02\x02\x00", } packet UserPasskeyNotification : Event (event_code = USER_PASSKEY_NOTIFICATION) { packet UserPasskeyNotification : Event (event_code = USER_PASSKEY_NOTIFICATION) { bd_addr : Address, bd_addr : Address, passkey : 20, // 0x00000-0xF423F (000000 - 999999) passkey : 20, // 0x00000-0xF423F (000000 - 999999) Loading
tools/rootcanal/model/controller/dual_mode_controller.cc +315 −2 Original line number Original line Diff line number Diff line Loading @@ -126,6 +126,10 @@ DualModeController::DualModeController(const std::string& properties_filename, SET_SUPPORTED(SETUP_SYNCHRONOUS_CONNECTION, SetupSynchronousConnection); SET_SUPPORTED(SETUP_SYNCHRONOUS_CONNECTION, SetupSynchronousConnection); SET_SUPPORTED(ACCEPT_SYNCHRONOUS_CONNECTION, AcceptSynchronousConnection); SET_SUPPORTED(ACCEPT_SYNCHRONOUS_CONNECTION, AcceptSynchronousConnection); SET_SUPPORTED(REJECT_SYNCHRONOUS_CONNECTION, RejectSynchronousConnection); 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(IO_CAPABILITY_REQUEST_REPLY, IoCapabilityRequestReply); SET_SUPPORTED(USER_CONFIRMATION_REQUEST_REPLY, UserConfirmationRequestReply); SET_SUPPORTED(USER_CONFIRMATION_REQUEST_REPLY, UserConfirmationRequestReply); SET_SUPPORTED(USER_CONFIRMATION_REQUEST_NEGATIVE_REPLY, SET_SUPPORTED(USER_CONFIRMATION_REQUEST_NEGATIVE_REPLY, Loading @@ -145,6 +149,7 @@ DualModeController::DualModeController(const std::string& properties_filename, SET_SUPPORTED(READ_INQUIRY_RESPONSE_TRANSMIT_POWER_LEVEL, SET_SUPPORTED(READ_INQUIRY_RESPONSE_TRANSMIT_POWER_LEVEL, ReadInquiryResponseTransmitPowerLevel); ReadInquiryResponseTransmitPowerLevel); SET_SUPPORTED(SEND_KEYPRESS_NOTIFICATION, SendKeypressNotification); SET_SUPPORTED(SEND_KEYPRESS_NOTIFICATION, SendKeypressNotification); SET_SUPPORTED(ENHANCED_FLUSH, EnhancedFlush); SET_HANDLER(SET_EVENT_MASK_PAGE_2, SetEventMaskPage2); SET_HANDLER(SET_EVENT_MASK_PAGE_2, SetEventMaskPage2); SET_SUPPORTED(READ_LOCAL_OOB_DATA, ReadLocalOobData); SET_SUPPORTED(READ_LOCAL_OOB_DATA, ReadLocalOobData); SET_SUPPORTED(READ_LOCAL_OOB_EXTENDED_DATA, ReadLocalOobExtendedData); SET_SUPPORTED(READ_LOCAL_OOB_EXTENDED_DATA, ReadLocalOobExtendedData); Loading Loading @@ -684,7 +689,8 @@ void DualModeController::SetupSynchronousConnection(CommandView command) { auto status = link_layer_controller_.SetupSynchronousConnection( auto status = link_layer_controller_.SetupSynchronousConnection( command_view.GetConnectionHandle(), command_view.GetTransmitBandwidth(), command_view.GetConnectionHandle(), command_view.GetTransmitBandwidth(), command_view.GetReceiveBandwidth(), command_view.GetMaxLatency(), 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()); command_view.GetPacketType()); send_event_(bluetooth::hci::SetupSynchronousConnectionStatusBuilder::Create( send_event_(bluetooth::hci::SetupSynchronousConnectionStatusBuilder::Create( Loading @@ -700,13 +706,304 @@ void DualModeController::AcceptSynchronousConnection(CommandView command) { auto status = link_layer_controller_.AcceptSynchronousConnection( auto status = link_layer_controller_.AcceptSynchronousConnection( command_view.GetBdAddr(), command_view.GetTransmitBandwidth(), command_view.GetBdAddr(), command_view.GetTransmitBandwidth(), command_view.GetReceiveBandwidth(), command_view.GetMaxLatency(), 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()); command_view.GetPacketType()); send_event_(bluetooth::hci::AcceptSynchronousConnectionStatusBuilder::Create( send_event_(bluetooth::hci::AcceptSynchronousConnectionStatusBuilder::Create( status, kNumCommandPackets)); 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) { void DualModeController::RejectSynchronousConnection(CommandView command) { auto command_view = gd_hci::RejectSynchronousConnectionView::Create( auto command_view = gd_hci::RejectSynchronousConnectionView::Create( gd_hci::ScoConnectionCommandView::Create( gd_hci::ScoConnectionCommandView::Create( Loading Loading @@ -959,6 +1256,22 @@ void DualModeController::SendKeypressNotification(CommandView command) { #endif /* ROOTCANAL_LMP */ #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) { void DualModeController::SetEventMaskPage2(CommandView command) { auto payload = auto payload = std::make_unique<bluetooth::packet::RawBuilder>(std::vector<uint8_t>( std::make_unique<bluetooth::packet::RawBuilder>(std::vector<uint8_t>( Loading
tools/rootcanal/model/controller/dual_mode_controller.h +9 −0 Original line number Original line Diff line number Diff line Loading @@ -222,6 +222,12 @@ class DualModeController : public Device { // 7.1.36 // 7.1.36 void IoCapabilityRequestNegativeReply(CommandView args); void IoCapabilityRequestNegativeReply(CommandView args); // 7.1.45 void EnhancedSetupSynchronousConnection(CommandView args); // 7.1.46 void EnhancedAcceptSynchronousConnection(CommandView args); // 7.1.53 // 7.1.53 void RemoteOobExtendedDataRequestReply(CommandView args); void RemoteOobExtendedDataRequestReply(CommandView args); Loading Loading @@ -372,6 +378,9 @@ class DualModeController : public Device { // 7.3.63 // 7.3.63 void SendKeypressNotification(CommandView args); void SendKeypressNotification(CommandView args); // 7.3.66 void EnhancedFlush(CommandView args); // 7.3.69 // 7.3.69 void SetEventMaskPage2(CommandView args); void SetEventMaskPage2(CommandView args); Loading