Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 1 | /* |
| 2 | * Copyright 2015 The Android Open Source Project |
| 3 | * |
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | * you may not use this file except in compliance with the License. |
| 6 | * You may obtain a copy of the License at |
| 7 | * |
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | * |
| 10 | * Unless required by applicable law or agreed to in writing, software |
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | * See the License for the specific language governing permissions and |
| 14 | * limitations under the License. |
| 15 | */ |
| 16 | |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 17 | #include "dual_mode_controller.h" |
| 18 | |
| 19 | #include <memory> |
| 20 | |
| 21 | #include <base/files/file_util.h> |
| 22 | #include <base/json/json_reader.h> |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 23 | #include <base/values.h> |
| 24 | |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 25 | #include "os/log.h" |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 26 | #include "packet/raw_builder.h" |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 27 | |
| 28 | #include "hci.h" |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 29 | |
| 30 | using std::vector; |
| 31 | using test_vendor_lib::hci::EventCode; |
| 32 | using test_vendor_lib::hci::OpCode; |
| 33 | |
| 34 | namespace { |
| 35 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 36 | size_t LastNonZero(bluetooth::packet::PacketView<true> view) { |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 37 | for (size_t i = view.size() - 1; i > 0; i--) { |
| 38 | if (view[i] != 0) { |
| 39 | return i; |
| 40 | } |
| 41 | } |
| 42 | return 0; |
| 43 | } |
| 44 | |
| 45 | } // namespace |
| 46 | |
| 47 | namespace test_vendor_lib { |
| 48 | constexpr char DualModeController::kControllerPropertiesFile[]; |
| 49 | constexpr uint16_t DualModeController::kSecurityManagerNumKeys; |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 50 | constexpr uint16_t kNumCommandPackets = 0x01; |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 51 | |
| 52 | // Device methods. |
| 53 | void DualModeController::Initialize(const std::vector<std::string>& args) { |
| 54 | if (args.size() < 2) return; |
| 55 | |
| 56 | Address addr; |
Hansong Zhang | 106fc60 | 2019-06-19 16:53:15 -0700 | [diff] [blame] | 57 | if (Address::FromString(args[1], addr)) { |
| 58 | properties_.SetAddress(addr); |
| 59 | } else { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 60 | LOG_ALWAYS_FATAL("Invalid address: %s", args[1].c_str()); |
Hansong Zhang | 106fc60 | 2019-06-19 16:53:15 -0700 | [diff] [blame] | 61 | } |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 62 | }; |
| 63 | |
| 64 | std::string DualModeController::GetTypeString() const { |
| 65 | return "Simulated Bluetooth Controller"; |
| 66 | } |
| 67 | |
Chienyuan | db55f31 | 2019-10-31 14:01:28 +0800 | [diff] [blame] | 68 | void DualModeController::IncomingPacket( |
| 69 | model::packets::LinkLayerPacketView incoming) { |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 70 | link_layer_controller_.IncomingPacket(incoming); |
| 71 | } |
| 72 | |
| 73 | void DualModeController::TimerTick() { |
| 74 | link_layer_controller_.TimerTick(); |
| 75 | } |
| 76 | |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 77 | void DualModeController::SendCommandCompleteUnknownOpCodeEvent(uint16_t command_opcode) const { |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 78 | std::unique_ptr<bluetooth::packet::RawBuilder> raw_builder_ptr = |
| 79 | std::make_unique<bluetooth::packet::RawBuilder>(); |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 80 | raw_builder_ptr->AddOctets1(kNumCommandPackets); |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 81 | raw_builder_ptr->AddOctets2(command_opcode); |
| 82 | raw_builder_ptr->AddOctets1( |
| 83 | static_cast<uint8_t>(bluetooth::hci::ErrorCode::UNKNOWN_HCI_COMMAND)); |
| 84 | |
| 85 | auto packet = bluetooth::hci::EventPacketBuilder::Create( |
| 86 | bluetooth::hci::EventCode::COMMAND_COMPLETE, std::move(raw_builder_ptr)); |
| 87 | send_event_(std::move(packet)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 88 | } |
| 89 | |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 90 | DualModeController::DualModeController(const std::string& properties_filename, uint16_t num_keys) |
| 91 | : Device(properties_filename), security_manager_(num_keys) { |
| 92 | loopback_mode_ = hci::LoopbackMode::NO; |
| 93 | |
| 94 | Address public_address; |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 95 | ASSERT(Address::FromString("3C:5A:B4:04:05:06", public_address)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 96 | properties_.SetAddress(public_address); |
| 97 | |
| 98 | link_layer_controller_.RegisterRemoteChannel( |
Chienyuan | db55f31 | 2019-10-31 14:01:28 +0800 | [diff] [blame] | 99 | [this](std::shared_ptr<model::packets::LinkLayerPacketBuilder> packet, |
| 100 | Phy::Type phy_type) { |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 101 | DualModeController::SendLinkLayerPacket(packet, phy_type); |
| 102 | }); |
| 103 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 104 | #define SET_HANDLER(opcode, method) \ |
| 105 | active_hci_commands_[static_cast<uint16_t>(opcode)] = \ |
| 106 | [this](bluetooth::packet::PacketView<true> param) { method(param); }; |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 107 | SET_HANDLER(OpCode::RESET, HciReset); |
| 108 | SET_HANDLER(OpCode::READ_BUFFER_SIZE, HciReadBufferSize); |
| 109 | SET_HANDLER(OpCode::HOST_BUFFER_SIZE, HciHostBufferSize); |
| 110 | SET_HANDLER(OpCode::SNIFF_SUBRATING, HciSniffSubrating); |
Calvin Huang | 63a0896 | 2019-10-31 19:12:25 -0700 | [diff] [blame] | 111 | SET_HANDLER(OpCode::READ_ENCRYPTION_KEY_SIZE, HciReadEncryptionKeySize); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 112 | SET_HANDLER(OpCode::READ_LOCAL_VERSION_INFORMATION, HciReadLocalVersionInformation); |
| 113 | SET_HANDLER(OpCode::READ_BD_ADDR, HciReadBdAddr); |
| 114 | SET_HANDLER(OpCode::READ_LOCAL_SUPPORTED_COMMANDS, HciReadLocalSupportedCommands); |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 115 | SET_HANDLER(OpCode::READ_LOCAL_SUPPORTED_FEATURES, HciReadLocalSupportedFeatures); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 116 | SET_HANDLER(OpCode::READ_LOCAL_SUPPORTED_CODECS, HciReadLocalSupportedCodecs); |
| 117 | SET_HANDLER(OpCode::READ_LOCAL_EXTENDED_FEATURES, HciReadLocalExtendedFeatures); |
| 118 | SET_HANDLER(OpCode::READ_REMOTE_EXTENDED_FEATURES, HciReadRemoteExtendedFeatures); |
Chienyuan | 9145e7a | 2019-10-02 15:18:55 +0800 | [diff] [blame] | 119 | SET_HANDLER(OpCode::SWITCH_ROLE, HciSwitchRole); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 120 | SET_HANDLER(OpCode::READ_REMOTE_SUPPORTED_FEATURES, HciReadRemoteSupportedFeatures); |
| 121 | SET_HANDLER(OpCode::READ_CLOCK_OFFSET, HciReadClockOffset); |
| 122 | SET_HANDLER(OpCode::IO_CAPABILITY_REQUEST_REPLY, HciIoCapabilityRequestReply); |
| 123 | SET_HANDLER(OpCode::USER_CONFIRMATION_REQUEST_REPLY, HciUserConfirmationRequestReply); |
| 124 | SET_HANDLER(OpCode::USER_CONFIRMATION_REQUEST_NEGATIVE_REPLY, HciUserConfirmationRequestNegativeReply); |
| 125 | SET_HANDLER(OpCode::IO_CAPABILITY_REQUEST_NEGATIVE_REPLY, HciIoCapabilityRequestNegativeReply); |
| 126 | SET_HANDLER(OpCode::WRITE_SIMPLE_PAIRING_MODE, HciWriteSimplePairingMode); |
| 127 | SET_HANDLER(OpCode::WRITE_LE_HOST_SUPPORT, HciWriteLeHostSupport); |
Calvin Huang | 63a0896 | 2019-10-31 19:12:25 -0700 | [diff] [blame] | 128 | SET_HANDLER(OpCode::WRITE_SECURE_CONNECTIONS_HOST_SUPPORT, |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 129 | HciWriteSecureConnectionsHostSupport); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 130 | SET_HANDLER(OpCode::SET_EVENT_MASK, HciSetEventMask); |
| 131 | SET_HANDLER(OpCode::WRITE_INQUIRY_MODE, HciWriteInquiryMode); |
| 132 | SET_HANDLER(OpCode::WRITE_PAGE_SCAN_TYPE, HciWritePageScanType); |
| 133 | SET_HANDLER(OpCode::WRITE_INQUIRY_SCAN_TYPE, HciWriteInquiryScanType); |
| 134 | SET_HANDLER(OpCode::AUTHENTICATION_REQUESTED, HciAuthenticationRequested); |
| 135 | SET_HANDLER(OpCode::SET_CONNECTION_ENCRYPTION, HciSetConnectionEncryption); |
Chienyuan | ad340b0 | 2019-09-25 19:23:21 +0800 | [diff] [blame] | 136 | SET_HANDLER(OpCode::CHANGE_CONNECTION_LINK_KEY, HciChangeConnectionLinkKey); |
Chienyuan | 9145e7a | 2019-10-02 15:18:55 +0800 | [diff] [blame] | 137 | SET_HANDLER(OpCode::MASTER_LINK_KEY, HciMasterLinkKey); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 138 | SET_HANDLER(OpCode::WRITE_AUTHENTICATION_ENABLE, HciWriteAuthenticationEnable); |
| 139 | SET_HANDLER(OpCode::READ_AUTHENTICATION_ENABLE, HciReadAuthenticationEnable); |
| 140 | SET_HANDLER(OpCode::WRITE_CLASS_OF_DEVICE, HciWriteClassOfDevice); |
| 141 | SET_HANDLER(OpCode::WRITE_PAGE_TIMEOUT, HciWritePageTimeout); |
| 142 | SET_HANDLER(OpCode::WRITE_LINK_SUPERVISION_TIMEOUT, HciWriteLinkSupervisionTimeout); |
Chienyuan | ad340b0 | 2019-09-25 19:23:21 +0800 | [diff] [blame] | 143 | SET_HANDLER(OpCode::HOLD_MODE, HciHoldMode); |
| 144 | SET_HANDLER(OpCode::SNIFF_MODE, HciSniffMode); |
| 145 | SET_HANDLER(OpCode::EXIT_SNIFF_MODE, HciExitSniffMode); |
| 146 | SET_HANDLER(OpCode::QOS_SETUP, HciQosSetup); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 147 | SET_HANDLER(OpCode::WRITE_DEFAULT_LINK_POLICY_SETTINGS, HciWriteDefaultLinkPolicySettings); |
Chienyuan | ad340b0 | 2019-09-25 19:23:21 +0800 | [diff] [blame] | 148 | SET_HANDLER(OpCode::FLOW_SPECIFICATION, HciFlowSpecification); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 149 | SET_HANDLER(OpCode::WRITE_LINK_POLICY_SETTINGS, HciWriteLinkPolicySettings); |
| 150 | SET_HANDLER(OpCode::CHANGE_CONNECTION_PACKET_TYPE, HciChangeConnectionPacketType); |
| 151 | SET_HANDLER(OpCode::WRITE_LOCAL_NAME, HciWriteLocalName); |
| 152 | SET_HANDLER(OpCode::READ_LOCAL_NAME, HciReadLocalName); |
| 153 | SET_HANDLER(OpCode::WRITE_EXTENDED_INQUIRY_RESPONSE, HciWriteExtendedInquiryResponse); |
Myles Watson | b293d73 | 2019-08-19 12:35:36 -0700 | [diff] [blame] | 154 | SET_HANDLER(OpCode::REFRESH_ENCRYPTION_KEY, HciRefreshEncryptionKey); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 155 | SET_HANDLER(OpCode::WRITE_VOICE_SETTING, HciWriteVoiceSetting); |
| 156 | SET_HANDLER(OpCode::WRITE_CURRENT_IAC_LAP, HciWriteCurrentIacLap); |
| 157 | SET_HANDLER(OpCode::WRITE_INQUIRY_SCAN_ACTIVITY, HciWriteInquiryScanActivity); |
| 158 | SET_HANDLER(OpCode::WRITE_SCAN_ENABLE, HciWriteScanEnable); |
| 159 | SET_HANDLER(OpCode::SET_EVENT_FILTER, HciSetEventFilter); |
| 160 | SET_HANDLER(OpCode::INQUIRY, HciInquiry); |
| 161 | SET_HANDLER(OpCode::INQUIRY_CANCEL, HciInquiryCancel); |
| 162 | SET_HANDLER(OpCode::ACCEPT_CONNECTION_REQUEST, HciAcceptConnectionRequest); |
| 163 | SET_HANDLER(OpCode::REJECT_CONNECTION_REQUEST, HciRejectConnectionRequest); |
| 164 | SET_HANDLER(OpCode::LINK_KEY_REQUEST_REPLY, HciLinkKeyRequestReply); |
| 165 | SET_HANDLER(OpCode::LINK_KEY_REQUEST_NEGATIVE_REPLY, HciLinkKeyRequestNegativeReply); |
| 166 | SET_HANDLER(OpCode::DELETE_STORED_LINK_KEY, HciDeleteStoredLinkKey); |
| 167 | SET_HANDLER(OpCode::REMOTE_NAME_REQUEST, HciRemoteNameRequest); |
| 168 | SET_HANDLER(OpCode::LE_SET_EVENT_MASK, HciLeSetEventMask); |
| 169 | SET_HANDLER(OpCode::LE_READ_BUFFER_SIZE, HciLeReadBufferSize); |
| 170 | SET_HANDLER(OpCode::LE_READ_LOCAL_SUPPORTED_FEATURES, HciLeReadLocalSupportedFeatures); |
| 171 | SET_HANDLER(OpCode::LE_SET_RANDOM_ADDRESS, HciLeSetRandomAddress); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 172 | SET_HANDLER(OpCode::LE_SET_ADVERTISING_PARAMETERS, HciLeSetAdvertisingParameters); |
Myles Watson | 99aea89 | 2019-09-02 15:54:08 -0700 | [diff] [blame] | 173 | SET_HANDLER(OpCode::LE_SET_ADVERTISING_DATA, HciLeSetAdvertisingData); |
| 174 | SET_HANDLER(OpCode::LE_SET_SCAN_RESPONSE_DATA, HciLeSetScanResponseData); |
| 175 | SET_HANDLER(OpCode::LE_SET_ADVERTISING_ENABLE, HciLeSetAdvertisingEnable); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 176 | SET_HANDLER(OpCode::LE_SET_SCAN_PARAMETERS, HciLeSetScanParameters); |
| 177 | SET_HANDLER(OpCode::LE_SET_SCAN_ENABLE, HciLeSetScanEnable); |
| 178 | SET_HANDLER(OpCode::LE_CREATE_CONNECTION, HciLeCreateConnection); |
| 179 | SET_HANDLER(OpCode::CREATE_CONNECTION, HciCreateConnection); |
| 180 | SET_HANDLER(OpCode::DISCONNECT, HciDisconnect); |
| 181 | SET_HANDLER(OpCode::LE_CREATE_CONNECTION_CANCEL, HciLeConnectionCancel); |
| 182 | SET_HANDLER(OpCode::LE_READ_WHITE_LIST_SIZE, HciLeReadWhiteListSize); |
| 183 | SET_HANDLER(OpCode::LE_CLEAR_WHITE_LIST, HciLeClearWhiteList); |
| 184 | SET_HANDLER(OpCode::LE_ADD_DEVICE_TO_WHITE_LIST, HciLeAddDeviceToWhiteList); |
| 185 | SET_HANDLER(OpCode::LE_REMOVE_DEVICE_FROM_WHITE_LIST, HciLeRemoveDeviceFromWhiteList); |
| 186 | SET_HANDLER(OpCode::LE_RAND, HciLeRand); |
| 187 | SET_HANDLER(OpCode::LE_READ_SUPPORTED_STATES, HciLeReadSupportedStates); |
| 188 | SET_HANDLER(OpCode::LE_GET_VENDOR_CAPABILITIES, HciLeVendorCap); |
| 189 | SET_HANDLER(OpCode::LE_MULTI_ADVT, HciLeVendorMultiAdv); |
| 190 | SET_HANDLER(OpCode::LE_ADV_FILTER, HciLeAdvertisingFilter); |
| 191 | SET_HANDLER(OpCode::LE_ENERGY_INFO, HciLeEnergyInfo); |
| 192 | SET_HANDLER(OpCode::LE_EXTENDED_SCAN_PARAMS, HciLeExtendedScanParams); |
| 193 | SET_HANDLER(OpCode::LE_READ_REMOTE_FEATURES, HciLeReadRemoteFeatures); |
| 194 | SET_HANDLER(OpCode::READ_REMOTE_VERSION_INFORMATION, HciReadRemoteVersionInformation); |
| 195 | SET_HANDLER(OpCode::LE_CONNECTION_UPDATE, HciLeConnectionUpdate); |
| 196 | SET_HANDLER(OpCode::LE_START_ENCRYPTION, HciLeStartEncryption); |
Calvin Huang | ee1980c | 2019-11-01 16:35:55 -0700 | [diff] [blame] | 197 | SET_HANDLER(OpCode::LE_ADD_DEVICE_TO_RESOLVING_LIST, |
| 198 | HciLeAddDeviceToResolvingList); |
| 199 | SET_HANDLER(OpCode::LE_REMOVE_DEVICE_FROM_RESOLVING_LIST, |
| 200 | HciLeRemoveDeviceFromResolvingList); |
| 201 | SET_HANDLER(OpCode::LE_CLEAR_RESOLVING_LIST, HciLeClearResolvingList); |
| 202 | SET_HANDLER(OpCode::LE_SET_PRIVACY_MODE, HciLeSetPrivacyMode); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 203 | // Testing Commands |
| 204 | SET_HANDLER(OpCode::READ_LOOPBACK_MODE, HciReadLoopbackMode); |
| 205 | SET_HANDLER(OpCode::WRITE_LOOPBACK_MODE, HciWriteLoopbackMode); |
| 206 | #undef SET_HANDLER |
| 207 | } |
| 208 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 209 | void DualModeController::HciSniffSubrating( |
| 210 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 211 | ASSERT_LOG(args.size() == 8, "%s size=%zu", __func__, args.size()); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 212 | |
| 213 | uint16_t handle = args.begin().extract<uint16_t>(); |
| 214 | |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 215 | auto packet = bluetooth::hci::SniffSubratingCompleteBuilder::Create( |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 216 | kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS, handle); |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 217 | send_event_(std::move(packet)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 218 | } |
| 219 | |
| 220 | void DualModeController::RegisterTaskScheduler( |
| 221 | std::function<AsyncTaskId(std::chrono::milliseconds, const TaskCallback&)> oneshot_scheduler) { |
| 222 | link_layer_controller_.RegisterTaskScheduler(oneshot_scheduler); |
| 223 | } |
| 224 | |
| 225 | void DualModeController::RegisterPeriodicTaskScheduler( |
| 226 | std::function<AsyncTaskId(std::chrono::milliseconds, std::chrono::milliseconds, const TaskCallback&)> |
| 227 | periodic_scheduler) { |
| 228 | link_layer_controller_.RegisterPeriodicTaskScheduler(periodic_scheduler); |
| 229 | } |
| 230 | |
| 231 | void DualModeController::RegisterTaskCancel(std::function<void(AsyncTaskId)> task_cancel) { |
| 232 | link_layer_controller_.RegisterTaskCancel(task_cancel); |
| 233 | } |
| 234 | |
| 235 | void DualModeController::HandleAcl(std::shared_ptr<std::vector<uint8_t>> packet) { |
Chienyuan | 85db6ee | 2019-11-21 22:07:09 +0800 | [diff] [blame] | 236 | bluetooth::hci::PacketView<bluetooth::hci::kLittleEndian> raw_packet(packet); |
| 237 | auto acl_packet = bluetooth::hci::AclPacketView::Create(raw_packet); |
| 238 | ASSERT(acl_packet.IsValid()); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 239 | if (loopback_mode_ == hci::LoopbackMode::LOCAL) { |
| 240 | uint16_t handle = acl_packet.GetHandle(); |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 241 | |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 242 | std::vector<bluetooth::hci::CompletedPackets> completed_packets; |
| 243 | bluetooth::hci::CompletedPackets cp; |
| 244 | cp.connection_handle_ = handle; |
| 245 | cp.host_num_of_completed_packets_ = kNumCommandPackets; |
| 246 | completed_packets.push_back(cp); |
| 247 | auto packet = bluetooth::hci::NumberOfCompletedPacketsBuilder::Create( |
| 248 | completed_packets); |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 249 | send_event_(std::move(packet)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 250 | return; |
| 251 | } |
| 252 | |
| 253 | link_layer_controller_.SendAclToRemote(acl_packet); |
| 254 | } |
| 255 | |
| 256 | void DualModeController::HandleSco(std::shared_ptr<std::vector<uint8_t>> packet) { |
Chienyuan | 85db6ee | 2019-11-21 22:07:09 +0800 | [diff] [blame] | 257 | bluetooth::hci::PacketView<bluetooth::hci::kLittleEndian> raw_packet(packet); |
| 258 | auto sco_packet = bluetooth::hci::ScoPacketView::Create(raw_packet); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 259 | if (loopback_mode_ == hci::LoopbackMode::LOCAL) { |
| 260 | uint16_t handle = sco_packet.GetHandle(); |
| 261 | send_sco_(packet); |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 262 | std::vector<bluetooth::hci::CompletedPackets> completed_packets; |
| 263 | bluetooth::hci::CompletedPackets cp; |
| 264 | cp.connection_handle_ = handle; |
| 265 | cp.host_num_of_completed_packets_ = kNumCommandPackets; |
| 266 | completed_packets.push_back(cp); |
| 267 | auto packet = bluetooth::hci::NumberOfCompletedPacketsBuilder::Create( |
| 268 | completed_packets); |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 269 | send_event_(std::move(packet)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 270 | return; |
| 271 | } |
| 272 | } |
| 273 | |
Jakub Pawlowski | de6c013 | 2019-11-12 16:14:32 +0100 | [diff] [blame] | 274 | void DualModeController::HandleIso( |
| 275 | std::shared_ptr<std::vector<uint8_t>> /* packet */) { |
| 276 | // TODO: implement handling similar to HandleSco |
| 277 | } |
| 278 | |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 279 | void DualModeController::HandleCommand(std::shared_ptr<std::vector<uint8_t>> packet) { |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 280 | bluetooth::hci::PacketView<bluetooth::hci::kLittleEndian> raw_packet(packet); |
| 281 | auto command_packet = bluetooth::hci::CommandPacketView::Create(raw_packet); |
| 282 | ASSERT(command_packet.IsValid()); |
| 283 | auto op = command_packet.GetOpCode(); |
| 284 | uint16_t opcode = static_cast<uint16_t>(op); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 285 | |
| 286 | if (loopback_mode_ == hci::LoopbackMode::LOCAL && |
| 287 | // Loopback exceptions. |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 288 | op != bluetooth::hci::OpCode::RESET && |
| 289 | op != bluetooth::hci::OpCode::SET_CONTROLLER_TO_HOST_FLOW_CONTROL && |
| 290 | op != bluetooth::hci::OpCode::HOST_BUFFER_SIZE && |
| 291 | op != bluetooth::hci::OpCode::HOST_NUM_COMPLETED_PACKETS && |
| 292 | op != bluetooth::hci::OpCode::READ_BUFFER_SIZE && |
| 293 | op != bluetooth::hci::OpCode::READ_LOOPBACK_MODE && |
| 294 | op != bluetooth::hci::OpCode::WRITE_LOOPBACK_MODE) { |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 295 | std::unique_ptr<bluetooth::packet::RawBuilder> raw_builder_ptr = |
| 296 | std::make_unique<bluetooth::packet::RawBuilder>(); |
| 297 | raw_builder_ptr->AddOctets(*packet); |
| 298 | auto packet = bluetooth::hci::LoopbackCommandBuilder::Create( |
| 299 | std::move(raw_builder_ptr)); |
| 300 | send_event_(std::move(packet)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 301 | } else if (active_hci_commands_.count(opcode) > 0) { |
| 302 | active_hci_commands_[opcode](command_packet.GetPayload()); |
| 303 | } else { |
| 304 | SendCommandCompleteUnknownOpCodeEvent(opcode); |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 305 | LOG_INFO("Unknown command, opcode: 0x%04X, OGF: 0x%04X, OCF: 0x%04X", |
| 306 | opcode, (opcode & 0xFC00) >> 10, opcode & 0x03FF); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 307 | } |
| 308 | } |
| 309 | |
| 310 | void DualModeController::RegisterEventChannel( |
| 311 | const std::function<void(std::shared_ptr<std::vector<uint8_t>>)>& callback) { |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 312 | send_event_ = |
| 313 | [callback](std::shared_ptr<bluetooth::hci::EventPacketBuilder> event) { |
| 314 | auto bytes = std::make_shared<std::vector<uint8_t>>(); |
| 315 | bluetooth::packet::BitInserter bit_inserter(*bytes); |
| 316 | bytes->reserve(event->size()); |
| 317 | event->Serialize(bit_inserter); |
| 318 | callback(std::move(bytes)); |
| 319 | }; |
| 320 | link_layer_controller_.RegisterEventChannel(send_event_); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 321 | } |
| 322 | |
| 323 | void DualModeController::RegisterAclChannel( |
| 324 | const std::function<void(std::shared_ptr<std::vector<uint8_t>>)>& callback) { |
Chienyuan | 85db6ee | 2019-11-21 22:07:09 +0800 | [diff] [blame] | 325 | send_acl_ = |
| 326 | [callback](std::shared_ptr<bluetooth::hci::AclPacketBuilder> acl_data) { |
| 327 | auto bytes = std::make_shared<std::vector<uint8_t>>(); |
| 328 | bluetooth::packet::BitInserter bit_inserter(*bytes); |
| 329 | bytes->reserve(acl_data->size()); |
| 330 | acl_data->Serialize(bit_inserter); |
| 331 | callback(std::move(bytes)); |
| 332 | }; |
| 333 | link_layer_controller_.RegisterAclChannel(send_acl_); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 334 | } |
| 335 | |
| 336 | void DualModeController::RegisterScoChannel( |
| 337 | const std::function<void(std::shared_ptr<std::vector<uint8_t>>)>& callback) { |
| 338 | link_layer_controller_.RegisterScoChannel(callback); |
| 339 | send_sco_ = callback; |
| 340 | } |
| 341 | |
Jakub Pawlowski | de6c013 | 2019-11-12 16:14:32 +0100 | [diff] [blame] | 342 | void DualModeController::RegisterIsoChannel( |
| 343 | const std::function<void(std::shared_ptr<std::vector<uint8_t>>)>& |
| 344 | callback) { |
| 345 | link_layer_controller_.RegisterIsoChannel(callback); |
| 346 | send_iso_ = callback; |
| 347 | } |
| 348 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 349 | void DualModeController::HciReset(bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 350 | ASSERT_LOG(args.size() == 0, "%s size=%zu", __func__, args.size()); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 351 | link_layer_controller_.Reset(); |
Hansong Zhang | 843271b | 2019-04-30 10:51:27 -0700 | [diff] [blame] | 352 | if (loopback_mode_ == hci::LoopbackMode::LOCAL) { |
| 353 | loopback_mode_ = hci::LoopbackMode::NO; |
| 354 | } |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 355 | |
Myles Watson | e066df4 | 2019-11-13 14:39:18 -0800 | [diff] [blame] | 356 | send_event_(bluetooth::hci::ResetCompleteBuilder::Create( |
| 357 | kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 358 | } |
| 359 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 360 | void DualModeController::HciReadBufferSize( |
| 361 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 362 | ASSERT_LOG(args.size() == 0, "%s size=%zu", __func__, args.size()); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 363 | |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 364 | auto packet = bluetooth::hci::ReadBufferSizeCompleteBuilder::Create( |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 365 | kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS, |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 366 | properties_.GetAclDataPacketSize(), |
| 367 | properties_.GetSynchronousDataPacketSize(), |
| 368 | properties_.GetTotalNumAclDataPackets(), |
| 369 | properties_.GetTotalNumSynchronousDataPackets()); |
| 370 | send_event_(std::move(packet)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 371 | } |
| 372 | |
Calvin Huang | 63a0896 | 2019-10-31 19:12:25 -0700 | [diff] [blame] | 373 | void DualModeController::HciReadEncryptionKeySize( |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 374 | bluetooth::packet::PacketView<true> args) { |
Calvin Huang | 63a0896 | 2019-10-31 19:12:25 -0700 | [diff] [blame] | 375 | ASSERT_LOG(args.size() == 2, "%s size=%zu", __func__, args.size()); |
| 376 | |
| 377 | uint16_t handle = args.begin().extract<uint16_t>(); |
| 378 | |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 379 | auto packet = bluetooth::hci::ReadEncryptionKeySizeCompleteBuilder::Create( |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 380 | kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS, handle, |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 381 | properties_.GetEncryptionKeySize()); |
| 382 | send_event_(std::move(packet)); |
Calvin Huang | 63a0896 | 2019-10-31 19:12:25 -0700 | [diff] [blame] | 383 | } |
| 384 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 385 | void DualModeController::HciHostBufferSize( |
| 386 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 387 | ASSERT_LOG(args.size() == 7, "%s size=%zu", __func__, args.size()); |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 388 | auto packet = bluetooth::hci::HostBufferSizeCompleteBuilder::Create( |
| 389 | kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS); |
| 390 | send_event_(std::move(packet)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 391 | } |
| 392 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 393 | void DualModeController::HciReadLocalVersionInformation( |
| 394 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 395 | ASSERT_LOG(args.size() == 0, "%s size=%zu", __func__, args.size()); |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 396 | |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 397 | bluetooth::hci::LocalVersionInformation local_version_information; |
| 398 | local_version_information.hci_version_ = |
| 399 | static_cast<bluetooth::hci::HciVersion>(properties_.GetVersion()); |
| 400 | local_version_information.hci_revision_ = properties_.GetRevision(); |
| 401 | local_version_information.lmp_version_ = |
| 402 | static_cast<bluetooth::hci::LmpVersion>(properties_.GetLmpPalVersion()); |
| 403 | local_version_information.manufacturer_name_ = |
| 404 | properties_.GetManufacturerName(); |
| 405 | local_version_information.lmp_subversion_ = properties_.GetLmpPalSubversion(); |
| 406 | auto packet = |
| 407 | bluetooth::hci::ReadLocalVersionInformationCompleteBuilder::Create( |
| 408 | kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS, |
| 409 | local_version_information); |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 410 | send_event_(std::move(packet)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 411 | } |
| 412 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 413 | void DualModeController::HciReadRemoteVersionInformation( |
| 414 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 415 | ASSERT_LOG(args.size() == 2, "%s size=%zu", __func__, args.size()); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 416 | |
| 417 | uint16_t handle = args.begin().extract<uint16_t>(); |
| 418 | |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 419 | auto status = link_layer_controller_.SendCommandToRemoteByHandle( |
| 420 | bluetooth::hci::OpCode::READ_REMOTE_VERSION_INFORMATION, args, handle); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 421 | |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 422 | auto packet = |
| 423 | bluetooth::hci::ReadRemoteVersionInformationStatusBuilder::Create( |
| 424 | status, kNumCommandPackets); |
| 425 | send_event_(std::move(packet)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 426 | } |
| 427 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 428 | void DualModeController::HciReadBdAddr( |
| 429 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 430 | ASSERT_LOG(args.size() == 0, "%s size=%zu", __func__, args.size()); |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 431 | auto packet = bluetooth::hci::ReadBdAddrCompleteBuilder::Create( |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 432 | kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS, |
| 433 | properties_.GetAddress()); |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 434 | send_event_(std::move(packet)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 435 | } |
| 436 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 437 | void DualModeController::HciReadLocalSupportedCommands( |
| 438 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 439 | ASSERT_LOG(args.size() == 0, "%s size=%zu", __func__, args.size()); |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 440 | |
| 441 | std::array<uint8_t, 64> supported_commands; |
| 442 | supported_commands.fill(0x00); |
| 443 | size_t len = properties_.GetSupportedCommands().size(); |
| 444 | if (len > 64) { |
| 445 | len = 64; |
| 446 | } |
| 447 | std::copy_n(properties_.GetSupportedCommands().begin(), len, |
| 448 | supported_commands.begin()); |
| 449 | |
| 450 | auto packet = |
| 451 | bluetooth::hci::ReadLocalSupportedCommandsCompleteBuilder::Create( |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 452 | kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS, |
| 453 | supported_commands); |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 454 | send_event_(std::move(packet)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 455 | } |
| 456 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 457 | void DualModeController::HciReadLocalSupportedFeatures( |
| 458 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 459 | ASSERT_LOG(args.size() == 0, "%s size=%zu", __func__, args.size()); |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 460 | auto packet = |
| 461 | bluetooth::hci::ReadLocalSupportedFeaturesCompleteBuilder::Create( |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 462 | kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS, |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 463 | properties_.GetSupportedFeatures()); |
| 464 | send_event_(std::move(packet)); |
Myles Watson | 14d5686 | 2019-08-19 13:03:46 -0700 | [diff] [blame] | 465 | } |
| 466 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 467 | void DualModeController::HciReadLocalSupportedCodecs( |
| 468 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 469 | ASSERT_LOG(args.size() == 0, "%s size=%zu", __func__, args.size()); |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 470 | auto packet = bluetooth::hci::ReadLocalSupportedCodecsCompleteBuilder::Create( |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 471 | kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS, |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 472 | properties_.GetSupportedCodecs(), properties_.GetVendorSpecificCodecs()); |
| 473 | send_event_(std::move(packet)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 474 | } |
| 475 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 476 | void DualModeController::HciReadLocalExtendedFeatures( |
| 477 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 478 | ASSERT_LOG(args.size() == 1, "%s size=%zu", __func__, args.size()); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 479 | uint8_t page_number = args.begin().extract<uint8_t>(); |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 480 | |
| 481 | auto pakcet = |
| 482 | bluetooth::hci::ReadLocalExtendedFeaturesCompleteBuilder::Create( |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 483 | kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS, page_number, |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 484 | properties_.GetExtendedFeaturesMaximumPageNumber(), |
| 485 | properties_.GetExtendedFeatures(page_number)); |
| 486 | send_event_(std::move(pakcet)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 487 | } |
| 488 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 489 | void DualModeController::HciReadRemoteExtendedFeatures( |
| 490 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 491 | ASSERT_LOG(args.size() == 3, "%s size=%zu", __func__, args.size()); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 492 | |
| 493 | uint16_t handle = args.begin().extract<uint16_t>(); |
| 494 | |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 495 | auto status = link_layer_controller_.SendCommandToRemoteByHandle( |
| 496 | bluetooth::hci::OpCode::READ_REMOTE_EXTENDED_FEATURES, args, handle); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 497 | |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 498 | auto packet = bluetooth::hci::ReadRemoteExtendedFeaturesStatusBuilder::Create( |
| 499 | status, kNumCommandPackets); |
| 500 | send_event_(std::move(packet)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 501 | } |
| 502 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 503 | void DualModeController::HciSwitchRole( |
| 504 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 505 | ASSERT_LOG(args.size() == 7, "%s size=%zu", __func__, args.size()); |
Chienyuan | 9145e7a | 2019-10-02 15:18:55 +0800 | [diff] [blame] | 506 | |
| 507 | Address address = args.begin().extract<Address>(); |
| 508 | uint8_t role = args.begin().extract<uint8_t>(); |
| 509 | |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 510 | auto status = link_layer_controller_.SwitchRole(address, role); |
Chienyuan | 9145e7a | 2019-10-02 15:18:55 +0800 | [diff] [blame] | 511 | |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 512 | auto packet = bluetooth::hci::SwitchRoleStatusBuilder::Create( |
| 513 | status, kNumCommandPackets); |
| 514 | send_event_(std::move(packet)); |
Chienyuan | 9145e7a | 2019-10-02 15:18:55 +0800 | [diff] [blame] | 515 | } |
| 516 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 517 | void DualModeController::HciReadRemoteSupportedFeatures( |
| 518 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 519 | ASSERT_LOG(args.size() == 2, "%s size=%zu", __func__, args.size()); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 520 | |
| 521 | uint16_t handle = args.begin().extract<uint16_t>(); |
| 522 | |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 523 | auto status = link_layer_controller_.SendCommandToRemoteByHandle( |
| 524 | bluetooth::hci::OpCode::READ_REMOTE_SUPPORTED_FEATURES, args, handle); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 525 | |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 526 | auto packet = |
| 527 | bluetooth::hci::ReadRemoteSupportedFeaturesStatusBuilder::Create( |
| 528 | status, kNumCommandPackets); |
| 529 | send_event_(std::move(packet)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 530 | } |
| 531 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 532 | void DualModeController::HciReadClockOffset( |
| 533 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 534 | ASSERT_LOG(args.size() == 2, "%s size=%zu", __func__, args.size()); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 535 | |
| 536 | uint16_t handle = args.begin().extract<uint16_t>(); |
| 537 | |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 538 | auto status = link_layer_controller_.SendCommandToRemoteByHandle( |
| 539 | bluetooth::hci::OpCode::READ_CLOCK_OFFSET, args, handle); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 540 | |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 541 | auto packet = bluetooth::hci::ReadClockOffsetStatusBuilder::Create( |
| 542 | status, kNumCommandPackets); |
| 543 | send_event_(std::move(packet)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 544 | } |
| 545 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 546 | void DualModeController::HciIoCapabilityRequestReply( |
| 547 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 548 | ASSERT_LOG(args.size() == 9, "%s size=%zu", __func__, args.size()); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 549 | |
| 550 | auto args_itr = args.begin(); |
| 551 | Address peer = args_itr.extract<Address>(); |
| 552 | uint8_t io_capability = args_itr.extract<uint8_t>(); |
| 553 | uint8_t oob_data_present_flag = args_itr.extract<uint8_t>(); |
| 554 | uint8_t authentication_requirements = args_itr.extract<uint8_t>(); |
| 555 | |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 556 | auto status = link_layer_controller_.IoCapabilityRequestReply( |
| 557 | peer, io_capability, oob_data_present_flag, authentication_requirements); |
| 558 | auto packet = bluetooth::hci::IoCapabilityRequestReplyCompleteBuilder::Create( |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 559 | kNumCommandPackets, status, peer); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 560 | |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 561 | send_event_(std::move(packet)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 562 | } |
| 563 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 564 | void DualModeController::HciUserConfirmationRequestReply( |
| 565 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 566 | ASSERT_LOG(args.size() == 6, "%s size=%zu", __func__, args.size()); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 567 | |
| 568 | Address peer = args.begin().extract<Address>(); |
| 569 | |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 570 | auto status = link_layer_controller_.UserConfirmationRequestReply(peer); |
| 571 | auto packet = |
| 572 | bluetooth::hci::UserConfirmationRequestReplyCompleteBuilder::Create( |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 573 | kNumCommandPackets, status, peer); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 574 | |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 575 | send_event_(std::move(packet)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 576 | } |
| 577 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 578 | void DualModeController::HciUserConfirmationRequestNegativeReply( |
| 579 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 580 | ASSERT_LOG(args.size() == 6, "%s size=%zu", __func__, args.size()); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 581 | |
| 582 | Address peer = args.begin().extract<Address>(); |
| 583 | |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 584 | auto status = |
| 585 | link_layer_controller_.UserConfirmationRequestNegativeReply(peer); |
| 586 | auto packet = |
| 587 | bluetooth::hci::UserConfirmationRequestNegativeReplyCompleteBuilder:: |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 588 | Create(kNumCommandPackets, status, peer); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 589 | |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 590 | send_event_(std::move(packet)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 591 | } |
| 592 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 593 | void DualModeController::HciUserPasskeyRequestReply( |
| 594 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 595 | ASSERT_LOG(args.size() == 10, "%s size=%zu", __func__, args.size()); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 596 | |
| 597 | auto args_itr = args.begin(); |
| 598 | Address peer = args_itr.extract<Address>(); |
| 599 | uint32_t numeric_value = args_itr.extract<uint32_t>(); |
| 600 | |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 601 | auto status = |
| 602 | link_layer_controller_.UserPasskeyRequestReply(peer, numeric_value); |
| 603 | auto packet = bluetooth::hci::UserPasskeyRequestReplyCompleteBuilder::Create( |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 604 | kNumCommandPackets, status, peer); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 605 | |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 606 | send_event_(std::move(packet)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 607 | } |
| 608 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 609 | void DualModeController::HciUserPasskeyRequestNegativeReply( |
| 610 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 611 | ASSERT_LOG(args.size() == 6, "%s size=%zu", __func__, args.size()); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 612 | |
| 613 | Address peer = args.begin().extract<Address>(); |
| 614 | |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 615 | auto status = link_layer_controller_.UserPasskeyRequestNegativeReply(peer); |
| 616 | auto packet = |
| 617 | bluetooth::hci::UserPasskeyRequestNegativeReplyCompleteBuilder::Create( |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 618 | kNumCommandPackets, status, peer); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 619 | |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 620 | send_event_(std::move(packet)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 621 | } |
| 622 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 623 | void DualModeController::HciRemoteOobDataRequestReply( |
| 624 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 625 | ASSERT_LOG(args.size() == 38, "%s size=%zu", __func__, args.size()); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 626 | |
| 627 | auto args_itr = args.begin(); |
| 628 | Address peer = args_itr.extract<Address>(); |
| 629 | std::vector<uint8_t> c; |
| 630 | std::vector<uint8_t> r; |
| 631 | for (size_t i = 0; i < 16; i++) { |
| 632 | c.push_back(args_itr.extract<uint8_t>()); |
| 633 | } |
| 634 | for (size_t i = 0; i < 16; i++) { |
| 635 | r.push_back(args_itr.extract<uint8_t>()); |
| 636 | } |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 637 | auto status = link_layer_controller_.RemoteOobDataRequestReply(peer, c, r); |
| 638 | auto packet = |
| 639 | bluetooth::hci::RemoteOobDataRequestReplyCompleteBuilder::Create( |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 640 | kNumCommandPackets, status, peer); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 641 | |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 642 | send_event_(std::move(packet)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 643 | } |
| 644 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 645 | void DualModeController::HciRemoteOobDataRequestNegativeReply( |
| 646 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 647 | ASSERT_LOG(args.size() == 6, "%s size=%zu", __func__, args.size()); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 648 | |
| 649 | Address peer = args.begin().extract<Address>(); |
| 650 | |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 651 | auto status = link_layer_controller_.RemoteOobDataRequestNegativeReply(peer); |
| 652 | auto packet = |
| 653 | bluetooth::hci::RemoteOobDataRequestNegativeReplyCompleteBuilder::Create( |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 654 | kNumCommandPackets, status, peer); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 655 | |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 656 | send_event_(std::move(packet)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 657 | } |
| 658 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 659 | void DualModeController::HciIoCapabilityRequestNegativeReply( |
| 660 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 661 | ASSERT_LOG(args.size() == 7, "%s size=%zu", __func__, args.size()); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 662 | |
| 663 | auto args_itr = args.begin(); |
| 664 | Address peer = args_itr.extract<Address>(); |
| 665 | hci::Status reason = args_itr.extract<hci::Status>(); |
| 666 | |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 667 | auto status = |
| 668 | link_layer_controller_.IoCapabilityRequestNegativeReply(peer, reason); |
| 669 | auto packet = |
| 670 | bluetooth::hci::IoCapabilityRequestNegativeReplyCompleteBuilder::Create( |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 671 | kNumCommandPackets, status, peer); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 672 | |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 673 | send_event_(std::move(packet)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 674 | } |
| 675 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 676 | void DualModeController::HciWriteSimplePairingMode( |
| 677 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 678 | ASSERT_LOG(args.size() == 1, "%s size=%zu", __func__, args.size()); |
| 679 | ASSERT(args[0] == 1 || args[0] == 0); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 680 | link_layer_controller_.WriteSimplePairingMode(args[0] == 1); |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 681 | auto packet = bluetooth::hci::WriteSimplePairingModeCompleteBuilder::Create( |
| 682 | kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS); |
| 683 | send_event_(std::move(packet)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 684 | } |
| 685 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 686 | void DualModeController::HciChangeConnectionPacketType( |
| 687 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 688 | ASSERT_LOG(args.size() == 4, "%s size=%zu", __func__, args.size()); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 689 | auto args_itr = args.begin(); |
| 690 | uint16_t handle = args_itr.extract<uint16_t>(); |
| 691 | uint16_t packet_type = args_itr.extract<uint16_t>(); |
| 692 | |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 693 | auto status = |
| 694 | link_layer_controller_.ChangeConnectionPacketType(handle, packet_type); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 695 | |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 696 | auto packet = bluetooth::hci::ChangeConnectionPacketTypeStatusBuilder::Create( |
| 697 | status, kNumCommandPackets); |
| 698 | send_event_(std::move(packet)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 699 | } |
| 700 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 701 | void DualModeController::HciWriteLeHostSupport( |
| 702 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 703 | ASSERT_LOG(args.size() == 2, "%s size=%zu", __func__, args.size()); |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 704 | auto packet = bluetooth::hci::WriteLeHostSupportCompleteBuilder::Create( |
| 705 | kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS); |
| 706 | send_event_(std::move(packet)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 707 | } |
| 708 | |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 709 | void DualModeController::HciWriteSecureConnectionsHostSupport( |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 710 | bluetooth::packet::PacketView<true> args) { |
Calvin Huang | 63a0896 | 2019-10-31 19:12:25 -0700 | [diff] [blame] | 711 | ASSERT_LOG(args.size() == 1, "%s size=%zu", __func__, args.size()); |
Myles Watson | 171ccb2 | 2019-11-13 09:37:29 -0800 | [diff] [blame] | 712 | properties_.SetExtendedFeatures(properties_.GetExtendedFeatures(1) | 0x8, 1); |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 713 | auto packet = |
| 714 | bluetooth::hci::WriteSecureConnectionsHostSupportCompleteBuilder::Create( |
| 715 | kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS); |
| 716 | send_event_(std::move(packet)); |
Calvin Huang | 63a0896 | 2019-10-31 19:12:25 -0700 | [diff] [blame] | 717 | } |
| 718 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 719 | void DualModeController::HciSetEventMask( |
| 720 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 721 | ASSERT_LOG(args.size() == 8, "%s size=%zu", __func__, args.size()); |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 722 | auto packet = bluetooth::hci::SetEventMaskCompleteBuilder::Create( |
| 723 | kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS); |
| 724 | send_event_(std::move(packet)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 725 | } |
| 726 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 727 | void DualModeController::HciWriteInquiryMode( |
| 728 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 729 | ASSERT_LOG(args.size() == 1, "%s size=%zu", __func__, args.size()); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 730 | link_layer_controller_.SetInquiryMode(args[0]); |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 731 | auto packet = bluetooth::hci::WriteInquiryModeCompleteBuilder::Create( |
| 732 | kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS); |
| 733 | send_event_(std::move(packet)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 734 | } |
| 735 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 736 | void DualModeController::HciWritePageScanType( |
| 737 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 738 | ASSERT_LOG(args.size() == 1, "%s size=%zu", __func__, args.size()); |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 739 | auto packet = bluetooth::hci::WritePageScanTypeCompleteBuilder::Create( |
| 740 | kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS); |
| 741 | send_event_(std::move(packet)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 742 | } |
| 743 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 744 | void DualModeController::HciWriteInquiryScanType( |
| 745 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 746 | ASSERT_LOG(args.size() == 1, "%s size=%zu", __func__, args.size()); |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 747 | auto packet = bluetooth::hci::WriteInquiryScanTypeCompleteBuilder::Create( |
| 748 | kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS); |
| 749 | send_event_(std::move(packet)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 750 | } |
| 751 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 752 | void DualModeController::HciAuthenticationRequested( |
| 753 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 754 | ASSERT_LOG(args.size() == 2, "%s size=%zu", __func__, args.size()); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 755 | uint16_t handle = args.begin().extract<uint16_t>(); |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 756 | auto status = link_layer_controller_.AuthenticationRequested(handle); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 757 | |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 758 | auto packet = bluetooth::hci::AuthenticationRequestedStatusBuilder::Create( |
| 759 | status, kNumCommandPackets); |
| 760 | send_event_(std::move(packet)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 761 | } |
| 762 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 763 | void DualModeController::HciSetConnectionEncryption( |
| 764 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 765 | ASSERT_LOG(args.size() == 3, "%s size=%zu", __func__, args.size()); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 766 | auto args_itr = args.begin(); |
| 767 | uint16_t handle = args_itr.extract<uint16_t>(); |
| 768 | uint8_t encryption_enable = args_itr.extract<uint8_t>(); |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 769 | auto status = |
| 770 | link_layer_controller_.SetConnectionEncryption(handle, encryption_enable); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 771 | |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 772 | auto packet = bluetooth::hci::SetConnectionEncryptionStatusBuilder::Create( |
| 773 | status, kNumCommandPackets); |
| 774 | send_event_(std::move(packet)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 775 | } |
| 776 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 777 | void DualModeController::HciChangeConnectionLinkKey( |
| 778 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 779 | ASSERT_LOG(args.size() == 2, "%s size=%zu", __func__, args.size()); |
Chienyuan | ad340b0 | 2019-09-25 19:23:21 +0800 | [diff] [blame] | 780 | auto args_itr = args.begin(); |
| 781 | uint16_t handle = args_itr.extract<uint16_t>(); |
| 782 | |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 783 | auto status = link_layer_controller_.ChangeConnectionLinkKey(handle); |
Chienyuan | ad340b0 | 2019-09-25 19:23:21 +0800 | [diff] [blame] | 784 | |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 785 | auto packet = bluetooth::hci::ChangeConnectionLinkKeyStatusBuilder::Create( |
| 786 | status, kNumCommandPackets); |
| 787 | send_event_(std::move(packet)); |
Chienyuan | ad340b0 | 2019-09-25 19:23:21 +0800 | [diff] [blame] | 788 | } |
| 789 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 790 | void DualModeController::HciMasterLinkKey( |
| 791 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 792 | ASSERT_LOG(args.size() == 1, "%s size=%zu", __func__, args.size()); |
Chienyuan | 9145e7a | 2019-10-02 15:18:55 +0800 | [diff] [blame] | 793 | auto args_itr = args.begin(); |
| 794 | uint8_t key_flag = args_itr.extract<uint8_t>(); |
| 795 | |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 796 | auto status = link_layer_controller_.MasterLinkKey(key_flag); |
Chienyuan | 9145e7a | 2019-10-02 15:18:55 +0800 | [diff] [blame] | 797 | |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 798 | auto packet = bluetooth::hci::MasterLinkKeyStatusBuilder::Create( |
| 799 | status, kNumCommandPackets); |
| 800 | send_event_(std::move(packet)); |
Chienyuan | 9145e7a | 2019-10-02 15:18:55 +0800 | [diff] [blame] | 801 | } |
| 802 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 803 | void DualModeController::HciWriteAuthenticationEnable( |
| 804 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 805 | ASSERT_LOG(args.size() == 1, "%s size=%zu", __func__, args.size()); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 806 | properties_.SetAuthenticationEnable(args[0]); |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 807 | auto packet = |
| 808 | bluetooth::hci::WriteAuthenticationEnableCompleteBuilder::Create( |
| 809 | kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS); |
| 810 | send_event_(std::move(packet)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 811 | } |
| 812 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 813 | void DualModeController::HciReadAuthenticationEnable( |
| 814 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 815 | ASSERT_LOG(args.size() == 0, "%s size=%zu", __func__, args.size()); |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 816 | auto packet = bluetooth::hci::ReadAuthenticationEnableCompleteBuilder::Create( |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 817 | kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS, |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 818 | static_cast<bluetooth::hci::AuthenticationEnable>( |
| 819 | properties_.GetAuthenticationEnable())); |
| 820 | send_event_(std::move(packet)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 821 | } |
| 822 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 823 | void DualModeController::HciWriteClassOfDevice( |
| 824 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 825 | ASSERT_LOG(args.size() == 3, "%s size=%zu", __func__, args.size()); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 826 | properties_.SetClassOfDevice(args[0], args[1], args[2]); |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 827 | auto packet = bluetooth::hci::WriteClassOfDeviceCompleteBuilder::Create( |
| 828 | kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS); |
| 829 | send_event_(std::move(packet)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 830 | } |
| 831 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 832 | void DualModeController::HciWritePageTimeout( |
| 833 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 834 | ASSERT_LOG(args.size() == 2, "%s size=%zu", __func__, args.size()); |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 835 | auto packet = bluetooth::hci::WritePageTimeoutCompleteBuilder::Create( |
| 836 | kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS); |
| 837 | send_event_(std::move(packet)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 838 | } |
| 839 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 840 | void DualModeController::HciHoldMode(bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 841 | ASSERT_LOG(args.size() == 6, "%s size=%zu", __func__, args.size()); |
Chienyuan | ad340b0 | 2019-09-25 19:23:21 +0800 | [diff] [blame] | 842 | auto args_itr = args.begin(); |
| 843 | uint16_t handle = args_itr.extract<uint16_t>(); |
| 844 | uint16_t hold_mode_max_interval = args_itr.extract<uint16_t>(); |
| 845 | uint16_t hold_mode_min_interval = args_itr.extract<uint16_t>(); |
| 846 | |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 847 | auto status = link_layer_controller_.HoldMode(handle, hold_mode_max_interval, |
| 848 | hold_mode_min_interval); |
Chienyuan | ad340b0 | 2019-09-25 19:23:21 +0800 | [diff] [blame] | 849 | |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 850 | auto packet = |
| 851 | bluetooth::hci::HoldModeStatusBuilder::Create(status, kNumCommandPackets); |
| 852 | send_event_(std::move(packet)); |
Chienyuan | ad340b0 | 2019-09-25 19:23:21 +0800 | [diff] [blame] | 853 | } |
| 854 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 855 | void DualModeController::HciSniffMode( |
| 856 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 857 | ASSERT_LOG(args.size() == 10, "%s size=%zu", __func__, args.size()); |
Chienyuan | ad340b0 | 2019-09-25 19:23:21 +0800 | [diff] [blame] | 858 | auto args_itr = args.begin(); |
| 859 | uint16_t handle = args_itr.extract<uint16_t>(); |
| 860 | uint16_t sniff_max_interval = args_itr.extract<uint16_t>(); |
| 861 | uint16_t sniff_min_interval = args_itr.extract<uint16_t>(); |
| 862 | uint16_t sniff_attempt = args_itr.extract<uint16_t>(); |
| 863 | uint16_t sniff_timeout = args_itr.extract<uint16_t>(); |
| 864 | |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 865 | auto status = link_layer_controller_.SniffMode(handle, sniff_max_interval, |
| 866 | sniff_min_interval, |
| 867 | sniff_attempt, sniff_timeout); |
Chienyuan | ad340b0 | 2019-09-25 19:23:21 +0800 | [diff] [blame] | 868 | |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 869 | auto packet = bluetooth::hci::SniffModeStatusBuilder::Create( |
| 870 | status, kNumCommandPackets); |
| 871 | send_event_(std::move(packet)); |
Chienyuan | ad340b0 | 2019-09-25 19:23:21 +0800 | [diff] [blame] | 872 | } |
| 873 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 874 | void DualModeController::HciExitSniffMode( |
| 875 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 876 | ASSERT_LOG(args.size() == 2, "%s size=%zu", __func__, args.size()); |
Chienyuan | ad340b0 | 2019-09-25 19:23:21 +0800 | [diff] [blame] | 877 | auto args_itr = args.begin(); |
| 878 | uint16_t handle = args_itr.extract<uint16_t>(); |
| 879 | |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 880 | auto status = link_layer_controller_.ExitSniffMode(handle); |
Chienyuan | ad340b0 | 2019-09-25 19:23:21 +0800 | [diff] [blame] | 881 | |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 882 | auto packet = bluetooth::hci::ExitSniffModeStatusBuilder::Create( |
| 883 | status, kNumCommandPackets); |
| 884 | send_event_(std::move(packet)); |
Chienyuan | ad340b0 | 2019-09-25 19:23:21 +0800 | [diff] [blame] | 885 | } |
| 886 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 887 | void DualModeController::HciQosSetup(bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 888 | ASSERT_LOG(args.size() == 20, "%s size=%zu", __func__, args.size()); |
Chienyuan | ad340b0 | 2019-09-25 19:23:21 +0800 | [diff] [blame] | 889 | auto args_itr = args.begin(); |
| 890 | uint16_t handle = args_itr.extract<uint16_t>(); |
| 891 | args_itr.extract<uint8_t>(); // unused |
| 892 | uint8_t service_type = args_itr.extract<uint8_t>(); |
| 893 | uint32_t token_rate = args_itr.extract<uint32_t>(); |
| 894 | uint32_t peak_bandwidth = args_itr.extract<uint32_t>(); |
| 895 | uint32_t latency = args_itr.extract<uint32_t>(); |
| 896 | uint32_t delay_variation = args_itr.extract<uint32_t>(); |
| 897 | |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 898 | auto status = |
| 899 | link_layer_controller_.QosSetup(handle, service_type, token_rate, |
| 900 | peak_bandwidth, latency, delay_variation); |
Chienyuan | ad340b0 | 2019-09-25 19:23:21 +0800 | [diff] [blame] | 901 | |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 902 | auto packet = |
| 903 | bluetooth::hci::QosSetupStatusBuilder::Create(status, kNumCommandPackets); |
| 904 | send_event_(std::move(packet)); |
Chienyuan | ad340b0 | 2019-09-25 19:23:21 +0800 | [diff] [blame] | 905 | } |
| 906 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 907 | void DualModeController::HciWriteDefaultLinkPolicySettings( |
| 908 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 909 | ASSERT_LOG(args.size() == 2, "%s size=%zu", __func__, args.size()); |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 910 | auto packet = |
| 911 | bluetooth::hci::WriteDefaultLinkPolicySettingsCompleteBuilder::Create( |
| 912 | kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS); |
| 913 | send_event_(std::move(packet)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 914 | } |
| 915 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 916 | void DualModeController::HciFlowSpecification( |
| 917 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 918 | ASSERT_LOG(args.size() == 21, "%s size=%zu", __func__, args.size()); |
Chienyuan | ad340b0 | 2019-09-25 19:23:21 +0800 | [diff] [blame] | 919 | auto args_itr = args.begin(); |
| 920 | uint16_t handle = args_itr.extract<uint16_t>(); |
| 921 | args_itr.extract<uint8_t>(); // unused |
| 922 | uint8_t flow_direction = args_itr.extract<uint8_t>(); |
| 923 | uint8_t service_type = args_itr.extract<uint8_t>(); |
| 924 | uint32_t token_rate = args_itr.extract<uint32_t>(); |
| 925 | uint32_t token_bucket_size = args_itr.extract<uint32_t>(); |
| 926 | uint32_t peak_bandwidth = args_itr.extract<uint32_t>(); |
| 927 | uint32_t access_latency = args_itr.extract<uint32_t>(); |
| 928 | |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 929 | auto status = link_layer_controller_.FlowSpecification( |
| 930 | handle, flow_direction, service_type, token_rate, token_bucket_size, |
| 931 | peak_bandwidth, access_latency); |
Chienyuan | ad340b0 | 2019-09-25 19:23:21 +0800 | [diff] [blame] | 932 | |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 933 | auto packet = bluetooth::hci::FlowSpecificationStatusBuilder::Create( |
| 934 | status, kNumCommandPackets); |
| 935 | send_event_(std::move(packet)); |
Chienyuan | ad340b0 | 2019-09-25 19:23:21 +0800 | [diff] [blame] | 936 | } |
| 937 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 938 | void DualModeController::HciWriteLinkPolicySettings( |
| 939 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 940 | ASSERT_LOG(args.size() == 4, "%s size=%zu", __func__, args.size()); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 941 | |
| 942 | auto args_itr = args.begin(); |
| 943 | uint16_t handle = args_itr.extract<uint16_t>(); |
| 944 | uint16_t settings = args_itr.extract<uint16_t>(); |
| 945 | |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 946 | auto status = |
| 947 | link_layer_controller_.WriteLinkPolicySettings(handle, settings); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 948 | |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 949 | auto packet = bluetooth::hci::WriteLinkPolicySettingsCompleteBuilder::Create( |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 950 | kNumCommandPackets, status, handle); |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 951 | send_event_(std::move(packet)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 952 | } |
| 953 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 954 | void DualModeController::HciWriteLinkSupervisionTimeout( |
| 955 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 956 | ASSERT_LOG(args.size() == 4, "%s size=%zu", __func__, args.size()); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 957 | |
| 958 | auto args_itr = args.begin(); |
| 959 | uint16_t handle = args_itr.extract<uint16_t>(); |
| 960 | uint16_t timeout = args_itr.extract<uint16_t>(); |
| 961 | |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 962 | auto status = |
| 963 | link_layer_controller_.WriteLinkSupervisionTimeout(handle, timeout); |
| 964 | auto packet = |
| 965 | bluetooth::hci::WriteLinkSupervisionTimeoutCompleteBuilder::Create( |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 966 | kNumCommandPackets, status, handle); |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 967 | send_event_(std::move(packet)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 968 | } |
| 969 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 970 | void DualModeController::HciReadLocalName( |
| 971 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 972 | ASSERT_LOG(args.size() == 0, "%s size=%zu", __func__, args.size()); |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 973 | |
| 974 | std::array<uint8_t, 248> local_name; |
| 975 | local_name.fill(0x00); |
| 976 | size_t len = properties_.GetName().size(); |
| 977 | if (len > 247) { |
| 978 | len = 247; // one byte for NULL octet (0x00) |
| 979 | } |
| 980 | std::copy_n(properties_.GetName().begin(), len, local_name.begin()); |
| 981 | |
| 982 | auto packet = bluetooth::hci::ReadLocalNameCompleteBuilder::Create( |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 983 | kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS, local_name); |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 984 | send_event_(std::move(packet)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 985 | } |
| 986 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 987 | void DualModeController::HciWriteLocalName( |
| 988 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 989 | ASSERT_LOG(args.size() == 248, "%s size=%zu", __func__, args.size()); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 990 | std::vector<uint8_t> clipped(args.begin(), args.begin() + LastNonZero(args) + 1); |
| 991 | properties_.SetName(clipped); |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 992 | auto packet = bluetooth::hci::WriteLocalNameCompleteBuilder::Create( |
| 993 | kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS); |
| 994 | send_event_(std::move(packet)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 995 | } |
| 996 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 997 | void DualModeController::HciWriteExtendedInquiryResponse( |
| 998 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 999 | ASSERT_LOG(args.size() == 241, "%s size=%zu", __func__, args.size()); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 1000 | // Strip FEC byte and trailing zeros |
| 1001 | std::vector<uint8_t> clipped(args.begin() + 1, args.begin() + LastNonZero(args) + 1); |
| 1002 | properties_.SetExtendedInquiryData(clipped); |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 1003 | auto packet = |
| 1004 | bluetooth::hci::WriteExtendedInquiryResponseCompleteBuilder::Create( |
| 1005 | kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS); |
| 1006 | send_event_(std::move(packet)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 1007 | } |
| 1008 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 1009 | void DualModeController::HciRefreshEncryptionKey( |
| 1010 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 1011 | ASSERT_LOG(args.size() == 2, "%s size=%zu", __func__, args.size()); |
Myles Watson | b293d73 | 2019-08-19 12:35:36 -0700 | [diff] [blame] | 1012 | auto args_itr = args.begin(); |
| 1013 | uint16_t handle = args_itr.extract<uint16_t>(); |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 1014 | auto status_packet = |
| 1015 | bluetooth::hci::RefreshEncryptionKeyStatusBuilder::Create( |
| 1016 | bluetooth::hci::ErrorCode::SUCCESS, kNumCommandPackets); |
| 1017 | send_event_(std::move(status_packet)); |
Myles Watson | b293d73 | 2019-08-19 12:35:36 -0700 | [diff] [blame] | 1018 | // TODO: Support this in the link layer |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 1019 | auto complete_packet = |
| 1020 | bluetooth::hci::EncryptionKeyRefreshCompleteBuilder::Create( |
| 1021 | bluetooth::hci::ErrorCode::SUCCESS, handle); |
| 1022 | send_event_(std::move(complete_packet)); |
Myles Watson | b293d73 | 2019-08-19 12:35:36 -0700 | [diff] [blame] | 1023 | } |
| 1024 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 1025 | void DualModeController::HciWriteVoiceSetting( |
| 1026 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 1027 | ASSERT_LOG(args.size() == 2, "%s size=%zu", __func__, args.size()); |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 1028 | auto packet = bluetooth::hci::WriteVoiceSettingCompleteBuilder::Create( |
| 1029 | kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS); |
| 1030 | send_event_(std::move(packet)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 1031 | } |
| 1032 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 1033 | void DualModeController::HciWriteCurrentIacLap( |
| 1034 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 1035 | ASSERT(args.size() > 0); |
| 1036 | ASSERT(args.size() == 1 + (3 * args[0])); // count + 3-byte IACs |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 1037 | auto packet = bluetooth::hci::WriteCurrentIacLapCompleteBuilder::Create( |
| 1038 | kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS); |
| 1039 | send_event_(std::move(packet)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 1040 | } |
| 1041 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 1042 | void DualModeController::HciWriteInquiryScanActivity( |
| 1043 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 1044 | ASSERT_LOG(args.size() == 4, "%s size=%zu", __func__, args.size()); |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 1045 | auto packet = bluetooth::hci::WriteInquiryScanActivityCompleteBuilder::Create( |
| 1046 | kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS); |
| 1047 | send_event_(std::move(packet)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 1048 | } |
| 1049 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 1050 | void DualModeController::HciWriteScanEnable( |
| 1051 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 1052 | ASSERT_LOG(args.size() == 1, "%s size=%zu", __func__, args.size()); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 1053 | link_layer_controller_.SetInquiryScanEnable(args[0] & 0x1); |
| 1054 | link_layer_controller_.SetPageScanEnable(args[0] & 0x2); |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 1055 | auto packet = bluetooth::hci::WriteScanEnableCompleteBuilder::Create( |
| 1056 | kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS); |
| 1057 | send_event_(std::move(packet)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 1058 | } |
| 1059 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 1060 | void DualModeController::HciSetEventFilter( |
| 1061 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 1062 | ASSERT(args.size() > 0); |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 1063 | auto packet = bluetooth::hci::SetEventFilterCompleteBuilder::Create( |
| 1064 | kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS); |
| 1065 | send_event_(std::move(packet)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 1066 | } |
| 1067 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 1068 | void DualModeController::HciInquiry(bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 1069 | ASSERT_LOG(args.size() == 5, "%s size=%zu", __func__, args.size()); |
| 1070 | link_layer_controller_.SetInquiryLAP(args[0] | (args[1], 8) | (args[2], 16)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 1071 | link_layer_controller_.SetInquiryMaxResponses(args[4]); |
| 1072 | link_layer_controller_.StartInquiry(std::chrono::milliseconds(args[3] * 1280)); |
| 1073 | |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 1074 | auto packet = bluetooth::hci::InquiryStatusBuilder::Create( |
| 1075 | bluetooth::hci::ErrorCode::SUCCESS, kNumCommandPackets); |
| 1076 | send_event_(std::move(packet)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 1077 | } |
| 1078 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 1079 | void DualModeController::HciInquiryCancel( |
| 1080 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 1081 | ASSERT_LOG(args.size() == 0, "%s size=%zu", __func__, args.size()); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 1082 | link_layer_controller_.InquiryCancel(); |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 1083 | auto packet = bluetooth::hci::InquiryCancelCompleteBuilder::Create( |
| 1084 | kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS); |
| 1085 | send_event_(std::move(packet)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 1086 | } |
| 1087 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 1088 | void DualModeController::HciAcceptConnectionRequest( |
| 1089 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 1090 | ASSERT_LOG(args.size() == 7, "%s size=%zu", __func__, args.size()); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 1091 | Address addr = args.begin().extract<Address>(); |
| 1092 | bool try_role_switch = args[6] == 0; |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 1093 | auto status = |
| 1094 | link_layer_controller_.AcceptConnectionRequest(addr, try_role_switch); |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 1095 | auto packet = bluetooth::hci::AcceptConnectionRequestStatusBuilder::Create( |
| 1096 | status, kNumCommandPackets); |
| 1097 | send_event_(std::move(packet)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 1098 | } |
| 1099 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 1100 | void DualModeController::HciRejectConnectionRequest( |
| 1101 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 1102 | ASSERT_LOG(args.size() == 7, "%s size=%zu", __func__, args.size()); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 1103 | auto args_itr = args.begin(); |
| 1104 | Address addr = args_itr.extract<Address>(); |
| 1105 | uint8_t reason = args_itr.extract<uint8_t>(); |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 1106 | auto status = link_layer_controller_.RejectConnectionRequest(addr, reason); |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 1107 | auto packet = bluetooth::hci::RejectConnectionRequestStatusBuilder::Create( |
| 1108 | status, kNumCommandPackets); |
| 1109 | send_event_(std::move(packet)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 1110 | } |
| 1111 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 1112 | void DualModeController::HciLinkKeyRequestReply( |
| 1113 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 1114 | ASSERT_LOG(args.size() == 22, "%s size=%zu", __func__, args.size()); |
Myles Watson | e066df4 | 2019-11-13 14:39:18 -0800 | [diff] [blame] | 1115 | auto args_it = args.begin(); |
| 1116 | Address addr = args_it.extract<Address>(); |
| 1117 | auto key = args.begin().extract<std::array<uint8_t, 16>>(); |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 1118 | auto status = link_layer_controller_.LinkKeyRequestReply(addr, key); |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 1119 | auto packet = bluetooth::hci::LinkKeyRequestReplyCompleteBuilder::Create( |
| 1120 | kNumCommandPackets, status); |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 1121 | send_event_(std::move(packet)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 1122 | } |
| 1123 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 1124 | void DualModeController::HciLinkKeyRequestNegativeReply( |
| 1125 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 1126 | ASSERT_LOG(args.size() == 6, "%s size=%zu", __func__, args.size()); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 1127 | Address addr = args.begin().extract<Address>(); |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 1128 | auto status = link_layer_controller_.LinkKeyRequestNegativeReply(addr); |
| 1129 | auto packet = |
| 1130 | bluetooth::hci::LinkKeyRequestNegativeReplyCompleteBuilder::Create( |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 1131 | kNumCommandPackets, status, addr); |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 1132 | send_event_(std::move(packet)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 1133 | } |
| 1134 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 1135 | void DualModeController::HciDeleteStoredLinkKey( |
| 1136 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 1137 | ASSERT_LOG(args.size() == 7, "%s size=%zu", __func__, args.size()); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 1138 | |
| 1139 | uint16_t deleted_keys = 0; |
| 1140 | |
| 1141 | if (args[6] == 0) { |
| 1142 | Address addr = args.begin().extract<Address>(); |
| 1143 | deleted_keys = security_manager_.DeleteKey(addr); |
| 1144 | } |
| 1145 | |
| 1146 | if (args[6] == 1) { |
| 1147 | security_manager_.DeleteAllKeys(); |
| 1148 | } |
| 1149 | |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 1150 | auto packet = bluetooth::hci::DeleteStoredLinkKeyCompleteBuilder::Create( |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 1151 | kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS, deleted_keys); |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 1152 | |
| 1153 | send_event_(std::move(packet)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 1154 | } |
| 1155 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 1156 | void DualModeController::HciRemoteNameRequest( |
| 1157 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 1158 | ASSERT_LOG(args.size() == 10, "%s size=%zu", __func__, args.size()); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 1159 | |
| 1160 | Address remote_addr = args.begin().extract<Address>(); |
| 1161 | |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 1162 | auto status = link_layer_controller_.SendCommandToRemoteByAddress( |
Myles Watson | e066df4 | 2019-11-13 14:39:18 -0800 | [diff] [blame] | 1163 | bluetooth::hci::OpCode::REMOTE_NAME_REQUEST, args, remote_addr); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 1164 | |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 1165 | auto packet = bluetooth::hci::RemoteNameRequestStatusBuilder::Create( |
| 1166 | status, kNumCommandPackets); |
| 1167 | send_event_(std::move(packet)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 1168 | } |
| 1169 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 1170 | void DualModeController::HciLeSetEventMask( |
| 1171 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 1172 | ASSERT_LOG(args.size() == 8, "%s size=%zu", __func__, args.size()); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 1173 | /* |
| 1174 | uint64_t mask = args.begin().extract<uint64_t>(); |
| 1175 | link_layer_controller_.SetLeEventMask(mask); |
| 1176 | */ |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 1177 | auto packet = bluetooth::hci::LeSetEventMaskCompleteBuilder::Create( |
| 1178 | kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS); |
| 1179 | send_event_(std::move(packet)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 1180 | } |
| 1181 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 1182 | void DualModeController::HciLeReadBufferSize( |
| 1183 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 1184 | ASSERT_LOG(args.size() == 0, "%s size=%zu", __func__, args.size()); |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 1185 | |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 1186 | bluetooth::hci::LeBufferSize le_buffer_size; |
| 1187 | le_buffer_size.le_data_packet_length_ = properties_.GetLeDataPacketLength(); |
| 1188 | le_buffer_size.total_num_le_packets_ = properties_.GetTotalNumLeDataPackets(); |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 1189 | |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 1190 | auto packet = bluetooth::hci::LeReadBufferSizeCompleteBuilder::Create( |
| 1191 | kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS, le_buffer_size); |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 1192 | send_event_(std::move(packet)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 1193 | } |
| 1194 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 1195 | void DualModeController::HciLeReadLocalSupportedFeatures( |
| 1196 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 1197 | ASSERT_LOG(args.size() == 0, "%s size=%zu", __func__, args.size()); |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 1198 | auto packet = |
| 1199 | bluetooth::hci::LeReadLocalSupportedFeaturesCompleteBuilder::Create( |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 1200 | kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS, |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 1201 | properties_.GetLeSupportedFeatures()); |
| 1202 | send_event_(std::move(packet)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 1203 | } |
| 1204 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 1205 | void DualModeController::HciLeSetRandomAddress( |
| 1206 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 1207 | ASSERT_LOG(args.size() == 6, "%s size=%zu", __func__, args.size()); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 1208 | properties_.SetLeAddress(args.begin().extract<Address>()); |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 1209 | auto packet = bluetooth::hci::LeSetRandomAddressCompleteBuilder::Create( |
| 1210 | kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS); |
| 1211 | send_event_(std::move(packet)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 1212 | } |
| 1213 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 1214 | void DualModeController::HciLeSetAdvertisingParameters( |
| 1215 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 1216 | ASSERT_LOG(args.size() == 15, "%s size=%zu", __func__, args.size()); |
Myles Watson | 99aea89 | 2019-09-02 15:54:08 -0700 | [diff] [blame] | 1217 | auto args_itr = args.begin(); |
| 1218 | properties_.SetLeAdvertisingParameters( |
| 1219 | args_itr.extract<uint16_t>() /* AdverisingIntervalMin */, |
| 1220 | args_itr.extract<uint16_t>() /* AdverisingIntervalMax */, args_itr.extract<uint8_t>() /* AdverisingType */, |
| 1221 | args_itr.extract<uint8_t>() /* OwnAddressType */, args_itr.extract<uint8_t>() /* PeerAddressType */, |
| 1222 | args_itr.extract<Address>() /* PeerAddress */, args_itr.extract<uint8_t>() /* AdvertisingChannelMap */, |
| 1223 | args_itr.extract<uint8_t>() /* AdvertisingFilterPolicy */ |
| 1224 | ); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 1225 | |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 1226 | auto packet = |
| 1227 | bluetooth::hci::LeSetAdvertisingParametersCompleteBuilder::Create( |
| 1228 | kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS); |
| 1229 | send_event_(std::move(packet)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 1230 | } |
| 1231 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 1232 | void DualModeController::HciLeSetAdvertisingData( |
| 1233 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 1234 | ASSERT_LOG(args.size() == 32, "%s size=%zu", __func__, args.size()); |
Myles Watson | 99aea89 | 2019-09-02 15:54:08 -0700 | [diff] [blame] | 1235 | properties_.SetLeAdvertisement(std::vector<uint8_t>(args.begin() + 1, args.end())); |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 1236 | auto packet = bluetooth::hci::LeSetAdvertisingDataCompleteBuilder::Create( |
| 1237 | kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS); |
| 1238 | send_event_(std::move(packet)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 1239 | } |
| 1240 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 1241 | void DualModeController::HciLeSetScanResponseData( |
| 1242 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 1243 | ASSERT_LOG(args.size() == 32, "%s size=%zu", __func__, args.size()); |
Myles Watson | 99aea89 | 2019-09-02 15:54:08 -0700 | [diff] [blame] | 1244 | properties_.SetLeScanResponse(std::vector<uint8_t>(args.begin() + 1, args.end())); |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 1245 | auto packet = bluetooth::hci::LeSetScanResponseDataCompleteBuilder::Create( |
| 1246 | kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS); |
| 1247 | send_event_(std::move(packet)); |
Myles Watson | 99aea89 | 2019-09-02 15:54:08 -0700 | [diff] [blame] | 1248 | } |
| 1249 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 1250 | void DualModeController::HciLeSetAdvertisingEnable( |
| 1251 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 1252 | ASSERT_LOG(args.size() == 1, "%s size=%zu", __func__, args.size()); |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 1253 | auto status = link_layer_controller_.SetLeAdvertisingEnable( |
| 1254 | args.begin().extract<uint8_t>()); |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 1255 | auto packet = bluetooth::hci::LeSetAdvertisingEnableCompleteBuilder::Create( |
| 1256 | kNumCommandPackets, status); |
| 1257 | send_event_(std::move(packet)); |
Myles Watson | 99aea89 | 2019-09-02 15:54:08 -0700 | [diff] [blame] | 1258 | } |
| 1259 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 1260 | void DualModeController::HciLeSetScanParameters( |
| 1261 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 1262 | ASSERT_LOG(args.size() == 7, "%s size=%zu", __func__, args.size()); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 1263 | link_layer_controller_.SetLeScanType(args[0]); |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 1264 | link_layer_controller_.SetLeScanInterval(args[1] | (args[2], 8)); |
| 1265 | link_layer_controller_.SetLeScanWindow(args[3] | (args[4], 8)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 1266 | link_layer_controller_.SetLeAddressType(args[5]); |
| 1267 | link_layer_controller_.SetLeScanFilterPolicy(args[6]); |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 1268 | auto packet = bluetooth::hci::LeSetScanParametersCompleteBuilder::Create( |
| 1269 | kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS); |
| 1270 | send_event_(std::move(packet)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 1271 | } |
| 1272 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 1273 | void DualModeController::HciLeSetScanEnable( |
| 1274 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 1275 | ASSERT_LOG(args.size() == 2, "%s size=%zu", __func__, args.size()); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 1276 | link_layer_controller_.SetLeScanEnable(args[0]); |
| 1277 | link_layer_controller_.SetLeFilterDuplicates(args[1]); |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 1278 | auto packet = bluetooth::hci::LeSetScanEnableCompleteBuilder::Create( |
| 1279 | kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS); |
| 1280 | send_event_(std::move(packet)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 1281 | } |
| 1282 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 1283 | void DualModeController::HciLeCreateConnection( |
| 1284 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 1285 | ASSERT_LOG(args.size() == 25, "%s size=%zu", __func__, args.size()); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 1286 | auto args_itr = args.begin(); |
| 1287 | link_layer_controller_.SetLeScanInterval(args_itr.extract<uint16_t>()); |
| 1288 | link_layer_controller_.SetLeScanWindow(args_itr.extract<uint16_t>()); |
| 1289 | uint8_t initiator_filter_policy = args_itr.extract<uint8_t>(); |
| 1290 | link_layer_controller_.SetLeInitiatorFilterPolicy(initiator_filter_policy); |
| 1291 | |
| 1292 | if (initiator_filter_policy == 0) { // White list not used |
| 1293 | uint8_t peer_address_type = args_itr.extract<uint8_t>(); |
| 1294 | Address peer_address = args_itr.extract<Address>(); |
| 1295 | link_layer_controller_.SetLePeerAddressType(peer_address_type); |
| 1296 | link_layer_controller_.SetLePeerAddress(peer_address); |
| 1297 | } |
| 1298 | link_layer_controller_.SetLeAddressType(args_itr.extract<uint8_t>()); |
| 1299 | link_layer_controller_.SetLeConnectionIntervalMin(args_itr.extract<uint16_t>()); |
| 1300 | link_layer_controller_.SetLeConnectionIntervalMax(args_itr.extract<uint16_t>()); |
| 1301 | link_layer_controller_.SetLeConnectionLatency(args_itr.extract<uint16_t>()); |
| 1302 | link_layer_controller_.SetLeSupervisionTimeout(args_itr.extract<uint16_t>()); |
| 1303 | link_layer_controller_.SetLeMinimumCeLength(args_itr.extract<uint16_t>()); |
| 1304 | link_layer_controller_.SetLeMaximumCeLength(args_itr.extract<uint16_t>()); |
| 1305 | |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 1306 | auto status = link_layer_controller_.SetLeConnect(true); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 1307 | |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 1308 | auto packet = bluetooth::hci::LeCreateConnectionStatusBuilder::Create( |
| 1309 | status, kNumCommandPackets); |
| 1310 | send_event_(std::move(packet)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 1311 | } |
| 1312 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 1313 | void DualModeController::HciLeConnectionUpdate( |
| 1314 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 1315 | ASSERT_LOG(args.size() == 14, "%s size=%zu", __func__, args.size()); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 1316 | |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 1317 | auto status_packet = bluetooth::hci::LeConnectionUpdateStatusBuilder::Create( |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 1318 | bluetooth::hci::ErrorCode::CONNECTION_REJECTED_UNACCEPTABLE_BD_ADDR, |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 1319 | kNumCommandPackets); |
| 1320 | send_event_(std::move(status_packet)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 1321 | |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 1322 | auto complete_packet = |
| 1323 | bluetooth::hci::LeConnectionUpdateCompleteBuilder::Create( |
| 1324 | bluetooth::hci::ErrorCode::SUCCESS, 0x0002, 0x0006, 0x0000, 0x01f4); |
| 1325 | send_event_(std::move(complete_packet)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 1326 | } |
| 1327 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 1328 | void DualModeController::HciCreateConnection( |
| 1329 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 1330 | ASSERT_LOG(args.size() == 13, "%s size=%zu", __func__, args.size()); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 1331 | |
| 1332 | auto args_itr = args.begin(); |
| 1333 | Address address = args_itr.extract<Address>(); |
| 1334 | uint16_t packet_type = args_itr.extract<uint16_t>(); |
| 1335 | uint8_t page_scan_mode = args_itr.extract<uint8_t>(); |
| 1336 | uint16_t clock_offset = args_itr.extract<uint16_t>(); |
| 1337 | uint8_t allow_role_switch = args_itr.extract<uint8_t>(); |
| 1338 | |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 1339 | auto status = link_layer_controller_.CreateConnection( |
| 1340 | address, packet_type, page_scan_mode, clock_offset, allow_role_switch); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 1341 | |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 1342 | auto packet = bluetooth::hci::CreateConnectionStatusBuilder::Create( |
| 1343 | status, kNumCommandPackets); |
| 1344 | send_event_(std::move(packet)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 1345 | } |
| 1346 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 1347 | void DualModeController::HciDisconnect( |
| 1348 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 1349 | ASSERT_LOG(args.size() == 3, "%s size=%zu", __func__, args.size()); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 1350 | |
| 1351 | auto args_itr = args.begin(); |
| 1352 | uint16_t handle = args_itr.extract<uint16_t>(); |
| 1353 | uint8_t reason = args_itr.extract<uint8_t>(); |
| 1354 | |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 1355 | auto status = link_layer_controller_.Disconnect(handle, reason); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 1356 | |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 1357 | auto packet = bluetooth::hci::DisconnectStatusBuilder::Create( |
| 1358 | status, kNumCommandPackets); |
| 1359 | send_event_(std::move(packet)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 1360 | } |
| 1361 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 1362 | void DualModeController::HciLeConnectionCancel( |
| 1363 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 1364 | ASSERT_LOG(args.size() == 0, "%s size=%zu", __func__, args.size()); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 1365 | link_layer_controller_.SetLeConnect(false); |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 1366 | auto packet = bluetooth::hci::LeCreateConnectionCancelStatusBuilder::Create( |
| 1367 | bluetooth::hci::ErrorCode::SUCCESS, kNumCommandPackets); |
| 1368 | send_event_(std::move(packet)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 1369 | /* For testing Jakub's patch: Figure out a neat way to call this without |
| 1370 | recompiling. I'm thinking about a bad device. */ |
| 1371 | /* |
| 1372 | SendCommandCompleteOnlyStatus(OpCode::LE_CREATE_CONNECTION_CANCEL, |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 1373 | bluetooth::hci::ErrorCode::COMMAND_DISALLOWED); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 1374 | */ |
| 1375 | } |
| 1376 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 1377 | void DualModeController::HciLeReadWhiteListSize( |
| 1378 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 1379 | ASSERT_LOG(args.size() == 0, "%s size=%zu", __func__, args.size()); |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 1380 | auto packet = bluetooth::hci::LeReadWhiteListSizeCompleteBuilder::Create( |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 1381 | kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS, |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 1382 | properties_.GetLeWhiteListSize()); |
| 1383 | send_event_(std::move(packet)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 1384 | } |
| 1385 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 1386 | void DualModeController::HciLeClearWhiteList( |
| 1387 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 1388 | ASSERT_LOG(args.size() == 0, "%s size=%zu", __func__, args.size()); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 1389 | link_layer_controller_.LeWhiteListClear(); |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 1390 | auto packet = bluetooth::hci::LeClearWhiteListCompleteBuilder::Create( |
| 1391 | kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS); |
| 1392 | send_event_(std::move(packet)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 1393 | } |
| 1394 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 1395 | void DualModeController::HciLeAddDeviceToWhiteList( |
| 1396 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 1397 | ASSERT_LOG(args.size() == 7, "%s size=%zu", __func__, args.size()); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 1398 | |
| 1399 | if (link_layer_controller_.LeWhiteListFull()) { |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 1400 | auto packet = bluetooth::hci::LeAddDeviceToWhiteListCompleteBuilder::Create( |
| 1401 | kNumCommandPackets, |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 1402 | bluetooth::hci::ErrorCode::MEMORY_CAPACITY_EXCEEDED); |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 1403 | send_event_(std::move(packet)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 1404 | return; |
| 1405 | } |
| 1406 | auto args_itr = args.begin(); |
| 1407 | uint8_t addr_type = args_itr.extract<uint8_t>(); |
| 1408 | Address address = args_itr.extract<Address>(); |
| 1409 | link_layer_controller_.LeWhiteListAddDevice(address, addr_type); |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 1410 | auto packet = bluetooth::hci::LeAddDeviceToWhiteListCompleteBuilder::Create( |
| 1411 | kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS); |
| 1412 | send_event_(std::move(packet)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 1413 | } |
| 1414 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 1415 | void DualModeController::HciLeRemoveDeviceFromWhiteList( |
| 1416 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 1417 | ASSERT_LOG(args.size() == 7, "%s size=%zu", __func__, args.size()); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 1418 | |
| 1419 | auto args_itr = args.begin(); |
| 1420 | uint8_t addr_type = args_itr.extract<uint8_t>(); |
| 1421 | Address address = args_itr.extract<Address>(); |
| 1422 | link_layer_controller_.LeWhiteListRemoveDevice(address, addr_type); |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 1423 | auto packet = |
| 1424 | bluetooth::hci::LeRemoveDeviceFromWhiteListCompleteBuilder::Create( |
| 1425 | kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS); |
| 1426 | send_event_(std::move(packet)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 1427 | } |
| 1428 | |
Calvin Huang | ee1980c | 2019-11-01 16:35:55 -0700 | [diff] [blame] | 1429 | void DualModeController::HciLeClearResolvingList( |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 1430 | bluetooth::packet::PacketView<true> args) { |
Calvin Huang | ee1980c | 2019-11-01 16:35:55 -0700 | [diff] [blame] | 1431 | ASSERT_LOG(args.size() == 0, "%s size=%zu", __func__, args.size()); |
| 1432 | link_layer_controller_.LeResolvingListClear(); |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 1433 | auto packet = bluetooth::hci::LeClearResolvingListCompleteBuilder::Create( |
| 1434 | kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS); |
| 1435 | send_event_(std::move(packet)); |
Calvin Huang | ee1980c | 2019-11-01 16:35:55 -0700 | [diff] [blame] | 1436 | } |
| 1437 | |
| 1438 | void DualModeController::HciLeAddDeviceToResolvingList( |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 1439 | bluetooth::packet::PacketView<true> args) { |
Calvin Huang | ee1980c | 2019-11-01 16:35:55 -0700 | [diff] [blame] | 1440 | ASSERT_LOG(args.size() == 39, "%s size=%zu", __func__, args.size()); |
| 1441 | |
| 1442 | if (link_layer_controller_.LeResolvingListFull()) { |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 1443 | auto packet = |
| 1444 | bluetooth::hci::LeAddDeviceToResolvingListCompleteBuilder::Create( |
| 1445 | kNumCommandPackets, |
| 1446 | bluetooth::hci::ErrorCode::MEMORY_CAPACITY_EXCEEDED); |
| 1447 | send_event_(std::move(packet)); |
Calvin Huang | ee1980c | 2019-11-01 16:35:55 -0700 | [diff] [blame] | 1448 | return; |
| 1449 | } |
| 1450 | auto args_itr = args.begin(); |
| 1451 | uint8_t addr_type = args_itr.extract<uint8_t>(); |
| 1452 | Address address = args_itr.extract<Address>(); |
| 1453 | std::array<uint8_t, LinkLayerController::kIrk_size> peerIrk; |
| 1454 | std::array<uint8_t, LinkLayerController::kIrk_size> localIrk; |
| 1455 | for (size_t irk_ind = 0; irk_ind < LinkLayerController::kIrk_size; |
| 1456 | irk_ind++) { |
| 1457 | peerIrk[irk_ind] = args_itr.extract<uint8_t>(); |
| 1458 | } |
| 1459 | |
| 1460 | for (size_t irk_ind = 0; irk_ind < LinkLayerController::kIrk_size; |
| 1461 | irk_ind++) { |
| 1462 | localIrk[irk_ind] = args_itr.extract<uint8_t>(); |
| 1463 | } |
| 1464 | |
| 1465 | link_layer_controller_.LeResolvingListAddDevice(address, addr_type, peerIrk, |
| 1466 | localIrk); |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 1467 | auto packet = |
| 1468 | bluetooth::hci::LeAddDeviceToResolvingListCompleteBuilder::Create( |
| 1469 | kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS); |
| 1470 | send_event_(std::move(packet)); |
Calvin Huang | ee1980c | 2019-11-01 16:35:55 -0700 | [diff] [blame] | 1471 | } |
| 1472 | |
| 1473 | void DualModeController::HciLeRemoveDeviceFromResolvingList( |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 1474 | bluetooth::packet::PacketView<true> args) { |
Calvin Huang | ee1980c | 2019-11-01 16:35:55 -0700 | [diff] [blame] | 1475 | ASSERT_LOG(args.size() == 7, "%s size=%zu", __func__, args.size()); |
| 1476 | |
| 1477 | auto args_itr = args.begin(); |
| 1478 | uint8_t addr_type = args_itr.extract<uint8_t>(); |
| 1479 | Address address = args_itr.extract<Address>(); |
| 1480 | link_layer_controller_.LeResolvingListRemoveDevice(address, addr_type); |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 1481 | auto packet = |
| 1482 | bluetooth::hci::LeRemoveDeviceFromResolvingListCompleteBuilder::Create( |
| 1483 | kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS); |
| 1484 | send_event_(std::move(packet)); |
Calvin Huang | ee1980c | 2019-11-01 16:35:55 -0700 | [diff] [blame] | 1485 | } |
| 1486 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 1487 | void DualModeController::HciLeSetPrivacyMode( |
| 1488 | bluetooth::packet::PacketView<true> args) { |
Calvin Huang | ee1980c | 2019-11-01 16:35:55 -0700 | [diff] [blame] | 1489 | ASSERT_LOG(args.size() == 8, "%s size=%zu", __func__, args.size()); |
| 1490 | |
| 1491 | auto args_itr = args.begin(); |
| 1492 | uint8_t peer_identity_address_type = args_itr.extract<uint8_t>(); |
| 1493 | Address peer_identity_address = args_itr.extract<Address>(); |
| 1494 | uint8_t privacy_mode = args_itr.extract<uint8_t>(); |
| 1495 | |
| 1496 | if (link_layer_controller_.LeResolvingListContainsDevice( |
| 1497 | peer_identity_address, peer_identity_address_type)) { |
| 1498 | link_layer_controller_.LeSetPrivacyMode( |
| 1499 | peer_identity_address_type, peer_identity_address, privacy_mode); |
| 1500 | } |
| 1501 | |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 1502 | auto packet = bluetooth::hci::LeSetPrivacyModeCompleteBuilder::Create( |
| 1503 | kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS); |
| 1504 | send_event_(std::move(packet)); |
Calvin Huang | ee1980c | 2019-11-01 16:35:55 -0700 | [diff] [blame] | 1505 | } |
| 1506 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 1507 | void DualModeController::HciLeReadRemoteFeatures( |
| 1508 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 1509 | ASSERT_LOG(args.size() == 2, "%s size=%zu", __func__, args.size()); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 1510 | |
| 1511 | uint16_t handle = args.begin().extract<uint16_t>(); |
| 1512 | |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 1513 | auto status = link_layer_controller_.SendCommandToRemoteByHandle( |
| 1514 | bluetooth::hci::OpCode::LE_READ_REMOTE_FEATURES, args, handle); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 1515 | |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 1516 | auto packet = bluetooth::hci::LeConnectionUpdateStatusBuilder::Create( |
| 1517 | status, kNumCommandPackets); |
| 1518 | send_event_(std::move(packet)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 1519 | } |
| 1520 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 1521 | void DualModeController::HciLeRand(bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 1522 | ASSERT_LOG(args.size() == 0, "%s size=%zu", __func__, args.size()); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 1523 | uint64_t random_val = 0; |
| 1524 | for (size_t rand_bytes = 0; rand_bytes < sizeof(uint64_t); rand_bytes += sizeof(RAND_MAX)) { |
| 1525 | random_val = (random_val << (8 * sizeof(RAND_MAX))) | random(); |
| 1526 | } |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 1527 | |
| 1528 | auto packet = bluetooth::hci::LeRandCompleteBuilder::Create( |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 1529 | kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS, random_val); |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 1530 | send_event_(std::move(packet)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 1531 | } |
| 1532 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 1533 | void DualModeController::HciLeReadSupportedStates( |
| 1534 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 1535 | ASSERT_LOG(args.size() == 0, "%s size=%zu", __func__, args.size()); |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 1536 | auto packet = bluetooth::hci::LeReadSupportedStatesCompleteBuilder::Create( |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 1537 | kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS, |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 1538 | properties_.GetLeSupportedStates()); |
| 1539 | send_event_(std::move(packet)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 1540 | } |
| 1541 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 1542 | void DualModeController::HciLeVendorCap( |
| 1543 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 1544 | ASSERT_LOG(args.size() == 0, "%s size=%zu", __func__, args.size()); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 1545 | vector<uint8_t> caps = properties_.GetLeVendorCap(); |
| 1546 | if (caps.size() == 0) { |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 1547 | SendCommandCompleteUnknownOpCodeEvent(static_cast<uint16_t>( |
| 1548 | bluetooth::hci::OpCode::LE_GET_VENDOR_CAPABILITIES)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 1549 | return; |
| 1550 | } |
| 1551 | |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 1552 | std::unique_ptr<bluetooth::packet::RawBuilder> raw_builder_ptr = |
| 1553 | std::make_unique<bluetooth::packet::RawBuilder>(); |
| 1554 | raw_builder_ptr->AddOctets1( |
| 1555 | static_cast<uint8_t>(bluetooth::hci::ErrorCode::SUCCESS)); |
| 1556 | raw_builder_ptr->AddOctets(properties_.GetLeVendorCap()); |
| 1557 | |
| 1558 | auto packet = bluetooth::hci::CommandCompleteBuilder::Create( |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 1559 | kNumCommandPackets, bluetooth::hci::OpCode::LE_GET_VENDOR_CAPABILITIES, |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 1560 | std::move(raw_builder_ptr)); |
| 1561 | send_event_(std::move(packet)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 1562 | } |
| 1563 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 1564 | void DualModeController::HciLeVendorMultiAdv( |
| 1565 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 1566 | ASSERT(args.size() > 0); |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 1567 | SendCommandCompleteUnknownOpCodeEvent( |
| 1568 | static_cast<uint16_t>(bluetooth::hci::OpCode::LE_MULTI_ADVT)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 1569 | } |
| 1570 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 1571 | void DualModeController::HciLeAdvertisingFilter( |
| 1572 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 1573 | ASSERT(args.size() > 0); |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 1574 | SendCommandCompleteUnknownOpCodeEvent( |
| 1575 | static_cast<uint16_t>(bluetooth::hci::OpCode::LE_ADV_FILTER)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 1576 | } |
| 1577 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 1578 | void DualModeController::HciLeEnergyInfo( |
| 1579 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 1580 | ASSERT(args.size() > 0); |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 1581 | SendCommandCompleteUnknownOpCodeEvent( |
| 1582 | static_cast<uint16_t>(bluetooth::hci::OpCode::LE_ENERGY_INFO)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 1583 | } |
| 1584 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 1585 | void DualModeController::HciLeExtendedScanParams( |
| 1586 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 1587 | ASSERT(args.size() > 0); |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 1588 | SendCommandCompleteUnknownOpCodeEvent( |
| 1589 | static_cast<uint16_t>(bluetooth::hci::OpCode::LE_EXTENDED_SCAN_PARAMS)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 1590 | } |
| 1591 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 1592 | void DualModeController::HciLeStartEncryption( |
| 1593 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 1594 | ASSERT_LOG(args.size() == 28, "%s size=%zu", __func__, args.size()); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 1595 | |
| 1596 | auto args_itr = args.begin(); |
| 1597 | uint16_t handle = args_itr.extract<uint16_t>(); |
| 1598 | // uint64_t random_number = args_itr.extract<uint64_t>(); |
| 1599 | // uint16_t encrypted_diversifier = args_itr.extract<uint16_t>(); |
| 1600 | // std::vector<uint8_t> long_term_key; |
| 1601 | // for (size_t i = 0; i < 16; i++) { |
| 1602 | // long_term_key.push_back(args_itr.extract<uint18_t>(); |
| 1603 | // } |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 1604 | auto status_packet = bluetooth::hci::LeStartEncryptionStatusBuilder::Create( |
| 1605 | bluetooth::hci::ErrorCode::SUCCESS, kNumCommandPackets); |
| 1606 | send_event_(std::move(status_packet)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 1607 | |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 1608 | auto complete_packet = bluetooth::hci::EncryptionChangeBuilder::Create( |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 1609 | bluetooth::hci::ErrorCode::SUCCESS, handle, |
| 1610 | bluetooth::hci::EncryptionEnabled::OFF); |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 1611 | send_event_(std::move(complete_packet)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 1612 | #if 0 |
| 1613 | |
| 1614 | std::shared_ptr<packets::AclPacketBuilder> encryption_information = |
| 1615 | std::make_shared<packets::AclPacketBuilder>( |
| 1616 | 0x0002, Acl::FIRST_AUTOMATICALLY_FLUSHABLE, Acl::POINT_TO_POINT, |
| 1617 | std::vector<uint8_t>({})); |
| 1618 | |
| 1619 | encryption_information->AddPayloadOctets2(0x0011); |
| 1620 | encryption_information->AddPayloadOctets2(0x0006); |
| 1621 | encryption_information->AddPayloadOctets1(0x06); |
| 1622 | encryption_information->AddPayloadOctets8(0x0706050403020100); |
| 1623 | encryption_information->AddPayloadOctets8(0x0F0E0D0C0B0A0908); |
| 1624 | |
| 1625 | send_acl_(encryption_information); |
| 1626 | |
| 1627 | encryption_information = std::make_shared<packets::AclPacketBuilder>( |
| 1628 | 0x0002, Acl::FIRST_AUTOMATICALLY_FLUSHABLE, Acl::POINT_TO_POINT, |
| 1629 | std::vector<uint8_t>({})); |
| 1630 | |
| 1631 | encryption_information->AddPayloadOctets2(0x000B); |
| 1632 | encryption_information->AddPayloadOctets2(0x0006); |
| 1633 | encryption_information->AddPayloadOctets1(0x07); |
| 1634 | encryption_information->AddPayloadOctets2(0xBEEF); |
| 1635 | encryption_information->AddPayloadOctets8(0x0706050403020100); |
| 1636 | |
| 1637 | send_acl_(encryption_information); |
| 1638 | |
| 1639 | encryption_information = std::make_shared<packets::AclPacketBuilder>( |
| 1640 | 0x0002, Acl::FIRST_AUTOMATICALLY_FLUSHABLE, Acl::POINT_TO_POINT, |
| 1641 | std::vector<uint8_t>({})); |
| 1642 | |
| 1643 | encryption_information->AddPayloadOctets2(0x0011); |
| 1644 | encryption_information->AddPayloadOctets2(0x0006); |
| 1645 | encryption_information->AddPayloadOctets1(0x08); |
| 1646 | encryption_information->AddPayloadOctets8(0x0F0E0D0C0B0A0908); |
| 1647 | encryption_information->AddPayloadOctets8(0x0706050403020100); |
| 1648 | |
| 1649 | send_acl_(encryption_information); |
| 1650 | |
| 1651 | encryption_information = std::make_shared<packets::AclPacketBuilder>( |
| 1652 | 0x0002, Acl::FIRST_AUTOMATICALLY_FLUSHABLE, Acl::POINT_TO_POINT, |
| 1653 | std::vector<uint8_t>({})); |
| 1654 | |
| 1655 | encryption_information->AddPayloadOctets2(0x0008); |
| 1656 | encryption_information->AddPayloadOctets2(0x0006); |
| 1657 | encryption_information->AddPayloadOctets1(0x09); |
| 1658 | encryption_information->AddPayloadOctets1(0x01); |
| 1659 | encryption_information->AddPayloadOctets6(0xDEADBEEFF00D); |
| 1660 | send_acl_(encryption_information); |
| 1661 | // send_event_(packets::EventPacketBuilder::CreateLeStartEncryption()->ToVector()); |
| 1662 | |
| 1663 | #endif |
| 1664 | } |
| 1665 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 1666 | void DualModeController::HciReadLoopbackMode( |
| 1667 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 1668 | ASSERT_LOG(args.size() == 0, "%s size=%zu", __func__, args.size()); |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 1669 | auto packet = bluetooth::hci::ReadLoopbackModeCompleteBuilder::Create( |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 1670 | kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS, |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 1671 | static_cast<bluetooth::hci::LoopbackMode>(loopback_mode_)); |
| 1672 | send_event_(std::move(packet)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 1673 | } |
| 1674 | |
Chienyuan | 676cefe | 2019-11-22 16:46:24 +0800 | [diff] [blame^] | 1675 | void DualModeController::HciWriteLoopbackMode( |
| 1676 | bluetooth::packet::PacketView<true> args) { |
Myles Watson | 1a0a0da | 2019-10-17 11:36:33 -0700 | [diff] [blame] | 1677 | ASSERT_LOG(args.size() == 1, "%s size=%zu", __func__, args.size()); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 1678 | loopback_mode_ = static_cast<hci::LoopbackMode>(args[0]); |
| 1679 | // ACL channel |
| 1680 | uint16_t acl_handle = 0x123; |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 1681 | auto packet_acl = bluetooth::hci::ConnectionCompleteBuilder::Create( |
| 1682 | bluetooth::hci::ErrorCode::SUCCESS, acl_handle, properties_.GetAddress(), |
| 1683 | bluetooth::hci::LinkType::ACL, bluetooth::hci::Enable::DISABLED); |
| 1684 | send_event_(std::move(packet_acl)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 1685 | // SCO channel |
| 1686 | uint16_t sco_handle = 0x345; |
Chienyuan | 3d8a803 | 2019-11-01 18:04:07 +0800 | [diff] [blame] | 1687 | auto packet_sco = bluetooth::hci::ConnectionCompleteBuilder::Create( |
| 1688 | bluetooth::hci::ErrorCode::SUCCESS, sco_handle, properties_.GetAddress(), |
| 1689 | bluetooth::hci::LinkType::SCO, bluetooth::hci::Enable::DISABLED); |
| 1690 | send_event_(std::move(packet_sco)); |
Chienyuan | c27da09 | 2019-11-20 19:29:43 +0800 | [diff] [blame] | 1691 | auto packet = bluetooth::hci::WriteLoopbackModeCompleteBuilder::Create( |
| 1692 | kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS); |
| 1693 | send_event_(std::move(packet)); |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 1694 | } |
| 1695 | |
Myles Watson | 205c32e | 2019-11-12 13:16:32 -0800 | [diff] [blame] | 1696 | void DualModeController::SetAddress(Address address) { |
| 1697 | properties_.SetAddress(address); |
| 1698 | } |
| 1699 | |
Myles Watson | e22dde2 | 2019-01-18 11:42:33 -0800 | [diff] [blame] | 1700 | } // namespace test_vendor_lib |