aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChienyuan <chienyuanhuang@google.com>2019-08-15 18:04:32 +0800
committerChienyuan <chienyuanhuang@google.com>2019-08-27 23:11:35 +0800
commita7ad3fb7fb4d4a8ded04e494c8a0ca802a7e3ad5 (patch)
tree63b7ee0971592de88680b73b961da5a9f4d1e347
parent4aa9aa7a938c22064691720510455153a6eae0ee (diff)
downloadbt-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.py6
-rw-r--r--gd/hci/controller.cc594
-rw-r--r--gd/hci/controller.h56
-rw-r--r--gd/hci/controller_test.cc203
-rw-r--r--gd/hci/facade.cc52
-rw-r--r--gd/hci/facade.proto2
-rw-r--r--gd/hci/hci_layer_test.cc30
-rw-r--r--gd/hci/hci_packets.pdl266
-rw-r--r--vendor_libs/test_vendor_lib/model/devices/device_properties.cc4
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;