diff options
author | Chienyuan <chienyuanhuang@google.com> | 2019-08-15 18:04:32 +0800 |
---|---|---|
committer | Chienyuan <chienyuanhuang@google.com> | 2019-08-27 23:11:35 +0800 |
commit | a7ad3fb7fb4d4a8ded04e494c8a0ca802a7e3ad5 (patch) | |
tree | 63b7ee0971592de88680b73b961da5a9f4d1e347 | |
parent | 4aa9aa7a938c22064691720510455153a6eae0ee (diff) | |
download | bt-a7ad3fb7fb4d4a8ded04e494c8a0ca802a7e3ad5.tar.gz |
GD: Implement internal HCI commands
Bug: 139329371
Test: run run_cert.sh
Change-Id: Ia9100bab1c1a212fd9031a8049dfd97e469ebad5
-rw-r--r-- | gd/hci/cert/simple_hci_test.py | 6 | ||||
-rw-r--r-- | gd/hci/controller.cc | 594 | ||||
-rw-r--r-- | gd/hci/controller.h | 56 | ||||
-rw-r--r-- | gd/hci/controller_test.cc | 203 | ||||
-rw-r--r-- | gd/hci/facade.cc | 52 | ||||
-rw-r--r-- | gd/hci/facade.proto | 2 | ||||
-rw-r--r-- | gd/hci/hci_layer_test.cc | 30 | ||||
-rw-r--r-- | gd/hci/hci_packets.pdl | 266 | ||||
-rw-r--r-- | vendor_libs/test_vendor_lib/model/devices/device_properties.cc | 4 |
9 files changed, 1188 insertions, 25 deletions
diff --git a/gd/hci/cert/simple_hci_test.py b/gd/hci/cert/simple_hci_test.py index 9b1b3c20c..d26b44c93 100644 --- a/gd/hci/cert/simple_hci_test.py +++ b/gd/hci/cert/simple_hci_test.py @@ -335,4 +335,10 @@ class SimpleHciTest(GdBaseTestClass): ) self.dut_command_complete_stream.unsubscribe() + self._disconnect_from_dut() + + def test_interal_hci_command(self): + self._connect_from_dut() + self.device_under_test.hci.TestInternalHciCommands(empty_pb2.Empty()) + self.device_under_test.hci.TestInternalHciLeCommands(empty_pb2.Empty()) self._disconnect_from_dut()
\ No newline at end of file diff --git a/gd/hci/controller.cc b/gd/hci/controller.cc index 4fdb93b3f..a88bcfe77 100644 --- a/gd/hci/controller.cc +++ b/gd/hci/controller.cc @@ -43,10 +43,67 @@ struct Controller::impl { hci_->RegisterEventHandler(EventCode::NUMBER_OF_COMPLETED_PACKETS, Bind(&Controller::impl::NumberOfCompletedPackets, common::Unretained(this)), module_.GetHandler()); + + hci_->EnqueueCommand(ReadLocalNameBuilder::Create(), + BindOnce(&Controller::impl::read_local_name_complete_handler, common::Unretained(this)), + module_.GetHandler()); + hci_->EnqueueCommand( + ReadLocalVersionInformationBuilder::Create(), + BindOnce(&Controller::impl::read_local_version_information_complete_handler, common::Unretained(this)), + module_.GetHandler()); + hci_->EnqueueCommand( + ReadLocalSupportedCommandsBuilder::Create(), + BindOnce(&Controller::impl::read_local_supported_commands_complete_handler, common::Unretained(this)), + module_.GetHandler()); + hci_->EnqueueCommand( + ReadLocalSupportedFeaturesBuilder::Create(), + BindOnce(&Controller::impl::read_local_supported_features_complete_handler, common::Unretained(this)), + module_.GetHandler()); + + // Wait for all extended features read + std::promise<void> features_promise; + auto features_future = features_promise.get_future(); + hci_->EnqueueCommand(ReadLocalExtendedFeaturesBuilder::Create(0x00), + BindOnce(&Controller::impl::read_local_extended_features_complete_handler, + common::Unretained(this), std::move(features_promise)), + module_.GetHandler()); + features_future.wait(); + hci_->EnqueueCommand(ReadBufferSizeBuilder::Create(), BindOnce(&Controller::impl::read_buffer_size_complete_handler, common::Unretained(this)), module_.GetHandler()); + hci_->EnqueueCommand(LeReadBufferSizeBuilder::Create(), + BindOnce(&Controller::impl::le_read_buffer_size_handler, common::Unretained(this)), + module_.GetHandler()); + + hci_->EnqueueCommand( + LeReadLocalSupportedFeaturesBuilder::Create(), + BindOnce(&Controller::impl::le_read_local_supported_features_handler, common::Unretained(this)), + module_.GetHandler()); + + hci_->EnqueueCommand(LeReadSupportedStatesBuilder::Create(), + BindOnce(&Controller::impl::le_read_supported_states_handler, common::Unretained(this)), + module_.GetHandler()); + + if (is_support(OpCode::LE_READ_MAXIMUM_DATA_LENGTH)) { + hci_->EnqueueCommand(LeReadMaximumDataLengthBuilder::Create(), + BindOnce(&Controller::impl::le_read_maximum_data_length_handler, common::Unretained(this)), + module_.GetHandler()); + } + if (is_support(OpCode::LE_READ_MAXIMUM_ADVERTISING_DATA_LENGTH)) { + hci_->EnqueueCommand( + LeReadMaximumAdvertisingDataLengthBuilder::Create(), + BindOnce(&Controller::impl::le_read_maximum_advertising_data_length_handler, common::Unretained(this)), + module_.GetHandler()); + } + if (is_support(OpCode::LE_READ_NUMBER_OF_SUPPORTED_ADVERTISING_SETS)) { + hci_->EnqueueCommand( + LeReadNumberOfSupportedAdvertisingSetsBuilder::Create(), + BindOnce(&Controller::impl::le_read_number_of_supported_advertising_sets_handler, common::Unretained(this)), + module_.GetHandler()); + } + // We only need to synchronize the last read. Make BD_ADDR to be the last one. std::promise<void> promise; auto future = promise.get_future(); @@ -80,6 +137,64 @@ struct Controller::impl { acl_credits_handler_ = handler; } + void read_local_name_complete_handler(CommandCompleteView view) { + auto complete_view = ReadLocalNameCompleteView::Create(view); + ASSERT(complete_view.IsValid()); + ErrorCode status = complete_view.GetStatus(); + ASSERT_LOG(status == ErrorCode::SUCCESS, "Status 0x%02hhx, %s", status, ErrorCodeText(status).c_str()); + std::array<uint8_t, 248> local_name_array = complete_view.GetLocalName(); + + local_name_ = std::string(local_name_array.begin(), local_name_array.end()); + // erase \0 + local_name_.erase(std::find(local_name_.begin(), local_name_.end(), '\0'), local_name_.end()); + } + + void read_local_version_information_complete_handler(CommandCompleteView view) { + auto complete_view = ReadLocalVersionInformationCompleteView::Create(view); + ASSERT(complete_view.IsValid()); + ErrorCode status = complete_view.GetStatus(); + ASSERT_LOG(status == ErrorCode::SUCCESS, "Status 0x%02hhx, %s", status, ErrorCodeText(status).c_str()); + + local_version_information_ = complete_view.GetLocalVersionInformation(); + } + + void read_local_supported_commands_complete_handler(CommandCompleteView view) { + auto complete_view = ReadLocalSupportedCommandsCompleteView::Create(view); + ASSERT(complete_view.IsValid()); + ErrorCode status = complete_view.GetStatus(); + ASSERT_LOG(status == ErrorCode::SUCCESS, "Status 0x%02hhx, %s", status, ErrorCodeText(status).c_str()); + local_supported_commands_ = complete_view.GetSupportedCommands(); + } + + void read_local_supported_features_complete_handler(CommandCompleteView view) { + auto complete_view = ReadLocalSupportedFeaturesCompleteView::Create(view); + ASSERT(complete_view.IsValid()); + ErrorCode status = complete_view.GetStatus(); + ASSERT_LOG(status == ErrorCode::SUCCESS, "Status 0x%02hhx, %s", status, ErrorCodeText(status).c_str()); + local_supported_features_ = complete_view.GetLmpFeatures(); + } + + void read_local_extended_features_complete_handler(std::promise<void> promise, CommandCompleteView view) { + auto complete_view = ReadLocalExtendedFeaturesCompleteView::Create(view); + ASSERT(complete_view.IsValid()); + ErrorCode status = complete_view.GetStatus(); + ASSERT_LOG(status == ErrorCode::SUCCESS, "Status 0x%02hhx, %s", status, ErrorCodeText(status).c_str()); + uint8_t page_number = complete_view.GetPageNumber(); + maximum_page_number_ = complete_view.GetMaximumPageNumber(); + extended_lmp_features_array_.push_back(complete_view.GetExtendedLmpFeatures()); + + // Query all extended features + if (page_number < maximum_page_number_) { + page_number++; + hci_->EnqueueCommand(ReadLocalExtendedFeaturesBuilder::Create(page_number), + BindOnce(&Controller::impl::read_local_extended_features_complete_handler, + common::Unretained(this), std::move(promise)), + module_.GetHandler()); + } else { + promise.set_value(); + } + } + void read_buffer_size_complete_handler(CommandCompleteView view) { auto complete_view = ReadBufferSizeCompleteView::Create(view); ASSERT(complete_view.IsValid()); @@ -101,18 +216,370 @@ struct Controller::impl { promise.set_value(); } + void le_read_buffer_size_handler(CommandCompleteView view) { + auto complete_view = LeReadBufferSizeCompleteView::Create(view); + ASSERT(complete_view.IsValid()); + ErrorCode status = complete_view.GetStatus(); + ASSERT_LOG(status == ErrorCode::SUCCESS, "Status 0x%02hhx, %s", status, ErrorCodeText(status).c_str()); + le_buffer_size_ = complete_view.GetLeBufferSize(); + } + + void le_read_local_supported_features_handler(CommandCompleteView view) { + auto complete_view = LeReadLocalSupportedFeaturesCompleteView::Create(view); + ASSERT(complete_view.IsValid()); + ErrorCode status = complete_view.GetStatus(); + ASSERT_LOG(status == ErrorCode::SUCCESS, "Status 0x%02hhx, %s", status, ErrorCodeText(status).c_str()); + le_local_supported_features_ = complete_view.GetLeFeatures(); + } + + void le_read_supported_states_handler(CommandCompleteView view) { + auto complete_view = LeReadSupportedStatesCompleteView::Create(view); + ASSERT(complete_view.IsValid()); + ErrorCode status = complete_view.GetStatus(); + ASSERT_LOG(status == ErrorCode::SUCCESS, "Status 0x%02hhx, %s", status, ErrorCodeText(status).c_str()); + le_supported_states_ = complete_view.GetLeStates(); + } + + void le_read_maximum_data_length_handler(CommandCompleteView view) { + auto complete_view = LeReadMaximumDataLengthCompleteView::Create(view); + ASSERT(complete_view.IsValid()); + ErrorCode status = complete_view.GetStatus(); + ASSERT_LOG(status == ErrorCode::SUCCESS, "Status 0x%02hhx, %s", status, ErrorCodeText(status).c_str()); + le_maximum_data_length_ = complete_view.GetLeMaximumDataLength(); + } + + void le_read_maximum_advertising_data_length_handler(CommandCompleteView view) { + auto complete_view = LeReadMaximumAdvertisingDataLengthCompleteView::Create(view); + ASSERT(complete_view.IsValid()); + ErrorCode status = complete_view.GetStatus(); + ASSERT_LOG(status == ErrorCode::SUCCESS, "Status 0x%02hhx, %s", status, ErrorCodeText(status).c_str()); + le_maximum_advertising_data_length_ = complete_view.GetMaximumAdvertisingDataLength(); + } + + void le_read_number_of_supported_advertising_sets_handler(CommandCompleteView view) { + auto complete_view = LeReadNumberOfSupportedAdvertisingSetsCompleteView::Create(view); + ASSERT(complete_view.IsValid()); + ErrorCode status = complete_view.GetStatus(); + ASSERT_LOG(status == ErrorCode::SUCCESS, "Status 0x%02hhx, %s", status, ErrorCodeText(status).c_str()); + le_number_supported_advertising_sets_ = complete_view.GetNumberSupportedAdvertisingSets(); + } + + void set_event_mask(uint64_t event_mask) { + std::unique_ptr<SetEventMaskBuilder> packet = SetEventMaskBuilder::Create(event_mask); + hci_->EnqueueCommand(std::move(packet), common::BindOnce([](CommandCompleteView complete) { /* TODO */ }), + module_.GetHandler()); + } + + void reset() { + std::unique_ptr<ResetBuilder> packet = ResetBuilder::Create(); + hci_->EnqueueCommand(std::move(packet), common::BindOnce([](CommandCompleteView complete) { /* TODO */ }), + module_.GetHandler()); + } + + void set_event_filter(std::unique_ptr<SetEventFilterBuilder> packet) { + hci_->EnqueueCommand(std::move(packet), common::BindOnce([](CommandCompleteView complete) { /* TODO */ }), + module_.GetHandler()); + } + + void write_local_name(std::string local_name) { + ASSERT(local_name.length() <= 248); + // Fill remaining char with 0 + local_name.append(std::string(248 - local_name.length(), '\0')); + std::array<uint8_t, 248> local_name_array; + std::copy(std::begin(local_name), std::end(local_name), std::begin(local_name_array)); + + std::unique_ptr<WriteLocalNameBuilder> packet = WriteLocalNameBuilder::Create(local_name_array); + hci_->EnqueueCommand(std::move(packet), common::BindOnce([](CommandCompleteView complete) { /* TODO */ }), + module_.GetHandler()); + } + + void host_buffer_size(uint16_t host_acl_data_packet_length, uint8_t host_synchronous_data_packet_length, + uint16_t host_total_num_acl_data_packets, uint16_t host_total_num_synchronous_data_packets) { + std::unique_ptr<HostBufferSizeBuilder> packet = + HostBufferSizeBuilder::Create(host_acl_data_packet_length, host_synchronous_data_packet_length, + host_total_num_acl_data_packets, host_total_num_synchronous_data_packets); + hci_->EnqueueCommand(std::move(packet), common::BindOnce([](CommandCompleteView complete) { /* TODO */ }), + module_.GetHandler()); + } + + void le_set_event_mask(uint64_t le_event_mask) { + std::unique_ptr<LeSetEventMaskBuilder> packet = LeSetEventMaskBuilder::Create(le_event_mask); + hci_->EnqueueCommand(std::move(packet), common::BindOnce([](CommandCompleteView complete) { /* TODO */ }), + module_.GetHandler()); + } + +#define OP_CODE_MAPPING(name) \ + case OpCode::name: { \ + uint16_t index = (uint16_t)OpCodeIndex::name; \ + uint16_t byte_index = index / 10; \ + uint16_t bit_index = index % 10; \ + bool supported = local_supported_commands_[byte_index] & (1 << bit_index); \ + if (!supported) { \ + LOG_WARN("unsupported command opcode: 0x%04x", (uint16_t)OpCode::name); \ + } \ + return supported; \ + } + + bool is_support(OpCode op_code) { + switch (op_code) { + OP_CODE_MAPPING(INQUIRY) + OP_CODE_MAPPING(INQUIRY_CANCEL) + OP_CODE_MAPPING(PERIODIC_INQUIRY_MODE) + OP_CODE_MAPPING(EXIT_PERIODIC_INQUIRY_MODE) + OP_CODE_MAPPING(CREATE_CONNECTION) + OP_CODE_MAPPING(DISCONNECT) + OP_CODE_MAPPING(CREATE_CONNECTION_CANCEL) + OP_CODE_MAPPING(ACCEPT_CONNECTION_REQUEST) + OP_CODE_MAPPING(REJECT_CONNECTION_REQUEST) + OP_CODE_MAPPING(LINK_KEY_REQUEST_REPLY) + OP_CODE_MAPPING(LINK_KEY_REQUEST_NEGATIVE_REPLY) + OP_CODE_MAPPING(PIN_CODE_REQUEST_REPLY) + OP_CODE_MAPPING(PIN_CODE_REQUEST_NEGATIVE_REPLY) + OP_CODE_MAPPING(CHANGE_CONNECTION_PACKET_TYPE) + OP_CODE_MAPPING(AUTHENTICATION_REQUESTED) + OP_CODE_MAPPING(SET_CONNECTION_ENCRYPTION) + OP_CODE_MAPPING(CHANGE_CONNECTION_LINK_KEY) + OP_CODE_MAPPING(MASTER_LINK_KEY) + OP_CODE_MAPPING(REMOTE_NAME_REQUEST) + OP_CODE_MAPPING(REMOTE_NAME_REQUEST_CANCEL) + OP_CODE_MAPPING(READ_REMOTE_SUPPORTED_FEATURES) + OP_CODE_MAPPING(READ_REMOTE_EXTENDED_FEATURES) + OP_CODE_MAPPING(READ_REMOTE_VERSION_INFORMATION) + OP_CODE_MAPPING(READ_CLOCK_OFFSET) + OP_CODE_MAPPING(READ_LMP_HANDLE) + OP_CODE_MAPPING(HOLD_MODE) + OP_CODE_MAPPING(SNIFF_MODE) + OP_CODE_MAPPING(EXIT_SNIFF_MODE) + OP_CODE_MAPPING(QOS_SETUP) + OP_CODE_MAPPING(ROLE_DISCOVERY) + OP_CODE_MAPPING(SWITCH_ROLE) + OP_CODE_MAPPING(READ_LINK_POLICY_SETTINGS) + OP_CODE_MAPPING(WRITE_LINK_POLICY_SETTINGS) + OP_CODE_MAPPING(READ_DEFAULT_LINK_POLICY_SETTINGS) + OP_CODE_MAPPING(WRITE_DEFAULT_LINK_POLICY_SETTINGS) + OP_CODE_MAPPING(FLOW_SPECIFICATION) + OP_CODE_MAPPING(SET_EVENT_MASK) + OP_CODE_MAPPING(RESET) + OP_CODE_MAPPING(SET_EVENT_FILTER) + OP_CODE_MAPPING(FLUSH) + OP_CODE_MAPPING(READ_PIN_TYPE) + OP_CODE_MAPPING(WRITE_PIN_TYPE) + OP_CODE_MAPPING(READ_STORED_LINK_KEY) + OP_CODE_MAPPING(WRITE_STORED_LINK_KEY) + OP_CODE_MAPPING(DELETE_STORED_LINK_KEY) + OP_CODE_MAPPING(WRITE_LOCAL_NAME) + OP_CODE_MAPPING(READ_LOCAL_NAME) + OP_CODE_MAPPING(READ_CONNECTION_ACCEPT_TIMEOUT) + OP_CODE_MAPPING(WRITE_CONNECTION_ACCEPT_TIMEOUT) + OP_CODE_MAPPING(READ_PAGE_TIMEOUT) + OP_CODE_MAPPING(WRITE_PAGE_TIMEOUT) + OP_CODE_MAPPING(READ_SCAN_ENABLE) + OP_CODE_MAPPING(WRITE_SCAN_ENABLE) + OP_CODE_MAPPING(READ_PAGE_SCAN_ACTIVITY) + OP_CODE_MAPPING(WRITE_PAGE_SCAN_ACTIVITY) + OP_CODE_MAPPING(READ_INQUIRY_SCAN_ACTIVITY) + OP_CODE_MAPPING(WRITE_INQUIRY_SCAN_ACTIVITY) + OP_CODE_MAPPING(READ_AUTHENTICATION_ENABLE) + OP_CODE_MAPPING(WRITE_AUTHENTICATION_ENABLE) + OP_CODE_MAPPING(READ_CLASS_OF_DEVICE) + OP_CODE_MAPPING(WRITE_CLASS_OF_DEVICE) + OP_CODE_MAPPING(READ_VOICE_SETTING) + OP_CODE_MAPPING(WRITE_VOICE_SETTING) + OP_CODE_MAPPING(READ_AUTOMATIC_FLUSH_TIMEOUT) + OP_CODE_MAPPING(WRITE_AUTOMATIC_FLUSH_TIMEOUT) + OP_CODE_MAPPING(READ_NUM_BROADCAST_RETRANSMITS) + OP_CODE_MAPPING(WRITE_NUM_BROADCAST_RETRANSMITS) + OP_CODE_MAPPING(READ_HOLD_MODE_ACTIVITY) + OP_CODE_MAPPING(WRITE_HOLD_MODE_ACTIVITY) + OP_CODE_MAPPING(READ_TRANSMIT_POWER_LEVEL) + OP_CODE_MAPPING(READ_SYNCHRONOUS_FLOW_CONTROL_ENABLE) + OP_CODE_MAPPING(WRITE_SYNCHRONOUS_FLOW_CONTROL_ENABLE) + OP_CODE_MAPPING(SET_CONTROLLER_TO_HOST_FLOW_CONTROL) + OP_CODE_MAPPING(HOST_BUFFER_SIZE) + OP_CODE_MAPPING(HOST_NUM_COMPLETED_PACKETS) + OP_CODE_MAPPING(READ_LINK_SUPERVISION_TIMEOUT) + OP_CODE_MAPPING(WRITE_LINK_SUPERVISION_TIMEOUT) + OP_CODE_MAPPING(READ_NUMBER_OF_SUPPORTED_IAC) + OP_CODE_MAPPING(READ_CURRENT_IAC_LAP) + OP_CODE_MAPPING(WRITE_CURRENT_IAC_LAP) + OP_CODE_MAPPING(SET_AFH_HOST_CHANNEL_CLASSIFICATION) + OP_CODE_MAPPING(READ_INQUIRY_SCAN_TYPE) + OP_CODE_MAPPING(WRITE_INQUIRY_SCAN_TYPE) + OP_CODE_MAPPING(READ_INQUIRY_MODE) + OP_CODE_MAPPING(WRITE_INQUIRY_MODE) + OP_CODE_MAPPING(READ_PAGE_SCAN_TYPE) + OP_CODE_MAPPING(WRITE_PAGE_SCAN_TYPE) + OP_CODE_MAPPING(READ_AFH_CHANNEL_ASSESSMENT_MODE) + OP_CODE_MAPPING(WRITE_AFH_CHANNEL_ASSESSMENT_MODE) + OP_CODE_MAPPING(READ_LOCAL_VERSION_INFORMATION) + OP_CODE_MAPPING(READ_LOCAL_SUPPORTED_FEATURES) + OP_CODE_MAPPING(READ_LOCAL_EXTENDED_FEATURES) + OP_CODE_MAPPING(READ_BUFFER_SIZE) + OP_CODE_MAPPING(READ_BD_ADDR) + OP_CODE_MAPPING(READ_FAILED_CONTACT_COUNTER) + OP_CODE_MAPPING(RESET_FAILED_CONTACT_COUNTER) + OP_CODE_MAPPING(READ_LINK_QUALITY) + OP_CODE_MAPPING(READ_RSSI) + OP_CODE_MAPPING(READ_AFH_CHANNEL_MAP) + OP_CODE_MAPPING(READ_CLOCK) + OP_CODE_MAPPING(READ_LOOPBACK_MODE) + OP_CODE_MAPPING(WRITE_LOOPBACK_MODE) + OP_CODE_MAPPING(ENABLE_DEVICE_UNDER_TEST_MODE) + OP_CODE_MAPPING(SETUP_SYNCHRONOUS_CONNECTION) + OP_CODE_MAPPING(ACCEPT_SYNCHRONOUS_CONNECTION) + OP_CODE_MAPPING(REJECT_SYNCHRONOUS_CONNECTION) + OP_CODE_MAPPING(READ_EXTENDED_INQUIRY_RESPONSE) + OP_CODE_MAPPING(WRITE_EXTENDED_INQUIRY_RESPONSE) + OP_CODE_MAPPING(REFRESH_ENCRYPTION_KEY) + OP_CODE_MAPPING(SNIFF_SUBRATING) + OP_CODE_MAPPING(READ_SIMPLE_PAIRING_MODE) + OP_CODE_MAPPING(WRITE_SIMPLE_PAIRING_MODE) + OP_CODE_MAPPING(READ_LOCAL_OOB_DATA) + OP_CODE_MAPPING(READ_INQUIRY_RESPONSE_TRANSMIT_POWER_LEVEL) + OP_CODE_MAPPING(WRITE_INQUIRY_TRANSMIT_POWER_LEVEL) + OP_CODE_MAPPING(IO_CAPABILITY_REQUEST_REPLY) + OP_CODE_MAPPING(USER_CONFIRMATION_REQUEST_REPLY) + OP_CODE_MAPPING(USER_CONFIRMATION_REQUEST_NEGATIVE_REPLY) + OP_CODE_MAPPING(USER_PASSKEY_REQUEST_REPLY) + OP_CODE_MAPPING(USER_PASSKEY_REQUEST_NEGATIVE_REPLY) + OP_CODE_MAPPING(REMOTE_OOB_DATA_REQUEST_REPLY) + OP_CODE_MAPPING(WRITE_SIMPLE_PAIRING_DEBUG_MODE) + OP_CODE_MAPPING(REMOTE_OOB_DATA_REQUEST_NEGATIVE_REPLY) + OP_CODE_MAPPING(SEND_KEYPRESS_NOTIFICATION) + OP_CODE_MAPPING(IO_CAPABILITY_REQUEST_NEGATIVE_REPLY) + OP_CODE_MAPPING(READ_ENCRYPTION_KEY_SIZE) + OP_CODE_MAPPING(READ_DATA_BLOCK_SIZE) + OP_CODE_MAPPING(READ_LE_HOST_SUPPORT) + OP_CODE_MAPPING(WRITE_LE_HOST_SUPPORT) + OP_CODE_MAPPING(LE_SET_EVENT_MASK) + OP_CODE_MAPPING(LE_READ_BUFFER_SIZE) + OP_CODE_MAPPING(LE_READ_LOCAL_SUPPORTED_FEATURES) + OP_CODE_MAPPING(LE_SET_RANDOM_ADDRESS) + OP_CODE_MAPPING(LE_SET_ADVERTISING_PARAMETERS) + OP_CODE_MAPPING(LE_READ_ADVERTISING_CHANNEL_TX_POWER) + OP_CODE_MAPPING(LE_SET_ADVERTISING_DATA) + OP_CODE_MAPPING(LE_SET_SCAN_RESPONSE_DATA) + OP_CODE_MAPPING(LE_SET_ADVERTISING_ENABLE) + OP_CODE_MAPPING(LE_SET_SCAN_PARAMETERS) + OP_CODE_MAPPING(LE_SET_SCAN_ENABLE) + OP_CODE_MAPPING(LE_CREATE_CONNECTION) + OP_CODE_MAPPING(LE_CREATE_CONNECTION_CANCEL) + OP_CODE_MAPPING(LE_READ_WHITE_LIST_SIZE) + OP_CODE_MAPPING(LE_CLEAR_WHITE_LIST) + OP_CODE_MAPPING(LE_ADD_DEVICE_TO_WHITE_LIST) + OP_CODE_MAPPING(LE_REMOVE_DEVICE_FROM_WHITE_LIST) + OP_CODE_MAPPING(LE_CONNECTION_UPDATE) + OP_CODE_MAPPING(LE_SET_HOST_CHANNEL_CLASSIFICATION) + OP_CODE_MAPPING(LE_READ_CHANNEL_MAP) + OP_CODE_MAPPING(LE_READ_REMOTE_FEATURES) + OP_CODE_MAPPING(LE_ENCRYPT) + OP_CODE_MAPPING(LE_RAND) + OP_CODE_MAPPING(LE_START_ENCRYPTION) + OP_CODE_MAPPING(LE_LONG_TERM_KEY_REQUEST_REPLY) + OP_CODE_MAPPING(LE_LONG_TERM_KEY_REQUEST_NEGATIVE_REPLY) + OP_CODE_MAPPING(LE_READ_SUPPORTED_STATES) + OP_CODE_MAPPING(LE_RECEIVER_TEST) + OP_CODE_MAPPING(LE_TRANSMITTER_TEST) + OP_CODE_MAPPING(LE_TEST_END) + OP_CODE_MAPPING(ENHANCED_SETUP_SYNCHRONOUS_CONNECTION) + OP_CODE_MAPPING(ENHANCED_ACCEPT_SYNCHRONOUS_CONNECTION) + OP_CODE_MAPPING(READ_LOCAL_SUPPORTED_CODECS) + OP_CODE_MAPPING(READ_SECURE_CONNECTIONS_HOST_SUPPORT) + OP_CODE_MAPPING(WRITE_SECURE_CONNECTIONS_HOST_SUPPORT) + OP_CODE_MAPPING(READ_LOCAL_OOB_EXTENDED_DATA) + OP_CODE_MAPPING(WRITE_SECURE_CONNECTIONS_TEST_MODE) + OP_CODE_MAPPING(LE_REMOTE_CONNECTION_PARAMETER_REQUEST_REPLY) + OP_CODE_MAPPING(LE_REMOTE_CONNECTION_PARAMETER_REQUEST_NEGATIVE_REPLY) + OP_CODE_MAPPING(LE_SET_DATA_LENGTH) + OP_CODE_MAPPING(LE_READ_SUGGESTED_DEFAULT_DATA_LENGTH) + OP_CODE_MAPPING(LE_WRITE_SUGGESTED_DEFAULT_DATA_LENGTH) + OP_CODE_MAPPING(LE_READ_LOCAL_P_256_PUBLIC_KEY_COMMAND) + OP_CODE_MAPPING(LE_GENERATE_DHKEY_COMMAND) + OP_CODE_MAPPING(LE_ADD_DEVICE_TO_RESOLVING_LIST) + OP_CODE_MAPPING(LE_REMOVE_DEVICE_FROM_RESOLVING_LIST) + OP_CODE_MAPPING(LE_CLEAR_RESOLVING_LIST) + OP_CODE_MAPPING(LE_READ_RESOLVING_LIST_SIZE) + OP_CODE_MAPPING(LE_READ_PEER_RESOLVABLE_ADDRESS) + OP_CODE_MAPPING(LE_READ_LOCAL_RESOLVABLE_ADDRESS) + OP_CODE_MAPPING(LE_SET_ADDRESS_RESOLUTION_ENABLE) + OP_CODE_MAPPING(LE_SET_RESOLVABLE_PRIVATE_ADDRESS_TIMEOUT) + OP_CODE_MAPPING(LE_READ_MAXIMUM_DATA_LENGTH) + OP_CODE_MAPPING(LE_READ_PHY) + OP_CODE_MAPPING(LE_SET_DEFAULT_PHY) + OP_CODE_MAPPING(LE_SET_PHY) + OP_CODE_MAPPING(LE_ENHANCED_RECEIVER_TEST) + OP_CODE_MAPPING(LE_ENHANCED_TRANSMITTER_TEST) + OP_CODE_MAPPING(LE_SET_EXTENDED_ADVERTISING_RANDOM_ADDRESS) + OP_CODE_MAPPING(LE_SET_EXTENDED_ADVERTISING_PARAMETERS) + OP_CODE_MAPPING(LE_SET_EXTENDED_ADVERTISING_DATA) + OP_CODE_MAPPING(LE_SET_EXTENDED_ADVERTISING_SCAN_RESPONSE) + OP_CODE_MAPPING(LE_SET_EXTENDED_ADVERTISING_ENABLE) + OP_CODE_MAPPING(LE_READ_MAXIMUM_ADVERTISING_DATA_LENGTH) + OP_CODE_MAPPING(LE_READ_NUMBER_OF_SUPPORTED_ADVERTISING_SETS) + OP_CODE_MAPPING(LE_REMOVE_ADVERTISING_SET) + OP_CODE_MAPPING(LE_CLEAR_ADVERTISING_SETS) + OP_CODE_MAPPING(LE_SET_PERIODIC_ADVERTISING_PARAM) + OP_CODE_MAPPING(LE_SET_PERIODIC_ADVERTISING_DATA) + OP_CODE_MAPPING(LE_SET_PERIODIC_ADVERTISING_ENABLE) + OP_CODE_MAPPING(LE_SET_EXTENDED_SCAN_PARAMETERS) + OP_CODE_MAPPING(LE_SET_EXTENDED_SCAN_ENABLE) + OP_CODE_MAPPING(LE_EXTENDED_CREATE_CONNECTION) + OP_CODE_MAPPING(LE_PERIODIC_ADVERTISING_CREATE_SYNC) + OP_CODE_MAPPING(LE_PERIODIC_ADVERTISING_CREATE_SYNC_CANCEL) + OP_CODE_MAPPING(LE_PERIODIC_ADVERTISING_TERMINATE_SYNC) + OP_CODE_MAPPING(LE_ADD_DEVICE_TO_PERIODIC_ADVERTISING_LIST) + OP_CODE_MAPPING(LE_REMOVE_DEVICE_FROM_PERIODIC_ADVERTISING_LIST) + OP_CODE_MAPPING(LE_CLEAR_PERIODIC_ADVERTISING_LIST) + OP_CODE_MAPPING(LE_READ_PERIODIC_ADVERTISING_LIST_SIZE) + OP_CODE_MAPPING(LE_READ_TRANSMIT_POWER) + OP_CODE_MAPPING(LE_READ_RF_PATH_COMPENSATION_POWER) + OP_CODE_MAPPING(LE_WRITE_RF_PATH_COMPENSATION_POWER) + OP_CODE_MAPPING(LE_SET_PRIVACY_MODE) + // vendor specific + case OpCode::LE_GET_VENDOR_CAPABILITIES: + case OpCode::LE_MULTI_ADVT: + case OpCode::LE_BATCH_SCAN: + case OpCode::LE_ADV_FILTER: + case OpCode::LE_TRACK_ADV: + case OpCode::LE_ENERGY_INFO: + case OpCode::LE_EXTENDED_SCAN_PARAMS: + case OpCode::CONTROLLER_DEBUG_INFO: + case OpCode::CONTROLLER_A2DP_OPCODE: + return true; + // undefined in local_supported_commands_ + case OpCode::CREATE_NEW_UNIT_KEY: + case OpCode::READ_LOCAL_SUPPORTED_COMMANDS: + return true; + case OpCode::NONE: + return false; + } + return false; + } +#undef OP_CODE_MAPPING + Controller& module_; HciLayer* hci_; Callback<void(uint16_t, uint16_t)> acl_credits_callback_; Handler* acl_credits_handler_ = nullptr; - + LocalVersionInformation local_version_information_; + std::array<uint8_t, 64> local_supported_commands_; + uint64_t local_supported_features_; + uint8_t maximum_page_number_; + std::vector<uint64_t> extended_lmp_features_array_; uint16_t acl_buffer_length_ = 0; uint16_t acl_buffers_ = 0; uint8_t sco_buffer_length_ = 0; uint16_t sco_buffers_ = 0; Address mac_address_; + std::string local_name_; + LeBufferSize le_buffer_size_; + uint64_t le_local_supported_features_; + uint64_t le_supported_states_; + LeMaximumDataLength le_maximum_data_length_; + uint16_t le_maximum_advertising_data_length_; + uint16_t le_number_supported_advertising_sets_; }; // namespace hci Controller::Controller() : impl_(std::make_unique<impl>(*this)) {} @@ -124,6 +591,33 @@ void Controller::RegisterCompletedAclPacketsCallback(Callback<void(uint16_t /* h impl_->RegisterCompletedAclPacketsCallback(cb, handler); // TODO hsz: why here? } +std::string Controller::GetControllerLocalName() { + return impl_->local_name_; +} + +LocalVersionInformation Controller::GetControllerLocalVersionInformation() { + return impl_->local_version_information_; +} + +std::array<uint8_t, 64> Controller::GetControllerLocalSupportedCommands() { + return impl_->local_supported_commands_; +} + +uint8_t Controller::GetControllerLocalExtendedFeaturesMaxPageNumber() { + return impl_->maximum_page_number_; +} + +uint64_t Controller::GetControllerLocalSupportedFeatures() { + return impl_->local_supported_features_; +} + +uint64_t Controller::GetControllerLocalExtendedFeatures(uint8_t page_number) { + if (page_number <= impl_->maximum_page_number_) { + return impl_->extended_lmp_features_array_[page_number]; + } + return 0x00; +} + uint16_t Controller::GetControllerAclPacketLength() { return impl_->acl_buffer_length_; } @@ -144,6 +638,104 @@ Address Controller::GetControllerMacAddress() { return impl_->mac_address_; } +void Controller::SetEventMask(uint64_t event_mask) { + GetHandler()->Post(common::BindOnce(&impl::set_event_mask, common::Unretained(impl_.get()), event_mask)); +} + +void Controller::Reset() { + GetHandler()->Post(common::BindOnce(&impl::reset, common::Unretained(impl_.get()))); +} + +void Controller::SetEventFilterClearAll() { + std::unique_ptr<SetEventFilterClearAllBuilder> packet = SetEventFilterClearAllBuilder::Create(); + GetHandler()->Post(common::BindOnce(&impl::set_event_filter, common::Unretained(impl_.get()), std::move(packet))); +} + +void Controller::SetEventFilterInquiryResultAllDevices() { + std::unique_ptr<SetEventFilterInquiryResultAllDevicesBuilder> packet = + SetEventFilterInquiryResultAllDevicesBuilder::Create(); + GetHandler()->Post(common::BindOnce(&impl::set_event_filter, common::Unretained(impl_.get()), std::move(packet))); +} + +void Controller::SetEventFilterInquiryResultClassOfDevice(ClassOfDevice class_of_device, + ClassOfDevice class_of_device_mask) { + std::unique_ptr<SetEventFilterInquiryResultClassOfDeviceBuilder> packet = + SetEventFilterInquiryResultClassOfDeviceBuilder::Create(class_of_device, class_of_device_mask); + GetHandler()->Post(common::BindOnce(&impl::set_event_filter, common::Unretained(impl_.get()), std::move(packet))); +} + +void Controller::SetEventFilterInquiryResultAddress(Address address) { + std::unique_ptr<SetEventFilterInquiryResultAddressBuilder> packet = + SetEventFilterInquiryResultAddressBuilder::Create(address); + GetHandler()->Post(common::BindOnce(&impl::set_event_filter, common::Unretained(impl_.get()), std::move(packet))); +} + +void Controller::SetEventFilterConnectionSetupAllDevices(AutoAcceptFlag auto_accept_flag) { + std::unique_ptr<SetEventFilterConnectionSetupAllDevicesBuilder> packet = + SetEventFilterConnectionSetupAllDevicesBuilder::Create(auto_accept_flag); + GetHandler()->Post(common::BindOnce(&impl::set_event_filter, common::Unretained(impl_.get()), std::move(packet))); +} + +void Controller::SetEventFilterConnectionSetupClassOfDevice(ClassOfDevice class_of_device, + ClassOfDevice class_of_device_mask, + AutoAcceptFlag auto_accept_flag) { + std::unique_ptr<SetEventFilterConnectionSetupClassOfDeviceBuilder> packet = + SetEventFilterConnectionSetupClassOfDeviceBuilder::Create(class_of_device, class_of_device_mask, + auto_accept_flag); + GetHandler()->Post(common::BindOnce(&impl::set_event_filter, common::Unretained(impl_.get()), std::move(packet))); +} + +void Controller::SetEventFilterConnectionSetupAddress(Address address, AutoAcceptFlag auto_accept_flag) { + std::unique_ptr<SetEventFilterConnectionSetupAddressBuilder> packet = + SetEventFilterConnectionSetupAddressBuilder::Create(address, auto_accept_flag); + GetHandler()->Post(common::BindOnce(&impl::set_event_filter, common::Unretained(impl_.get()), std::move(packet))); +} + +void Controller::WriteLocalName(std::string local_name) { + impl_->local_name_ = local_name; + GetHandler()->Post(common::BindOnce(&impl::write_local_name, common::Unretained(impl_.get()), local_name)); +} + +void Controller::HostBufferSize(uint16_t host_acl_data_packet_length, uint8_t host_synchronous_data_packet_length, + uint16_t host_total_num_acl_data_packets, + uint16_t host_total_num_synchronous_data_packets) { + GetHandler()->Post(common::BindOnce(&impl::host_buffer_size, common::Unretained(impl_.get()), + host_acl_data_packet_length, host_synchronous_data_packet_length, + host_total_num_acl_data_packets, host_total_num_synchronous_data_packets)); +} + +void Controller::LeSetEventMask(uint64_t le_event_mask) { + GetHandler()->Post(common::BindOnce(&impl::le_set_event_mask, common::Unretained(impl_.get()), le_event_mask)); +} + +LeBufferSize Controller::GetControllerLeBufferSize() { + return impl_->le_buffer_size_; +} + +uint64_t Controller::GetControllerLeLocalSupportedFeatures() { + return impl_->le_local_supported_features_; +} + +uint64_t Controller::GetControllerLeSupportedStates() { + return impl_->le_supported_states_; +} + +LeMaximumDataLength Controller::GetControllerLeMaximumDataLength() { + return impl_->le_maximum_data_length_; +} + +uint16_t Controller::GetControllerLeMaximumAdvertisingDataLength() { + return impl_->le_maximum_advertising_data_length_; +} + +uint16_t Controller::GetControllerLeNumberOfSupportedAdverisingSets() { + return impl_->le_number_supported_advertising_sets_; +} + +bool Controller::IsSupport(bluetooth::hci::OpCode op_code) { + return impl_->is_support(op_code); +} + const ModuleFactory Controller::Factory = ModuleFactory([]() { return new Controller(); }); void Controller::ListDependencies(ModuleList* list) { diff --git a/gd/hci/controller.h b/gd/hci/controller.h index f7e9397e6..0ce1dc8db 100644 --- a/gd/hci/controller.h +++ b/gd/hci/controller.h @@ -34,6 +34,18 @@ class Controller : public Module { virtual void RegisterCompletedAclPacketsCallback( common::Callback<void(uint16_t /* handle */, uint16_t /* num_packets */)> cb, os::Handler* handler); + virtual std::string GetControllerLocalName(); + + virtual LocalVersionInformation GetControllerLocalVersionInformation(); + + virtual std::array<uint8_t, 64> GetControllerLocalSupportedCommands(); + + virtual uint64_t GetControllerLocalSupportedFeatures(); + + virtual uint8_t GetControllerLocalExtendedFeaturesMaxPageNumber(); + + virtual uint64_t GetControllerLocalExtendedFeatures(uint8_t page_number); + virtual uint16_t GetControllerAclPacketLength(); virtual uint16_t GetControllerNumAclPacketBuffers(); @@ -44,6 +56,50 @@ class Controller : public Module { virtual Address GetControllerMacAddress(); + virtual void SetEventMask(uint64_t event_mask); + + virtual void Reset(); + + virtual void SetEventFilterClearAll(); + + virtual void SetEventFilterInquiryResultAllDevices(); + + virtual void SetEventFilterInquiryResultClassOfDevice(ClassOfDevice class_of_device, + ClassOfDevice class_of_device_mask); + + virtual void SetEventFilterInquiryResultAddress(Address address); + + virtual void SetEventFilterConnectionSetupAllDevices(AutoAcceptFlag auto_accept_flag); + + virtual void SetEventFilterConnectionSetupClassOfDevice(ClassOfDevice class_of_device, + ClassOfDevice class_of_device_mask, + AutoAcceptFlag auto_accept_flag); + + virtual void SetEventFilterConnectionSetupAddress(Address address, AutoAcceptFlag auto_accept_flag); + + virtual void WriteLocalName(std::string local_name); + + virtual void HostBufferSize(uint16_t host_acl_data_packet_length, uint8_t host_synchronous_data_packet_length, + uint16_t host_total_num_acl_data_packets, + uint16_t host_total_num_synchronous_data_packets); + + // LE controller commands + virtual void LeSetEventMask(uint64_t le_event_mask); + + LeBufferSize GetControllerLeBufferSize(); + + uint64_t GetControllerLeLocalSupportedFeatures(); + + uint64_t GetControllerLeSupportedStates(); + + LeMaximumDataLength GetControllerLeMaximumDataLength(); + + uint16_t GetControllerLeMaximumAdvertisingDataLength(); + + uint16_t GetControllerLeNumberOfSupportedAdverisingSets(); + + bool IsSupport(OpCode op_code); + static const ModuleFactory Factory; protected: diff --git a/gd/hci/controller_test.cc b/gd/hci/controller_test.cc index bc93698e4..44d1faf03 100644 --- a/gd/hci/controller_test.cc +++ b/gd/hci/controller_test.cc @@ -75,6 +75,45 @@ class TestHciLayer : public HciLayer { uint8_t num_packets = 1; std::unique_ptr<packet::BasePacketBuilder> event_builder; switch (command.GetOpCode()) { + case (OpCode::READ_LOCAL_NAME): { + std::array<uint8_t, 248> local_name = {'D', 'U', 'T', '\0'}; + event_builder = ReadLocalNameCompleteBuilder::Create(num_packets, ErrorCode::SUCCESS, local_name); + } break; + case (OpCode::READ_LOCAL_VERSION_INFORMATION): { + LocalVersionInformation local_version_information; + local_version_information.hci_version_ = HciVersion::V_5_0; + local_version_information.hci_revision_ = 0x1234; + local_version_information.lmp_version_ = LmpVersion::V_4_2; + local_version_information.manufacturer_name_ = 0xBAD; + local_version_information.lmp_subversion_ = 0x5678; + event_builder = ReadLocalVersionInformationCompleteBuilder::Create(num_packets, ErrorCode::SUCCESS, + local_version_information); + } break; + case (OpCode::READ_LOCAL_SUPPORTED_COMMANDS): { + std::array<uint8_t, 64> supported_commands; + for (int i = 0; i < 37; i++) { + supported_commands[i] = 0xff; + } + for (int i = 37; i < 64; i++) { + supported_commands[i] = 0x00; + } + event_builder = + ReadLocalSupportedCommandsCompleteBuilder::Create(num_packets, ErrorCode::SUCCESS, supported_commands); + } break; + case (OpCode::READ_LOCAL_SUPPORTED_FEATURES): { + uint64_t lmp_features = 0x012345678abcdef; + event_builder = + ReadLocalSupportedFeaturesCompleteBuilder::Create(num_packets, ErrorCode::SUCCESS, lmp_features); + } break; + case (OpCode::READ_LOCAL_EXTENDED_FEATURES): { + ReadLocalExtendedFeaturesView read_command = ReadLocalExtendedFeaturesView::Create(command); + ASSERT(read_command.IsValid()); + uint8_t page_bumber = read_command.GetPageNumber(); + uint64_t lmp_features = 0x012345678abcdef; + lmp_features += page_bumber; + event_builder = ReadLocalExtendedFeaturesCompleteBuilder::Create(num_packets, ErrorCode::SUCCESS, page_bumber, + 0x02, lmp_features); + } break; case (OpCode::READ_BUFFER_SIZE): { event_builder = ReadBufferSizeCompleteBuilder::Create( num_packets, ErrorCode::SUCCESS, acl_data_packet_length, synchronous_data_packet_length, @@ -83,6 +122,45 @@ class TestHciLayer : public HciLayer { case (OpCode::READ_BD_ADDR): { event_builder = ReadBdAddrCompleteBuilder::Create(num_packets, ErrorCode::SUCCESS, Address::kAny); } break; + case (OpCode::LE_READ_BUFFER_SIZE): { + LeBufferSize le_buffer_size; + le_buffer_size.le_data_packet_length_ = 0x16; + le_buffer_size.total_num_le_packets_ = 0x08; + event_builder = LeReadBufferSizeCompleteBuilder::Create(num_packets, ErrorCode::SUCCESS, le_buffer_size); + } break; + case (OpCode::LE_READ_LOCAL_SUPPORTED_FEATURES): { + event_builder = + LeReadLocalSupportedFeaturesCompleteBuilder::Create(num_packets, ErrorCode::SUCCESS, 0x001f123456789abc); + } break; + case (OpCode::LE_READ_SUPPORTED_STATES): { + event_builder = + LeReadSupportedStatesCompleteBuilder::Create(num_packets, ErrorCode::SUCCESS, 0x001f123456789abe); + } break; + case (OpCode::LE_READ_MAXIMUM_DATA_LENGTH): { + LeMaximumDataLength le_maximum_data_length; + le_maximum_data_length.supported_max_tx_octets_ = 0x12; + le_maximum_data_length.supported_max_tx_time_ = 0x34; + le_maximum_data_length.supported_max_rx_octets_ = 0x56; + le_maximum_data_length.supported_max_rx_time_ = 0x78; + event_builder = + LeReadMaximumDataLengthCompleteBuilder::Create(num_packets, ErrorCode::SUCCESS, le_maximum_data_length); + } break; + case (OpCode::LE_READ_MAXIMUM_ADVERTISING_DATA_LENGTH): { + event_builder = + LeReadMaximumAdvertisingDataLengthCompleteBuilder::Create(num_packets, ErrorCode::SUCCESS, 0x0672); + } break; + case (OpCode::LE_READ_NUMBER_OF_SUPPORTED_ADVERTISING_SETS): { + event_builder = + LeReadNumberOfSupportedAdvertisingSetsCompleteBuilder::Create(num_packets, ErrorCode::SUCCESS, 0xF0); + } break; + case (OpCode::SET_EVENT_MASK): + case (OpCode::RESET): + case (OpCode::SET_EVENT_FILTER): + case (OpCode::HOST_BUFFER_SIZE): + case (OpCode::LE_SET_EVENT_MASK): + command_queue_.push(command); + not_empty_.notify_all(); + return; default: LOG_INFO("Dropping unhandled packet"); return; @@ -124,6 +202,23 @@ class TestHciLayer : public HciLayer { client_handler_->Post(common::BindOnce(number_of_completed_packets_callback_, event)); } + CommandPacketView GetCommand(OpCode op_code) { + std::unique_lock<std::mutex> lock(mutex_); + std::chrono::milliseconds time = std::chrono::milliseconds(3000); + + // wait for command + while (command_queue_.size() == 0) { + if (not_empty_.wait_for(lock, time) == std::cv_status::timeout) { + break; + } + } + ASSERT(command_queue_.size() > 0); + CommandPacketView command = command_queue_.front(); + EXPECT_EQ(command.GetOpCode(), op_code); + command_queue_.pop(); + return command; + } + void ListDependencies(ModuleList* list) override {} void Start() override {} void Stop() override {} @@ -136,6 +231,9 @@ class TestHciLayer : public HciLayer { private: common::Callback<void(EventPacketView)> number_of_completed_packets_callback_; os::Handler* client_handler_; + std::queue<CommandPacketView> command_queue_; + mutable std::mutex mutex_; + std::condition_variable not_empty_; }; class ControllerTest : public ::testing::Test { @@ -168,6 +266,111 @@ TEST_F(ControllerTest, read_controller_info) { ASSERT_EQ(controller_->GetControllerScoPacketLength(), test_hci_layer_->synchronous_data_packet_length); ASSERT_EQ(controller_->GetControllerNumScoPacketBuffers(), test_hci_layer_->total_num_synchronous_data_packets); ASSERT_EQ(controller_->GetControllerMacAddress(), Address::kAny); + LocalVersionInformation local_version_information = controller_->GetControllerLocalVersionInformation(); + ASSERT_EQ(local_version_information.hci_version_, HciVersion::V_5_0); + ASSERT_EQ(local_version_information.hci_revision_, 0x1234); + ASSERT_EQ(local_version_information.lmp_version_, LmpVersion::V_4_2); + ASSERT_EQ(local_version_information.manufacturer_name_, 0xBAD); + ASSERT_EQ(local_version_information.lmp_subversion_, 0x5678); + std::array<uint8_t, 64> supported_commands; + for (int i = 0; i < 37; i++) { + supported_commands[i] = 0xff; + } + for (int i = 37; i < 64; i++) { + supported_commands[i] = 0x00; + } + ASSERT_EQ(controller_->GetControllerLocalSupportedCommands(), supported_commands); + ASSERT_EQ(controller_->GetControllerLocalSupportedFeatures(), 0x012345678abcdef); + ASSERT_EQ(controller_->GetControllerLocalExtendedFeaturesMaxPageNumber(), 0x02); + ASSERT_EQ(controller_->GetControllerLocalExtendedFeatures(0), 0x012345678abcdef); + ASSERT_EQ(controller_->GetControllerLocalExtendedFeatures(1), 0x012345678abcdf0); + ASSERT_EQ(controller_->GetControllerLocalExtendedFeatures(2), 0x012345678abcdf1); + ASSERT_EQ(controller_->GetControllerLocalExtendedFeatures(100), 0x00); + ASSERT_EQ(controller_->GetControllerLeBufferSize().le_data_packet_length_, 0x16); + ASSERT_EQ(controller_->GetControllerLeBufferSize().total_num_le_packets_, 0x08); + ASSERT_EQ(controller_->GetControllerLeLocalSupportedFeatures(), 0x001f123456789abc); + ASSERT_EQ(controller_->GetControllerLeSupportedStates(), 0x001f123456789abe); + ASSERT_EQ(controller_->GetControllerLeMaximumDataLength().supported_max_tx_octets_, 0x12); + ASSERT_EQ(controller_->GetControllerLeMaximumDataLength().supported_max_rx_octets_, 0x56); + ASSERT_EQ(controller_->GetControllerLeMaximumAdvertisingDataLength(), 0x0672); + ASSERT_EQ(controller_->GetControllerLeNumberOfSupportedAdverisingSets(), 0xF0); +} + +TEST_F(ControllerTest, read_write_local_name) { + ASSERT_EQ(controller_->GetControllerLocalName(), "DUT"); + controller_->WriteLocalName("New name"); + ASSERT_EQ(controller_->GetControllerLocalName(), "New name"); +} + +TEST_F(ControllerTest, send_set_event_mask_command) { + controller_->SetEventMask(0x00001FFFFFFFFFFF); + auto packet = test_hci_layer_->GetCommand(OpCode::SET_EVENT_MASK); + auto command = SetEventMaskView::Create(packet); + ASSERT(command.IsValid()); + ASSERT_EQ(command.GetEventMask(), 0x00001FFFFFFFFFFF); +} + +TEST_F(ControllerTest, send_reset_command) { + controller_->Reset(); + auto packet = test_hci_layer_->GetCommand(OpCode::RESET); + auto command = ResetView::Create(packet); + ASSERT(command.IsValid()); +} + +TEST_F(ControllerTest, send_set_event_filter_command) { + controller_->SetEventFilterInquiryResultAllDevices(); + auto packet = test_hci_layer_->GetCommand(OpCode::SET_EVENT_FILTER); + auto set_event_filter_view1 = SetEventFilterView::Create(packet); + auto set_event_filter_inquiry_result_view1 = SetEventFilterInquiryResultView::Create(set_event_filter_view1); + auto command1 = SetEventFilterInquiryResultAllDevicesView::Create(set_event_filter_inquiry_result_view1); + ASSERT(command1.IsValid()); + + ClassOfDevice class_of_device({0xab, 0xcd, 0xef}); + ClassOfDevice class_of_device_mask({0x12, 0x34, 0x56}); + controller_->SetEventFilterInquiryResultClassOfDevice(class_of_device, class_of_device_mask); + packet = test_hci_layer_->GetCommand(OpCode::SET_EVENT_FILTER); + auto set_event_filter_view2 = SetEventFilterView::Create(packet); + auto set_event_filter_inquiry_result_view2 = SetEventFilterInquiryResultView::Create(set_event_filter_view2); + auto command2 = SetEventFilterInquiryResultClassOfDeviceView::Create(set_event_filter_inquiry_result_view2); + ASSERT(command2.IsValid()); + ASSERT_EQ(command2.GetClassOfDevice(), class_of_device); + + Address bdaddr({0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc}); + controller_->SetEventFilterConnectionSetupAddress(bdaddr, AutoAcceptFlag::AUTO_ACCEPT_ON_ROLE_SWITCH_ENABLED); + packet = test_hci_layer_->GetCommand(OpCode::SET_EVENT_FILTER); + auto set_event_filter_view3 = SetEventFilterView::Create(packet); + auto set_event_filter_connection_setup_view = SetEventFilterConnectionSetupView::Create(set_event_filter_view3); + auto command3 = SetEventFilterConnectionSetupAddressView::Create(set_event_filter_connection_setup_view); + ASSERT(command3.IsValid()); + ASSERT_EQ(command3.GetAddress(), bdaddr); +} + +TEST_F(ControllerTest, send_host_buffer_size_command) { + controller_->HostBufferSize(0xFF00, 0xF1, 0xFF02, 0xFF03); + auto packet = test_hci_layer_->GetCommand(OpCode::HOST_BUFFER_SIZE); + auto command = HostBufferSizeView::Create(packet); + ASSERT(command.IsValid()); + ASSERT_EQ(command.GetHostAclDataPacketLength(), 0xFF00); + ASSERT_EQ(command.GetHostSynchronousDataPacketLength(), 0xF1); + ASSERT_EQ(command.GetHostTotalNumAclDataPackets(), 0xFF02); + ASSERT_EQ(command.GetHostTotalNumSynchronousDataPackets(), 0xFF03); +} + +TEST_F(ControllerTest, send_le_set_event_mask_command) { + controller_->LeSetEventMask(0x000000000000001F); + auto packet = test_hci_layer_->GetCommand(OpCode::LE_SET_EVENT_MASK); + auto command = LeSetEventMaskView::Create(packet); + ASSERT(command.IsValid()); + ASSERT_EQ(command.GetLeEventMask(), 0x000000000000001F); +} + +TEST_F(ControllerTest, is_supported_test) { + ASSERT_TRUE(controller_->IsSupport(OpCode::INQUIRY)); + ASSERT_TRUE(controller_->IsSupport(OpCode::REJECT_CONNECTION_REQUEST)); + ASSERT_TRUE(controller_->IsSupport(OpCode::ACCEPT_CONNECTION_REQUEST)); + ASSERT_FALSE(controller_->IsSupport(OpCode::LE_REMOVE_ADVERTISING_SET)); + ASSERT_FALSE(controller_->IsSupport(OpCode::LE_CLEAR_ADVERTISING_SETS)); + ASSERT_FALSE(controller_->IsSupport(OpCode::LE_SET_PERIODIC_ADVERTISING_PARAM)); } std::promise<void> credits1_set; diff --git a/gd/hci/facade.cc b/gd/hci/facade.cc index 8ac68abf9..57c62923d 100644 --- a/gd/hci/facade.cc +++ b/gd/hci/facade.cc @@ -123,6 +123,58 @@ class AclManagerFacadeService : public AclManagerFacade::Service, public ::bluet return acl_stream_.HandleRequest(context, request, writer); } + ::grpc::Status TestInternalHciCommands(::grpc::ServerContext* context, const ::google::protobuf::Empty* request, + ::google::protobuf::Empty* response) { + LocalVersionInformation local_version_information = controller_->GetControllerLocalVersionInformation(); + LOG_DEBUG("local name : %s", controller_->GetControllerLocalName().c_str()); + controller_->WriteLocalName("Device Under Test"); + LOG_DEBUG("new local name : %s", controller_->GetControllerLocalName().c_str()); + LOG_DEBUG("manufacturer name : %d", local_version_information.manufacturer_name_); + LOG_DEBUG("hci version : %x", (uint16_t)local_version_information.hci_version_); + LOG_DEBUG("lmp version : %x", (uint16_t)local_version_information.lmp_version_); + LOG_DEBUG("supported commands : %x", controller_->GetControllerLocalSupportedCommands()[0]); + LOG_DEBUG("supported features : %lx", controller_->GetControllerLocalSupportedFeatures()); + LOG_DEBUG("local extended features :"); + for (int i = 0; i <= controller_->GetControllerLocalExtendedFeaturesMaxPageNumber() + 1; i++) { + LOG_DEBUG("page %d, %lx", i, controller_->GetControllerLocalExtendedFeatures(i)); + } + + controller_->SetEventMask(0x00001FFFFFFFFFFF); + controller_->SetEventFilterInquiryResultAllDevices(); + ClassOfDevice class_of_device({0xab, 0xcd, 0xef}); + ClassOfDevice class_of_device_mask({0x12, 0x34, 0x56}); + controller_->SetEventFilterInquiryResultClassOfDevice(class_of_device, class_of_device_mask); + Address bdaddr({0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc}); + controller_->SetEventFilterInquiryResultAddress(bdaddr); + controller_->SetEventFilterConnectionSetupAllDevices(AutoAcceptFlag::AUTO_ACCEPT_OFF); + controller_->SetEventFilterConnectionSetupClassOfDevice(class_of_device, class_of_device_mask, + AutoAcceptFlag::AUTO_ACCEPT_ON_ROLE_SWITCH_DISABLED); + controller_->SetEventFilterConnectionSetupAddress(bdaddr, AutoAcceptFlag::AUTO_ACCEPT_ON_ROLE_SWITCH_ENABLED); + controller_->SetEventFilterClearAll(); + controller_->HostBufferSize(0xFF00, 0xF1, 0xFF02, 0xFF03); + return ::grpc::Status::OK; + } + + ::grpc::Status TestInternalHciLeCommands(::grpc::ServerContext* context, const ::google::protobuf::Empty* request, + ::google::protobuf::Empty* response) { + LOG_DEBUG("le data packet length : %d", controller_->GetControllerLeBufferSize().le_data_packet_length_); + LOG_DEBUG("total num le packets : %d", controller_->GetControllerLeBufferSize().total_num_le_packets_); + LOG_DEBUG("le local supported features : %lx", controller_->GetControllerLeLocalSupportedFeatures()); + LOG_DEBUG("le supported states : %lx", controller_->GetControllerLeSupportedStates()); + LOG_DEBUG("le supported max tx octets : %d", + controller_->GetControllerLeMaximumDataLength().supported_max_tx_octets_); + LOG_DEBUG("le supported max tx times : %d", controller_->GetControllerLeMaximumDataLength().supported_max_tx_time_); + LOG_DEBUG("le supported max rx octets : %d", + controller_->GetControllerLeMaximumDataLength().supported_max_rx_octets_); + LOG_DEBUG("le supported max rx times : %d", controller_->GetControllerLeMaximumDataLength().supported_max_rx_time_); + LOG_DEBUG("le maximum advertising data length %d", controller_->GetControllerLeMaximumAdvertisingDataLength()); + LOG_DEBUG("le number of supported advertising sets %d", + controller_->GetControllerLeNumberOfSupportedAdverisingSets()); + + controller_->LeSetEventMask(0x000000000000001F); + return ::grpc::Status::OK; + } + void on_incoming_acl(std::string address) { auto connection = acl_connections_.find(address); if (connection == acl_connections_.end()) { diff --git a/gd/hci/facade.proto b/gd/hci/facade.proto index 19a07bd00..4ccfccbd5 100644 --- a/gd/hci/facade.proto +++ b/gd/hci/facade.proto @@ -15,6 +15,8 @@ service AclManagerFacade { rpc FetchConnectionFailed(facade.EventStreamRequest) returns (stream ConnectionFailedEvent) {} rpc SendAclData(AclData) returns (google.protobuf.Empty) {} rpc FetchAclData(facade.EventStreamRequest) returns (stream AclData) {} + rpc TestInternalHciCommands(google.protobuf.Empty) returns (google.protobuf.Empty) {} + rpc TestInternalHciLeCommands(google.protobuf.Empty) returns (google.protobuf.Empty) {} } service ClassicSecurityManagerFacade { diff --git a/gd/hci/hci_layer_test.cc b/gd/hci/hci_layer_test.cc index 6326758d0..b73233a5b 100644 --- a/gd/hci/hci_layer_test.cc +++ b/gd/hci/hci_layer_test.cc @@ -384,13 +384,14 @@ TEST_F(HciTest, noOpCredits) { // Send the response event ErrorCode error_code = ErrorCode::SUCCESS; - HciVersion hci_version = HciVersion::V_5_0; - uint16_t hci_subversion = 0x1234; - LmpVersion lmp_version = LmpVersion::V_4_2; - uint16_t manufacturer_name = 0xBAD; - uint16_t lmp_subversion = 0x5678; - hal->callbacks->hciEventReceived(GetPacketBytes(ReadLocalVersionInformationCompleteBuilder::Create( - num_packets, error_code, hci_version, hci_subversion, lmp_version, manufacturer_name, lmp_subversion))); + LocalVersionInformation local_version_information; + local_version_information.hci_version_ = HciVersion::V_5_0; + local_version_information.hci_revision_ = 0x1234; + local_version_information.lmp_version_ = LmpVersion::V_4_2; + local_version_information.manufacturer_name_ = 0xBAD; + local_version_information.lmp_subversion_ = 0x5678; + hal->callbacks->hciEventReceived(GetPacketBytes( + ReadLocalVersionInformationCompleteBuilder::Create(num_packets, error_code, local_version_information))); // Wait for the event auto event_status = event_future.wait_for(kTimeout); @@ -430,13 +431,14 @@ TEST_F(HciTest, creditsTest) { // Send the response event uint8_t num_packets = 1; ErrorCode error_code = ErrorCode::SUCCESS; - HciVersion hci_version = HciVersion::V_5_0; - uint16_t hci_subversion = 0x1234; - LmpVersion lmp_version = LmpVersion::V_4_2; - uint16_t manufacturer_name = 0xBAD; - uint16_t lmp_subversion = 0x5678; - hal->callbacks->hciEventReceived(GetPacketBytes(ReadLocalVersionInformationCompleteBuilder::Create( - num_packets, error_code, hci_version, hci_subversion, lmp_version, manufacturer_name, lmp_subversion))); + LocalVersionInformation local_version_information; + local_version_information.hci_version_ = HciVersion::V_5_0; + local_version_information.hci_revision_ = 0x1234; + local_version_information.lmp_version_ = LmpVersion::V_4_2; + local_version_information.manufacturer_name_ = 0xBAD; + local_version_information.lmp_subversion_ = 0x5678; + hal->callbacks->hciEventReceived(GetPacketBytes( + ReadLocalVersionInformationCompleteBuilder::Create(num_packets, error_code, local_version_information))); // Wait for the event auto event_status = event_future.wait_for(kTimeout); diff --git a/gd/hci/hci_packets.pdl b/gd/hci/hci_packets.pdl index b2ec0da7e..d753091eb 100644 --- a/gd/hci/hci_packets.pdl +++ b/gd/hci/hci_packets.pdl @@ -311,6 +311,224 @@ enum OpCode : 16 { CONTROLLER_A2DP_OPCODE = 0xFD5D, } +// For mapping Local Supported Commands command +// Value = Octet * 10 + bit +enum OpCodeIndex : 16 { + INQUIRY = 0, + INQUIRY_CANCEL = 1, + PERIODIC_INQUIRY_MODE = 2, + EXIT_PERIODIC_INQUIRY_MODE = 3, + CREATE_CONNECTION = 4, + DISCONNECT = 5, + CREATE_CONNECTION_CANCEL = 7, + ACCEPT_CONNECTION_REQUEST = 10, + REJECT_CONNECTION_REQUEST = 11, + LINK_KEY_REQUEST_REPLY = 12, + LINK_KEY_REQUEST_NEGATIVE_REPLY = 13, + PIN_CODE_REQUEST_REPLY = 14, + PIN_CODE_REQUEST_NEGATIVE_REPLY = 15, + CHANGE_CONNECTION_PACKET_TYPE = 16, + AUTHENTICATION_REQUESTED = 17, + SET_CONNECTION_ENCRYPTION = 20, + CHANGE_CONNECTION_LINK_KEY = 21, + MASTER_LINK_KEY = 22, + REMOTE_NAME_REQUEST = 23, + REMOTE_NAME_REQUEST_CANCEL = 24, + READ_REMOTE_SUPPORTED_FEATURES = 25, + READ_REMOTE_EXTENDED_FEATURES = 26, + READ_REMOTE_VERSION_INFORMATION = 27, + READ_CLOCK_OFFSET = 30, + READ_LMP_HANDLE = 31, + HOLD_MODE = 41, + SNIFF_MODE = 42, + EXIT_SNIFF_MODE = 43, + QOS_SETUP = 46, + ROLE_DISCOVERY = 47, + SWITCH_ROLE = 50, + READ_LINK_POLICY_SETTINGS = 51, + WRITE_LINK_POLICY_SETTINGS = 52, + READ_DEFAULT_LINK_POLICY_SETTINGS = 53, + WRITE_DEFAULT_LINK_POLICY_SETTINGS = 54, + FLOW_SPECIFICATION = 55, + SET_EVENT_MASK = 56, + RESET = 57, + SET_EVENT_FILTER = 60, + FLUSH = 61, + READ_PIN_TYPE = 62, + WRITE_PIN_TYPE = 63, + READ_STORED_LINK_KEY = 65, + WRITE_STORED_LINK_KEY = 66, + DELETE_STORED_LINK_KEY = 67, + WRITE_LOCAL_NAME = 70, + READ_LOCAL_NAME = 71, + READ_CONNECTION_ACCEPT_TIMEOUT = 72, + WRITE_CONNECTION_ACCEPT_TIMEOUT = 73, + READ_PAGE_TIMEOUT = 74, + WRITE_PAGE_TIMEOUT = 75, + READ_SCAN_ENABLE = 76, + WRITE_SCAN_ENABLE = 77, + READ_PAGE_SCAN_ACTIVITY = 80, + WRITE_PAGE_SCAN_ACTIVITY = 81, + READ_INQUIRY_SCAN_ACTIVITY = 82, + WRITE_INQUIRY_SCAN_ACTIVITY = 83, + READ_AUTHENTICATION_ENABLE = 84, + WRITE_AUTHENTICATION_ENABLE = 85, + READ_CLASS_OF_DEVICE = 90, + WRITE_CLASS_OF_DEVICE = 91, + READ_VOICE_SETTING = 92, + WRITE_VOICE_SETTING = 93, + READ_AUTOMATIC_FLUSH_TIMEOUT = 94, + WRITE_AUTOMATIC_FLUSH_TIMEOUT = 95, + READ_NUM_BROADCAST_RETRANSMITS = 96, + WRITE_NUM_BROADCAST_RETRANSMITS = 97, + READ_HOLD_MODE_ACTIVITY = 100, + WRITE_HOLD_MODE_ACTIVITY = 101, + READ_TRANSMIT_POWER_LEVEL = 102, + READ_SYNCHRONOUS_FLOW_CONTROL_ENABLE = 103, + WRITE_SYNCHRONOUS_FLOW_CONTROL_ENABLE = 104, + SET_CONTROLLER_TO_HOST_FLOW_CONTROL = 105, + HOST_BUFFER_SIZE = 106, + HOST_NUM_COMPLETED_PACKETS = 107, + READ_LINK_SUPERVISION_TIMEOUT = 110, + WRITE_LINK_SUPERVISION_TIMEOUT = 111, + READ_NUMBER_OF_SUPPORTED_IAC = 112, + READ_CURRENT_IAC_LAP = 113, + WRITE_CURRENT_IAC_LAP = 114, + SET_AFH_HOST_CHANNEL_CLASSIFICATION = 121, + READ_INQUIRY_SCAN_TYPE = 124, + WRITE_INQUIRY_SCAN_TYPE = 125, + READ_INQUIRY_MODE = 126, + WRITE_INQUIRY_MODE = 127, + READ_PAGE_SCAN_TYPE = 130, + WRITE_PAGE_SCAN_TYPE = 131, + READ_AFH_CHANNEL_ASSESSMENT_MODE = 132, + WRITE_AFH_CHANNEL_ASSESSMENT_MODE = 133, + READ_LOCAL_VERSION_INFORMATION = 143, + READ_LOCAL_SUPPORTED_FEATURES = 145, + READ_LOCAL_EXTENDED_FEATURES = 146, + READ_BUFFER_SIZE = 147, + READ_BD_ADDR = 151, + READ_FAILED_CONTACT_COUNTER = 152, + RESET_FAILED_CONTACT_COUNTER = 153, + READ_LINK_QUALITY = 154, + READ_RSSI = 155, + READ_AFH_CHANNEL_MAP = 156, + READ_CLOCK = 157, + READ_LOOPBACK_MODE = 160, + WRITE_LOOPBACK_MODE = 161, + ENABLE_DEVICE_UNDER_TEST_MODE = 162, + SETUP_SYNCHRONOUS_CONNECTION = 163, + ACCEPT_SYNCHRONOUS_CONNECTION = 164, + REJECT_SYNCHRONOUS_CONNECTION = 165, + READ_EXTENDED_INQUIRY_RESPONSE = 170, + WRITE_EXTENDED_INQUIRY_RESPONSE = 171, + REFRESH_ENCRYPTION_KEY = 172, + SNIFF_SUBRATING = 174, + READ_SIMPLE_PAIRING_MODE = 175, + WRITE_SIMPLE_PAIRING_MODE = 176, + READ_LOCAL_OOB_DATA = 177, + READ_INQUIRY_RESPONSE_TRANSMIT_POWER_LEVEL = 180, + WRITE_INQUIRY_TRANSMIT_POWER_LEVEL = 181, + IO_CAPABILITY_REQUEST_REPLY = 187, + USER_CONFIRMATION_REQUEST_REPLY = 190, + USER_CONFIRMATION_REQUEST_NEGATIVE_REPLY = 191, + USER_PASSKEY_REQUEST_REPLY = 192, + USER_PASSKEY_REQUEST_NEGATIVE_REPLY = 193, + REMOTE_OOB_DATA_REQUEST_REPLY = 194, + WRITE_SIMPLE_PAIRING_DEBUG_MODE = 195, + REMOTE_OOB_DATA_REQUEST_NEGATIVE_REPLY = 197, + SEND_KEYPRESS_NOTIFICATION = 202, + IO_CAPABILITY_REQUEST_NEGATIVE_REPLY = 203, + READ_ENCRYPTION_KEY_SIZE = 204, + READ_DATA_BLOCK_SIZE = 232, + READ_LE_HOST_SUPPORT = 245, + WRITE_LE_HOST_SUPPORT = 246, + LE_SET_EVENT_MASK = 250, + LE_READ_BUFFER_SIZE = 251, + LE_READ_LOCAL_SUPPORTED_FEATURES = 252, + LE_SET_RANDOM_ADDRESS = 254, + LE_SET_ADVERTISING_PARAMETERS = 255, + LE_READ_ADVERTISING_CHANNEL_TX_POWER = 256, + LE_SET_ADVERTISING_DATA = 257, + LE_SET_SCAN_RESPONSE_DATA = 260, + LE_SET_ADVERTISING_ENABLE = 261, + LE_SET_SCAN_PARAMETERS = 262, + LE_SET_SCAN_ENABLE = 263, + LE_CREATE_CONNECTION = 264, + LE_CREATE_CONNECTION_CANCEL = 265, + LE_READ_WHITE_LIST_SIZE = 266, + LE_CLEAR_WHITE_LIST = 267, + LE_ADD_DEVICE_TO_WHITE_LIST = 270, + LE_REMOVE_DEVICE_FROM_WHITE_LIST = 271, + LE_CONNECTION_UPDATE = 272, + LE_SET_HOST_CHANNEL_CLASSIFICATION = 273, + LE_READ_CHANNEL_MAP = 274, + LE_READ_REMOTE_FEATURES = 275, + LE_ENCRYPT = 276, + LE_RAND = 277, + LE_START_ENCRYPTION = 280, + LE_LONG_TERM_KEY_REQUEST_REPLY = 281, + LE_LONG_TERM_KEY_REQUEST_NEGATIVE_REPLY = 282, + LE_READ_SUPPORTED_STATES = 283, + LE_RECEIVER_TEST = 284, + LE_TRANSMITTER_TEST = 285, + LE_TEST_END = 286, + ENHANCED_SETUP_SYNCHRONOUS_CONNECTION = 293, + ENHANCED_ACCEPT_SYNCHRONOUS_CONNECTION = 294, + READ_LOCAL_SUPPORTED_CODECS = 295, + READ_SECURE_CONNECTIONS_HOST_SUPPORT = 322, + WRITE_SECURE_CONNECTIONS_HOST_SUPPORT = 323, + READ_LOCAL_OOB_EXTENDED_DATA = 326, + WRITE_SECURE_CONNECTIONS_TEST_MODE = 327, + LE_REMOTE_CONNECTION_PARAMETER_REQUEST_REPLY = 334, + LE_REMOTE_CONNECTION_PARAMETER_REQUEST_NEGATIVE_REPLY = 335, + LE_SET_DATA_LENGTH = 336, + LE_READ_SUGGESTED_DEFAULT_DATA_LENGTH = 337, + LE_WRITE_SUGGESTED_DEFAULT_DATA_LENGTH = 340, + LE_READ_LOCAL_P_256_PUBLIC_KEY_COMMAND = 341, + LE_GENERATE_DHKEY_COMMAND = 342, + LE_ADD_DEVICE_TO_RESOLVING_LIST = 343, + LE_REMOVE_DEVICE_FROM_RESOLVING_LIST = 344, + LE_CLEAR_RESOLVING_LIST = 345, + LE_READ_RESOLVING_LIST_SIZE = 346, + LE_READ_PEER_RESOLVABLE_ADDRESS = 347, + LE_READ_LOCAL_RESOLVABLE_ADDRESS = 350, + LE_SET_ADDRESS_RESOLUTION_ENABLE = 351, + LE_SET_RESOLVABLE_PRIVATE_ADDRESS_TIMEOUT = 352, + LE_READ_MAXIMUM_DATA_LENGTH = 353, + LE_READ_PHY = 354, + LE_SET_DEFAULT_PHY = 355, + LE_SET_PHY = 356, + LE_ENHANCED_RECEIVER_TEST = 357, + LE_ENHANCED_TRANSMITTER_TEST = 360, + LE_SET_EXTENDED_ADVERTISING_RANDOM_ADDRESS = 361, + LE_SET_EXTENDED_ADVERTISING_PARAMETERS = 362, + LE_SET_EXTENDED_ADVERTISING_DATA = 363, + LE_SET_EXTENDED_ADVERTISING_SCAN_RESPONSE = 364, + LE_SET_EXTENDED_ADVERTISING_ENABLE = 365, + LE_READ_MAXIMUM_ADVERTISING_DATA_LENGTH = 366, + LE_READ_NUMBER_OF_SUPPORTED_ADVERTISING_SETS = 367, + LE_REMOVE_ADVERTISING_SET = 370, + LE_CLEAR_ADVERTISING_SETS = 371, + LE_SET_PERIODIC_ADVERTISING_PARAM = 372, + LE_SET_PERIODIC_ADVERTISING_DATA = 373, + LE_SET_PERIODIC_ADVERTISING_ENABLE = 374, + LE_SET_EXTENDED_SCAN_PARAMETERS = 375, + LE_SET_EXTENDED_SCAN_ENABLE = 376, + LE_EXTENDED_CREATE_CONNECTION = 377, + LE_PERIODIC_ADVERTISING_CREATE_SYNC = 380, + LE_PERIODIC_ADVERTISING_CREATE_SYNC_CANCEL = 381, + LE_PERIODIC_ADVERTISING_TERMINATE_SYNC = 382, + LE_ADD_DEVICE_TO_PERIODIC_ADVERTISING_LIST = 383, + LE_REMOVE_DEVICE_FROM_PERIODIC_ADVERTISING_LIST = 384, + LE_CLEAR_PERIODIC_ADVERTISING_LIST = 385, + LE_READ_PERIODIC_ADVERTISING_LIST_SIZE = 386, + LE_READ_TRANSMIT_POWER = 387, + LE_READ_RF_PATH_COMPENSATION_POWER = 390, + LE_WRITE_RF_PATH_COMPENSATION_POWER = 391, + LE_SET_PRIVACY_MODE = 392, +} + packet CommandPacket { op_code : OpCode, _size_(_payload_) : 8, @@ -1541,8 +1759,7 @@ enum LmpVersion : 8 { V_5_1 = 0x0a, } -packet ReadLocalVersionInformationComplete : CommandComplete (command_op_code = READ_LOCAL_VERSION_INFORMATION) { - status : ErrorCode, +struct LocalVersionInformation { hci_version : HciVersion, hci_revision : 16, lmp_version : LmpVersion, @@ -1550,6 +1767,11 @@ packet ReadLocalVersionInformationComplete : CommandComplete (command_op_code = lmp_subversion : 16, } +packet ReadLocalVersionInformationComplete : CommandComplete (command_op_code = READ_LOCAL_VERSION_INFORMATION) { + status : ErrorCode, + local_version_information : LocalVersionInformation, +} + packet ReadLocalSupportedCommands : CommandPacket (op_code = READ_LOCAL_SUPPORTED_COMMANDS) { } @@ -1707,10 +1929,14 @@ packet LeSetEventMaskComplete : CommandComplete (command_op_code = LE_SET_EVENT_ packet LeReadBufferSize : CommandPacket (op_code = LE_READ_BUFFER_SIZE) { } +struct LeBufferSize { + le_data_packet_length : 16, + total_num_le_packets : 8, +} + packet LeReadBufferSizeComplete : CommandComplete (command_op_code = LE_READ_BUFFER_SIZE) { status : ErrorCode, - hc_le_data_packet_length : 16, - hc_total_num_le_packets : 8, + le_buffer_size : LeBufferSize, } packet LeReadLocalSupportedFeatures : CommandPacket (op_code = LE_READ_LOCAL_SUPPORTED_FEATURES) { @@ -1963,7 +2189,11 @@ packet LeLongTermKeyRequestNegativeReply : LeSecurityCommand (op_code = LE_LONG_ } packet LeReadSupportedStates : CommandPacket (op_code = LE_READ_SUPPORTED_STATES) { - _payload_, // placeholder (unimplemented) +} + +packet LeReadSupportedStatesComplete : CommandComplete (command_op_code = LE_READ_SUPPORTED_STATES) { + status : ErrorCode, + le_states : 64, } packet LeReceiverTest : CommandPacket (op_code = LE_RECEIVER_TEST) { @@ -2040,7 +2270,19 @@ packet LeSetResolvablePrivateAddressTimeout : LeSecurityCommand (op_code = LE_SE } packet LeReadMaximumDataLength : CommandPacket (op_code = LE_READ_MAXIMUM_DATA_LENGTH) { - _payload_, // placeholder (unimplemented) +} + +struct LeMaximumDataLength { + supported_max_tx_octets : 16, + supported_max_tx_time: 16, + supported_max_rx_octets : 16, + supported_max_rx_time: 16, +} + + +packet LeReadMaximumDataLengthComplete : CommandComplete (command_op_code = LE_READ_MAXIMUM_DATA_LENGTH) { + status : ErrorCode, + le_maximum_data_length : LeMaximumDataLength, } packet LeReadPhy : LeConnectionManagementCommand (op_code = LE_READ_PHY) { @@ -2084,11 +2326,19 @@ packet LeSetExtendedAdvertisingEnable : LeAdvertisingCommand (op_code = LE_SET_E } packet LeReadMaximumAdvertisingDataLength : CommandPacket (op_code = LE_READ_MAXIMUM_ADVERTISING_DATA_LENGTH) { - _payload_, // placeholder (unimplemented) +} + +packet LeReadMaximumAdvertisingDataLengthComplete : CommandComplete (command_op_code = LE_READ_MAXIMUM_ADVERTISING_DATA_LENGTH) { + status : ErrorCode, + maximum_advertising_data_length : 16, } packet LeReadNumberOfSupportedAdvertisingSets : CommandPacket (op_code = LE_READ_NUMBER_OF_SUPPORTED_ADVERTISING_SETS) { - _payload_, // placeholder (unimplemented) +} + +packet LeReadNumberOfSupportedAdvertisingSetsComplete : CommandComplete (command_op_code = LE_READ_NUMBER_OF_SUPPORTED_ADVERTISING_SETS) { + status : ErrorCode, + number_supported_advertising_sets : 8, } packet LeRemoveAdvertisingSet : LeAdvertisingCommand (op_code = LE_REMOVE_ADVERTISING_SET) { diff --git a/vendor_libs/test_vendor_lib/model/devices/device_properties.cc b/vendor_libs/test_vendor_lib/model/devices/device_properties.cc index 29f8adeec..0983b1976 100644 --- a/vendor_libs/test_vendor_lib/model/devices/device_properties.cc +++ b/vendor_libs/test_vendor_lib/model/devices/device_properties.cc @@ -61,10 +61,10 @@ DeviceProperties::DeviceProperties(const std::string& file_name) supported_codecs_ = {0}; // Only SBC is supported. vendor_specific_codecs_ = {}; - for (int i = 0; i < 36; i++) supported_commands_.push_back(0xff); + for (int i = 0; i < 35; i++) supported_commands_.push_back(0xff); // Mark HCI_LE_Transmitter_Test[v2] and newer commands as unsupported // TODO: Implement a better mapping. - for (int i = 36; i < 64; i++) supported_commands_.push_back(0x00); + for (int i = 35; i < 64; i++) supported_commands_.push_back(0x00); le_supported_features_ = 0x1f; le_supported_states_ = 0x3ffffffffff; |