1 /*
2 * Copyright 2017 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
17 #include "link_layer_controller.h"
18
19 #include <hci/hci_packets.h>
20 #ifdef ROOTCANAL_LMP
21 #include <lmp.h>
22 #endif /* ROOTCANAL_LMP */
23
24 #include "crypto_toolbox/crypto_toolbox.h"
25 #include "log.h"
26 #include "packet/raw_builder.h"
27
28 using std::vector;
29 using namespace std::chrono;
30 using bluetooth::hci::Address;
31 using bluetooth::hci::AddressType;
32 using bluetooth::hci::AddressWithType;
33 using bluetooth::hci::DirectAdvertisingAddressType;
34 using bluetooth::hci::EventCode;
35 using bluetooth::hci::LLFeaturesBits;
36 using bluetooth::hci::SubeventCode;
37
38 using namespace model::packets;
39 using model::packets::PacketType;
40 using namespace std::literals;
41
42 // Temporay define, to be replaced when verbose log level is implemented.
43 #define LOG_VERB(...) LOG_INFO(__VA_ARGS__)
44
45 namespace rootcanal {
46
47 constexpr uint16_t kNumCommandPackets = 0x01;
48
49 constexpr milliseconds kNoDelayMs(0);
50
51 // TODO: Model Rssi?
GetRssi()52 static uint8_t GetRssi() {
53 static uint8_t rssi = 0;
54 rssi += 5;
55 if (rssi > 128) {
56 rssi = rssi % 7;
57 }
58 return -(rssi);
59 }
60
GetAddress() const61 const Address& LinkLayerController::GetAddress() const { return address_; }
62
PeerDeviceAddress(Address address,PeerAddressType peer_address_type)63 AddressWithType PeerDeviceAddress(Address address,
64 PeerAddressType peer_address_type) {
65 switch (peer_address_type) {
66 case PeerAddressType::PUBLIC_DEVICE_OR_IDENTITY_ADDRESS:
67 return AddressWithType(address, AddressType::PUBLIC_DEVICE_ADDRESS);
68 case PeerAddressType::RANDOM_DEVICE_OR_IDENTITY_ADDRESS:
69 return AddressWithType(address, AddressType::RANDOM_DEVICE_ADDRESS);
70 }
71 }
72
PeerIdentityAddress(Address address,PeerAddressType peer_address_type)73 AddressWithType PeerIdentityAddress(Address address,
74 PeerAddressType peer_address_type) {
75 switch (peer_address_type) {
76 case PeerAddressType::PUBLIC_DEVICE_OR_IDENTITY_ADDRESS:
77 return AddressWithType(address, AddressType::PUBLIC_IDENTITY_ADDRESS);
78 case PeerAddressType::RANDOM_DEVICE_OR_IDENTITY_ADDRESS:
79 return AddressWithType(address, AddressType::RANDOM_IDENTITY_ADDRESS);
80 }
81 }
82
IsEventUnmasked(EventCode event) const83 bool LinkLayerController::IsEventUnmasked(EventCode event) const {
84 uint64_t bit = UINT64_C(1) << (static_cast<uint8_t>(event) - 1);
85 return (event_mask_ & bit) != 0;
86 }
87
IsLeEventUnmasked(SubeventCode subevent) const88 bool LinkLayerController::IsLeEventUnmasked(SubeventCode subevent) const {
89 uint64_t bit = UINT64_C(1) << (static_cast<uint8_t>(subevent) - 1);
90 return IsEventUnmasked(EventCode::LE_META_EVENT) &&
91 (le_event_mask_ & bit) != 0;
92 }
93
FilterAcceptListBusy()94 bool LinkLayerController::FilterAcceptListBusy() {
95 // Filter Accept List cannot be modified when
96 // • any advertising filter policy uses the Filter Accept List and
97 // advertising is enabled,
98 if (legacy_advertiser_.IsEnabled() &&
99 legacy_advertiser_.advertising_filter_policy !=
100 bluetooth::hci::AdvertisingFilterPolicy::ALL_DEVICES) {
101 return true;
102 }
103
104 for (auto const& [_, advertiser] : extended_advertisers_) {
105 if (advertiser.IsEnabled() &&
106 advertiser.advertising_filter_policy !=
107 bluetooth::hci::AdvertisingFilterPolicy::ALL_DEVICES) {
108 return true;
109 }
110 }
111
112 // • the scanning filter policy uses the Filter Accept List and scanning
113 // is enabled,
114 if (scanner_.IsEnabled() &&
115 (scanner_.scan_filter_policy ==
116 bluetooth::hci::LeScanningFilterPolicy::FILTER_ACCEPT_LIST_ONLY ||
117 scanner_.scan_filter_policy ==
118 bluetooth::hci::LeScanningFilterPolicy::
119 FILTER_ACCEPT_LIST_AND_INITIATORS_IDENTITY)) {
120 return true;
121 }
122
123 // • the initiator filter policy uses the Filter Accept List and an
124 // HCI_LE_Create_Connection or HCI_LE_Extended_Create_Connection
125 // command is pending.
126 if (initiator_.IsEnabled() &&
127 initiator_.initiator_filter_policy ==
128 bluetooth::hci::InitiatorFilterPolicy::USE_FILTER_ACCEPT_LIST) {
129 return true;
130 }
131
132 return false;
133 }
134
LeFilterAcceptListContainsDevice(FilterAcceptListAddressType address_type,Address address)135 bool LinkLayerController::LeFilterAcceptListContainsDevice(
136 FilterAcceptListAddressType address_type, Address address) {
137 for (auto const& entry : le_filter_accept_list_) {
138 if (entry.address_type == address_type &&
139 (address_type == FilterAcceptListAddressType::ANONYMOUS_ADVERTISERS ||
140 entry.address == address)) {
141 return true;
142 }
143 }
144
145 return false;
146 }
147
LeFilterAcceptListContainsDevice(AddressWithType address)148 bool LinkLayerController::LeFilterAcceptListContainsDevice(
149 AddressWithType address) {
150 FilterAcceptListAddressType address_type;
151 switch (address.GetAddressType()) {
152 case AddressType::PUBLIC_DEVICE_ADDRESS:
153 case AddressType::PUBLIC_IDENTITY_ADDRESS:
154 address_type = FilterAcceptListAddressType::PUBLIC;
155 break;
156 case AddressType::RANDOM_DEVICE_ADDRESS:
157 case AddressType::RANDOM_IDENTITY_ADDRESS:
158 address_type = FilterAcceptListAddressType::RANDOM;
159 break;
160 }
161
162 return LeFilterAcceptListContainsDevice(address_type, address.GetAddress());
163 }
164
ResolvingListBusy()165 bool LinkLayerController::ResolvingListBusy() {
166 // The resolving list cannot be modified when
167 // • Advertising (other than periodic advertising) is enabled,
168 if (legacy_advertiser_.IsEnabled()) {
169 return true;
170 }
171
172 for (auto const& [_, advertiser] : extended_advertisers_) {
173 if (advertiser.IsEnabled()) {
174 return true;
175 }
176 }
177
178 // • Scanning is enabled,
179 if (scanner_.IsEnabled()) {
180 return true;
181 }
182
183 // • an HCI_LE_Create_Connection, HCI_LE_Extended_Create_Connection, or
184 // HCI_LE_Periodic_Advertising_Create_Sync command is pending.
185 if (initiator_.IsEnabled()) {
186 return true;
187 }
188
189 return false;
190 }
191
ResolvePrivateAddress(AddressWithType address,IrkSelection irk)192 std::optional<AddressWithType> LinkLayerController::ResolvePrivateAddress(
193 AddressWithType address, IrkSelection irk) {
194 if (!address.IsRpa()) {
195 return address;
196 }
197
198 if (!le_resolving_list_enabled_) {
199 return {};
200 }
201
202 for (auto const& entry : le_resolving_list_) {
203 std::array<uint8_t, LinkLayerController::kIrkSize> const& used_irk =
204 irk == IrkSelection::Local ? entry.local_irk : entry.peer_irk;
205
206 if (address.IsRpaThatMatchesIrk(used_irk)) {
207 return PeerIdentityAddress(entry.peer_identity_address,
208 entry.peer_identity_address_type);
209 }
210 }
211
212 return {};
213 }
214
215 static Address generate_rpa(
216 std::array<uint8_t, LinkLayerController::kIrkSize> irk);
217
218 std::optional<AddressWithType>
GenerateResolvablePrivateAddress(AddressWithType address,IrkSelection irk)219 LinkLayerController::GenerateResolvablePrivateAddress(AddressWithType address,
220 IrkSelection irk) {
221 if (!le_resolving_list_enabled_) {
222 return {};
223 }
224
225 for (auto const& entry : le_resolving_list_) {
226 if (address.GetAddress() == entry.peer_identity_address &&
227 address.ToPeerAddressType() == entry.peer_identity_address_type) {
228 std::array<uint8_t, LinkLayerController::kIrkSize> const& used_irk =
229 irk == IrkSelection::Local ? entry.local_irk : entry.peer_irk;
230
231 return AddressWithType{generate_rpa(used_irk),
232 AddressType::RANDOM_DEVICE_ADDRESS};
233 }
234 }
235
236 return {};
237 }
238
239 // =============================================================================
240 // General LE Commands
241 // =============================================================================
242
243 // HCI LE Set Random Address command (Vol 4, Part E § 7.8.4).
LeSetRandomAddress(Address random_address)244 ErrorCode LinkLayerController::LeSetRandomAddress(Address random_address) {
245 // If the Host issues this command when any of advertising (created using
246 // legacy advertising commands), scanning, or initiating are enabled,
247 // the Controller shall return the error code Command Disallowed (0x0C).
248 if (legacy_advertiser_.IsEnabled() || scanner_.IsEnabled() ||
249 initiator_.IsEnabled()) {
250 LOG_INFO("advertising, scanning or initiating are currently active");
251 return ErrorCode::COMMAND_DISALLOWED;
252 }
253
254 if (random_address == Address::kEmpty) {
255 LOG_INFO("the random address may not be set to 00:00:00:00:00:00");
256 return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
257 }
258
259 LOG_INFO("device random address configured to %s",
260 random_address.ToString().c_str());
261 random_address_ = random_address;
262 return ErrorCode::SUCCESS;
263 }
264
265 // HCI LE Set Host Feature command (Vol 4, Part E § 7.8.45).
LeSetResolvablePrivateAddressTimeout(uint16_t rpa_timeout)266 ErrorCode LinkLayerController::LeSetResolvablePrivateAddressTimeout(
267 uint16_t rpa_timeout) {
268 // Note: no documented status code for this case.
269 if (rpa_timeout < 0x1 || rpa_timeout > 0x0e10) {
270 LOG_INFO(
271 "rpa_timeout (0x%04x) is outside the range of supported values "
272 " 0x1 - 0x0e10",
273 rpa_timeout);
274 return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
275 }
276
277 resolvable_private_address_timeout_ = seconds(rpa_timeout);
278 return ErrorCode::SUCCESS;
279 }
280
281 // HCI LE Set Host Feature command (Vol 4, Part E § 7.8.115).
LeSetHostFeature(uint8_t bit_number,uint8_t bit_value)282 ErrorCode LinkLayerController::LeSetHostFeature(uint8_t bit_number,
283 uint8_t bit_value) {
284 if (bit_number >= 64 || bit_value > 1) {
285 return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
286 }
287
288 // If Bit_Value is set to 0x01 and Bit_Number specifies a feature bit that
289 // requires support of a feature that the Controller does not support,
290 // the Controller shall return the error code Unsupported Feature or
291 // Parameter Value (0x11).
292 // TODO
293
294 // If the Host issues this command while the Controller has a connection to
295 // another device, the Controller shall return the error code
296 // Command Disallowed (0x0C).
297 if (HasAclConnection()) {
298 return ErrorCode::COMMAND_DISALLOWED;
299 }
300
301 uint64_t bit_mask = UINT64_C(1) << bit_number;
302 if (bit_mask ==
303 static_cast<uint64_t>(
304 LLFeaturesBits::CONNECTED_ISOCHRONOUS_STREAM_HOST_SUPPORT)) {
305 connected_isochronous_stream_host_support_ = bit_value != 0;
306 } else if (bit_mask ==
307 static_cast<uint64_t>(
308 LLFeaturesBits::CONNECTION_SUBRATING_HOST_SUPPORT)) {
309 connection_subrating_host_support_ = bit_value != 0;
310 }
311 // If Bit_Number specifies a feature bit that is not controlled by the Host,
312 // the Controller shall return the error code Unsupported Feature or
313 // Parameter Value (0x11).
314 else {
315 return ErrorCode::UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE;
316 }
317
318 if (bit_value != 0) {
319 le_host_supported_features_ |= bit_mask;
320 } else {
321 le_host_supported_features_ &= ~bit_mask;
322 }
323
324 return ErrorCode::SUCCESS;
325 }
326
327 // =============================================================================
328 // LE Resolving List
329 // =============================================================================
330
331 // HCI command LE_Add_Device_To_Resolving_List (Vol 4, Part E § 7.8.38).
LeAddDeviceToResolvingList(PeerAddressType peer_identity_address_type,Address peer_identity_address,std::array<uint8_t,kIrkSize> peer_irk,std::array<uint8_t,kIrkSize> local_irk)332 ErrorCode LinkLayerController::LeAddDeviceToResolvingList(
333 PeerAddressType peer_identity_address_type, Address peer_identity_address,
334 std::array<uint8_t, kIrkSize> peer_irk,
335 std::array<uint8_t, kIrkSize> local_irk) {
336 // This command shall not be used when address resolution is enabled in the
337 // Controller and:
338 // • Advertising (other than periodic advertising) is enabled,
339 // • Scanning is enabled, or
340 // • an HCI_LE_Create_Connection, HCI_LE_Extended_Create_Connection, or
341 // HCI_LE_Periodic_Advertising_Create_Sync command is pending.
342 if (le_resolving_list_enabled_ && ResolvingListBusy()) {
343 LOG_INFO(
344 "device is currently advertising, scanning, or establishing an"
345 " LE connection");
346 return ErrorCode::COMMAND_DISALLOWED;
347 }
348
349 // When a Controller cannot add a device to the list because there is no space
350 // available, it shall return the error code Memory Capacity Exceeded (0x07).
351 if (le_resolving_list_.size() >= properties_.le_resolving_list_size) {
352 LOG_INFO("resolving list is full");
353 return ErrorCode::MEMORY_CAPACITY_EXCEEDED;
354 }
355
356 // If there is an existing entry in the resolving list with the same
357 // Peer_Identity_Address and Peer_Identity_Address_Type, or with the same
358 // Peer_IRK, the Controller should return the error code Invalid HCI Command
359 // Parameters (0x12).
360 for (auto const& entry : le_resolving_list_) {
361 if ((entry.peer_identity_address_type == peer_identity_address_type &&
362 entry.peer_identity_address == peer_identity_address) ||
363 entry.peer_irk == peer_irk) {
364 LOG_INFO("device is already present in the resolving list");
365 return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
366 }
367 }
368
369 le_resolving_list_.emplace_back(
370 ResolvingListEntry{peer_identity_address_type, peer_identity_address,
371 peer_irk, local_irk, PrivacyMode::NETWORK});
372 return ErrorCode::SUCCESS;
373 }
374
375 // HCI command LE_Remove_Device_From_Resolving_List (Vol 4, Part E § 7.8.39).
LeRemoveDeviceFromResolvingList(PeerAddressType peer_identity_address_type,Address peer_identity_address)376 ErrorCode LinkLayerController::LeRemoveDeviceFromResolvingList(
377 PeerAddressType peer_identity_address_type, Address peer_identity_address) {
378 // This command shall not be used when address resolution is enabled in the
379 // Controller and:
380 // • Advertising (other than periodic advertising) is enabled,
381 // • Scanning is enabled, or
382 // • an HCI_LE_Create_Connection, HCI_LE_Extended_Create_Connection, or
383 // HCI_LE_Periodic_Advertising_Create_Sync command is pending.
384 if (le_resolving_list_enabled_ && ResolvingListBusy()) {
385 LOG_INFO(
386 "device is currently advertising, scanning, or establishing an"
387 " LE connection");
388 return ErrorCode::COMMAND_DISALLOWED;
389 }
390
391 for (auto it = le_resolving_list_.begin(); it != le_resolving_list_.end();
392 it++) {
393 if (it->peer_identity_address_type == peer_identity_address_type &&
394 it->peer_identity_address == peer_identity_address) {
395 le_resolving_list_.erase(it);
396 return ErrorCode::SUCCESS;
397 }
398 }
399
400 // When a Controller cannot remove a device from the resolving list because
401 // it is not found, it shall return the error code
402 // Unknown Connection Identifier (0x02).
403 LOG_INFO("peer address not found in the resolving list");
404 return ErrorCode::UNKNOWN_CONNECTION;
405 }
406
407 // HCI command LE_Clear_Resolving_List (Vol 4, Part E § 7.8.40).
LeClearResolvingList()408 ErrorCode LinkLayerController::LeClearResolvingList() {
409 // This command shall not be used when address resolution is enabled in the
410 // Controller and:
411 // • Advertising (other than periodic advertising) is enabled,
412 // • Scanning is enabled, or
413 // • an HCI_LE_Create_Connection, HCI_LE_Extended_Create_Connection, or
414 // HCI_LE_Periodic_Advertising_Create_Sync command is pending.
415 if (le_resolving_list_enabled_ && ResolvingListBusy()) {
416 LOG_INFO(
417 "device is currently advertising, scanning,"
418 " or establishing an LE connection");
419 return ErrorCode::COMMAND_DISALLOWED;
420 }
421
422 le_resolving_list_.clear();
423 return ErrorCode::SUCCESS;
424 }
425
426 // HCI command LE_Set_Address_Resolution_Enable (Vol 4, Part E § 7.8.44).
LeSetAddressResolutionEnable(bool enable)427 ErrorCode LinkLayerController::LeSetAddressResolutionEnable(bool enable) {
428 // This command shall not be used when:
429 // • Advertising (other than periodic advertising) is enabled,
430 // • Scanning is enabled, or
431 // • an HCI_LE_Create_Connection, HCI_LE_Extended_Create_Connection, or
432 // HCI_LE_Periodic_Advertising_Create_Sync command is pending.
433 if (ResolvingListBusy()) {
434 LOG_INFO(
435 "device is currently advertising, scanning,"
436 " or establishing an LE connection");
437 return ErrorCode::COMMAND_DISALLOWED;
438 }
439
440 le_resolving_list_enabled_ = enable;
441 return ErrorCode::SUCCESS;
442 }
443
444 // HCI command LE_Set_Privacy_Mode (Vol 4, Part E § 7.8.77).
LeSetPrivacyMode(PeerAddressType peer_identity_address_type,Address peer_identity_address,bluetooth::hci::PrivacyMode privacy_mode)445 ErrorCode LinkLayerController::LeSetPrivacyMode(
446 PeerAddressType peer_identity_address_type, Address peer_identity_address,
447 bluetooth::hci::PrivacyMode privacy_mode) {
448 // This command shall not be used when address resolution is enabled in the
449 // Controller and:
450 // • Advertising (other than periodic advertising) is enabled,
451 // • Scanning is enabled, or
452 // • an HCI_LE_Create_Connection, HCI_LE_Extended_Create_Connection, or
453 // HCI_LE_Periodic_Advertising_Create_Sync command is pending.
454 if (le_resolving_list_enabled_ && ResolvingListBusy()) {
455 LOG_INFO(
456 "device is currently advertising, scanning,"
457 " or establishing an LE connection");
458 return ErrorCode::COMMAND_DISALLOWED;
459 }
460
461 for (auto& entry : le_resolving_list_) {
462 if (entry.peer_identity_address_type == peer_identity_address_type &&
463 entry.peer_identity_address == peer_identity_address) {
464 entry.privacy_mode = privacy_mode;
465 return ErrorCode::SUCCESS;
466 }
467 }
468
469 // If the device is not on the resolving list, the Controller shall return
470 // the error code Unknown Connection Identifier (0x02).
471 LOG_INFO("peer address not found in the resolving list");
472 return ErrorCode::UNKNOWN_CONNECTION;
473 }
474
475 // =============================================================================
476 // LE Filter Accept List
477 // =============================================================================
478
479 // HCI command LE_Clear_Filter_Accept_List (Vol 4, Part E § 7.8.15).
LeClearFilterAcceptList()480 ErrorCode LinkLayerController::LeClearFilterAcceptList() {
481 // This command shall not be used when:
482 // • any advertising filter policy uses the Filter Accept List and
483 // advertising is enabled,
484 // • the scanning filter policy uses the Filter Accept List and scanning
485 // is enabled, or
486 // • the initiator filter policy uses the Filter Accept List and an
487 // HCI_LE_Create_Connection or HCI_LE_Extended_Create_Connection
488 // command is pending.
489 if (FilterAcceptListBusy()) {
490 LOG_INFO(
491 "device is currently advertising, scanning,"
492 " or establishing an LE connection using the filter accept list");
493 return ErrorCode::COMMAND_DISALLOWED;
494 }
495
496 le_filter_accept_list_.clear();
497 return ErrorCode::SUCCESS;
498 }
499
500 // HCI command LE_Add_Device_To_Filter_Accept_List (Vol 4, Part E § 7.8.16).
LeAddDeviceToFilterAcceptList(FilterAcceptListAddressType address_type,Address address)501 ErrorCode LinkLayerController::LeAddDeviceToFilterAcceptList(
502 FilterAcceptListAddressType address_type, Address address) {
503 // This command shall not be used when:
504 // • any advertising filter policy uses the Filter Accept List and
505 // advertising is enabled,
506 // • the scanning filter policy uses the Filter Accept List and scanning
507 // is enabled, or
508 // • the initiator filter policy uses the Filter Accept List and an
509 // HCI_LE_Create_Connection or HCI_LE_Extended_Create_Connection
510 // command is pending.
511 if (FilterAcceptListBusy()) {
512 LOG_INFO(
513 "device is currently advertising, scanning,"
514 " or establishing an LE connection using the filter accept list");
515 return ErrorCode::COMMAND_DISALLOWED;
516 }
517
518 // When a Controller cannot add a device to the Filter Accept List
519 // because there is no space available, it shall return the error code
520 // Memory Capacity Exceeded (0x07).
521 if (le_filter_accept_list_.size() >= properties_.le_filter_accept_list_size) {
522 LOG_INFO("filter accept list is full");
523 return ErrorCode::MEMORY_CAPACITY_EXCEEDED;
524 }
525
526 le_filter_accept_list_.emplace_back(
527 FilterAcceptListEntry{address_type, address});
528 return ErrorCode::SUCCESS;
529 }
530
531 // HCI command LE_Remove_Device_From_Filter_Accept_List (Vol 4, Part E
532 // § 7.8.17).
LeRemoveDeviceFromFilterAcceptList(FilterAcceptListAddressType address_type,Address address)533 ErrorCode LinkLayerController::LeRemoveDeviceFromFilterAcceptList(
534 FilterAcceptListAddressType address_type, Address address) {
535 // This command shall not be used when:
536 // • any advertising filter policy uses the Filter Accept List and
537 // advertising is enabled,
538 // • the scanning filter policy uses the Filter Accept List and scanning
539 // is enabled, or
540 // • the initiator filter policy uses the Filter Accept List and an
541 // HCI_LE_Create_Connection or HCI_LE_Extended_Create_Connection
542 // command is pending.
543 if (FilterAcceptListBusy()) {
544 LOG_INFO(
545 "device is currently advertising, scanning,"
546 " or establishing an LE connection using the filter accept list");
547 return ErrorCode::COMMAND_DISALLOWED;
548 }
549
550 for (auto it = le_filter_accept_list_.begin();
551 it != le_filter_accept_list_.end(); it++) {
552 // Address shall be ignored when Address_Type is set to 0xFF.
553 if (it->address_type == address_type &&
554 (address_type == FilterAcceptListAddressType::ANONYMOUS_ADVERTISERS ||
555 it->address == address)) {
556 le_filter_accept_list_.erase(it);
557 return ErrorCode::SUCCESS;
558 }
559 }
560
561 // Note: this case is not documented.
562 LOG_INFO("address not found in the filter accept list");
563 return ErrorCode::SUCCESS;
564 }
565
566 // =============================================================================
567 // LE Legacy Scanning
568 // =============================================================================
569
570 // HCI command LE_Set_Scan_Parameters (Vol 4, Part E § 7.8.10).
LeSetScanParameters(bluetooth::hci::LeScanType scan_type,uint16_t scan_interval,uint16_t scan_window,bluetooth::hci::OwnAddressType own_address_type,bluetooth::hci::LeScanningFilterPolicy scanning_filter_policy)571 ErrorCode LinkLayerController::LeSetScanParameters(
572 bluetooth::hci::LeScanType scan_type, uint16_t scan_interval,
573 uint16_t scan_window, bluetooth::hci::OwnAddressType own_address_type,
574 bluetooth::hci::LeScanningFilterPolicy scanning_filter_policy) {
575 // Legacy advertising commands are disallowed when extended advertising
576 // commands were used since the last reset.
577 if (!SelectLegacyAdvertising()) {
578 LOG_INFO(
579 "legacy advertising command rejected because extended advertising"
580 " is being used");
581 return ErrorCode::COMMAND_DISALLOWED;
582 }
583
584 // The Host shall not issue this command when scanning is enabled in the
585 // Controller; if it is the Command Disallowed error code shall be used.
586 if (scanner_.IsEnabled()) {
587 LOG_INFO("scanning is currently enabled");
588 return ErrorCode::COMMAND_DISALLOWED;
589 }
590
591 // Note: no explicit error code stated for invalid interval and window
592 // values but assuming Unsupported Feature or Parameter Value (0x11)
593 // error code based on similar advertising command.
594 if (scan_interval < 0x4 || scan_interval > 0x4000 || scan_window < 0x4 ||
595 scan_window > 0x4000) {
596 LOG_INFO(
597 "le_scan_interval (0x%04x) and/or"
598 " le_scan_window (0x%04x) are outside the range"
599 " of supported values (0x0004 - 0x4000)",
600 scan_interval, scan_window);
601 return ErrorCode::UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE;
602 }
603
604 // The LE_Scan_Window parameter shall always be set to a value smaller
605 // or equal to the value set for the LE_Scan_Interval parameter.
606 if (scan_window > scan_interval) {
607 LOG_INFO("le_scan_window (0x%04x) is larger than le_scan_interval (0x%04x)",
608 scan_window, scan_interval);
609 return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
610 }
611
612 scanner_.le_1m_phy.enabled = true;
613 scanner_.le_coded_phy.enabled = false;
614 scanner_.le_1m_phy.scan_type = scan_type;
615 scanner_.le_1m_phy.scan_interval = scan_interval;
616 scanner_.le_1m_phy.scan_window = scan_window;
617 scanner_.own_address_type = own_address_type;
618 scanner_.scan_filter_policy = scanning_filter_policy;
619 return ErrorCode::SUCCESS;
620 }
621
622 // HCI command LE_Set_Scan_Enable (Vol 4, Part E § 7.8.11).
LeSetScanEnable(bool enable,bool filter_duplicates)623 ErrorCode LinkLayerController::LeSetScanEnable(bool enable,
624 bool filter_duplicates) {
625 // Legacy advertising commands are disallowed when extended advertising
626 // commands were used since the last reset.
627 if (!SelectLegacyAdvertising()) {
628 LOG_INFO(
629 "legacy advertising command rejected because extended advertising"
630 " is being used");
631 return ErrorCode::COMMAND_DISALLOWED;
632 }
633
634 if (!enable) {
635 scanner_.scan_enable = false;
636 scanner_.history.clear();
637 return ErrorCode::SUCCESS;
638 }
639
640 // TODO: additional checks would apply in the case of a LE only Controller
641 // with no configured public device address.
642
643 // If LE_Scan_Enable is set to 0x01, the scanning parameters' Own_Address_Type
644 // parameter is set to 0x01 or 0x03, and the random address for the device
645 // has not been initialized using the HCI_LE_Set_Random_Address command,
646 // the Controller shall return the error code
647 // Invalid HCI Command Parameters (0x12).
648 if ((scanner_.own_address_type ==
649 bluetooth::hci::OwnAddressType::RANDOM_DEVICE_ADDRESS ||
650 scanner_.own_address_type ==
651 bluetooth::hci::OwnAddressType::RESOLVABLE_OR_RANDOM_ADDRESS) &&
652 random_address_ == Address::kEmpty) {
653 LOG_INFO(
654 "own_address_type is Random_Device_Address or"
655 " Resolvable_or_Random_Address but the Random_Address"
656 " has not been initialized");
657 return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
658 }
659
660 scanner_.scan_enable = true;
661 scanner_.history.clear();
662 scanner_.timeout = {};
663 scanner_.periodical_timeout = {};
664 scanner_.filter_duplicates = filter_duplicates
665 ? bluetooth::hci::FilterDuplicates::ENABLED
666 : bluetooth::hci::FilterDuplicates::DISABLED;
667 return ErrorCode::SUCCESS;
668 }
669
670 // =============================================================================
671 // LE Extended Scanning
672 // =============================================================================
673
674 // HCI command LE_Set_Extended_Scan_Parameters (Vol 4, Part E § 7.8.64).
LeSetExtendedScanParameters(bluetooth::hci::OwnAddressType own_address_type,bluetooth::hci::LeScanningFilterPolicy scanning_filter_policy,uint8_t scanning_phys,std::vector<bluetooth::hci::PhyScanParameters> scanning_phy_parameters)675 ErrorCode LinkLayerController::LeSetExtendedScanParameters(
676 bluetooth::hci::OwnAddressType own_address_type,
677 bluetooth::hci::LeScanningFilterPolicy scanning_filter_policy,
678 uint8_t scanning_phys,
679 std::vector<bluetooth::hci::PhyScanParameters> scanning_phy_parameters) {
680 // Extended advertising commands are disallowed when legacy advertising
681 // commands were used since the last reset.
682 if (!SelectExtendedAdvertising()) {
683 LOG_INFO(
684 "extended advertising command rejected because legacy advertising"
685 " is being used");
686 return ErrorCode::COMMAND_DISALLOWED;
687 }
688
689 // If the Host issues this command when scanning is enabled in the Controller,
690 // the Controller shall return the error code Command Disallowed (0x0C).
691 if (scanner_.IsEnabled()) {
692 LOG_INFO("scanning is currently enabled");
693 return ErrorCode::COMMAND_DISALLOWED;
694 }
695
696 // If the Host specifies a PHY that is not supported by the Controller,
697 // including a bit that is reserved for future use, it should return the
698 // error code Unsupported Feature or Parameter Value (0x11).
699 if ((scanning_phys & 0xfa) != 0) {
700 LOG_INFO(
701 "scanning_phys (%02x) enables PHYs that are not supported by"
702 " the controller",
703 scanning_phys);
704 return ErrorCode::UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE;
705 }
706
707 // TODO(c++20) std::popcount
708 if (__builtin_popcount(scanning_phys) !=
709 int(scanning_phy_parameters.size())) {
710 LOG_INFO(
711 "scanning_phy_parameters (%zu)"
712 " does not match scanning_phys (%02x)",
713 scanning_phy_parameters.size(), scanning_phys);
714 return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
715 }
716
717 // Note: no explicit error code stated for empty scanning_phys
718 // but assuming Unsupported Feature or Parameter Value (0x11)
719 // error code based on HCI Extended LE Create Connecton command.
720 if (scanning_phys == 0) {
721 LOG_INFO("scanning_phys is empty");
722 return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
723 }
724
725 for (auto const& parameter : scanning_phy_parameters) {
726 // If the requested scan cannot be supported by the implementation,
727 // the Controller shall return the error code
728 // Invalid HCI Command Parameters (0x12).
729 if (parameter.le_scan_interval_ < 0x4 || parameter.le_scan_window_ < 0x4) {
730 LOG_INFO(
731 "le_scan_interval (0x%04x) and/or"
732 " le_scan_window (0x%04x) are outside the range"
733 " of supported values (0x0004 - 0xffff)",
734 parameter.le_scan_interval_, parameter.le_scan_window_);
735 return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
736 }
737
738 if (parameter.le_scan_window_ > parameter.le_scan_interval_) {
739 LOG_INFO(
740 "le_scan_window (0x%04x) is larger than le_scan_interval (0x%04x)",
741 parameter.le_scan_window_, parameter.le_scan_interval_);
742 return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
743 }
744 }
745
746 scanner_.own_address_type = own_address_type;
747 scanner_.scan_filter_policy = scanning_filter_policy;
748 scanner_.le_1m_phy.enabled = false;
749 scanner_.le_coded_phy.enabled = false;
750 int offset = 0;
751
752 if (scanning_phys & 0x1) {
753 scanner_.le_1m_phy = Scanner::PhyParameters{
754 .enabled = true,
755 .scan_type = scanning_phy_parameters[offset].le_scan_type_,
756 .scan_interval = scanning_phy_parameters[offset].le_scan_interval_,
757 .scan_window = scanning_phy_parameters[offset].le_scan_window_,
758 };
759 offset++;
760 }
761
762 if (scanning_phys & 0x4) {
763 scanner_.le_coded_phy = Scanner::PhyParameters{
764 .enabled = true,
765 .scan_type = scanning_phy_parameters[offset].le_scan_type_,
766 .scan_interval = scanning_phy_parameters[offset].le_scan_interval_,
767 .scan_window = scanning_phy_parameters[offset].le_scan_window_,
768 };
769 offset++;
770 }
771
772 return ErrorCode::SUCCESS;
773 }
774
775 // HCI command LE_Set_Extended_Scan_Enable (Vol 4, Part E § 7.8.65).
LeSetExtendedScanEnable(bool enable,bluetooth::hci::FilterDuplicates filter_duplicates,uint16_t duration,uint16_t period)776 ErrorCode LinkLayerController::LeSetExtendedScanEnable(
777 bool enable, bluetooth::hci::FilterDuplicates filter_duplicates,
778 uint16_t duration, uint16_t period) {
779 // Extended advertising commands are disallowed when legacy advertising
780 // commands were used since the last reset.
781 if (!SelectExtendedAdvertising()) {
782 LOG_INFO(
783 "extended advertising command rejected because legacy advertising"
784 " is being used");
785 return ErrorCode::COMMAND_DISALLOWED;
786 }
787
788 if (!enable) {
789 scanner_.scan_enable = false;
790 scanner_.history.clear();
791 return ErrorCode::SUCCESS;
792 }
793
794 // The Period parameter shall be ignored when the Duration parameter is zero.
795 if (duration == 0) {
796 period = 0;
797 }
798
799 // If Filter_Duplicates is set to 0x02 and either Period or Duration to zero,
800 // the Controller shall return the error code
801 // Invalid HCI Command Parameters (0x12).
802 if (filter_duplicates ==
803 bluetooth::hci::FilterDuplicates::RESET_EACH_PERIOD &&
804 (period == 0 || duration == 0)) {
805 LOG_INFO(
806 "filter_duplicates is Reset_Each_Period but either"
807 " the period or duration is 0");
808 return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
809 }
810
811 auto duration_ms = std::chrono::milliseconds(10 * duration);
812 auto period_ms = std::chrono::milliseconds(1280 * period);
813
814 // If both the Duration and Period parameters are non-zero and the Duration is
815 // greater than or equal to the Period, the Controller shall return the
816 // error code Invalid HCI Command Parameters (0x12).
817 if (period != 0 && duration != 0 && duration_ms >= period_ms) {
818 LOG_INFO("the period is greater than or equal to the duration");
819 return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
820 }
821
822 // TODO: additional checks would apply in the case of a LE only Controller
823 // with no configured public device address.
824
825 // If LE_Scan_Enable is set to 0x01, the scanning parameters' Own_Address_Type
826 // parameter is set to 0x01 or 0x03, and the random address for the device
827 // has not been initialized using the HCI_LE_Set_Random_Address command,
828 // the Controller shall return the error code
829 // Invalid HCI Command Parameters (0x12).
830 if ((scanner_.own_address_type ==
831 bluetooth::hci::OwnAddressType::RANDOM_DEVICE_ADDRESS ||
832 scanner_.own_address_type ==
833 bluetooth::hci::OwnAddressType::RESOLVABLE_OR_RANDOM_ADDRESS) &&
834 random_address_ == Address::kEmpty) {
835 LOG_INFO(
836 "own_address_type is Random_Device_Address or"
837 " Resolvable_or_Random_Address but the Random_Address"
838 " has not been initialized");
839 return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
840 }
841
842 scanner_.scan_enable = true;
843 scanner_.history.clear();
844 scanner_.timeout = {};
845 scanner_.periodical_timeout = {};
846 scanner_.filter_duplicates = filter_duplicates;
847 scanner_.duration = duration_ms;
848 scanner_.period = period_ms;
849
850 auto now = std::chrono::steady_clock::now();
851
852 // At the end of a single scan (Duration non-zero but Period zero), an
853 // HCI_LE_Scan_Timeout event shall be generated.
854 if (duration != 0) {
855 scanner_.timeout = now + scanner_.duration;
856 }
857 if (period != 0) {
858 scanner_.periodical_timeout = now + scanner_.period;
859 }
860
861 return ErrorCode::SUCCESS;
862 }
863
864 // =============================================================================
865 // LE Legacy Connection
866 // =============================================================================
867
868 // HCI LE Create Connection command (Vol 4, Part E § 7.8.12).
LeCreateConnection(uint16_t scan_interval,uint16_t scan_window,bluetooth::hci::InitiatorFilterPolicy initiator_filter_policy,AddressWithType peer_address,bluetooth::hci::OwnAddressType own_address_type,uint16_t connection_interval_min,uint16_t connection_interval_max,uint16_t max_latency,uint16_t supervision_timeout,uint16_t min_ce_length,uint16_t max_ce_length)869 ErrorCode LinkLayerController::LeCreateConnection(
870 uint16_t scan_interval, uint16_t scan_window,
871 bluetooth::hci::InitiatorFilterPolicy initiator_filter_policy,
872 AddressWithType peer_address,
873 bluetooth::hci::OwnAddressType own_address_type,
874 uint16_t connection_interval_min, uint16_t connection_interval_max,
875 uint16_t max_latency, uint16_t supervision_timeout, uint16_t min_ce_length,
876 uint16_t max_ce_length) {
877 // Legacy advertising commands are disallowed when extended advertising
878 // commands were used since the last reset.
879 if (!SelectLegacyAdvertising()) {
880 LOG_INFO(
881 "legacy advertising command rejected because extended advertising"
882 " is being used");
883 return ErrorCode::COMMAND_DISALLOWED;
884 }
885
886 // If the Host issues this command when another HCI_LE_Create_Connection
887 // command is pending in the Controller, the Controller shall return the
888 // error code Command Disallowed (0x0C).
889 if (initiator_.IsEnabled()) {
890 LOG_INFO("initiator is currently enabled");
891 return ErrorCode::COMMAND_DISALLOWED;
892 }
893
894 // Note: no explicit error code stated for invalid interval and window
895 // values but assuming Unsupported Feature or Parameter Value (0x11)
896 // error code based on similar advertising command.
897 if (scan_interval < 0x4 || scan_interval > 0x4000 || scan_window < 0x4 ||
898 scan_window > 0x4000) {
899 LOG_INFO(
900 "scan_interval (0x%04x) and/or "
901 "scan_window (0x%04x) are outside the range"
902 " of supported values (0x4 - 0x4000)",
903 scan_interval, scan_window);
904 return ErrorCode::UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE;
905 }
906
907 // The LE_Scan_Window parameter shall be set to a value smaller or equal to
908 // the value set for the LE_Scan_Interval parameter.
909 if (scan_interval < scan_window) {
910 LOG_INFO("scan_window (0x%04x) is larger than scan_interval (0x%04x)",
911 scan_window, scan_interval);
912 return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
913 }
914
915 // Note: no explicit error code stated for invalid connection interval
916 // values but assuming Unsupported Feature or Parameter Value (0x11)
917 // error code based on similar advertising command.
918 if (connection_interval_min < 0x6 || connection_interval_min > 0x0c80 ||
919 connection_interval_max < 0x6 || connection_interval_max > 0x0c80) {
920 LOG_INFO(
921 "connection_interval_min (0x%04x) and/or "
922 "connection_interval_max (0x%04x) are outside the range"
923 " of supported values (0x6 - 0x0c80)",
924 connection_interval_min, connection_interval_max);
925 return ErrorCode::UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE;
926 }
927
928 // The Connection_Interval_Min parameter shall not be greater than the
929 // Connection_Interval_Max parameter.
930 if (connection_interval_max < connection_interval_min) {
931 LOG_INFO(
932 "connection_interval_min (0x%04x) is larger than"
933 " connection_interval_max (0x%04x)",
934 connection_interval_min, connection_interval_max);
935 return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
936 }
937
938 // Note: no explicit error code stated for invalid max_latency
939 // values but assuming Unsupported Feature or Parameter Value (0x11)
940 // error code based on similar advertising command.
941 if (max_latency > 0x01f3) {
942 LOG_INFO(
943 "max_latency (0x%04x) is outside the range"
944 " of supported values (0x0 - 0x01f3)",
945 max_latency);
946 return ErrorCode::UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE;
947 }
948
949 // Note: no explicit error code stated for invalid supervision timeout
950 // values but assuming Unsupported Feature or Parameter Value (0x11)
951 // error code based on similar advertising command.
952 if (supervision_timeout < 0xa || supervision_timeout > 0x0c80) {
953 LOG_INFO(
954 "supervision_timeout (0x%04x) is outside the range"
955 " of supported values (0xa - 0x0c80)",
956 supervision_timeout);
957 return ErrorCode::UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE;
958 }
959
960 // The Supervision_Timeout in milliseconds shall be larger than
961 // (1 + Max_Latency) * Connection_Interval_Max * 2, where
962 // Connection_Interval_Max is given in milliseconds.
963 milliseconds min_supervision_timeout = duration_cast<milliseconds>(
964 (1 + max_latency) * slots(2 * connection_interval_max) * 2);
965 if (supervision_timeout * 10ms < min_supervision_timeout) {
966 LOG_INFO(
967 "supervision_timeout (%d ms) is smaller that the minimal supervision "
968 "timeout allowed by connection_interval_max and max_latency (%u ms)",
969 supervision_timeout * 10,
970 static_cast<unsigned>(min_supervision_timeout / 1ms));
971 return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
972 }
973
974 // TODO: additional checks would apply in the case of a LE only Controller
975 // with no configured public device address.
976
977 // If the Own_Address_Type parameter is set to 0x01 and the random
978 // address for the device has not been initialized using the
979 // HCI_LE_Set_Random_Address command, the Controller shall return the
980 // error code Invalid HCI Command Parameters (0x12).
981 if (own_address_type == OwnAddressType::RANDOM_DEVICE_ADDRESS &&
982 random_address_ == Address::kEmpty) {
983 LOG_INFO(
984 "own_address_type is Random_Device_Address but the Random_Address"
985 " has not been initialized");
986 return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
987 }
988
989 // If the Own_Address_Type parameter is set to 0x03, the
990 // Initiator_Filter_Policy parameter is set to 0x00, the controller's
991 // resolving list did not contain matching entry, and the random address for
992 // the device has not been initialized using the HCI_LE_Set_Random_Address
993 // command, the Controller shall return the error code
994 // Invalid HCI Command Parameters (0x12).
995 if (own_address_type == OwnAddressType::RESOLVABLE_OR_RANDOM_ADDRESS &&
996 initiator_filter_policy == InitiatorFilterPolicy::USE_PEER_ADDRESS &&
997 !GenerateResolvablePrivateAddress(peer_address, IrkSelection::Local) &&
998 random_address_ == Address::kEmpty) {
999 LOG_INFO(
1000 "own_address_type is Resolvable_Or_Random_Address but the"
1001 " Resolving_List does not contain a matching entry and the"
1002 " Random_Address is not initialized");
1003 return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
1004 }
1005
1006 initiator_.connect_enable = true;
1007 initiator_.initiator_filter_policy = initiator_filter_policy;
1008 initiator_.peer_address = peer_address;
1009 initiator_.own_address_type = own_address_type;
1010 initiator_.le_1m_phy.enabled = true;
1011 initiator_.le_1m_phy.scan_interval = scan_interval;
1012 initiator_.le_1m_phy.scan_window = scan_window;
1013 initiator_.le_1m_phy.connection_interval_min = connection_interval_min;
1014 initiator_.le_1m_phy.connection_interval_max = connection_interval_max;
1015 initiator_.le_1m_phy.max_latency = max_latency;
1016 initiator_.le_1m_phy.supervision_timeout = supervision_timeout;
1017 initiator_.le_1m_phy.min_ce_length = min_ce_length;
1018 initiator_.le_1m_phy.max_ce_length = max_ce_length;
1019 initiator_.le_2m_phy.enabled = false;
1020 initiator_.le_coded_phy.enabled = false;
1021 initiator_.pending_connect_request = {};
1022 return ErrorCode::SUCCESS;
1023 }
1024
1025 // HCI LE Create Connection Cancel command (Vol 4, Part E § 7.8.12).
LeCreateConnectionCancel()1026 ErrorCode LinkLayerController::LeCreateConnectionCancel() {
1027 // If no HCI_LE_Create_Connection or HCI_LE_Extended_Create_Connection
1028 // command is pending, then the Controller shall return the error code
1029 // Command Disallowed (0x0C).
1030 if (!initiator_.IsEnabled()) {
1031 LOG_INFO("initiator is currently disabled");
1032 return ErrorCode::COMMAND_DISALLOWED;
1033 }
1034
1035 // If the cancellation was successful then, after the HCI_Command_Complete
1036 // event for the HCI_LE_Create_Connection_Cancel command, either an LE
1037 // Connection Complete or an HCI_LE_Enhanced_Connection_Complete event
1038 // shall be generated. In either case, the event shall be sent with the error
1039 // code Unknown Connection Identifier (0x02).
1040 if (IsLeEventUnmasked(SubeventCode::ENHANCED_CONNECTION_COMPLETE)) {
1041 ScheduleTask(0ms, [this] {
1042 send_event_(bluetooth::hci::LeEnhancedConnectionCompleteBuilder::Create(
1043 ErrorCode::UNKNOWN_CONNECTION, 0, Role::CENTRAL,
1044 AddressType::PUBLIC_DEVICE_ADDRESS, Address(), Address(), Address(),
1045 0, 0, 0, bluetooth::hci::ClockAccuracy::PPM_500));
1046 });
1047 } else if (IsLeEventUnmasked(SubeventCode::CONNECTION_COMPLETE)) {
1048 ScheduleTask(0ms, [this] {
1049 send_event_(bluetooth::hci::LeConnectionCompleteBuilder::Create(
1050 ErrorCode::UNKNOWN_CONNECTION, 0, Role::CENTRAL,
1051 AddressType::PUBLIC_DEVICE_ADDRESS, Address(), 0, 0, 0,
1052 bluetooth::hci::ClockAccuracy::PPM_500));
1053 });
1054 }
1055
1056 initiator_.Disable();
1057 return ErrorCode::SUCCESS;
1058 }
1059
1060 // =============================================================================
1061 // LE Extended Connection
1062 // =============================================================================
1063
1064 // HCI LE Extended Create Connection command (Vol 4, Part E § 7.8.66).
LeExtendedCreateConnection(bluetooth::hci::InitiatorFilterPolicy initiator_filter_policy,bluetooth::hci::OwnAddressType own_address_type,AddressWithType peer_address,uint8_t initiating_phys,std::vector<bluetooth::hci::LeCreateConnPhyScanParameters> initiating_phy_parameters)1065 ErrorCode LinkLayerController::LeExtendedCreateConnection(
1066 bluetooth::hci::InitiatorFilterPolicy initiator_filter_policy,
1067 bluetooth::hci::OwnAddressType own_address_type,
1068 AddressWithType peer_address, uint8_t initiating_phys,
1069 std::vector<bluetooth::hci::LeCreateConnPhyScanParameters>
1070 initiating_phy_parameters) {
1071 // Extended advertising commands are disallowed when legacy advertising
1072 // commands were used since the last reset.
1073 if (!SelectExtendedAdvertising()) {
1074 LOG_INFO(
1075 "extended advertising command rejected because legacy advertising"
1076 " is being used");
1077 return ErrorCode::COMMAND_DISALLOWED;
1078 }
1079
1080 // If the Host issues this command when another
1081 // HCI_LE_Extended_Create_Connection command is pending in the Controller,
1082 // the Controller shall return the error code Command Disallowed (0x0C).
1083 if (initiator_.IsEnabled()) {
1084 LOG_INFO("initiator is currently enabled");
1085 return ErrorCode::COMMAND_DISALLOWED;
1086 }
1087
1088 // If the Host specifies a PHY that is not supported by the Controller,
1089 // including a bit that is reserved for future use, the latter should return
1090 // the error code Unsupported Feature or Parameter Value (0x11).
1091 if ((initiating_phys & 0xf8) != 0) {
1092 LOG_INFO(
1093 "initiating_phys (%02x) enables PHYs that are not supported by"
1094 " the controller",
1095 initiating_phys);
1096 return ErrorCode::UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE;
1097 }
1098
1099 // TODO(c++20) std::popcount
1100 if (__builtin_popcount(initiating_phys) !=
1101 int(initiating_phy_parameters.size())) {
1102 LOG_INFO(
1103 "initiating_phy_parameters (%zu)"
1104 " does not match initiating_phys (%02x)",
1105 initiating_phy_parameters.size(), initiating_phys);
1106 return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
1107 }
1108
1109 // If the Initiating_PHYs parameter does not have at least one bit set for a
1110 // PHY allowed for scanning on the primary advertising physical channel, the
1111 // Controller shall return the error code
1112 // Invalid HCI Command Parameters (0x12).
1113 if (initiating_phys == 0) {
1114 LOG_INFO("initiating_phys is empty");
1115 return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
1116 }
1117
1118 for (auto const& parameter : initiating_phy_parameters) {
1119 // Note: no explicit error code stated for invalid interval and window
1120 // values but assuming Unsupported Feature or Parameter Value (0x11)
1121 // error code based on similar advertising command.
1122 if (parameter.scan_interval_ < 0x4 || parameter.scan_interval_ > 0x4000 ||
1123 parameter.scan_window_ < 0x4 || parameter.scan_window_ > 0x4000) {
1124 LOG_INFO(
1125 "scan_interval (0x%04x) and/or "
1126 "scan_window (0x%04x) are outside the range"
1127 " of supported values (0x4 - 0x4000)",
1128 parameter.scan_interval_, parameter.scan_window_);
1129 return ErrorCode::UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE;
1130 }
1131
1132 // The LE_Scan_Window parameter shall be set to a value smaller or equal to
1133 // the value set for the LE_Scan_Interval parameter.
1134 if (parameter.scan_interval_ < parameter.scan_window_) {
1135 LOG_INFO("scan_window (0x%04x) is larger than scan_interval (0x%04x)",
1136 parameter.scan_window_, parameter.scan_interval_);
1137 return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
1138 }
1139
1140 // Note: no explicit error code stated for invalid connection interval
1141 // values but assuming Unsupported Feature or Parameter Value (0x11)
1142 // error code based on similar advertising command.
1143 if (parameter.conn_interval_min_ < 0x6 ||
1144 parameter.conn_interval_min_ > 0x0c80 ||
1145 parameter.conn_interval_max_ < 0x6 ||
1146 parameter.conn_interval_max_ > 0x0c80) {
1147 LOG_INFO(
1148 "connection_interval_min (0x%04x) and/or "
1149 "connection_interval_max (0x%04x) are outside the range"
1150 " of supported values (0x6 - 0x0c80)",
1151 parameter.conn_interval_min_, parameter.conn_interval_max_);
1152 return ErrorCode::UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE;
1153 }
1154
1155 // The Connection_Interval_Min parameter shall not be greater than the
1156 // Connection_Interval_Max parameter.
1157 if (parameter.conn_interval_max_ < parameter.conn_interval_min_) {
1158 LOG_INFO(
1159 "connection_interval_min (0x%04x) is larger than"
1160 " connection_interval_max (0x%04x)",
1161 parameter.conn_interval_min_, parameter.conn_interval_max_);
1162 return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
1163 }
1164
1165 // Note: no explicit error code stated for invalid max_latency
1166 // values but assuming Unsupported Feature or Parameter Value (0x11)
1167 // error code based on similar advertising command.
1168 if (parameter.conn_latency_ > 0x01f3) {
1169 LOG_INFO(
1170 "max_latency (0x%04x) is outside the range"
1171 " of supported values (0x0 - 0x01f3)",
1172 parameter.conn_latency_);
1173 return ErrorCode::UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE;
1174 }
1175
1176 // Note: no explicit error code stated for invalid supervision timeout
1177 // values but assuming Unsupported Feature or Parameter Value (0x11)
1178 // error code based on similar advertising command.
1179 if (parameter.supervision_timeout_ < 0xa ||
1180 parameter.supervision_timeout_ > 0x0c80) {
1181 LOG_INFO(
1182 "supervision_timeout (0x%04x) is outside the range"
1183 " of supported values (0xa - 0x0c80)",
1184 parameter.supervision_timeout_);
1185 return ErrorCode::UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE;
1186 }
1187
1188 // The Supervision_Timeout in milliseconds shall be larger than
1189 // (1 + Max_Latency) * Connection_Interval_Max * 2, where
1190 // Connection_Interval_Max is given in milliseconds.
1191 milliseconds min_supervision_timeout = duration_cast<milliseconds>(
1192 (1 + parameter.conn_latency_) *
1193 slots(2 * parameter.conn_interval_max_) * 2);
1194 if (parameter.supervision_timeout_ * 10ms < min_supervision_timeout) {
1195 LOG_INFO(
1196 "supervision_timeout (%d ms) is smaller that the minimal supervision "
1197 "timeout allowed by connection_interval_max and max_latency (%u ms)",
1198 parameter.supervision_timeout_ * 10,
1199 static_cast<unsigned>(min_supervision_timeout / 1ms));
1200 return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
1201 }
1202 }
1203
1204 // TODO: additional checks would apply in the case of a LE only Controller
1205 // with no configured public device address.
1206
1207 // If the Own_Address_Type parameter is set to 0x01 and the random
1208 // address for the device has not been initialized using the
1209 // HCI_LE_Set_Random_Address command, the Controller shall return the
1210 // error code Invalid HCI Command Parameters (0x12).
1211 if (own_address_type == OwnAddressType::RANDOM_DEVICE_ADDRESS &&
1212 random_address_ == Address::kEmpty) {
1213 LOG_INFO(
1214 "own_address_type is Random_Device_Address but the Random_Address"
1215 " has not been initialized");
1216 return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
1217 }
1218
1219 // If the Own_Address_Type parameter is set to 0x03, the
1220 // Initiator_Filter_Policy parameter is set to 0x00, the controller's
1221 // resolving list did not contain matching entry, and the random address for
1222 // the device has not been initialized using the HCI_LE_Set_Random_Address
1223 // command, the Controller shall return the error code
1224 // Invalid HCI Command Parameters (0x12).
1225 if (own_address_type == OwnAddressType::RESOLVABLE_OR_RANDOM_ADDRESS &&
1226 initiator_filter_policy == InitiatorFilterPolicy::USE_PEER_ADDRESS &&
1227 !GenerateResolvablePrivateAddress(peer_address, IrkSelection::Local) &&
1228 random_address_ == Address::kEmpty) {
1229 LOG_INFO(
1230 "own_address_type is Resolvable_Or_Random_Address but the"
1231 " Resolving_List does not contain a matching entry and the"
1232 " Random_Address is not initialized");
1233 return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
1234 }
1235
1236 initiator_.connect_enable = true;
1237 initiator_.initiator_filter_policy = initiator_filter_policy;
1238 initiator_.peer_address = peer_address;
1239 initiator_.own_address_type = own_address_type;
1240 initiator_.pending_connect_request = {};
1241
1242 initiator_.le_1m_phy.enabled = false;
1243 initiator_.le_2m_phy.enabled = false;
1244 initiator_.le_coded_phy.enabled = false;
1245 int offset = 0;
1246
1247 if (initiating_phys & 0x1) {
1248 initiator_.le_1m_phy = Initiator::PhyParameters{
1249 .enabled = true,
1250 .scan_interval = initiating_phy_parameters[offset].scan_interval_,
1251 .scan_window = initiating_phy_parameters[offset].scan_window_,
1252 .connection_interval_min =
1253 initiating_phy_parameters[offset].conn_interval_min_,
1254 .connection_interval_max =
1255 initiating_phy_parameters[offset].conn_interval_max_,
1256 .max_latency = initiating_phy_parameters[offset].conn_latency_,
1257 .supervision_timeout =
1258 initiating_phy_parameters[offset].supervision_timeout_,
1259 .min_ce_length = initiating_phy_parameters[offset].min_ce_length_,
1260 .max_ce_length = initiating_phy_parameters[offset].max_ce_length_,
1261 };
1262 offset++;
1263 }
1264
1265 if (initiating_phys & 0x2) {
1266 initiator_.le_2m_phy = Initiator::PhyParameters{
1267 .enabled = true,
1268 .scan_interval = initiating_phy_parameters[offset].scan_interval_,
1269 .scan_window = initiating_phy_parameters[offset].scan_window_,
1270 .connection_interval_min =
1271 initiating_phy_parameters[offset].conn_interval_min_,
1272 .connection_interval_max =
1273 initiating_phy_parameters[offset].conn_interval_max_,
1274 .max_latency = initiating_phy_parameters[offset].conn_latency_,
1275 .supervision_timeout =
1276 initiating_phy_parameters[offset].supervision_timeout_,
1277 .min_ce_length = initiating_phy_parameters[offset].min_ce_length_,
1278 .max_ce_length = initiating_phy_parameters[offset].max_ce_length_,
1279 };
1280 offset++;
1281 }
1282
1283 if (initiating_phys & 0x4) {
1284 initiator_.le_coded_phy = Initiator::PhyParameters{
1285 .enabled = true,
1286 .scan_interval = initiating_phy_parameters[offset].scan_interval_,
1287 .scan_window = initiating_phy_parameters[offset].scan_window_,
1288 .connection_interval_min =
1289 initiating_phy_parameters[offset].conn_interval_min_,
1290 .connection_interval_max =
1291 initiating_phy_parameters[offset].conn_interval_max_,
1292 .max_latency = initiating_phy_parameters[offset].conn_latency_,
1293 .supervision_timeout =
1294 initiating_phy_parameters[offset].supervision_timeout_,
1295 .min_ce_length = initiating_phy_parameters[offset].min_ce_length_,
1296 .max_ce_length = initiating_phy_parameters[offset].max_ce_length_,
1297 };
1298 offset++;
1299 }
1300
1301 return ErrorCode::SUCCESS;
1302 }
1303
SetSecureSimplePairingSupport(bool enable)1304 void LinkLayerController::SetSecureSimplePairingSupport(bool enable) {
1305 uint64_t bit = 0x1;
1306 secure_simple_pairing_host_support_ = enable;
1307 if (enable) {
1308 host_supported_features_ |= bit;
1309 } else {
1310 host_supported_features_ &= ~bit;
1311 }
1312 }
1313
SetLeHostSupport(bool enable)1314 void LinkLayerController::SetLeHostSupport(bool enable) {
1315 // TODO: Vol 2, Part C § 3.5 Feature requirements.
1316 // (65) LE Supported (Host) implies
1317 // (38) LE Supported (Controller)
1318 uint64_t bit = 0x2;
1319 le_host_support_ = enable;
1320 if (enable) {
1321 host_supported_features_ |= bit;
1322 } else {
1323 host_supported_features_ &= ~bit;
1324 }
1325 }
1326
SetSecureConnectionsSupport(bool enable)1327 void LinkLayerController::SetSecureConnectionsSupport(bool enable) {
1328 // TODO: Vol 2, Part C § 3.5 Feature requirements.
1329 // (67) Secure Connections (Host Support) implies
1330 // (64) Secure Simple Pairing (Host Support) and
1331 // (136) Secure Connections (Controller Support)
1332 uint64_t bit = 0x8;
1333 secure_connections_host_support_ = enable;
1334 if (enable) {
1335 host_supported_features_ |= bit;
1336 } else {
1337 host_supported_features_ &= ~bit;
1338 }
1339 }
1340
SetLocalName(std::array<uint8_t,248> const & local_name)1341 void LinkLayerController::SetLocalName(
1342 std::array<uint8_t, 248> const& local_name) {
1343 std::copy(local_name.begin(), local_name.end(), local_name_.begin());
1344 }
1345
SetLocalName(std::vector<uint8_t> const & local_name)1346 void LinkLayerController::SetLocalName(std::vector<uint8_t> const& local_name) {
1347 ASSERT(local_name.size() <= local_name_.size());
1348 local_name_.fill(0);
1349 std::copy(local_name.begin(), local_name.end(), local_name_.begin());
1350 }
1351
SetExtendedInquiryResponse(std::vector<uint8_t> const & extended_inquiry_response)1352 void LinkLayerController::SetExtendedInquiryResponse(
1353 std::vector<uint8_t> const& extended_inquiry_response) {
1354 ASSERT(extended_inquiry_response.size() <= extended_inquiry_response_.size());
1355 extended_inquiry_response_.fill(0);
1356 std::copy(extended_inquiry_response.begin(), extended_inquiry_response.end(),
1357 extended_inquiry_response_.begin());
1358 }
1359
1360 #ifdef ROOTCANAL_LMP
LinkLayerController(const Address & address,const ControllerProperties & properties)1361 LinkLayerController::LinkLayerController(const Address& address,
1362 const ControllerProperties& properties)
1363 : address_(address),
1364 properties_(properties),
1365 lm_(nullptr, link_manager_destroy) {
1366 ops_ = {
1367 .user_pointer = this,
1368 .get_handle =
1369 [](void* user, const uint8_t(*address)[6]) {
1370 auto controller = static_cast<LinkLayerController*>(user);
1371
1372 return controller->connections_.GetHandleOnlyAddress(
1373 Address(*address));
1374 },
1375
1376 .get_address =
1377 [](void* user, uint16_t handle, uint8_t(*result)[6]) {
1378 auto controller = static_cast<LinkLayerController*>(user);
1379
1380 auto address =
1381 controller->connections_.GetAddress(handle).GetAddress();
1382 std::copy(address.data(), address.data() + 6,
1383 reinterpret_cast<uint8_t*>(result));
1384 },
1385
1386 .extended_features =
1387 [](void* user, uint8_t features_page) {
1388 auto controller = static_cast<LinkLayerController*>(user);
1389 return controller->GetLmpFeatures(features_page);
1390 },
1391
1392 .send_hci_event =
1393 [](void* user, const uint8_t* data, uintptr_t len) {
1394 auto controller = static_cast<LinkLayerController*>(user);
1395
1396 auto event_code = static_cast<EventCode>(data[0]);
1397 auto payload = std::make_unique<bluetooth::packet::RawBuilder>(
1398 std::vector(data + 2, data + len));
1399
1400 controller->send_event_(bluetooth::hci::EventBuilder::Create(
1401 event_code, std::move(payload)));
1402 },
1403
1404 .send_lmp_packet =
1405 [](void* user, const uint8_t(*to)[6], const uint8_t* data,
1406 uintptr_t len) {
1407 auto controller = static_cast<LinkLayerController*>(user);
1408
1409 auto payload = std::make_unique<bluetooth::packet::RawBuilder>(
1410 std::vector(data, data + len));
1411
1412 Address source = controller->GetAddress();
1413 Address dest(*to);
1414
1415 controller->SendLinkLayerPacket(model::packets::LmpBuilder::Create(
1416 source, dest, std::move(payload)));
1417 }};
1418
1419 lm_.reset(link_manager_create(ops_));
1420 }
1421 #else
LinkLayerController(const Address & address,const ControllerProperties & properties)1422 LinkLayerController::LinkLayerController(const Address& address,
1423 const ControllerProperties& properties)
1424 : address_(address), properties_(properties) {}
1425 #endif
1426
SendLeLinkLayerPacket(std::unique_ptr<model::packets::LinkLayerPacketBuilder> packet)1427 void LinkLayerController::SendLeLinkLayerPacket(
1428 std::unique_ptr<model::packets::LinkLayerPacketBuilder> packet) {
1429 std::shared_ptr<model::packets::LinkLayerPacketBuilder> shared_packet =
1430 std::move(packet);
1431 ScheduleTask(kNoDelayMs, [this, shared_packet]() {
1432 send_to_remote_(shared_packet, Phy::Type::LOW_ENERGY);
1433 });
1434 }
1435
SendLinkLayerPacket(std::unique_ptr<model::packets::LinkLayerPacketBuilder> packet)1436 void LinkLayerController::SendLinkLayerPacket(
1437 std::unique_ptr<model::packets::LinkLayerPacketBuilder> packet) {
1438 std::shared_ptr<model::packets::LinkLayerPacketBuilder> shared_packet =
1439 std::move(packet);
1440 ScheduleTask(kNoDelayMs, [this, shared_packet]() {
1441 send_to_remote_(shared_packet, Phy::Type::BR_EDR);
1442 });
1443 }
1444
SendLeLinkLayerPacketWithRssi(Address source_address,Address destination_address,uint8_t rssi,std::unique_ptr<model::packets::LinkLayerPacketBuilder> packet)1445 void LinkLayerController::SendLeLinkLayerPacketWithRssi(
1446 Address source_address, Address destination_address, uint8_t rssi,
1447 std::unique_ptr<model::packets::LinkLayerPacketBuilder> packet) {
1448 std::shared_ptr<model::packets::RssiWrapperBuilder> shared_packet =
1449 model::packets::RssiWrapperBuilder::Create(
1450 source_address, destination_address, rssi, std::move(packet));
1451 ScheduleTask(kNoDelayMs, [this, shared_packet]() {
1452 send_to_remote_(shared_packet, Phy::Type::LOW_ENERGY);
1453 });
1454 }
1455
SendLeCommandToRemoteByAddress(OpCode opcode,const Address & own_address,const Address & peer_address)1456 ErrorCode LinkLayerController::SendLeCommandToRemoteByAddress(
1457 OpCode opcode, const Address& own_address, const Address& peer_address) {
1458 switch (opcode) {
1459 case (OpCode::LE_READ_REMOTE_FEATURES):
1460 SendLeLinkLayerPacket(model::packets::LeReadRemoteFeaturesBuilder::Create(
1461 own_address, peer_address));
1462 break;
1463 default:
1464 LOG_INFO("Dropping unhandled command 0x%04x",
1465 static_cast<uint16_t>(opcode));
1466 return ErrorCode::UNKNOWN_HCI_COMMAND;
1467 }
1468
1469 return ErrorCode::SUCCESS;
1470 }
1471
SendCommandToRemoteByAddress(OpCode opcode,bluetooth::packet::PacketView<true> args,const Address & own_address,const Address & peer_address)1472 ErrorCode LinkLayerController::SendCommandToRemoteByAddress(
1473 OpCode opcode, bluetooth::packet::PacketView<true> args,
1474 const Address& own_address, const Address& peer_address) {
1475 switch (opcode) {
1476 case (OpCode::REMOTE_NAME_REQUEST):
1477 // LMP features get requested with remote name requests.
1478 SendLinkLayerPacket(model::packets::ReadRemoteLmpFeaturesBuilder::Create(
1479 own_address, peer_address));
1480 SendLinkLayerPacket(model::packets::RemoteNameRequestBuilder::Create(
1481 own_address, peer_address));
1482 break;
1483 case (OpCode::READ_REMOTE_SUPPORTED_FEATURES):
1484 SendLinkLayerPacket(
1485 model::packets::ReadRemoteSupportedFeaturesBuilder::Create(
1486 own_address, peer_address));
1487 break;
1488 case (OpCode::READ_REMOTE_EXTENDED_FEATURES): {
1489 uint8_t page_number =
1490 (args.begin() + 2).extract<uint8_t>(); // skip the handle
1491 SendLinkLayerPacket(
1492 model::packets::ReadRemoteExtendedFeaturesBuilder::Create(
1493 own_address, peer_address, page_number));
1494 } break;
1495 case (OpCode::READ_REMOTE_VERSION_INFORMATION):
1496 SendLinkLayerPacket(
1497 model::packets::ReadRemoteVersionInformationBuilder::Create(
1498 own_address, peer_address));
1499 break;
1500 case (OpCode::READ_CLOCK_OFFSET):
1501 SendLinkLayerPacket(model::packets::ReadClockOffsetBuilder::Create(
1502 own_address, peer_address));
1503 break;
1504 default:
1505 LOG_INFO("Dropping unhandled command 0x%04x",
1506 static_cast<uint16_t>(opcode));
1507 return ErrorCode::UNKNOWN_HCI_COMMAND;
1508 }
1509
1510 return ErrorCode::SUCCESS;
1511 }
1512
SendCommandToRemoteByHandle(OpCode opcode,bluetooth::packet::PacketView<true> args,uint16_t handle)1513 ErrorCode LinkLayerController::SendCommandToRemoteByHandle(
1514 OpCode opcode, bluetooth::packet::PacketView<true> args, uint16_t handle) {
1515 if (!connections_.HasHandle(handle)) {
1516 return ErrorCode::UNKNOWN_CONNECTION;
1517 }
1518
1519 switch (opcode) {
1520 case (OpCode::LE_READ_REMOTE_FEATURES):
1521 return SendLeCommandToRemoteByAddress(
1522 opcode, connections_.GetOwnAddress(handle).GetAddress(),
1523 connections_.GetAddress(handle).GetAddress());
1524 default:
1525 return SendCommandToRemoteByAddress(
1526 opcode, args, connections_.GetOwnAddress(handle).GetAddress(),
1527 connections_.GetAddress(handle).GetAddress());
1528 }
1529 }
1530
SendAclToRemote(bluetooth::hci::AclView acl_packet)1531 ErrorCode LinkLayerController::SendAclToRemote(
1532 bluetooth::hci::AclView acl_packet) {
1533 uint16_t handle = acl_packet.GetHandle();
1534 if (!connections_.HasHandle(handle)) {
1535 return ErrorCode::UNKNOWN_CONNECTION;
1536 }
1537
1538 AddressWithType my_address = connections_.GetOwnAddress(handle);
1539 AddressWithType destination = connections_.GetAddress(handle);
1540 Phy::Type phy = connections_.GetPhyType(handle);
1541
1542 ScheduleTask(kNoDelayMs, [this, handle]() {
1543 std::vector<bluetooth::hci::CompletedPackets> completed_packets;
1544 bluetooth::hci::CompletedPackets cp;
1545 cp.connection_handle_ = handle;
1546 cp.host_num_of_completed_packets_ = kNumCommandPackets;
1547 completed_packets.push_back(cp);
1548 send_event_(bluetooth::hci::NumberOfCompletedPacketsBuilder::Create(
1549 completed_packets));
1550 });
1551
1552 auto acl_payload = acl_packet.GetPayload();
1553
1554 std::unique_ptr<bluetooth::packet::RawBuilder> raw_builder_ptr =
1555 std::make_unique<bluetooth::packet::RawBuilder>();
1556 std::vector<uint8_t> payload_bytes(acl_payload.begin(), acl_payload.end());
1557
1558 uint16_t first_two_bytes =
1559 static_cast<uint16_t>(acl_packet.GetHandle()) +
1560 (static_cast<uint16_t>(acl_packet.GetPacketBoundaryFlag()) << 12) +
1561 (static_cast<uint16_t>(acl_packet.GetBroadcastFlag()) << 14);
1562 raw_builder_ptr->AddOctets2(first_two_bytes);
1563 raw_builder_ptr->AddOctets2(static_cast<uint16_t>(payload_bytes.size()));
1564 raw_builder_ptr->AddOctets(payload_bytes);
1565
1566 auto acl = model::packets::AclBuilder::Create(my_address.GetAddress(),
1567 destination.GetAddress(),
1568 std::move(raw_builder_ptr));
1569
1570 switch (phy) {
1571 case Phy::Type::BR_EDR:
1572 SendLinkLayerPacket(std::move(acl));
1573 break;
1574 case Phy::Type::LOW_ENERGY:
1575 SendLeLinkLayerPacket(std::move(acl));
1576 break;
1577 }
1578 return ErrorCode::SUCCESS;
1579 }
1580
SendScoToRemote(bluetooth::hci::ScoView sco_packet)1581 ErrorCode LinkLayerController::SendScoToRemote(
1582 bluetooth::hci::ScoView sco_packet) {
1583 uint16_t handle = sco_packet.GetHandle();
1584 if (!connections_.HasScoHandle(handle)) {
1585 return ErrorCode::UNKNOWN_CONNECTION;
1586 }
1587
1588 // TODO: SCO flow control
1589 Address source = GetAddress();
1590 Address destination = connections_.GetScoAddress(handle);
1591
1592 auto sco_data = sco_packet.GetData();
1593 std::vector<uint8_t> sco_data_bytes(sco_data.begin(), sco_data.end());
1594
1595 SendLinkLayerPacket(model::packets::ScoBuilder::Create(
1596 source, destination,
1597 std::make_unique<bluetooth::packet::RawBuilder>(sco_data_bytes)));
1598 return ErrorCode::SUCCESS;
1599 }
1600
IncomingPacket(model::packets::LinkLayerPacketView incoming)1601 void LinkLayerController::IncomingPacket(
1602 model::packets::LinkLayerPacketView incoming) {
1603 ASSERT(incoming.IsValid());
1604 if (incoming.GetType() == PacketType::RSSI_WRAPPER) {
1605 auto rssi_wrapper = model::packets::RssiWrapperView::Create(incoming);
1606 ASSERT(rssi_wrapper.IsValid());
1607 auto wrapped =
1608 model::packets::LinkLayerPacketView::Create(rssi_wrapper.GetPayload());
1609 IncomingPacketWithRssi(wrapped, rssi_wrapper.GetRssi());
1610 } else {
1611 IncomingPacketWithRssi(incoming, GetRssi());
1612 }
1613 }
1614
IncomingPacketWithRssi(model::packets::LinkLayerPacketView incoming,uint8_t rssi)1615 void LinkLayerController::IncomingPacketWithRssi(
1616 model::packets::LinkLayerPacketView incoming, uint8_t rssi) {
1617 ASSERT(incoming.IsValid());
1618 auto destination_address = incoming.GetDestinationAddress();
1619
1620 // Match broadcasts
1621 bool address_matches = (destination_address == Address::kEmpty);
1622
1623 // Address match is performed in specific handlers for these PDU types.
1624 switch (incoming.GetType()) {
1625 case model::packets::PacketType::LE_SCAN:
1626 case model::packets::PacketType::LE_SCAN_RESPONSE:
1627 case model::packets::PacketType::LE_LEGACY_ADVERTISING_PDU:
1628 case model::packets::PacketType::LE_EXTENDED_ADVERTISING_PDU:
1629 case model::packets::PacketType::LE_CONNECT:
1630 address_matches = true;
1631 break;
1632 default:
1633 break;
1634 }
1635
1636 // Check public address
1637 if (destination_address == address_ ||
1638 destination_address == random_address_) {
1639 address_matches = true;
1640 }
1641
1642 // Check current connection address
1643 if (destination_address == initiator_.initiating_address) {
1644 address_matches = true;
1645 }
1646
1647 // Check connection addresses
1648 auto source_address = incoming.GetSourceAddress();
1649 auto handle = connections_.GetHandleOnlyAddress(source_address);
1650 if (handle != kReservedHandle) {
1651 if (connections_.GetOwnAddress(handle).GetAddress() ==
1652 destination_address) {
1653 address_matches = true;
1654
1655 // Update link timeout for valid ACL connections
1656 connections_.ResetLinkTimer(handle);
1657 }
1658 }
1659
1660 // Drop packets not addressed to me
1661 if (!address_matches) {
1662 LOG_INFO("%s | Dropping packet not addressed to me %s->%s (type 0x%x)",
1663 address_.ToString().c_str(), source_address.ToString().c_str(),
1664 destination_address.ToString().c_str(),
1665 static_cast<int>(incoming.GetType()));
1666 return;
1667 }
1668
1669 switch (incoming.GetType()) {
1670 case model::packets::PacketType::ACL:
1671 IncomingAclPacket(incoming);
1672 break;
1673 case model::packets::PacketType::SCO:
1674 IncomingScoPacket(incoming);
1675 break;
1676 case model::packets::PacketType::DISCONNECT:
1677 IncomingDisconnectPacket(incoming);
1678 break;
1679 #ifdef ROOTCANAL_LMP
1680 case model::packets::PacketType::LMP:
1681 IncomingLmpPacket(incoming);
1682 break;
1683 #else
1684 case model::packets::PacketType::ENCRYPT_CONNECTION:
1685 IncomingEncryptConnection(incoming);
1686 break;
1687 case model::packets::PacketType::ENCRYPT_CONNECTION_RESPONSE:
1688 IncomingEncryptConnectionResponse(incoming);
1689 break;
1690 case model::packets::PacketType::IO_CAPABILITY_REQUEST:
1691 IncomingIoCapabilityRequestPacket(incoming);
1692 break;
1693 case model::packets::PacketType::IO_CAPABILITY_RESPONSE:
1694 IncomingIoCapabilityResponsePacket(incoming);
1695 break;
1696 case model::packets::PacketType::IO_CAPABILITY_NEGATIVE_RESPONSE:
1697 IncomingIoCapabilityNegativeResponsePacket(incoming);
1698 break;
1699 case PacketType::KEYPRESS_NOTIFICATION:
1700 IncomingKeypressNotificationPacket(incoming);
1701 break;
1702 case (model::packets::PacketType::PASSKEY):
1703 IncomingPasskeyPacket(incoming);
1704 break;
1705 case (model::packets::PacketType::PASSKEY_FAILED):
1706 IncomingPasskeyFailedPacket(incoming);
1707 break;
1708 case (model::packets::PacketType::PIN_REQUEST):
1709 IncomingPinRequestPacket(incoming);
1710 break;
1711 case (model::packets::PacketType::PIN_RESPONSE):
1712 IncomingPinResponsePacket(incoming);
1713 break;
1714 #endif /* ROOTCANAL_LMP */
1715 case model::packets::PacketType::INQUIRY:
1716 if (inquiry_scan_enable_) {
1717 IncomingInquiryPacket(incoming, rssi);
1718 }
1719 break;
1720 case model::packets::PacketType::INQUIRY_RESPONSE:
1721 IncomingInquiryResponsePacket(incoming);
1722 break;
1723 case PacketType::ISO:
1724 IncomingIsoPacket(incoming);
1725 break;
1726 case PacketType::ISO_CONNECTION_REQUEST:
1727 IncomingIsoConnectionRequestPacket(incoming);
1728 break;
1729 case PacketType::ISO_CONNECTION_RESPONSE:
1730 IncomingIsoConnectionResponsePacket(incoming);
1731 break;
1732 case model::packets::PacketType::LE_LEGACY_ADVERTISING_PDU:
1733 IncomingLeLegacyAdvertisingPdu(incoming, rssi);
1734 return;
1735 case model::packets::PacketType::LE_EXTENDED_ADVERTISING_PDU:
1736 IncomingLeExtendedAdvertisingPdu(incoming, rssi);
1737 return;
1738 case model::packets::PacketType::LE_CONNECT:
1739 IncomingLeConnectPacket(incoming);
1740 break;
1741 case model::packets::PacketType::LE_CONNECT_COMPLETE:
1742 IncomingLeConnectCompletePacket(incoming);
1743 break;
1744 case model::packets::PacketType::LE_CONNECTION_PARAMETER_REQUEST:
1745 IncomingLeConnectionParameterRequest(incoming);
1746 break;
1747 case model::packets::PacketType::LE_CONNECTION_PARAMETER_UPDATE:
1748 IncomingLeConnectionParameterUpdate(incoming);
1749 break;
1750 case model::packets::PacketType::LE_ENCRYPT_CONNECTION:
1751 IncomingLeEncryptConnection(incoming);
1752 break;
1753 case model::packets::PacketType::LE_ENCRYPT_CONNECTION_RESPONSE:
1754 IncomingLeEncryptConnectionResponse(incoming);
1755 break;
1756 case (model::packets::PacketType::LE_READ_REMOTE_FEATURES):
1757 IncomingLeReadRemoteFeatures(incoming);
1758 break;
1759 case (model::packets::PacketType::LE_READ_REMOTE_FEATURES_RESPONSE):
1760 IncomingLeReadRemoteFeaturesResponse(incoming);
1761 break;
1762 case model::packets::PacketType::LE_SCAN:
1763 IncomingLeScanPacket(incoming);
1764 break;
1765 case model::packets::PacketType::LE_SCAN_RESPONSE:
1766 IncomingLeScanResponsePacket(incoming, rssi);
1767 break;
1768 case model::packets::PacketType::PAGE:
1769 if (page_scan_enable_) {
1770 IncomingPagePacket(incoming);
1771 }
1772 break;
1773 case model::packets::PacketType::PAGE_RESPONSE:
1774 IncomingPageResponsePacket(incoming);
1775 break;
1776 case model::packets::PacketType::PAGE_REJECT:
1777 IncomingPageRejectPacket(incoming);
1778 break;
1779 case (model::packets::PacketType::REMOTE_NAME_REQUEST):
1780 IncomingRemoteNameRequest(incoming);
1781 break;
1782 case (model::packets::PacketType::REMOTE_NAME_REQUEST_RESPONSE):
1783 IncomingRemoteNameRequestResponse(incoming);
1784 break;
1785 case (model::packets::PacketType::READ_REMOTE_SUPPORTED_FEATURES):
1786 IncomingReadRemoteSupportedFeatures(incoming);
1787 break;
1788 case (model::packets::PacketType::READ_REMOTE_SUPPORTED_FEATURES_RESPONSE):
1789 IncomingReadRemoteSupportedFeaturesResponse(incoming);
1790 break;
1791 case (model::packets::PacketType::READ_REMOTE_LMP_FEATURES):
1792 IncomingReadRemoteLmpFeatures(incoming);
1793 break;
1794 case (model::packets::PacketType::READ_REMOTE_LMP_FEATURES_RESPONSE):
1795 IncomingReadRemoteLmpFeaturesResponse(incoming);
1796 break;
1797 case (model::packets::PacketType::READ_REMOTE_EXTENDED_FEATURES):
1798 IncomingReadRemoteExtendedFeatures(incoming);
1799 break;
1800 case (model::packets::PacketType::READ_REMOTE_EXTENDED_FEATURES_RESPONSE):
1801 IncomingReadRemoteExtendedFeaturesResponse(incoming);
1802 break;
1803 case (model::packets::PacketType::READ_REMOTE_VERSION_INFORMATION):
1804 IncomingReadRemoteVersion(incoming);
1805 break;
1806 case (model::packets::PacketType::READ_REMOTE_VERSION_INFORMATION_RESPONSE):
1807 IncomingReadRemoteVersionResponse(incoming);
1808 break;
1809 case (model::packets::PacketType::READ_CLOCK_OFFSET):
1810 IncomingReadClockOffset(incoming);
1811 break;
1812 case (model::packets::PacketType::READ_CLOCK_OFFSET_RESPONSE):
1813 IncomingReadClockOffsetResponse(incoming);
1814 break;
1815 case (model::packets::PacketType::RSSI_WRAPPER):
1816 LOG_ERROR("Dropping double-wrapped RSSI packet");
1817 break;
1818 case model::packets::PacketType::SCO_CONNECTION_REQUEST:
1819 IncomingScoConnectionRequest(incoming);
1820 break;
1821 case model::packets::PacketType::SCO_CONNECTION_RESPONSE:
1822 IncomingScoConnectionResponse(incoming);
1823 break;
1824 case model::packets::PacketType::SCO_DISCONNECT:
1825 IncomingScoDisconnect(incoming);
1826 break;
1827 case model::packets::PacketType::PING_REQUEST:
1828 IncomingPingRequest(incoming);
1829 break;
1830 case model::packets::PacketType::PING_RESPONSE:
1831 // ping responses require no action
1832 break;
1833 default:
1834 LOG_WARN("Dropping unhandled packet of type %s",
1835 model::packets::PacketTypeText(incoming.GetType()).c_str());
1836 }
1837 }
1838
IncomingAclPacket(model::packets::LinkLayerPacketView incoming)1839 void LinkLayerController::IncomingAclPacket(
1840 model::packets::LinkLayerPacketView incoming) {
1841 auto acl = model::packets::AclView::Create(incoming);
1842 ASSERT(acl.IsValid());
1843 auto payload = acl.GetPayload();
1844 std::shared_ptr<std::vector<uint8_t>> payload_bytes =
1845 std::make_shared<std::vector<uint8_t>>(payload.begin(), payload.end());
1846
1847 LOG_INFO("Acl Packet [%d] %s -> %s", static_cast<int>(payload_bytes->size()),
1848 incoming.GetSourceAddress().ToString().c_str(),
1849 incoming.GetDestinationAddress().ToString().c_str());
1850
1851 bluetooth::hci::PacketView<bluetooth::hci::kLittleEndian> raw_packet(
1852 payload_bytes);
1853 auto acl_view = bluetooth::hci::AclView::Create(raw_packet);
1854 ASSERT(acl_view.IsValid());
1855
1856 uint16_t local_handle =
1857 connections_.GetHandleOnlyAddress(incoming.GetSourceAddress());
1858
1859 std::vector<uint8_t> payload_data(acl_view.GetPayload().begin(),
1860 acl_view.GetPayload().end());
1861 uint16_t acl_buffer_size = properties_.acl_data_packet_length;
1862 int num_packets =
1863 (payload_data.size() + acl_buffer_size - 1) / acl_buffer_size;
1864
1865 auto pb_flag_controller_to_host = acl_view.GetPacketBoundaryFlag();
1866 if (pb_flag_controller_to_host ==
1867 bluetooth::hci::PacketBoundaryFlag::FIRST_NON_AUTOMATICALLY_FLUSHABLE) {
1868 pb_flag_controller_to_host =
1869 bluetooth::hci::PacketBoundaryFlag::FIRST_AUTOMATICALLY_FLUSHABLE;
1870 }
1871 for (int i = 0; i < num_packets; i++) {
1872 size_t start_index = acl_buffer_size * i;
1873 size_t end_index =
1874 std::min(start_index + acl_buffer_size, payload_data.size());
1875 std::vector<uint8_t> fragment(&payload_data[start_index],
1876 &payload_data[end_index]);
1877 std::unique_ptr<bluetooth::packet::RawBuilder> raw_builder_ptr =
1878 std::make_unique<bluetooth::packet::RawBuilder>(fragment);
1879 auto acl_packet = bluetooth::hci::AclBuilder::Create(
1880 local_handle, pb_flag_controller_to_host, acl_view.GetBroadcastFlag(),
1881 std::move(raw_builder_ptr));
1882 pb_flag_controller_to_host =
1883 bluetooth::hci::PacketBoundaryFlag::CONTINUING_FRAGMENT;
1884
1885 send_acl_(std::move(acl_packet));
1886 }
1887 }
1888
IncomingScoPacket(model::packets::LinkLayerPacketView incoming)1889 void LinkLayerController::IncomingScoPacket(
1890 model::packets::LinkLayerPacketView incoming) {
1891 Address source = incoming.GetSourceAddress();
1892 uint16_t sco_handle = connections_.GetScoHandle(source);
1893 if (!connections_.HasScoHandle(sco_handle)) {
1894 LOG_INFO("Spurious SCO packet from %s", source.ToString().c_str());
1895 return;
1896 }
1897
1898 auto sco = model::packets::ScoView::Create(incoming);
1899 ASSERT(sco.IsValid());
1900 auto sco_data = sco.GetPayload();
1901 std::vector<uint8_t> sco_data_bytes(sco_data.begin(), sco_data.end());
1902
1903 LOG_INFO("Sco Packet [%d] %s -> %s", static_cast<int>(sco_data_bytes.size()),
1904 incoming.GetSourceAddress().ToString().c_str(),
1905 incoming.GetDestinationAddress().ToString().c_str());
1906
1907 send_sco_(bluetooth::hci::ScoBuilder::Create(
1908 sco_handle, bluetooth::hci::PacketStatusFlag::CORRECTLY_RECEIVED,
1909 sco_data_bytes));
1910 }
1911
IncomingRemoteNameRequest(model::packets::LinkLayerPacketView packet)1912 void LinkLayerController::IncomingRemoteNameRequest(
1913 model::packets::LinkLayerPacketView packet) {
1914 auto view = model::packets::RemoteNameRequestView::Create(packet);
1915 ASSERT(view.IsValid());
1916
1917 SendLinkLayerPacket(model::packets::RemoteNameRequestResponseBuilder::Create(
1918 packet.GetDestinationAddress(), packet.GetSourceAddress(), local_name_));
1919 }
1920
IncomingRemoteNameRequestResponse(model::packets::LinkLayerPacketView packet)1921 void LinkLayerController::IncomingRemoteNameRequestResponse(
1922 model::packets::LinkLayerPacketView packet) {
1923 auto view = model::packets::RemoteNameRequestResponseView::Create(packet);
1924 ASSERT(view.IsValid());
1925
1926 if (IsEventUnmasked(EventCode::REMOTE_NAME_REQUEST_COMPLETE)) {
1927 send_event_(bluetooth::hci::RemoteNameRequestCompleteBuilder::Create(
1928 ErrorCode::SUCCESS, packet.GetSourceAddress(), view.GetName()));
1929 }
1930 }
1931
IncomingReadRemoteLmpFeatures(model::packets::LinkLayerPacketView packet)1932 void LinkLayerController::IncomingReadRemoteLmpFeatures(
1933 model::packets::LinkLayerPacketView packet) {
1934 SendLinkLayerPacket(
1935 model::packets::ReadRemoteLmpFeaturesResponseBuilder::Create(
1936 packet.GetDestinationAddress(), packet.GetSourceAddress(),
1937 host_supported_features_));
1938 }
1939
IncomingReadRemoteLmpFeaturesResponse(model::packets::LinkLayerPacketView packet)1940 void LinkLayerController::IncomingReadRemoteLmpFeaturesResponse(
1941 model::packets::LinkLayerPacketView packet) {
1942 auto view = model::packets::ReadRemoteLmpFeaturesResponseView::Create(packet);
1943 ASSERT(view.IsValid());
1944 if (IsEventUnmasked(EventCode::REMOTE_HOST_SUPPORTED_FEATURES_NOTIFICATION)) {
1945 send_event_(
1946 bluetooth::hci::RemoteHostSupportedFeaturesNotificationBuilder::Create(
1947 packet.GetSourceAddress(), view.GetFeatures()));
1948 }
1949 }
1950
IncomingReadRemoteSupportedFeatures(model::packets::LinkLayerPacketView packet)1951 void LinkLayerController::IncomingReadRemoteSupportedFeatures(
1952 model::packets::LinkLayerPacketView packet) {
1953 SendLinkLayerPacket(
1954 model::packets::ReadRemoteSupportedFeaturesResponseBuilder::Create(
1955 packet.GetDestinationAddress(), packet.GetSourceAddress(),
1956 properties_.lmp_features[0]));
1957 }
1958
IncomingReadRemoteSupportedFeaturesResponse(model::packets::LinkLayerPacketView packet)1959 void LinkLayerController::IncomingReadRemoteSupportedFeaturesResponse(
1960 model::packets::LinkLayerPacketView packet) {
1961 auto view =
1962 model::packets::ReadRemoteSupportedFeaturesResponseView::Create(packet);
1963 ASSERT(view.IsValid());
1964 Address source = packet.GetSourceAddress();
1965 uint16_t handle = connections_.GetHandleOnlyAddress(source);
1966 if (handle == kReservedHandle) {
1967 LOG_INFO("Discarding response from a disconnected device %s",
1968 source.ToString().c_str());
1969 return;
1970 }
1971 if (IsEventUnmasked(EventCode::READ_REMOTE_SUPPORTED_FEATURES_COMPLETE)) {
1972 send_event_(
1973 bluetooth::hci::ReadRemoteSupportedFeaturesCompleteBuilder::Create(
1974 ErrorCode::SUCCESS, handle, view.GetFeatures()));
1975 }
1976 }
1977
IncomingReadRemoteExtendedFeatures(model::packets::LinkLayerPacketView packet)1978 void LinkLayerController::IncomingReadRemoteExtendedFeatures(
1979 model::packets::LinkLayerPacketView packet) {
1980 auto view = model::packets::ReadRemoteExtendedFeaturesView::Create(packet);
1981 ASSERT(view.IsValid());
1982 uint8_t page_number = view.GetPageNumber();
1983 uint8_t error_code = static_cast<uint8_t>(ErrorCode::SUCCESS);
1984 if (page_number >= properties_.lmp_features.size()) {
1985 error_code = static_cast<uint8_t>(ErrorCode::INVALID_LMP_OR_LL_PARAMETERS);
1986 }
1987 SendLinkLayerPacket(
1988 model::packets::ReadRemoteExtendedFeaturesResponseBuilder::Create(
1989 packet.GetDestinationAddress(), packet.GetSourceAddress(), error_code,
1990 page_number, GetMaxLmpFeaturesPageNumber(),
1991 GetLmpFeatures(page_number)));
1992 }
1993
IncomingReadRemoteExtendedFeaturesResponse(model::packets::LinkLayerPacketView packet)1994 void LinkLayerController::IncomingReadRemoteExtendedFeaturesResponse(
1995 model::packets::LinkLayerPacketView packet) {
1996 auto view =
1997 model::packets::ReadRemoteExtendedFeaturesResponseView::Create(packet);
1998 ASSERT(view.IsValid());
1999 Address source = packet.GetSourceAddress();
2000 uint16_t handle = connections_.GetHandleOnlyAddress(source);
2001 if (handle == kReservedHandle) {
2002 LOG_INFO("Discarding response from a disconnected device %s",
2003 source.ToString().c_str());
2004 return;
2005 }
2006 if (IsEventUnmasked(EventCode::READ_REMOTE_EXTENDED_FEATURES_COMPLETE)) {
2007 send_event_(
2008 bluetooth::hci::ReadRemoteExtendedFeaturesCompleteBuilder::Create(
2009 static_cast<ErrorCode>(view.GetStatus()), handle,
2010 view.GetPageNumber(), view.GetMaxPageNumber(), view.GetFeatures()));
2011 }
2012 }
2013
IncomingReadRemoteVersion(model::packets::LinkLayerPacketView packet)2014 void LinkLayerController::IncomingReadRemoteVersion(
2015 model::packets::LinkLayerPacketView packet) {
2016 SendLinkLayerPacket(
2017 model::packets::ReadRemoteVersionInformationResponseBuilder::Create(
2018 packet.GetDestinationAddress(), packet.GetSourceAddress(),
2019 static_cast<uint8_t>(properties_.lmp_version),
2020 static_cast<uint16_t>(properties_.lmp_subversion),
2021 properties_.company_identifier));
2022 }
2023
IncomingReadRemoteVersionResponse(model::packets::LinkLayerPacketView packet)2024 void LinkLayerController::IncomingReadRemoteVersionResponse(
2025 model::packets::LinkLayerPacketView packet) {
2026 auto view =
2027 model::packets::ReadRemoteVersionInformationResponseView::Create(packet);
2028 ASSERT(view.IsValid());
2029 Address source = packet.GetSourceAddress();
2030 uint16_t handle = connections_.GetHandleOnlyAddress(source);
2031 if (handle == kReservedHandle) {
2032 LOG_INFO("Discarding response from a disconnected device %s",
2033 source.ToString().c_str());
2034 return;
2035 }
2036 if (IsEventUnmasked(EventCode::READ_REMOTE_VERSION_INFORMATION_COMPLETE)) {
2037 send_event_(
2038 bluetooth::hci::ReadRemoteVersionInformationCompleteBuilder::Create(
2039 ErrorCode::SUCCESS, handle, view.GetLmpVersion(),
2040 view.GetManufacturerName(), view.GetLmpSubversion()));
2041 }
2042 }
2043
IncomingReadClockOffset(model::packets::LinkLayerPacketView packet)2044 void LinkLayerController::IncomingReadClockOffset(
2045 model::packets::LinkLayerPacketView packet) {
2046 SendLinkLayerPacket(model::packets::ReadClockOffsetResponseBuilder::Create(
2047 packet.GetDestinationAddress(), packet.GetSourceAddress(),
2048 GetClockOffset()));
2049 }
2050
IncomingReadClockOffsetResponse(model::packets::LinkLayerPacketView packet)2051 void LinkLayerController::IncomingReadClockOffsetResponse(
2052 model::packets::LinkLayerPacketView packet) {
2053 auto view = model::packets::ReadClockOffsetResponseView::Create(packet);
2054 ASSERT(view.IsValid());
2055 Address source = packet.GetSourceAddress();
2056 uint16_t handle = connections_.GetHandleOnlyAddress(source);
2057 if (handle == kReservedHandle) {
2058 LOG_INFO("Discarding response from a disconnected device %s",
2059 source.ToString().c_str());
2060 return;
2061 }
2062 if (IsEventUnmasked(EventCode::READ_CLOCK_OFFSET_COMPLETE)) {
2063 send_event_(bluetooth::hci::ReadClockOffsetCompleteBuilder::Create(
2064 ErrorCode::SUCCESS, handle, view.GetOffset()));
2065 }
2066 }
2067
IncomingDisconnectPacket(model::packets::LinkLayerPacketView incoming)2068 void LinkLayerController::IncomingDisconnectPacket(
2069 model::packets::LinkLayerPacketView incoming) {
2070 LOG_INFO("Disconnect Packet");
2071 auto disconnect = model::packets::DisconnectView::Create(incoming);
2072 ASSERT(disconnect.IsValid());
2073
2074 Address peer = incoming.GetSourceAddress();
2075 uint16_t handle = connections_.GetHandleOnlyAddress(peer);
2076 if (handle == kReservedHandle) {
2077 LOG_INFO("Discarding disconnect from a disconnected device %s",
2078 peer.ToString().c_str());
2079 return;
2080 }
2081 #ifdef ROOTCANAL_LMP
2082 auto is_br_edr = connections_.GetPhyType(handle) == Phy::Type::BR_EDR;
2083 #endif
2084 ASSERT_LOG(connections_.Disconnect(handle, cancel_task_),
2085 "GetHandle() returned invalid handle %hx", handle);
2086
2087 uint8_t reason = disconnect.GetReason();
2088 SendDisconnectionCompleteEvent(handle, ErrorCode(reason));
2089 #ifdef ROOTCANAL_LMP
2090 if (is_br_edr) {
2091 ASSERT(link_manager_remove_link(
2092 lm_.get(), reinterpret_cast<uint8_t(*)[6]>(peer.data())));
2093 }
2094 #endif
2095 }
2096
2097 #ifndef ROOTCANAL_LMP
IncomingEncryptConnection(model::packets::LinkLayerPacketView incoming)2098 void LinkLayerController::IncomingEncryptConnection(
2099 model::packets::LinkLayerPacketView incoming) {
2100 LOG_INFO("IncomingEncryptConnection");
2101
2102 // TODO: Check keys
2103 Address peer = incoming.GetSourceAddress();
2104 uint16_t handle = connections_.GetHandleOnlyAddress(peer);
2105 if (handle == kReservedHandle) {
2106 LOG_INFO("Unknown connection @%s", peer.ToString().c_str());
2107 return;
2108 }
2109 if (IsEventUnmasked(EventCode::ENCRYPTION_CHANGE)) {
2110 send_event_(bluetooth::hci::EncryptionChangeBuilder::Create(
2111 ErrorCode::SUCCESS, handle, bluetooth::hci::EncryptionEnabled::ON));
2112 }
2113
2114 uint16_t count = security_manager_.ReadKey(peer);
2115 if (count == 0) {
2116 LOG_ERROR("NO KEY HERE for %s", peer.ToString().c_str());
2117 return;
2118 }
2119 auto array = security_manager_.GetKey(peer);
2120 std::vector<uint8_t> key_vec{array.begin(), array.end()};
2121 SendLinkLayerPacket(model::packets::EncryptConnectionResponseBuilder::Create(
2122 GetAddress(), peer, key_vec));
2123 }
2124
IncomingEncryptConnectionResponse(model::packets::LinkLayerPacketView incoming)2125 void LinkLayerController::IncomingEncryptConnectionResponse(
2126 model::packets::LinkLayerPacketView incoming) {
2127 LOG_INFO("IncomingEncryptConnectionResponse");
2128 // TODO: Check keys
2129 uint16_t handle =
2130 connections_.GetHandleOnlyAddress(incoming.GetSourceAddress());
2131 if (handle == kReservedHandle) {
2132 LOG_INFO("Unknown connection @%s",
2133 incoming.GetSourceAddress().ToString().c_str());
2134 return;
2135 }
2136 if (IsEventUnmasked(EventCode::ENCRYPTION_CHANGE)) {
2137 send_event_(bluetooth::hci::EncryptionChangeBuilder::Create(
2138 ErrorCode::SUCCESS, handle, bluetooth::hci::EncryptionEnabled::ON));
2139 }
2140 }
2141 #endif /* !ROOTCANAL_LMP */
2142
IncomingInquiryPacket(model::packets::LinkLayerPacketView incoming,uint8_t rssi)2143 void LinkLayerController::IncomingInquiryPacket(
2144 model::packets::LinkLayerPacketView incoming, uint8_t rssi) {
2145 auto inquiry = model::packets::InquiryView::Create(incoming);
2146 ASSERT(inquiry.IsValid());
2147
2148 Address peer = incoming.GetSourceAddress();
2149 uint8_t lap = inquiry.GetLap();
2150
2151 // Filter out inquiry packets with IAC not present in the
2152 // list Current_IAC_LAP.
2153 if (std::none_of(current_iac_lap_list_.cbegin(), current_iac_lap_list_.cend(),
2154 [lap](auto iac_lap) { return iac_lap.lap_ == lap; })) {
2155 return;
2156 }
2157
2158 switch (inquiry.GetInquiryType()) {
2159 case (model::packets::InquiryType::STANDARD): {
2160 SendLinkLayerPacket(model::packets::InquiryResponseBuilder::Create(
2161 GetAddress(), peer, static_cast<uint8_t>(GetPageScanRepetitionMode()),
2162 class_of_device_, GetClockOffset()));
2163 } break;
2164 case (model::packets::InquiryType::RSSI): {
2165 SendLinkLayerPacket(
2166 model::packets::InquiryResponseWithRssiBuilder::Create(
2167 GetAddress(), peer,
2168 static_cast<uint8_t>(GetPageScanRepetitionMode()),
2169 class_of_device_, GetClockOffset(), rssi));
2170 } break;
2171 case (model::packets::InquiryType::EXTENDED): {
2172 SendLinkLayerPacket(
2173 model::packets::ExtendedInquiryResponseBuilder::Create(
2174 GetAddress(), peer,
2175 static_cast<uint8_t>(GetPageScanRepetitionMode()),
2176 class_of_device_, GetClockOffset(), rssi,
2177 extended_inquiry_response_));
2178
2179 } break;
2180 default:
2181 LOG_WARN("Unhandled Incoming Inquiry of type %d",
2182 static_cast<int>(inquiry.GetType()));
2183 return;
2184 }
2185 // TODO: Send an Inquiry Response Notification Event 7.7.74
2186 }
2187
IncomingInquiryResponsePacket(model::packets::LinkLayerPacketView incoming)2188 void LinkLayerController::IncomingInquiryResponsePacket(
2189 model::packets::LinkLayerPacketView incoming) {
2190 auto basic_inquiry_response =
2191 model::packets::BasicInquiryResponseView::Create(incoming);
2192 ASSERT(basic_inquiry_response.IsValid());
2193 std::vector<uint8_t> eir;
2194
2195 switch (basic_inquiry_response.GetInquiryType()) {
2196 case (model::packets::InquiryType::STANDARD): {
2197 // TODO: Support multiple inquiries in the same packet.
2198 auto inquiry_response =
2199 model::packets::InquiryResponseView::Create(basic_inquiry_response);
2200 ASSERT(inquiry_response.IsValid());
2201
2202 auto page_scan_repetition_mode =
2203 (bluetooth::hci::PageScanRepetitionMode)
2204 inquiry_response.GetPageScanRepetitionMode();
2205
2206 std::vector<bluetooth::hci::InquiryResponse> responses;
2207 responses.emplace_back();
2208 responses.back().bd_addr_ = inquiry_response.GetSourceAddress();
2209 responses.back().page_scan_repetition_mode_ = page_scan_repetition_mode;
2210 responses.back().class_of_device_ = inquiry_response.GetClassOfDevice();
2211 responses.back().clock_offset_ = inquiry_response.GetClockOffset();
2212 if (IsEventUnmasked(EventCode::INQUIRY_RESULT)) {
2213 send_event_(bluetooth::hci::InquiryResultBuilder::Create(responses));
2214 }
2215 } break;
2216
2217 case (model::packets::InquiryType::RSSI): {
2218 auto inquiry_response =
2219 model::packets::InquiryResponseWithRssiView::Create(
2220 basic_inquiry_response);
2221 ASSERT(inquiry_response.IsValid());
2222
2223 auto page_scan_repetition_mode =
2224 (bluetooth::hci::PageScanRepetitionMode)
2225 inquiry_response.GetPageScanRepetitionMode();
2226
2227 std::vector<bluetooth::hci::InquiryResponseWithRssi> responses;
2228 responses.emplace_back();
2229 responses.back().address_ = inquiry_response.GetSourceAddress();
2230 responses.back().page_scan_repetition_mode_ = page_scan_repetition_mode;
2231 responses.back().class_of_device_ = inquiry_response.GetClassOfDevice();
2232 responses.back().clock_offset_ = inquiry_response.GetClockOffset();
2233 responses.back().rssi_ = inquiry_response.GetRssi();
2234 if (IsEventUnmasked(EventCode::INQUIRY_RESULT_WITH_RSSI)) {
2235 send_event_(
2236 bluetooth::hci::InquiryResultWithRssiBuilder::Create(responses));
2237 }
2238 } break;
2239
2240 case (model::packets::InquiryType::EXTENDED): {
2241 auto inquiry_response =
2242 model::packets::ExtendedInquiryResponseView::Create(
2243 basic_inquiry_response);
2244 ASSERT(inquiry_response.IsValid());
2245
2246 send_event_(bluetooth::hci::ExtendedInquiryResultRawBuilder::Create(
2247 inquiry_response.GetSourceAddress(),
2248 static_cast<bluetooth::hci::PageScanRepetitionMode>(
2249 inquiry_response.GetPageScanRepetitionMode()),
2250 inquiry_response.GetClassOfDevice(),
2251 inquiry_response.GetClockOffset(), inquiry_response.GetRssi(),
2252 std::vector<uint8_t>(extended_inquiry_response_.begin(),
2253 extended_inquiry_response_.end())));
2254 } break;
2255 default:
2256 LOG_WARN("Unhandled Incoming Inquiry Response of type %d",
2257 static_cast<int>(basic_inquiry_response.GetInquiryType()));
2258 }
2259 }
2260
2261 #ifndef ROOTCANAL_LMP
IncomingIoCapabilityRequestPacket(model::packets::LinkLayerPacketView incoming)2262 void LinkLayerController::IncomingIoCapabilityRequestPacket(
2263 model::packets::LinkLayerPacketView incoming) {
2264 Address peer = incoming.GetSourceAddress();
2265 uint16_t handle = connections_.GetHandle(AddressWithType(
2266 peer, bluetooth::hci::AddressType::PUBLIC_DEVICE_ADDRESS));
2267 if (handle == kReservedHandle) {
2268 LOG_INFO("Device not connected %s", peer.ToString().c_str());
2269 return;
2270 }
2271
2272 if (!secure_simple_pairing_host_support_) {
2273 LOG_WARN("Trying PIN pairing for %s",
2274 incoming.GetDestinationAddress().ToString().c_str());
2275 SendLinkLayerPacket(
2276 model::packets::IoCapabilityNegativeResponseBuilder::Create(
2277 incoming.GetDestinationAddress(), incoming.GetSourceAddress(),
2278 static_cast<uint8_t>(
2279 ErrorCode::UNSUPPORTED_REMOTE_OR_LMP_FEATURE)));
2280 if (!security_manager_.AuthenticationInProgress()) {
2281 security_manager_.AuthenticationRequest(incoming.GetSourceAddress(),
2282 handle, false);
2283 }
2284 security_manager_.SetPinRequested(peer);
2285 if (IsEventUnmasked(EventCode::PIN_CODE_REQUEST)) {
2286 send_event_(bluetooth::hci::PinCodeRequestBuilder::Create(
2287 incoming.GetSourceAddress()));
2288 }
2289 return;
2290 }
2291
2292 auto request = model::packets::IoCapabilityRequestView::Create(incoming);
2293 ASSERT(request.IsValid());
2294
2295 uint8_t io_capability = request.GetIoCapability();
2296 uint8_t oob_data_present = request.GetOobDataPresent();
2297 uint8_t authentication_requirements = request.GetAuthenticationRequirements();
2298
2299 if (IsEventUnmasked(EventCode::IO_CAPABILITY_RESPONSE)) {
2300 send_event_(bluetooth::hci::IoCapabilityResponseBuilder::Create(
2301 peer, static_cast<bluetooth::hci::IoCapability>(io_capability),
2302 static_cast<bluetooth::hci::OobDataPresent>(oob_data_present),
2303 static_cast<bluetooth::hci::AuthenticationRequirements>(
2304 authentication_requirements)));
2305 }
2306
2307 bool pairing_started = security_manager_.AuthenticationInProgress();
2308 if (!pairing_started) {
2309 security_manager_.AuthenticationRequest(peer, handle, false);
2310 StartSimplePairing(peer);
2311 }
2312
2313 security_manager_.SetPeerIoCapability(peer, io_capability, oob_data_present,
2314 authentication_requirements);
2315 if (pairing_started) {
2316 PairingType pairing_type = security_manager_.GetSimplePairingType();
2317 if (pairing_type != PairingType::INVALID) {
2318 ScheduleTask(kNoDelayMs, [this, peer, pairing_type]() {
2319 AuthenticateRemoteStage1(peer, pairing_type);
2320 });
2321 } else {
2322 LOG_INFO("Security Manager returned INVALID");
2323 }
2324 }
2325 }
2326
IncomingIoCapabilityResponsePacket(model::packets::LinkLayerPacketView incoming)2327 void LinkLayerController::IncomingIoCapabilityResponsePacket(
2328 model::packets::LinkLayerPacketView incoming) {
2329 auto response = model::packets::IoCapabilityResponseView::Create(incoming);
2330 ASSERT(response.IsValid());
2331 if (!secure_simple_pairing_host_support_) {
2332 LOG_WARN("Only simple pairing mode is implemented");
2333 SendLinkLayerPacket(
2334 model::packets::IoCapabilityNegativeResponseBuilder::Create(
2335 incoming.GetDestinationAddress(), incoming.GetSourceAddress(),
2336 static_cast<uint8_t>(
2337 ErrorCode::UNSUPPORTED_REMOTE_OR_LMP_FEATURE)));
2338 return;
2339 }
2340
2341 Address peer = incoming.GetSourceAddress();
2342 uint8_t io_capability = response.GetIoCapability();
2343 uint8_t oob_data_present = response.GetOobDataPresent();
2344 uint8_t authentication_requirements =
2345 response.GetAuthenticationRequirements();
2346
2347 security_manager_.SetPeerIoCapability(peer, io_capability, oob_data_present,
2348 authentication_requirements);
2349
2350 if (IsEventUnmasked(EventCode::IO_CAPABILITY_RESPONSE)) {
2351 send_event_(bluetooth::hci::IoCapabilityResponseBuilder::Create(
2352 peer, static_cast<bluetooth::hci::IoCapability>(io_capability),
2353 static_cast<bluetooth::hci::OobDataPresent>(oob_data_present),
2354 static_cast<bluetooth::hci::AuthenticationRequirements>(
2355 authentication_requirements)));
2356 }
2357
2358 PairingType pairing_type = security_manager_.GetSimplePairingType();
2359 if (pairing_type != PairingType::INVALID) {
2360 ScheduleTask(kNoDelayMs, [this, peer, pairing_type]() {
2361 AuthenticateRemoteStage1(peer, pairing_type);
2362 });
2363 } else {
2364 LOG_INFO("Security Manager returned INVALID");
2365 }
2366 }
2367
IncomingIoCapabilityNegativeResponsePacket(model::packets::LinkLayerPacketView incoming)2368 void LinkLayerController::IncomingIoCapabilityNegativeResponsePacket(
2369 model::packets::LinkLayerPacketView incoming) {
2370 Address peer = incoming.GetSourceAddress();
2371
2372 ASSERT(security_manager_.GetAuthenticationAddress() == peer);
2373
2374 security_manager_.InvalidateIoCapabilities();
2375 LOG_INFO("%s doesn't support SSP, try PIN",
2376 incoming.GetSourceAddress().ToString().c_str());
2377 security_manager_.SetPinRequested(peer);
2378 if (IsEventUnmasked(EventCode::PIN_CODE_REQUEST)) {
2379 send_event_(bluetooth::hci::PinCodeRequestBuilder::Create(
2380 incoming.GetSourceAddress()));
2381 }
2382 }
2383 #endif /* !ROOTCANAL_LMP */
2384
IncomingIsoPacket(LinkLayerPacketView incoming)2385 void LinkLayerController::IncomingIsoPacket(LinkLayerPacketView incoming) {
2386 auto iso = IsoDataPacketView::Create(incoming);
2387 ASSERT(iso.IsValid());
2388
2389 uint16_t cis_handle = iso.GetHandle();
2390 if (!connections_.HasCisHandle(cis_handle)) {
2391 LOG_INFO("Dropping ISO packet to unknown handle 0x%hx", cis_handle);
2392 return;
2393 }
2394 if (!connections_.HasConnectedCis(cis_handle)) {
2395 LOG_INFO("Dropping ISO packet to a disconnected handle 0x%hx", cis_handle);
2396 return;
2397 }
2398
2399 auto sc = iso.GetSc();
2400 switch (sc) {
2401 case StartContinuation::START: {
2402 auto iso_start = IsoStartView::Create(iso);
2403 ASSERT(iso_start.IsValid());
2404 if (iso.GetCmplt() == Complete::COMPLETE) {
2405 send_iso_(bluetooth::hci::IsoWithoutTimestampBuilder::Create(
2406 cis_handle, bluetooth::hci::IsoPacketBoundaryFlag::COMPLETE_SDU,
2407 0 /* seq num */, bluetooth::hci::IsoPacketStatusFlag::VALID,
2408 std::make_unique<bluetooth::packet::RawBuilder>(
2409 std::vector<uint8_t>(iso_start.GetPayload().begin(),
2410 iso_start.GetPayload().end()))));
2411 } else {
2412 send_iso_(bluetooth::hci::IsoWithoutTimestampBuilder::Create(
2413 cis_handle, bluetooth::hci::IsoPacketBoundaryFlag::FIRST_FRAGMENT,
2414 0 /* seq num */, bluetooth::hci::IsoPacketStatusFlag::VALID,
2415 std::make_unique<bluetooth::packet::RawBuilder>(
2416 std::vector<uint8_t>(iso_start.GetPayload().begin(),
2417 iso_start.GetPayload().end()))));
2418 }
2419 } break;
2420 case StartContinuation::CONTINUATION: {
2421 auto continuation = IsoContinuationView::Create(iso);
2422 ASSERT(continuation.IsValid());
2423 if (iso.GetCmplt() == Complete::COMPLETE) {
2424 send_iso_(bluetooth::hci::IsoWithoutTimestampBuilder::Create(
2425 cis_handle, bluetooth::hci::IsoPacketBoundaryFlag::LAST_FRAGMENT,
2426 0 /* seq num */, bluetooth::hci::IsoPacketStatusFlag::VALID,
2427 std::make_unique<bluetooth::packet::RawBuilder>(
2428 std::vector<uint8_t>(continuation.GetPayload().begin(),
2429 continuation.GetPayload().end()))));
2430 } else {
2431 send_iso_(bluetooth::hci::IsoWithoutTimestampBuilder::Create(
2432 cis_handle,
2433 bluetooth::hci::IsoPacketBoundaryFlag::CONTINUATION_FRAGMENT,
2434 0 /* seq num */, bluetooth::hci::IsoPacketStatusFlag::VALID,
2435 std::make_unique<bluetooth::packet::RawBuilder>(
2436 std::vector<uint8_t>(continuation.GetPayload().begin(),
2437 continuation.GetPayload().end()))));
2438 }
2439 } break;
2440 }
2441 }
2442
HandleIso(bluetooth::hci::IsoView iso)2443 void LinkLayerController::HandleIso(bluetooth::hci::IsoView iso) {
2444 auto cis_handle = iso.GetConnectionHandle();
2445 if (!connections_.HasCisHandle(cis_handle)) {
2446 LOG_INFO("Dropping ISO packet to unknown handle 0x%hx", cis_handle);
2447 return;
2448 }
2449 if (!connections_.HasConnectedCis(cis_handle)) {
2450 LOG_INFO("Dropping ISO packet to disconnected handle 0x%hx", cis_handle);
2451 return;
2452 }
2453
2454 auto acl_handle = connections_.GetAclHandleForCisHandle(cis_handle);
2455 uint16_t remote_handle =
2456 connections_.GetRemoteCisHandleForCisHandle(cis_handle);
2457 model::packets::StartContinuation start_flag =
2458 model::packets::StartContinuation::START;
2459 model::packets::Complete complete_flag = model::packets::Complete::COMPLETE;
2460 switch (iso.GetPbFlag()) {
2461 case bluetooth::hci::IsoPacketBoundaryFlag::COMPLETE_SDU:
2462 start_flag = model::packets::StartContinuation::START;
2463 complete_flag = model::packets::Complete::COMPLETE;
2464 break;
2465 case bluetooth::hci::IsoPacketBoundaryFlag::CONTINUATION_FRAGMENT:
2466 start_flag = model::packets::StartContinuation::CONTINUATION;
2467 complete_flag = model::packets::Complete::INCOMPLETE;
2468 break;
2469 case bluetooth::hci::IsoPacketBoundaryFlag::FIRST_FRAGMENT:
2470 start_flag = model::packets::StartContinuation::START;
2471 complete_flag = model::packets::Complete::INCOMPLETE;
2472 break;
2473 case bluetooth::hci::IsoPacketBoundaryFlag::LAST_FRAGMENT:
2474 start_flag = model::packets::StartContinuation::CONTINUATION;
2475 complete_flag = model::packets::Complete::INCOMPLETE;
2476 break;
2477 }
2478 if (start_flag == model::packets::StartContinuation::START) {
2479 if (iso.GetTsFlag() == bluetooth::hci::TimeStampFlag::PRESENT) {
2480 auto timestamped = bluetooth::hci::IsoWithTimestampView::Create(iso);
2481 ASSERT(timestamped.IsValid());
2482 uint32_t timestamp = timestamped.GetTimeStamp();
2483 std::unique_ptr<bluetooth::packet::RawBuilder> payload =
2484 std::make_unique<bluetooth::packet::RawBuilder>();
2485 for (const auto it : timestamped.GetPayload()) {
2486 payload->AddOctets1(it);
2487 }
2488
2489 SendLeLinkLayerPacket(model::packets::IsoStartBuilder::Create(
2490 connections_.GetOwnAddress(acl_handle).GetAddress(),
2491 connections_.GetAddress(acl_handle).GetAddress(), remote_handle,
2492 complete_flag, timestamp, std::move(payload)));
2493 } else {
2494 auto pkt = bluetooth::hci::IsoWithoutTimestampView::Create(iso);
2495 ASSERT(pkt.IsValid());
2496
2497 auto payload =
2498 std::make_unique<bluetooth::packet::RawBuilder>(std::vector<uint8_t>(
2499 pkt.GetPayload().begin(), pkt.GetPayload().end()));
2500
2501 SendLeLinkLayerPacket(model::packets::IsoStartBuilder::Create(
2502 connections_.GetOwnAddress(acl_handle).GetAddress(),
2503 connections_.GetAddress(acl_handle).GetAddress(), remote_handle,
2504 complete_flag, 0, std::move(payload)));
2505 }
2506 } else {
2507 auto pkt = bluetooth::hci::IsoWithoutTimestampView::Create(iso);
2508 ASSERT(pkt.IsValid());
2509 std::unique_ptr<bluetooth::packet::RawBuilder> payload =
2510 std::make_unique<bluetooth::packet::RawBuilder>(std::vector<uint8_t>(
2511 pkt.GetPayload().begin(), pkt.GetPayload().end()));
2512 SendLeLinkLayerPacket(model::packets::IsoContinuationBuilder::Create(
2513 connections_.GetOwnAddress(acl_handle).GetAddress(),
2514 connections_.GetAddress(acl_handle).GetAddress(), remote_handle,
2515 complete_flag, std::move(payload)));
2516 }
2517 }
2518
IncomingIsoConnectionRequestPacket(LinkLayerPacketView incoming)2519 void LinkLayerController::IncomingIsoConnectionRequestPacket(
2520 LinkLayerPacketView incoming) {
2521 auto req = IsoConnectionRequestView::Create(incoming);
2522 ASSERT(req.IsValid());
2523 std::vector<bluetooth::hci::CisParametersConfig> stream_configs;
2524 bluetooth::hci::CisParametersConfig stream_config;
2525
2526 stream_config.max_sdu_m_to_s_ = req.GetMaxSduMToS();
2527 stream_config.max_sdu_s_to_m_ = req.GetMaxSduSToM();
2528
2529 stream_configs.push_back(stream_config);
2530
2531 uint8_t group_id = req.GetCigId();
2532
2533 /* CIG should be created by the local host before use */
2534 bluetooth::hci::CreateCisConfig config;
2535 config.cis_connection_handle_ = req.GetRequesterCisHandle();
2536
2537 config.acl_connection_handle_ =
2538 connections_.GetHandleOnlyAddress(incoming.GetSourceAddress());
2539 connections_.CreatePendingCis(config);
2540 connections_.SetRemoteCisHandle(config.cis_connection_handle_,
2541 req.GetRequesterCisHandle());
2542 if (IsEventUnmasked(EventCode::LE_META_EVENT)) {
2543 send_event_(bluetooth::hci::LeCisRequestBuilder::Create(
2544 config.acl_connection_handle_, config.cis_connection_handle_, group_id,
2545 req.GetId()));
2546 }
2547 }
2548
IncomingIsoConnectionResponsePacket(LinkLayerPacketView incoming)2549 void LinkLayerController::IncomingIsoConnectionResponsePacket(
2550 LinkLayerPacketView incoming) {
2551 auto response = IsoConnectionResponseView::Create(incoming);
2552 ASSERT(response.IsValid());
2553
2554 bluetooth::hci::CreateCisConfig config;
2555 config.acl_connection_handle_ = response.GetRequesterAclHandle();
2556 config.cis_connection_handle_ = response.GetRequesterCisHandle();
2557 if (!connections_.HasPendingCisConnection(config.cis_connection_handle_)) {
2558 LOG_INFO("Ignoring connection response with unknown CIS handle 0x%04hx",
2559 config.cis_connection_handle_);
2560 return;
2561 }
2562 ErrorCode status = static_cast<ErrorCode>(response.GetStatus());
2563 if (status != ErrorCode::SUCCESS) {
2564 if (IsEventUnmasked(EventCode::LE_META_EVENT)) {
2565 send_event_(bluetooth::hci::LeCisEstablishedBuilder::Create(
2566 status, config.cis_connection_handle_, 0, 0, 0, 0,
2567 bluetooth::hci::SecondaryPhyType::NO_PACKETS,
2568 bluetooth::hci::SecondaryPhyType::NO_PACKETS, 0, 0, 0, 0, 0, 0, 0,
2569 0));
2570 }
2571 return;
2572 }
2573 connections_.SetRemoteCisHandle(config.cis_connection_handle_,
2574 response.GetResponderCisHandle());
2575 connections_.ConnectCis(config.cis_connection_handle_);
2576 auto stream_parameters =
2577 connections_.GetStreamParameters(config.cis_connection_handle_);
2578 auto group_parameters =
2579 connections_.GetGroupParameters(stream_parameters.group_id);
2580 // TODO: Which of these are important enough to fake?
2581 uint32_t cig_sync_delay = 0x100;
2582 uint32_t cis_sync_delay = 0x200;
2583 uint32_t latency_m_to_s = group_parameters.max_transport_latency_m_to_s;
2584 uint32_t latency_s_to_m = group_parameters.max_transport_latency_s_to_m;
2585 uint8_t nse = 1;
2586 uint8_t bn_m_to_s = 0;
2587 uint8_t bn_s_to_m = 0;
2588 uint8_t ft_m_to_s = 0;
2589 uint8_t ft_s_to_m = 0;
2590 uint8_t max_pdu_m_to_s = 0x40;
2591 uint8_t max_pdu_s_to_m = 0x40;
2592 uint16_t iso_interval = 0x100;
2593 if (IsEventUnmasked(EventCode::LE_META_EVENT)) {
2594 send_event_(bluetooth::hci::LeCisEstablishedBuilder::Create(
2595 status, config.cis_connection_handle_, cig_sync_delay, cis_sync_delay,
2596 latency_m_to_s, latency_s_to_m,
2597 bluetooth::hci::SecondaryPhyType::NO_PACKETS,
2598 bluetooth::hci::SecondaryPhyType::NO_PACKETS, nse, bn_m_to_s, bn_s_to_m,
2599 ft_m_to_s, ft_s_to_m, max_pdu_m_to_s, max_pdu_s_to_m, iso_interval));
2600 }
2601 }
2602
2603 #ifndef ROOTCANAL_LMP
IncomingKeypressNotificationPacket(model::packets::LinkLayerPacketView incoming)2604 void LinkLayerController::IncomingKeypressNotificationPacket(
2605 model::packets::LinkLayerPacketView incoming) {
2606 auto keypress = model::packets::KeypressNotificationView::Create(incoming);
2607 ASSERT(keypress.IsValid());
2608 auto notification_type = keypress.GetNotificationType();
2609 if (notification_type >
2610 model::packets::PasskeyNotificationType::ENTRY_COMPLETED) {
2611 LOG_WARN("Dropping unknown notification type %d",
2612 static_cast<int>(notification_type));
2613 return;
2614 }
2615 if (IsEventUnmasked(EventCode::KEYPRESS_NOTIFICATION)) {
2616 send_event_(bluetooth::hci::KeypressNotificationBuilder::Create(
2617 incoming.GetSourceAddress(),
2618 static_cast<bluetooth::hci::KeypressNotificationType>(
2619 notification_type)));
2620 }
2621 }
2622 #endif /* !ROOTCANAL_LMP */
2623
generate_rpa(std::array<uint8_t,LinkLayerController::kIrkSize> irk)2624 static Address generate_rpa(
2625 std::array<uint8_t, LinkLayerController::kIrkSize> irk) {
2626 // most significant bit, bit7, bit6 is 01 to be resolvable random
2627 // Bits of the random part of prand shall not be all 1 or all 0
2628 std::array<uint8_t, 3> prand;
2629 prand[0] = std::rand();
2630 prand[1] = std::rand();
2631 prand[2] = std::rand();
2632
2633 constexpr uint8_t BLE_RESOLVE_ADDR_MSB = 0x40;
2634 prand[2] &= ~0xC0; // BLE Address mask
2635 if ((prand[0] == 0x00 && prand[1] == 0x00 && prand[2] == 0x00) ||
2636 (prand[0] == 0xFF && prand[1] == 0xFF && prand[2] == 0x3F)) {
2637 prand[0] = (uint8_t)(std::rand() % 0xFE + 1);
2638 }
2639 prand[2] |= BLE_RESOLVE_ADDR_MSB;
2640
2641 Address rpa;
2642 rpa.address[3] = prand[0];
2643 rpa.address[4] = prand[1];
2644 rpa.address[5] = prand[2];
2645
2646 /* encrypt with IRK */
2647 bluetooth::crypto_toolbox::Octet16 p =
2648 bluetooth::crypto_toolbox::aes_128(irk, prand.data(), 3);
2649
2650 /* set hash to be LSB of rpAddress */
2651 rpa.address[0] = p[0];
2652 rpa.address[1] = p[1];
2653 rpa.address[2] = p[2];
2654 LOG_INFO("RPA %s", rpa.ToString().c_str());
2655 return rpa;
2656 }
2657
2658 // Handle legacy advertising PDUs while in the Scanning state.
ScanIncomingLeLegacyAdvertisingPdu(model::packets::LeLegacyAdvertisingPduView & pdu,uint8_t rssi)2659 void LinkLayerController::ScanIncomingLeLegacyAdvertisingPdu(
2660 model::packets::LeLegacyAdvertisingPduView& pdu, uint8_t rssi) {
2661 if (!scanner_.IsEnabled()) {
2662 return;
2663 }
2664
2665 auto advertising_type = pdu.GetAdvertisingType();
2666 std::vector<uint8_t> advertising_data = pdu.GetAdvertisingData();
2667
2668 AddressWithType advertising_address{
2669 pdu.GetSourceAddress(),
2670 static_cast<AddressType>(pdu.GetAdvertisingAddressType())};
2671
2672 AddressWithType target_address{
2673 pdu.GetDestinationAddress(),
2674 static_cast<AddressType>(pdu.GetTargetAddressType())};
2675
2676 bool scannable_advertising =
2677 advertising_type == model::packets::LegacyAdvertisingType::ADV_IND ||
2678 advertising_type == model::packets::LegacyAdvertisingType::ADV_SCAN_IND;
2679
2680 bool directed_advertising =
2681 advertising_type == model::packets::LegacyAdvertisingType::ADV_DIRECT_IND;
2682
2683 bool connectable_advertising =
2684 advertising_type == model::packets::LegacyAdvertisingType::ADV_IND ||
2685 advertising_type == model::packets::LegacyAdvertisingType::ADV_DIRECT_IND;
2686
2687 // TODO: check originating PHY, compare against active scanning PHYs
2688 // (scanner_.le_1m_phy or scanner_.le_coded_phy).
2689
2690 // When a scanner receives an advertising packet that contains a resolvable
2691 // private address for the advertiser’s device address (AdvA field) and
2692 // address resolution is enabled, the Link Layer shall resolve the private
2693 // address. The scanner’s filter policy shall then determine if the scanner
2694 // responds with a scan request.
2695 AddressWithType resolved_advertising_address =
2696 ResolvePrivateAddress(advertising_address, IrkSelection::Peer)
2697 .value_or(advertising_address);
2698
2699 std::optional<AddressWithType> resolved_target_address =
2700 ResolvePrivateAddress(target_address, IrkSelection::Peer);
2701
2702 if (resolved_advertising_address != advertising_address) {
2703 LOG_VERB("Resolved the advertising address %s(%hhx) to %s(%hhx)",
2704 advertising_address.ToString().c_str(),
2705 advertising_address.GetAddressType(),
2706 resolved_advertising_address.ToString().c_str(),
2707 resolved_advertising_address.GetAddressType());
2708 }
2709
2710 // Vol 6, Part B § 4.3.3 Scanner filter policy
2711 switch (scanner_.scan_filter_policy) {
2712 case bluetooth::hci::LeScanningFilterPolicy::ACCEPT_ALL:
2713 case bluetooth::hci::LeScanningFilterPolicy::CHECK_INITIATORS_IDENTITY:
2714 break;
2715 case bluetooth::hci::LeScanningFilterPolicy::FILTER_ACCEPT_LIST_ONLY:
2716 case bluetooth::hci::LeScanningFilterPolicy::
2717 FILTER_ACCEPT_LIST_AND_INITIATORS_IDENTITY:
2718 if (!LeFilterAcceptListContainsDevice(resolved_advertising_address)) {
2719 LOG_VERB(
2720 "Legacy advertising ignored by scanner because the advertising "
2721 "address %s(%hhx) is not in the filter accept list",
2722 resolved_advertising_address.ToString().c_str(),
2723 resolved_advertising_address.GetAddressType());
2724 return;
2725 }
2726 break;
2727 }
2728
2729 // When LE_Set_Scan_Enable is used:
2730 //
2731 // When the Scanning_Filter_Policy is set to 0x02 or 0x03 (see Section 7.8.10)
2732 // and a directed advertisement was received where the advertiser used a
2733 // resolvable private address which the Controller is unable to resolve, an
2734 // HCI_LE_Directed_Advertising_Report event shall be generated instead of an
2735 // HCI_LE_Advertising_Report event.
2736 bool should_send_directed_advertising_report = false;
2737
2738 if (directed_advertising) {
2739 switch (scanner_.scan_filter_policy) {
2740 // In both basic scanner filter policy modes, a directed advertising PDU
2741 // shall be ignored unless either:
2742 // • the TargetA field is identical to the scanner's device address, or
2743 // • the TargetA field is a resolvable private address, address
2744 // resolution is
2745 // enabled, and the address is resolved successfully
2746 case bluetooth::hci::LeScanningFilterPolicy::ACCEPT_ALL:
2747 case bluetooth::hci::LeScanningFilterPolicy::FILTER_ACCEPT_LIST_ONLY:
2748 if (!IsLocalPublicOrRandomAddress(target_address) &&
2749 !(target_address.IsRpa() && resolved_target_address)) {
2750 LOG_VERB(
2751 "Legacy advertising ignored by scanner because the directed "
2752 "address %s(%hhx) does not match the current device or cannot be "
2753 "resolved",
2754 target_address.ToString().c_str(),
2755 target_address.GetAddressType());
2756 return;
2757 }
2758 break;
2759 // These are identical to the basic modes except
2760 // that a directed advertising PDU shall be ignored unless either:
2761 // • the TargetA field is identical to the scanner's device address, or
2762 // • the TargetA field is a resolvable private address.
2763 case bluetooth::hci::LeScanningFilterPolicy::CHECK_INITIATORS_IDENTITY:
2764 case bluetooth::hci::LeScanningFilterPolicy::
2765 FILTER_ACCEPT_LIST_AND_INITIATORS_IDENTITY:
2766 if (!IsLocalPublicOrRandomAddress(target_address) &&
2767 !target_address.IsRpa()) {
2768 LOG_VERB(
2769 "Legacy advertising ignored by scanner because the directed "
2770 "address %s(%hhx) does not match the current device or is not a "
2771 "resovable private address",
2772 target_address.ToString().c_str(),
2773 target_address.GetAddressType());
2774 return;
2775 }
2776 should_send_directed_advertising_report =
2777 target_address.IsRpa() && !resolved_target_address;
2778 break;
2779 }
2780 }
2781
2782 bool should_send_advertising_report = true;
2783 if (scanner_.filter_duplicates !=
2784 bluetooth::hci::FilterDuplicates::DISABLED) {
2785 if (scanner_.IsPacketInHistory(pdu)) {
2786 should_send_advertising_report = false;
2787 } else {
2788 scanner_.AddPacketToHistory(pdu);
2789 }
2790 }
2791
2792 // Legacy scanning, directed advertising.
2793 if (LegacyAdvertising() && should_send_advertising_report &&
2794 should_send_directed_advertising_report &&
2795 IsLeEventUnmasked(SubeventCode::DIRECTED_ADVERTISING_REPORT)) {
2796 bluetooth::hci::LeDirectedAdvertisingResponse response;
2797 response.event_type_ =
2798 bluetooth::hci::DirectAdvertisingEventType::ADV_DIRECT_IND;
2799 response.address_type_ =
2800 static_cast<bluetooth::hci::DirectAdvertisingAddressType>(
2801 resolved_advertising_address.GetAddressType());
2802 response.address_ = resolved_advertising_address.GetAddress();
2803 response.direct_address_type_ =
2804 bluetooth::hci::DirectAddressType::RANDOM_DEVICE_ADDRESS;
2805 response.direct_address_ = target_address.GetAddress();
2806 response.rssi_ = rssi;
2807
2808 send_event_(
2809 bluetooth::hci::LeDirectedAdvertisingReportBuilder::Create({response}));
2810 }
2811
2812 // Legacy scanning, un-directed advertising.
2813 if (LegacyAdvertising() && should_send_advertising_report &&
2814 !should_send_directed_advertising_report &&
2815 IsLeEventUnmasked(SubeventCode::ADVERTISING_REPORT)) {
2816 bluetooth::hci::LeAdvertisingResponseRaw response;
2817 response.address_type_ = resolved_advertising_address.GetAddressType();
2818 response.address_ = resolved_advertising_address.GetAddress();
2819 response.advertising_data_ = advertising_data;
2820 response.rssi_ = rssi;
2821
2822 switch (advertising_type) {
2823 case model::packets::LegacyAdvertisingType::ADV_IND:
2824 response.event_type_ = bluetooth::hci::AdvertisingEventType::ADV_IND;
2825 break;
2826 case model::packets::LegacyAdvertisingType::ADV_DIRECT_IND:
2827 response.event_type_ =
2828 bluetooth::hci::AdvertisingEventType::ADV_DIRECT_IND;
2829 break;
2830 case model::packets::LegacyAdvertisingType::ADV_SCAN_IND:
2831 response.event_type_ =
2832 bluetooth::hci::AdvertisingEventType::ADV_SCAN_IND;
2833 break;
2834 case model::packets::LegacyAdvertisingType::ADV_NONCONN_IND:
2835 response.event_type_ =
2836 bluetooth::hci::AdvertisingEventType::ADV_NONCONN_IND;
2837 break;
2838 }
2839
2840 send_event_(
2841 bluetooth::hci::LeAdvertisingReportRawBuilder::Create({response}));
2842 }
2843
2844 // Extended scanning.
2845 if (ExtendedAdvertising() && should_send_advertising_report &&
2846 IsLeEventUnmasked(SubeventCode::EXTENDED_ADVERTISING_REPORT)) {
2847 bluetooth::hci::LeExtendedAdvertisingResponseRaw response;
2848 response.connectable_ = connectable_advertising;
2849 response.scannable_ = scannable_advertising;
2850 response.directed_ = directed_advertising;
2851 response.scan_response_ = false;
2852 response.legacy_ = true;
2853 response.data_status_ = bluetooth::hci::DataStatus::COMPLETE;
2854 response.address_type_ =
2855 static_cast<bluetooth::hci::DirectAdvertisingAddressType>(
2856 resolved_advertising_address.GetAddressType());
2857 response.address_ = resolved_advertising_address.GetAddress();
2858 response.primary_phy_ = bluetooth::hci::PrimaryPhyType::LE_1M;
2859 response.secondary_phy_ = bluetooth::hci::SecondaryPhyType::NO_PACKETS;
2860 response.advertising_sid_ = 0xff; // Not ADI field provided.
2861 response.tx_power_ = 0x7f; // TX power information not available.
2862 response.rssi_ = rssi;
2863 response.periodic_advertising_interval_ = 0; // No periodic advertising.
2864 response.direct_address_type_ =
2865 bluetooth::hci::DirectAdvertisingAddressType::NO_ADDRESS_PROVIDED;
2866 response.direct_address_ = Address::kEmpty;
2867 response.advertising_data_ = advertising_data;
2868
2869 send_event_(bluetooth::hci::LeExtendedAdvertisingReportRawBuilder::Create(
2870 {response}));
2871 }
2872
2873 // Did the user enable Active scanning ?
2874 bool active_scanning =
2875 (scanner_.le_1m_phy.enabled &&
2876 scanner_.le_1m_phy.scan_type == bluetooth::hci::LeScanType::ACTIVE) ||
2877 (scanner_.le_coded_phy.enabled &&
2878 scanner_.le_coded_phy.scan_type == bluetooth::hci::LeScanType::ACTIVE);
2879
2880 // Active scanning.
2881 // Note: only send SCAN requests in response to scannable advertising
2882 // events (ADV_IND, ADV_SCAN_IND).
2883 if (!scannable_advertising) {
2884 LOG_VERB(
2885 "Not sending LE Scan request to advertising address %s(%hhx) because "
2886 "it is not scannable",
2887 advertising_address.ToString().c_str(),
2888 advertising_address.GetAddressType());
2889 } else if (!active_scanning) {
2890 LOG_VERB(
2891 "Not sending LE Scan request to advertising address %s(%hhx) because "
2892 "the scanner is passive",
2893 advertising_address.ToString().c_str(),
2894 advertising_address.GetAddressType());
2895 } else if (scanner_.pending_scan_request) {
2896 LOG_VERB(
2897 "Not sending LE Scan request to advertising address %s(%hhx) because "
2898 "an LE Scan request is already pending",
2899 advertising_address.ToString().c_str(),
2900 advertising_address.GetAddressType());
2901 } else if (!should_send_advertising_report) {
2902 LOG_VERB(
2903 "Not sending LE Scan request to advertising address %s(%hhx) because "
2904 "the advertising message was filtered",
2905 advertising_address.ToString().c_str(),
2906 advertising_address.GetAddressType());
2907 } else {
2908 // TODO: apply privacy mode in resolving list.
2909 // Scan requests with public or random device addresses must be ignored
2910 // when the peer has network privacy mode.
2911
2912 AddressWithType public_address{address_,
2913 AddressType::PUBLIC_DEVICE_ADDRESS};
2914 AddressWithType random_address{random_address_,
2915 AddressType::RANDOM_DEVICE_ADDRESS};
2916 std::optional<AddressWithType> resolvable_scanning_address =
2917 GenerateResolvablePrivateAddress(resolved_advertising_address,
2918 IrkSelection::Local);
2919
2920 // The ScanA field of the scanning PDU is generated using the
2921 // Resolving List’s Local IRK value and the Resolvable Private Address
2922 // Generation procedure (see Section 1.3.2.2), or the address is provided
2923 // by the Host.
2924 AddressWithType scanning_address;
2925 switch (scanner_.own_address_type) {
2926 case bluetooth::hci::OwnAddressType::PUBLIC_DEVICE_ADDRESS:
2927 scanning_address = public_address;
2928 break;
2929 case bluetooth::hci::OwnAddressType::RANDOM_DEVICE_ADDRESS:
2930 // The random address is checked in Le_Set_Scan_Enable or
2931 // Le_Set_Extended_Scan_Enable.
2932 ASSERT(random_address_ != Address::kEmpty);
2933 scanning_address = random_address;
2934 break;
2935 case bluetooth::hci::OwnAddressType::RESOLVABLE_OR_PUBLIC_ADDRESS:
2936 scanning_address = resolvable_scanning_address.value_or(public_address);
2937 break;
2938 case bluetooth::hci::OwnAddressType::RESOLVABLE_OR_RANDOM_ADDRESS:
2939 // The random address is checked in Le_Set_Scan_Enable or
2940 // Le_Set_Extended_Scan_Enable.
2941 ASSERT(random_address_ != Address::kEmpty);
2942 scanning_address = resolvable_scanning_address.value_or(random_address);
2943 break;
2944 }
2945
2946 // Save the original advertising type to report if the advertising
2947 // is connectable in the scan response report.
2948 scanner_.connectable_scan_response = connectable_advertising;
2949 scanner_.pending_scan_request = advertising_address;
2950
2951 LOG_INFO(
2952 "Sending LE Scan request to advertising address %s(%hhx) with scanning "
2953 "address %s(%hhx)",
2954 advertising_address.ToString().c_str(),
2955 advertising_address.GetAddressType(),
2956 scanning_address.ToString().c_str(), scanning_address.GetAddressType());
2957
2958 // The advertiser’s device address (AdvA field) in the scan request PDU
2959 // shall be the same as the advertiser’s device address (AdvA field)
2960 // received in the advertising PDU to which the scanner is responding.
2961 SendLeLinkLayerPacket(model::packets::LeScanBuilder::Create(
2962 scanning_address.GetAddress(), advertising_address.GetAddress(),
2963 static_cast<model::packets::AddressType>(
2964 scanning_address.GetAddressType()),
2965 static_cast<model::packets::AddressType>(
2966 advertising_address.GetAddressType())));
2967 }
2968 }
2969
ConnectIncomingLeLegacyAdvertisingPdu(model::packets::LeLegacyAdvertisingPduView & pdu)2970 void LinkLayerController::ConnectIncomingLeLegacyAdvertisingPdu(
2971 model::packets::LeLegacyAdvertisingPduView& pdu) {
2972 if (!initiator_.IsEnabled()) {
2973 return;
2974 }
2975
2976 auto advertising_type = pdu.GetAdvertisingType();
2977 bool connectable_advertising =
2978 advertising_type == model::packets::LegacyAdvertisingType::ADV_IND ||
2979 advertising_type == model::packets::LegacyAdvertisingType::ADV_DIRECT_IND;
2980 bool directed_advertising =
2981 advertising_type == model::packets::LegacyAdvertisingType::ADV_DIRECT_IND;
2982
2983 // Connection.
2984 // Note: only send CONNECT requests in response to connectable advertising
2985 // events (ADV_IND, ADV_DIRECT_IND).
2986 if (!connectable_advertising) {
2987 LOG_VERB(
2988 "Legacy advertising ignored by initiator because it is not "
2989 "connectable");
2990 return;
2991 }
2992 if (initiator_.pending_connect_request) {
2993 LOG_VERB(
2994 "Legacy advertising ignored because an LE Connect request is already "
2995 "pending");
2996 return;
2997 }
2998
2999 AddressWithType advertising_address{
3000 pdu.GetSourceAddress(),
3001 static_cast<AddressType>(pdu.GetAdvertisingAddressType())};
3002
3003 AddressWithType target_address{
3004 pdu.GetDestinationAddress(),
3005 static_cast<AddressType>(pdu.GetTargetAddressType())};
3006
3007 AddressWithType resolved_advertising_address =
3008 ResolvePrivateAddress(advertising_address, IrkSelection::Peer)
3009 .value_or(advertising_address);
3010
3011 AddressWithType resolved_target_address =
3012 ResolvePrivateAddress(target_address, IrkSelection::Peer)
3013 .value_or(target_address);
3014
3015 // Vol 6, Part B § 4.3.5 Initiator filter policy.
3016 switch (initiator_.initiator_filter_policy) {
3017 case bluetooth::hci::InitiatorFilterPolicy::USE_PEER_ADDRESS:
3018 if (resolved_advertising_address != initiator_.peer_address) {
3019 LOG_VERB(
3020 "Legacy advertising ignored by initiator because the "
3021 "advertising address %s does not match the peer address %s",
3022 resolved_advertising_address.ToString().c_str(),
3023 initiator_.peer_address.ToString().c_str());
3024 return;
3025 }
3026 break;
3027 case bluetooth::hci::InitiatorFilterPolicy::USE_FILTER_ACCEPT_LIST:
3028 if (!LeFilterAcceptListContainsDevice(resolved_advertising_address)) {
3029 LOG_VERB(
3030 "Legacy advertising ignored by initiator because the "
3031 "advertising address %s is not in the filter accept list",
3032 resolved_advertising_address.ToString().c_str());
3033 return;
3034 }
3035 break;
3036 }
3037
3038 // When an initiator receives a directed connectable advertising event that
3039 // contains a resolvable private address for the target’s address
3040 // (TargetA field) and address resolution is enabled, the Link Layer shall
3041 // resolve the private address using the resolving list’s Local IRK values.
3042 // An initiator that has been instructed by the Host to use Resolvable Private
3043 // Addresses shall not respond to directed connectable advertising events that
3044 // contain Public or Static addresses for the target’s address (TargetA
3045 // field).
3046 if (directed_advertising) {
3047 if (!IsLocalPublicOrRandomAddress(resolved_target_address)) {
3048 LOG_VERB(
3049 "Directed legacy advertising ignored by initiator because the "
3050 "target address %s does not match the current device addresses",
3051 resolved_advertising_address.ToString().c_str());
3052 return;
3053 }
3054 if (resolved_target_address == target_address &&
3055 (initiator_.own_address_type ==
3056 OwnAddressType::RESOLVABLE_OR_PUBLIC_ADDRESS ||
3057 initiator_.own_address_type ==
3058 OwnAddressType::RESOLVABLE_OR_RANDOM_ADDRESS)) {
3059 LOG_VERB(
3060 "Directed legacy advertising ignored by initiator because the "
3061 "target address %s is static or public and the initiator is "
3062 "configured to use resolvable addresses",
3063 resolved_advertising_address.ToString().c_str());
3064 return;
3065 }
3066 }
3067
3068 AddressWithType public_address{address_, AddressType::PUBLIC_DEVICE_ADDRESS};
3069 AddressWithType random_address{random_address_,
3070 AddressType::RANDOM_DEVICE_ADDRESS};
3071 std::optional<AddressWithType> resolvable_initiating_address =
3072 GenerateResolvablePrivateAddress(resolved_advertising_address,
3073 IrkSelection::Local);
3074
3075 // The Link Layer shall use resolvable private addresses for the initiator’s
3076 // device address (InitA field) when initiating connection establishment with
3077 // an associated device that exists in the Resolving List.
3078 AddressWithType initiating_address;
3079 switch (initiator_.own_address_type) {
3080 case bluetooth::hci::OwnAddressType::PUBLIC_DEVICE_ADDRESS:
3081 initiating_address = public_address;
3082 break;
3083 case bluetooth::hci::OwnAddressType::RANDOM_DEVICE_ADDRESS:
3084 // The random address is checked in Le_Create_Connection or
3085 // Le_Extended_Create_Connection.
3086 ASSERT(random_address_ != Address::kEmpty);
3087 initiating_address = random_address;
3088 break;
3089 case bluetooth::hci::OwnAddressType::RESOLVABLE_OR_PUBLIC_ADDRESS:
3090 initiating_address =
3091 resolvable_initiating_address.value_or(public_address);
3092 break;
3093 case bluetooth::hci::OwnAddressType::RESOLVABLE_OR_RANDOM_ADDRESS:
3094 // The random address is checked in Le_Create_Connection or
3095 // Le_Extended_Create_Connection.
3096 ASSERT(random_address_ != Address::kEmpty);
3097 initiating_address =
3098 resolvable_initiating_address.value_or(random_address);
3099 break;
3100 }
3101
3102 if (!connections_.CreatePendingLeConnection(
3103 advertising_address,
3104 resolved_advertising_address != advertising_address
3105 ? resolved_advertising_address
3106 : AddressWithType{},
3107 initiating_address)) {
3108 LOG_WARN("CreatePendingLeConnection failed for connection to %s",
3109 advertising_address.ToString().c_str());
3110 }
3111
3112 initiator_.pending_connect_request = advertising_address;
3113
3114 LOG_INFO("Sending LE Connect request to %s with initiating address %s",
3115 resolved_advertising_address.ToString().c_str(),
3116 initiating_address.ToString().c_str());
3117
3118 // The advertiser’s device address (AdvA field) in the initiating PDU
3119 // shall be the same as the advertiser’s device address (AdvA field)
3120 // received in the advertising event PDU to which the initiator is
3121 // responding.
3122 SendLeLinkLayerPacket(model::packets::LeConnectBuilder::Create(
3123 initiating_address.GetAddress(), advertising_address.GetAddress(),
3124 static_cast<model::packets::AddressType>(
3125 initiating_address.GetAddressType()),
3126 static_cast<model::packets::AddressType>(
3127 advertising_address.GetAddressType()),
3128 initiator_.le_1m_phy.connection_interval_min,
3129 initiator_.le_1m_phy.connection_interval_max,
3130 initiator_.le_1m_phy.max_latency,
3131 initiator_.le_1m_phy.supervision_timeout));
3132 }
3133
IncomingLeLegacyAdvertisingPdu(model::packets::LinkLayerPacketView incoming,uint8_t rssi)3134 void LinkLayerController::IncomingLeLegacyAdvertisingPdu(
3135 model::packets::LinkLayerPacketView incoming, uint8_t rssi) {
3136 auto pdu = model::packets::LeLegacyAdvertisingPduView::Create(incoming);
3137 ASSERT(pdu.IsValid());
3138
3139 ScanIncomingLeLegacyAdvertisingPdu(pdu, rssi);
3140 ConnectIncomingLeLegacyAdvertisingPdu(pdu);
3141 }
3142
3143 // Handle legacy advertising PDUs while in the Scanning state.
ScanIncomingLeExtendedAdvertisingPdu(model::packets::LeExtendedAdvertisingPduView & pdu,uint8_t rssi)3144 void LinkLayerController::ScanIncomingLeExtendedAdvertisingPdu(
3145 model::packets::LeExtendedAdvertisingPduView& pdu, uint8_t rssi) {
3146 if (!scanner_.IsEnabled()) {
3147 return;
3148 }
3149 if (!ExtendedAdvertising()) {
3150 LOG_VERB("Extended advertising ignored because the scanner is legacy");
3151 return;
3152 }
3153
3154 std::vector<uint8_t> advertising_data = pdu.GetAdvertisingData();
3155 AddressWithType advertising_address{
3156 pdu.GetSourceAddress(),
3157 static_cast<AddressType>(pdu.GetAdvertisingAddressType())};
3158
3159 AddressWithType target_address{
3160 pdu.GetDestinationAddress(),
3161 static_cast<AddressType>(pdu.GetTargetAddressType())};
3162
3163 bool scannable_advertising = pdu.GetScannable();
3164 bool connectable_advertising = pdu.GetConnectable();
3165 bool directed_advertising = pdu.GetDirected();
3166
3167 // TODO: check originating PHY, compare against active scanning PHYs
3168 // (scanner_.le_1m_phy or scanner_.le_coded_phy).
3169
3170 // When a scanner receives an advertising packet that contains a resolvable
3171 // private address for the advertiser’s device address (AdvA field) and
3172 // address resolution is enabled, the Link Layer shall resolve the private
3173 // address. The scanner’s filter policy shall then determine if the scanner
3174 // responds with a scan request.
3175 AddressWithType resolved_advertising_address =
3176 ResolvePrivateAddress(advertising_address, IrkSelection::Peer)
3177 .value_or(advertising_address);
3178
3179 std::optional<AddressWithType> resolved_target_address =
3180 ResolvePrivateAddress(target_address, IrkSelection::Peer);
3181
3182 if (resolved_advertising_address != advertising_address) {
3183 LOG_VERB("Resolved the advertising address %s(%hhx) to %s(%hhx)",
3184 advertising_address.ToString().c_str(),
3185 advertising_address.GetAddressType(),
3186 resolved_advertising_address.ToString().c_str(),
3187 resolved_advertising_address.GetAddressType());
3188 }
3189
3190 // Vol 6, Part B § 4.3.3 Scanner filter policy
3191 switch (scanner_.scan_filter_policy) {
3192 case bluetooth::hci::LeScanningFilterPolicy::ACCEPT_ALL:
3193 case bluetooth::hci::LeScanningFilterPolicy::CHECK_INITIATORS_IDENTITY:
3194 break;
3195 case bluetooth::hci::LeScanningFilterPolicy::FILTER_ACCEPT_LIST_ONLY:
3196 case bluetooth::hci::LeScanningFilterPolicy::
3197 FILTER_ACCEPT_LIST_AND_INITIATORS_IDENTITY:
3198 if (!LeFilterAcceptListContainsDevice(resolved_advertising_address)) {
3199 LOG_VERB(
3200 "Extended advertising ignored by scanner because the advertising "
3201 "address %s(%hhx) is not in the filter accept list",
3202 resolved_advertising_address.ToString().c_str(),
3203 resolved_advertising_address.GetAddressType());
3204 return;
3205 }
3206 break;
3207 }
3208
3209 if (directed_advertising) {
3210 switch (scanner_.scan_filter_policy) {
3211 // In both basic scanner filter policy modes, a directed advertising PDU
3212 // shall be ignored unless either:
3213 // • the TargetA field is identical to the scanner's device address, or
3214 // • the TargetA field is a resolvable private address, address
3215 // resolution is enabled, and the address is resolved successfully
3216 case bluetooth::hci::LeScanningFilterPolicy::ACCEPT_ALL:
3217 case bluetooth::hci::LeScanningFilterPolicy::FILTER_ACCEPT_LIST_ONLY:
3218 if (!IsLocalPublicOrRandomAddress(target_address) &&
3219 !(target_address.IsRpa() && resolved_target_address)) {
3220 LOG_VERB(
3221 "Extended advertising ignored by scanner because the directed "
3222 "address %s(%hhx) does not match the current device or cannot be "
3223 "resolved",
3224 target_address.ToString().c_str(),
3225 target_address.GetAddressType());
3226 return;
3227 }
3228 break;
3229 // These are identical to the basic modes except
3230 // that a directed advertising PDU shall be ignored unless either:
3231 // • the TargetA field is identical to the scanner's device address, or
3232 // • the TargetA field is a resolvable private address.
3233 case bluetooth::hci::LeScanningFilterPolicy::CHECK_INITIATORS_IDENTITY:
3234 case bluetooth::hci::LeScanningFilterPolicy::
3235 FILTER_ACCEPT_LIST_AND_INITIATORS_IDENTITY:
3236 if (!IsLocalPublicOrRandomAddress(target_address) &&
3237 !target_address.IsRpa()) {
3238 LOG_VERB(
3239 "Extended advertising ignored by scanner because the directed "
3240 "address %s(%hhx) does not match the current device or is not a "
3241 "resovable private address",
3242 target_address.ToString().c_str(),
3243 target_address.GetAddressType());
3244 return;
3245 }
3246 break;
3247 }
3248 }
3249
3250 bool should_send_advertising_report = true;
3251 if (scanner_.filter_duplicates !=
3252 bluetooth::hci::FilterDuplicates::DISABLED) {
3253 if (scanner_.IsPacketInHistory(pdu)) {
3254 should_send_advertising_report = false;
3255 } else {
3256 scanner_.AddPacketToHistory(pdu);
3257 }
3258 }
3259
3260 if (should_send_advertising_report &&
3261 IsLeEventUnmasked(SubeventCode::EXTENDED_ADVERTISING_REPORT)) {
3262 bluetooth::hci::LeExtendedAdvertisingResponseRaw response;
3263 response.connectable_ = connectable_advertising;
3264 response.scannable_ = scannable_advertising;
3265 response.directed_ = directed_advertising;
3266 response.scan_response_ = false;
3267 response.legacy_ = false;
3268 response.data_status_ = bluetooth::hci::DataStatus::COMPLETE;
3269 response.address_type_ =
3270 static_cast<bluetooth::hci::DirectAdvertisingAddressType>(
3271 resolved_advertising_address.GetAddressType());
3272 response.address_ = resolved_advertising_address.GetAddress();
3273 response.primary_phy_ = bluetooth::hci::PrimaryPhyType::LE_1M;
3274 response.secondary_phy_ = bluetooth::hci::SecondaryPhyType::NO_PACKETS;
3275 response.advertising_sid_ = 0xff; // Not ADI field provided.
3276 response.tx_power_ = 0x7f; // TX power information not available.
3277 response.rssi_ = rssi;
3278 response.periodic_advertising_interval_ = 0; // No periodic advertising.
3279 response.direct_address_type_ =
3280 bluetooth::hci::DirectAdvertisingAddressType::NO_ADDRESS_PROVIDED;
3281 response.direct_address_ = Address::kEmpty;
3282 response.advertising_data_ = advertising_data;
3283
3284 send_event_(bluetooth::hci::LeExtendedAdvertisingReportRawBuilder::Create(
3285 {response}));
3286 }
3287
3288 // Did the user enable Active scanning ?
3289 bool active_scanning =
3290 (scanner_.le_1m_phy.enabled &&
3291 scanner_.le_1m_phy.scan_type == bluetooth::hci::LeScanType::ACTIVE) ||
3292 (scanner_.le_coded_phy.enabled &&
3293 scanner_.le_coded_phy.scan_type == bluetooth::hci::LeScanType::ACTIVE);
3294
3295 // Active scanning.
3296 // Note: only send SCAN requests in response to scannable advertising
3297 // events (ADV_IND, ADV_SCAN_IND).
3298 if (!scannable_advertising) {
3299 LOG_VERB(
3300 "Not sending LE Scan request to advertising address %s(%hhx) because "
3301 "it is not scannable",
3302 advertising_address.ToString().c_str(),
3303 advertising_address.GetAddressType());
3304 } else if (!active_scanning) {
3305 LOG_VERB(
3306 "Not sending LE Scan request to advertising address %s(%hhx) because "
3307 "the scanner is passive",
3308 advertising_address.ToString().c_str(),
3309 advertising_address.GetAddressType());
3310 } else if (scanner_.pending_scan_request) {
3311 LOG_VERB(
3312 "Not sending LE Scan request to advertising address %s(%hhx) because "
3313 "an LE Scan request is already pending",
3314 advertising_address.ToString().c_str(),
3315 advertising_address.GetAddressType());
3316 } else if (!should_send_advertising_report) {
3317 LOG_VERB(
3318 "Not sending LE Scan request to advertising address %s(%hhx) because "
3319 "the advertising message was filtered",
3320 advertising_address.ToString().c_str(),
3321 advertising_address.GetAddressType());
3322 } else {
3323 // TODO: apply privacy mode in resolving list.
3324 // Scan requests with public or random device addresses must be ignored
3325 // when the peer has network privacy mode.
3326
3327 AddressWithType public_address{address_,
3328 AddressType::PUBLIC_DEVICE_ADDRESS};
3329 AddressWithType random_address{random_address_,
3330 AddressType::RANDOM_DEVICE_ADDRESS};
3331 std::optional<AddressWithType> resolvable_address =
3332 GenerateResolvablePrivateAddress(resolved_advertising_address,
3333 IrkSelection::Local);
3334
3335 // The ScanA field of the scanning PDU is generated using the
3336 // Resolving List’s Local IRK value and the Resolvable Private Address
3337 // Generation procedure (see Section 1.3.2.2), or the address is provided
3338 // by the Host.
3339 AddressWithType scanning_address;
3340 std::optional<AddressWithType> resolvable_scanning_address;
3341 switch (scanner_.own_address_type) {
3342 case bluetooth::hci::OwnAddressType::PUBLIC_DEVICE_ADDRESS:
3343 scanning_address = public_address;
3344 break;
3345 case bluetooth::hci::OwnAddressType::RANDOM_DEVICE_ADDRESS:
3346 // The random address is checked in Le_Set_Scan_Enable or
3347 // Le_Set_Extended_Scan_Enable.
3348 ASSERT(random_address_ != Address::kEmpty);
3349 scanning_address = random_address;
3350 break;
3351 case bluetooth::hci::OwnAddressType::RESOLVABLE_OR_PUBLIC_ADDRESS:
3352 scanning_address = resolvable_address.value_or(public_address);
3353 break;
3354 case bluetooth::hci::OwnAddressType::RESOLVABLE_OR_RANDOM_ADDRESS:
3355 // The random address is checked in Le_Set_Scan_Enable or
3356 // Le_Set_Extended_Scan_Enable.
3357 ASSERT(random_address_ != Address::kEmpty);
3358 scanning_address = resolvable_address.value_or(random_address);
3359 break;
3360 }
3361
3362 // Save the original advertising type to report if the advertising
3363 // is connectable in the scan response report.
3364 scanner_.connectable_scan_response = connectable_advertising;
3365 scanner_.pending_scan_request = advertising_address;
3366
3367 LOG_INFO(
3368 "Sending LE Scan request to advertising address %s(%hhx) with scanning "
3369 "address %s(%hhx)",
3370 advertising_address.ToString().c_str(),
3371 advertising_address.GetAddressType(),
3372 scanning_address.ToString().c_str(), scanning_address.GetAddressType());
3373
3374 // The advertiser’s device address (AdvA field) in the scan request PDU
3375 // shall be the same as the advertiser’s device address (AdvA field)
3376 // received in the advertising PDU to which the scanner is responding.
3377 SendLeLinkLayerPacket(model::packets::LeScanBuilder::Create(
3378 scanning_address.GetAddress(), advertising_address.GetAddress(),
3379 static_cast<model::packets::AddressType>(
3380 scanning_address.GetAddressType()),
3381 static_cast<model::packets::AddressType>(
3382 advertising_address.GetAddressType())));
3383 }
3384 }
3385
ConnectIncomingLeExtendedAdvertisingPdu(model::packets::LeExtendedAdvertisingPduView & pdu)3386 void LinkLayerController::ConnectIncomingLeExtendedAdvertisingPdu(
3387 model::packets::LeExtendedAdvertisingPduView& pdu) {
3388 if (!initiator_.IsEnabled()) {
3389 return;
3390 }
3391 if (!ExtendedAdvertising()) {
3392 LOG_VERB("Extended advertising ignored because the initiator is legacy");
3393 return;
3394 }
3395
3396 // Connection.
3397 // Note: only send CONNECT requests in response to connectable advertising
3398 // events (ADV_IND, ADV_DIRECT_IND).
3399 if (!pdu.GetConnectable()) {
3400 LOG_VERB(
3401 "Extended advertising ignored by initiator because it is not "
3402 "connectable");
3403 return;
3404 }
3405 if (initiator_.pending_connect_request) {
3406 LOG_VERB(
3407 "Extended advertising ignored because an LE Connect request is already "
3408 "pending");
3409 return;
3410 }
3411
3412 AddressWithType advertising_address{
3413 pdu.GetSourceAddress(),
3414 static_cast<AddressType>(pdu.GetAdvertisingAddressType())};
3415
3416 AddressWithType target_address{
3417 pdu.GetDestinationAddress(),
3418 static_cast<AddressType>(pdu.GetTargetAddressType())};
3419
3420 AddressWithType resolved_advertising_address =
3421 ResolvePrivateAddress(advertising_address, IrkSelection::Peer)
3422 .value_or(advertising_address);
3423
3424 AddressWithType resolved_target_address =
3425 ResolvePrivateAddress(target_address, IrkSelection::Peer)
3426 .value_or(target_address);
3427
3428 // Vol 6, Part B § 4.3.5 Initiator filter policy.
3429 switch (initiator_.initiator_filter_policy) {
3430 case bluetooth::hci::InitiatorFilterPolicy::USE_PEER_ADDRESS:
3431 if (resolved_advertising_address != initiator_.peer_address) {
3432 LOG_VERB(
3433 "Extended advertising ignored by initiator because the "
3434 "advertising address %s does not match the peer address %s",
3435 resolved_advertising_address.ToString().c_str(),
3436 initiator_.peer_address.ToString().c_str());
3437 return;
3438 }
3439 break;
3440 case bluetooth::hci::InitiatorFilterPolicy::USE_FILTER_ACCEPT_LIST:
3441 if (!LeFilterAcceptListContainsDevice(resolved_advertising_address)) {
3442 LOG_VERB(
3443 "Extended advertising ignored by initiator because the "
3444 "advertising address %s is not in the filter accept list",
3445 resolved_advertising_address.ToString().c_str());
3446 return;
3447 }
3448 break;
3449 }
3450
3451 // When an initiator receives a directed connectable advertising event that
3452 // contains a resolvable private address for the target’s address
3453 // (TargetA field) and address resolution is enabled, the Link Layer shall
3454 // resolve the private address using the resolving list’s Local IRK values.
3455 // An initiator that has been instructed by the Host to use Resolvable Private
3456 // Addresses shall not respond to directed connectable advertising events that
3457 // contain Public or Static addresses for the target’s address (TargetA
3458 // field).
3459 if (pdu.GetDirected()) {
3460 if (!IsLocalPublicOrRandomAddress(resolved_target_address)) {
3461 LOG_VERB(
3462 "Directed extended advertising ignored by initiator because the "
3463 "target address %s does not match the current device addresses",
3464 resolved_advertising_address.ToString().c_str());
3465 return;
3466 }
3467 if (resolved_target_address == target_address &&
3468 (initiator_.own_address_type ==
3469 OwnAddressType::RESOLVABLE_OR_PUBLIC_ADDRESS ||
3470 initiator_.own_address_type ==
3471 OwnAddressType::RESOLVABLE_OR_RANDOM_ADDRESS)) {
3472 LOG_VERB(
3473 "Directed extended advertising ignored by initiator because the "
3474 "target address %s is static or public and the initiator is "
3475 "configured to use resolvable addresses",
3476 resolved_advertising_address.ToString().c_str());
3477 return;
3478 }
3479 }
3480
3481 AddressWithType public_address{address_, AddressType::PUBLIC_DEVICE_ADDRESS};
3482 AddressWithType random_address{random_address_,
3483 AddressType::RANDOM_DEVICE_ADDRESS};
3484 std::optional<AddressWithType> resolvable_initiating_address =
3485 GenerateResolvablePrivateAddress(resolved_advertising_address,
3486 IrkSelection::Local);
3487
3488 // The Link Layer shall use resolvable private addresses for the initiator’s
3489 // device address (InitA field) when initiating connection establishment with
3490 // an associated device that exists in the Resolving List.
3491 AddressWithType initiating_address;
3492 switch (initiator_.own_address_type) {
3493 case bluetooth::hci::OwnAddressType::PUBLIC_DEVICE_ADDRESS:
3494 initiating_address = public_address;
3495 break;
3496 case bluetooth::hci::OwnAddressType::RANDOM_DEVICE_ADDRESS:
3497 // The random address is checked in Le_Create_Connection or
3498 // Le_Extended_Create_Connection.
3499 ASSERT(random_address_ != Address::kEmpty);
3500 initiating_address = random_address;
3501 break;
3502 case bluetooth::hci::OwnAddressType::RESOLVABLE_OR_PUBLIC_ADDRESS:
3503 initiating_address =
3504 resolvable_initiating_address.value_or(public_address);
3505 break;
3506 case bluetooth::hci::OwnAddressType::RESOLVABLE_OR_RANDOM_ADDRESS:
3507 // The random address is checked in Le_Create_Connection or
3508 // Le_Extended_Create_Connection.
3509 ASSERT(random_address_ != Address::kEmpty);
3510 initiating_address =
3511 resolvable_initiating_address.value_or(random_address);
3512 break;
3513 }
3514
3515 if (!connections_.CreatePendingLeConnection(
3516 advertising_address,
3517 resolved_advertising_address != advertising_address
3518 ? resolved_advertising_address
3519 : AddressWithType{},
3520 initiating_address)) {
3521 LOG_WARN("CreatePendingLeConnection failed for connection to %s",
3522 advertising_address.ToString().c_str());
3523 }
3524
3525 initiator_.pending_connect_request = advertising_address;
3526
3527 LOG_INFO("Sending LE Connect request to %s with initiating address %s",
3528 resolved_advertising_address.ToString().c_str(),
3529 initiating_address.ToString().c_str());
3530
3531 // The advertiser’s device address (AdvA field) in the initiating PDU
3532 // shall be the same as the advertiser’s device address (AdvA field)
3533 // received in the advertising event PDU to which the initiator is
3534 // responding.
3535 SendLeLinkLayerPacket(model::packets::LeConnectBuilder::Create(
3536 initiating_address.GetAddress(), advertising_address.GetAddress(),
3537 static_cast<model::packets::AddressType>(
3538 initiating_address.GetAddressType()),
3539 static_cast<model::packets::AddressType>(
3540 advertising_address.GetAddressType()),
3541 initiator_.le_1m_phy.connection_interval_min,
3542 initiator_.le_1m_phy.connection_interval_max,
3543 initiator_.le_1m_phy.max_latency,
3544 initiator_.le_1m_phy.supervision_timeout));
3545 }
3546
IncomingLeExtendedAdvertisingPdu(model::packets::LinkLayerPacketView incoming,uint8_t rssi)3547 void LinkLayerController::IncomingLeExtendedAdvertisingPdu(
3548 model::packets::LinkLayerPacketView incoming, uint8_t rssi) {
3549 auto pdu = model::packets::LeExtendedAdvertisingPduView::Create(incoming);
3550 ASSERT(pdu.IsValid());
3551
3552 ScanIncomingLeExtendedAdvertisingPdu(pdu, rssi);
3553 ConnectIncomingLeExtendedAdvertisingPdu(pdu);
3554 }
3555
IncomingScoConnectionRequest(model::packets::LinkLayerPacketView incoming)3556 void LinkLayerController::IncomingScoConnectionRequest(
3557 model::packets::LinkLayerPacketView incoming) {
3558 Address address = incoming.GetSourceAddress();
3559 auto request = model::packets::ScoConnectionRequestView::Create(incoming);
3560 ASSERT(request.IsValid());
3561
3562 LOG_INFO("Received eSCO connection request from %s",
3563 address.ToString().c_str());
3564
3565 // Automatically reject if connection request was already sent
3566 // from the current device.
3567 if (connections_.HasPendingScoConnection(address)) {
3568 LOG_INFO(
3569 "Rejecting eSCO connection request from %s, "
3570 "an eSCO connection already exist with this device",
3571 address.ToString().c_str());
3572
3573 SendLinkLayerPacket(model::packets::ScoConnectionResponseBuilder::Create(
3574 GetAddress(), address,
3575 (uint8_t)ErrorCode::SYNCHRONOUS_CONNECTION_LIMIT_EXCEEDED, 0, 0, 0, 0,
3576 0, 0));
3577 return;
3578 }
3579
3580 // Create local connection context.
3581 ScoConnectionParameters connection_parameters = {
3582 request.GetTransmitBandwidth(), request.GetReceiveBandwidth(),
3583 request.GetMaxLatency(), request.GetVoiceSetting(),
3584 request.GetRetransmissionEffort(), request.GetPacketType()};
3585
3586 bool extended = connection_parameters.IsExtended();
3587 connections_.CreateScoConnection(
3588 address, connection_parameters,
3589 extended ? ScoState::SCO_STATE_SENT_ESCO_CONNECTION_REQUEST
3590 : ScoState::SCO_STATE_SENT_SCO_CONNECTION_REQUEST,
3591 ScoDatapath::NORMAL);
3592
3593 // Send connection request event and wait for Accept or Reject command.
3594 send_event_(bluetooth::hci::ConnectionRequestBuilder::Create(
3595 address, request.GetClassOfDevice(),
3596 extended ? bluetooth::hci::ConnectionRequestLinkType::ESCO
3597 : bluetooth::hci::ConnectionRequestLinkType::SCO));
3598 }
3599
IncomingScoConnectionResponse(model::packets::LinkLayerPacketView incoming)3600 void LinkLayerController::IncomingScoConnectionResponse(
3601 model::packets::LinkLayerPacketView incoming) {
3602 Address address = incoming.GetSourceAddress();
3603 auto response = model::packets::ScoConnectionResponseView::Create(incoming);
3604 ASSERT(response.IsValid());
3605 auto status = ErrorCode(response.GetStatus());
3606 bool is_legacy = connections_.IsLegacyScoConnection(address);
3607
3608 LOG_INFO("Received eSCO connection response with status 0x%02x from %s",
3609 static_cast<unsigned>(status),
3610 incoming.GetSourceAddress().ToString().c_str());
3611
3612 if (status == ErrorCode::SUCCESS) {
3613 bool extended = response.GetExtended();
3614 ScoLinkParameters link_parameters = {
3615 response.GetTransmissionInterval(),
3616 response.GetRetransmissionWindow(),
3617 response.GetRxPacketLength(),
3618 response.GetTxPacketLength(),
3619 response.GetAirMode(),
3620 extended,
3621 };
3622
3623 connections_.AcceptPendingScoConnection(
3624 address, link_parameters, [this, address] {
3625 return LinkLayerController::StartScoStream(address);
3626 });
3627
3628 if (is_legacy) {
3629 send_event_(bluetooth::hci::ConnectionCompleteBuilder::Create(
3630 ErrorCode::SUCCESS, connections_.GetScoHandle(address), address,
3631 bluetooth::hci::LinkType::SCO, bluetooth::hci::Enable::DISABLED));
3632 } else {
3633 send_event_(bluetooth::hci::SynchronousConnectionCompleteBuilder::Create(
3634 ErrorCode::SUCCESS, connections_.GetScoHandle(address), address,
3635 extended ? bluetooth::hci::ScoLinkType::ESCO
3636 : bluetooth::hci::ScoLinkType::SCO,
3637 extended ? response.GetTransmissionInterval() : 0,
3638 extended ? response.GetRetransmissionWindow() : 0,
3639 extended ? response.GetRxPacketLength() : 0,
3640 extended ? response.GetTxPacketLength() : 0,
3641 bluetooth::hci::ScoAirMode(response.GetAirMode())));
3642 }
3643 } else {
3644 connections_.CancelPendingScoConnection(address);
3645 if (is_legacy) {
3646 send_event_(bluetooth::hci::ConnectionCompleteBuilder::Create(
3647 status, 0, address, bluetooth::hci::LinkType::SCO,
3648 bluetooth::hci::Enable::DISABLED));
3649 } else {
3650 ScoConnectionParameters connection_parameters =
3651 connections_.GetScoConnectionParameters(address);
3652 send_event_(bluetooth::hci::SynchronousConnectionCompleteBuilder::Create(
3653 status, 0, address,
3654 connection_parameters.IsExtended() ? bluetooth::hci::ScoLinkType::ESCO
3655 : bluetooth::hci::ScoLinkType::SCO,
3656 0, 0, 0, 0, bluetooth::hci::ScoAirMode::TRANSPARENT));
3657 }
3658 }
3659 }
3660
IncomingScoDisconnect(model::packets::LinkLayerPacketView incoming)3661 void LinkLayerController::IncomingScoDisconnect(
3662 model::packets::LinkLayerPacketView incoming) {
3663 Address address = incoming.GetSourceAddress();
3664 auto request = model::packets::ScoDisconnectView::Create(incoming);
3665 ASSERT(request.IsValid());
3666 auto reason = request.GetReason();
3667 uint16_t handle = connections_.GetScoHandle(address);
3668
3669 LOG_INFO(
3670 "Received eSCO disconnection request with"
3671 " reason 0x%02x from %s",
3672 static_cast<unsigned>(reason),
3673 incoming.GetSourceAddress().ToString().c_str());
3674
3675 if (handle != kReservedHandle) {
3676 connections_.Disconnect(handle, cancel_task_);
3677 SendDisconnectionCompleteEvent(handle, ErrorCode(reason));
3678 }
3679 }
3680
3681 #ifdef ROOTCANAL_LMP
IncomingLmpPacket(model::packets::LinkLayerPacketView incoming)3682 void LinkLayerController::IncomingLmpPacket(
3683 model::packets::LinkLayerPacketView incoming) {
3684 Address address = incoming.GetSourceAddress();
3685 auto request = model::packets::LmpView::Create(incoming);
3686 ASSERT(request.IsValid());
3687 auto payload = request.GetPayload();
3688 auto packet = std::vector(payload.begin(), payload.end());
3689
3690 ASSERT(link_manager_ingest_lmp(
3691 lm_.get(), reinterpret_cast<uint8_t(*)[6]>(address.data()), packet.data(),
3692 packet.size()));
3693 }
3694 #endif /* ROOTCANAL_LMP */
3695
HandleLeConnection(AddressWithType address,AddressWithType own_address,bluetooth::hci::Role role,uint16_t connection_interval,uint16_t connection_latency,uint16_t supervision_timeout,bool send_le_channel_selection_algorithm_event)3696 uint16_t LinkLayerController::HandleLeConnection(
3697 AddressWithType address, AddressWithType own_address,
3698 bluetooth::hci::Role role, uint16_t connection_interval,
3699 uint16_t connection_latency, uint16_t supervision_timeout,
3700 bool send_le_channel_selection_algorithm_event) {
3701 // Note: the HCI_LE_Connection_Complete event is not sent if the
3702 // HCI_LE_Enhanced_Connection_Complete event (see Section 7.7.65.10) is
3703 // unmasked.
3704
3705 uint16_t handle = connections_.CreateLeConnection(address, own_address, role);
3706 if (handle == kReservedHandle) {
3707 LOG_WARN("No pending connection for connection from %s",
3708 address.ToString().c_str());
3709 return kReservedHandle;
3710 }
3711
3712 if (IsLeEventUnmasked(SubeventCode::ENHANCED_CONNECTION_COMPLETE)) {
3713 AddressWithType peer_resolved_address =
3714 connections_.GetResolvedAddress(handle);
3715 Address peer_resolvable_private_address;
3716 Address connection_address = address.GetAddress();
3717 AddressType peer_address_type = address.GetAddressType();
3718 if (peer_resolved_address != AddressWithType()) {
3719 peer_resolvable_private_address = address.GetAddress();
3720 if (peer_resolved_address.GetAddressType() ==
3721 AddressType::PUBLIC_DEVICE_ADDRESS) {
3722 peer_address_type = AddressType::PUBLIC_IDENTITY_ADDRESS;
3723 } else if (peer_resolved_address.GetAddressType() ==
3724 AddressType::RANDOM_DEVICE_ADDRESS) {
3725 peer_address_type = AddressType::RANDOM_IDENTITY_ADDRESS;
3726 } else {
3727 LOG_WARN("Unhandled resolved address type %s -> %s",
3728 address.ToString().c_str(),
3729 peer_resolved_address.ToString().c_str());
3730 }
3731 connection_address = peer_resolved_address.GetAddress();
3732 }
3733 Address local_resolved_address = own_address.GetAddress();
3734 if (local_resolved_address == GetAddress() ||
3735 local_resolved_address == random_address_) {
3736 local_resolved_address = Address::kEmpty;
3737 }
3738
3739 send_event_(bluetooth::hci::LeEnhancedConnectionCompleteBuilder::Create(
3740 ErrorCode::SUCCESS, handle, role, peer_address_type, connection_address,
3741 local_resolved_address, peer_resolvable_private_address,
3742 connection_interval, connection_latency, supervision_timeout,
3743 static_cast<bluetooth::hci::ClockAccuracy>(0x00)));
3744 } else if (IsLeEventUnmasked(SubeventCode::CONNECTION_COMPLETE)) {
3745 send_event_(bluetooth::hci::LeConnectionCompleteBuilder::Create(
3746 ErrorCode::SUCCESS, handle, role, address.GetAddressType(),
3747 address.GetAddress(), connection_interval, connection_latency,
3748 supervision_timeout, static_cast<bluetooth::hci::ClockAccuracy>(0x00)));
3749 }
3750
3751 // Note: the HCI_LE_Connection_Complete event is immediately followed by
3752 // an HCI_LE_Channel_Selection_Algorithm event if the connection is created
3753 // using the LE_Extended_Create_Connection command (see Section 7.7.8.66).
3754 if (send_le_channel_selection_algorithm_event &&
3755 IsLeEventUnmasked(SubeventCode::CHANNEL_SELECTION_ALGORITHM)) {
3756 // The selection channel algorithm probably will have no impact
3757 // on emulation.
3758 send_event_(bluetooth::hci::LeChannelSelectionAlgorithmBuilder::Create(
3759 handle, bluetooth::hci::ChannelSelectionAlgorithm::ALGORITHM_1));
3760 }
3761
3762 if (own_address.GetAddress() == initiator_.initiating_address) {
3763 initiator_.initiating_address = Address::kEmpty;
3764 }
3765 return handle;
3766 }
3767
3768 // Handle CONNECT_IND PDUs for the legacy advertiser.
ProcessIncomingLegacyConnectRequest(model::packets::LeConnectView const & connect_ind)3769 bool LinkLayerController::ProcessIncomingLegacyConnectRequest(
3770 model::packets::LeConnectView const& connect_ind) {
3771 if (!legacy_advertiser_.IsEnabled()) {
3772 return false;
3773 }
3774 if (!legacy_advertiser_.IsConnectable()) {
3775 LOG_VERB(
3776 "LE Connect request ignored by legacy advertiser because it is not "
3777 "connectable");
3778 return false;
3779 }
3780
3781 AddressWithType advertising_address{
3782 connect_ind.GetDestinationAddress(),
3783 static_cast<AddressType>(connect_ind.GetAdvertisingAddressType()),
3784 };
3785
3786 AddressWithType initiating_address{
3787 connect_ind.GetSourceAddress(),
3788 static_cast<AddressType>(connect_ind.GetInitiatingAddressType()),
3789 };
3790
3791 if (legacy_advertiser_.GetAdvertisingAddress() != advertising_address) {
3792 LOG_VERB(
3793 "LE Connect request ignored by legacy advertiser because the "
3794 "advertising address %s(%hhx) does not match %s(%hhx)",
3795 advertising_address.ToString().c_str(),
3796 advertising_address.GetAddressType(),
3797 legacy_advertiser_.GetAdvertisingAddress().ToString().c_str(),
3798 legacy_advertiser_.GetAdvertisingAddress().GetAddressType());
3799 return false;
3800 }
3801
3802 // When an advertiser receives a connection request that contains a resolvable
3803 // private address for the initiator’s address (InitA field) and address
3804 // resolution is enabled, the Link Layer shall resolve the private address.
3805 // The advertising filter policy shall then determine if the
3806 // advertiser establishes a connection.
3807 AddressWithType resolved_initiating_address =
3808 ResolvePrivateAddress(initiating_address, IrkSelection::Peer)
3809 .value_or(initiating_address);
3810
3811 if (resolved_initiating_address != initiating_address) {
3812 LOG_VERB("Resolved the initiating address %s(%hhx) to %s(%hhx)",
3813 initiating_address.ToString().c_str(),
3814 initiating_address.GetAddressType(),
3815 resolved_initiating_address.ToString().c_str(),
3816 resolved_initiating_address.GetAddressType());
3817 }
3818
3819 // When the Link Layer is [...] connectable directed advertising events the
3820 // advertising filter policy shall be ignored.
3821 if (legacy_advertiser_.IsDirected()) {
3822 if (legacy_advertiser_.GetTargetAddress() != resolved_initiating_address) {
3823 LOG_VERB(
3824 "LE Connect request ignored by legacy advertiser because the "
3825 "initiating address %s(%hhx) does not match the target address "
3826 "%s(%hhx)",
3827 resolved_initiating_address.ToString().c_str(),
3828 resolved_initiating_address.GetAddressType(),
3829 legacy_advertiser_.GetTargetAddress().ToString().c_str(),
3830 legacy_advertiser_.GetTargetAddress().GetAddressType());
3831 return false;
3832 }
3833 } else {
3834 // Check if initiator address is in the filter accept list
3835 // for this advertiser.
3836 switch (legacy_advertiser_.advertising_filter_policy) {
3837 case bluetooth::hci::AdvertisingFilterPolicy::ALL_DEVICES:
3838 case bluetooth::hci::AdvertisingFilterPolicy::LISTED_SCAN:
3839 break;
3840 case bluetooth::hci::AdvertisingFilterPolicy::LISTED_CONNECT:
3841 case bluetooth::hci::AdvertisingFilterPolicy::LISTED_SCAN_AND_CONNECT:
3842 if (!LeFilterAcceptListContainsDevice(resolved_initiating_address)) {
3843 LOG_VERB(
3844 "LE Connect request ignored by legacy advertiser because the "
3845 "initiating address %s(%hhx) is not in the filter accept list",
3846 resolved_initiating_address.ToString().c_str(),
3847 resolved_initiating_address.GetAddressType());
3848 return false;
3849 }
3850 break;
3851 }
3852 }
3853
3854 LOG_INFO(
3855 "Accepting LE Connect request to legacy advertiser from initiating "
3856 "address %s(%hhx)",
3857 resolved_initiating_address.ToString().c_str(),
3858 resolved_initiating_address.GetAddressType());
3859
3860 if (!connections_.CreatePendingLeConnection(
3861 initiating_address,
3862 resolved_initiating_address != initiating_address
3863 ? resolved_initiating_address
3864 : AddressWithType{},
3865 advertising_address)) {
3866 LOG_WARN(
3867 "CreatePendingLeConnection failed for connection from %s (type %hhx)",
3868 initiating_address.GetAddress().ToString().c_str(),
3869 initiating_address.GetAddressType());
3870 return false;
3871 }
3872
3873 (void)HandleLeConnection(
3874 initiating_address, advertising_address, bluetooth::hci::Role::PERIPHERAL,
3875 connect_ind.GetLeConnectionIntervalMax(),
3876 connect_ind.GetLeConnectionLatency(),
3877 connect_ind.GetLeConnectionSupervisionTimeout(), false);
3878
3879 SendLeLinkLayerPacket(model::packets::LeConnectCompleteBuilder::Create(
3880 advertising_address.GetAddress(), initiating_address.GetAddress(),
3881 static_cast<model::packets::AddressType>(
3882 initiating_address.GetAddressType()),
3883 static_cast<model::packets::AddressType>(
3884 advertising_address.GetAddressType()),
3885 connect_ind.GetLeConnectionIntervalMax(),
3886 connect_ind.GetLeConnectionLatency(),
3887 connect_ind.GetLeConnectionSupervisionTimeout()));
3888
3889 legacy_advertiser_.Disable();
3890 return true;
3891 }
3892
3893 // Handle CONNECT_IND PDUs for the selected extended advertiser.
ProcessIncomingExtendedConnectRequest(ExtendedAdvertiser & advertiser,model::packets::LeConnectView const & connect_ind)3894 bool LinkLayerController::ProcessIncomingExtendedConnectRequest(
3895 ExtendedAdvertiser& advertiser,
3896 model::packets::LeConnectView const& connect_ind) {
3897 if (!advertiser.IsEnabled()) {
3898 return false;
3899 }
3900 if (!advertiser.IsConnectable()) {
3901 LOG_VERB(
3902 "LE Connect request ignored by extended advertiser %d because it is "
3903 "not connectable",
3904 advertiser.advertising_handle);
3905 return false;
3906 }
3907
3908 AddressWithType advertising_address{
3909 connect_ind.GetDestinationAddress(),
3910 static_cast<AddressType>(connect_ind.GetAdvertisingAddressType()),
3911 };
3912
3913 AddressWithType initiating_address{
3914 connect_ind.GetSourceAddress(),
3915 static_cast<AddressType>(connect_ind.GetInitiatingAddressType()),
3916 };
3917
3918 if (advertiser.GetAdvertisingAddress() != advertising_address) {
3919 LOG_VERB(
3920 "LE Connect request ignored by extended advertiser %d because the "
3921 "advertising address %s(%hhx) does not match %s(%hhx)",
3922 advertiser.advertising_handle, advertising_address.ToString().c_str(),
3923 advertising_address.GetAddressType(),
3924 advertiser.GetAdvertisingAddress().ToString().c_str(),
3925 advertiser.GetAdvertisingAddress().GetAddressType());
3926 return false;
3927 }
3928
3929 // When an advertiser receives a connection request that contains a resolvable
3930 // private address for the initiator’s address (InitA field) and address
3931 // resolution is enabled, the Link Layer shall resolve the private address.
3932 // The advertising filter policy shall then determine if the
3933 // advertiser establishes a connection.
3934 AddressWithType resolved_initiating_address =
3935 ResolvePrivateAddress(initiating_address, IrkSelection::Peer)
3936 .value_or(initiating_address);
3937
3938 if (resolved_initiating_address != initiating_address) {
3939 LOG_VERB("Resolved the initiating address %s(%hhx) to %s(%hhx)",
3940 initiating_address.ToString().c_str(),
3941 initiating_address.GetAddressType(),
3942 resolved_initiating_address.ToString().c_str(),
3943 resolved_initiating_address.GetAddressType());
3944 }
3945
3946 // When the Link Layer is [...] connectable directed advertising events the
3947 // advertising filter policy shall be ignored.
3948 if (advertiser.IsDirected()) {
3949 if (advertiser.GetTargetAddress() != resolved_initiating_address) {
3950 LOG_VERB(
3951 "LE Connect request ignored by extended advertiser %d because the "
3952 "initiating address %s(%hhx) does not match the target address "
3953 "%s(%hhx)",
3954 advertiser.advertising_handle,
3955 resolved_initiating_address.ToString().c_str(),
3956 resolved_initiating_address.GetAddressType(),
3957 advertiser.GetTargetAddress().ToString().c_str(),
3958 advertiser.GetTargetAddress().GetAddressType());
3959 return false;
3960 }
3961 } else {
3962 // Check if initiator address is in the filter accept list
3963 // for this advertiser.
3964 switch (advertiser.advertising_filter_policy) {
3965 case bluetooth::hci::AdvertisingFilterPolicy::ALL_DEVICES:
3966 case bluetooth::hci::AdvertisingFilterPolicy::LISTED_SCAN:
3967 break;
3968 case bluetooth::hci::AdvertisingFilterPolicy::LISTED_CONNECT:
3969 case bluetooth::hci::AdvertisingFilterPolicy::LISTED_SCAN_AND_CONNECT:
3970 if (!LeFilterAcceptListContainsDevice(resolved_initiating_address)) {
3971 LOG_VERB(
3972 "LE Connect request ignored by extended advertiser %d because "
3973 "the initiating address %s(%hhx) is not in the filter accept "
3974 "list",
3975 advertiser.advertising_handle,
3976 resolved_initiating_address.ToString().c_str(),
3977 resolved_initiating_address.GetAddressType());
3978 return false;
3979 }
3980 break;
3981 }
3982 }
3983
3984 LOG_INFO(
3985 "Accepting LE Connect request to extended advertiser %d from initiating "
3986 "address %s(%hhx)",
3987 advertiser.advertising_handle,
3988 resolved_initiating_address.ToString().c_str(),
3989 resolved_initiating_address.GetAddressType());
3990
3991 if (!connections_.CreatePendingLeConnection(
3992 initiating_address,
3993 resolved_initiating_address != initiating_address
3994 ? resolved_initiating_address
3995 : AddressWithType{},
3996 advertising_address)) {
3997 LOG_WARN(
3998 "CreatePendingLeConnection failed for connection from %s (type %hhx)",
3999 initiating_address.GetAddress().ToString().c_str(),
4000 initiating_address.GetAddressType());
4001 return false;
4002 }
4003
4004 advertiser.Disable();
4005
4006 uint16_t connection_handle = HandleLeConnection(
4007 initiating_address, advertising_address, bluetooth::hci::Role::PERIPHERAL,
4008 connect_ind.GetLeConnectionIntervalMax(),
4009 connect_ind.GetLeConnectionLatency(),
4010 connect_ind.GetLeConnectionSupervisionTimeout(), false);
4011
4012 SendLeLinkLayerPacket(model::packets::LeConnectCompleteBuilder::Create(
4013 advertising_address.GetAddress(), initiating_address.GetAddress(),
4014 static_cast<model::packets::AddressType>(
4015 initiating_address.GetAddressType()),
4016 static_cast<model::packets::AddressType>(
4017 advertising_address.GetAddressType()),
4018 connect_ind.GetLeConnectionIntervalMax(),
4019 connect_ind.GetLeConnectionLatency(),
4020 connect_ind.GetLeConnectionSupervisionTimeout()));
4021
4022 // If the advertising set is connectable and a connection gets created, an
4023 // HCI_LE_Connection_Complete or HCI_LE_Enhanced_Connection_Complete
4024 // event shall be generated followed by an HCI_LE_Advertising_Set_Terminated
4025 // event with the Status parameter set to 0x00. The Controller should not send
4026 // any other events in between these two events
4027
4028 if (IsLeEventUnmasked(SubeventCode::ADVERTISING_SET_TERMINATED)) {
4029 send_event_(bluetooth::hci::LeAdvertisingSetTerminatedBuilder::Create(
4030 ErrorCode::SUCCESS, advertiser.advertising_handle, connection_handle,
4031 advertiser.num_completed_extended_advertising_events));
4032 }
4033
4034 return true;
4035 }
4036
IncomingLeConnectPacket(model::packets::LinkLayerPacketView incoming)4037 void LinkLayerController::IncomingLeConnectPacket(
4038 model::packets::LinkLayerPacketView incoming) {
4039 model::packets::LeConnectView connect =
4040 model::packets::LeConnectView::Create(incoming);
4041 ASSERT(connect.IsValid());
4042
4043 if (ProcessIncomingLegacyConnectRequest(connect)) {
4044 return;
4045 }
4046
4047 for (auto& [_, advertiser] : extended_advertisers_) {
4048 if (ProcessIncomingExtendedConnectRequest(advertiser, connect)) {
4049 return;
4050 }
4051 }
4052 }
4053
IncomingLeConnectCompletePacket(model::packets::LinkLayerPacketView incoming)4054 void LinkLayerController::IncomingLeConnectCompletePacket(
4055 model::packets::LinkLayerPacketView incoming) {
4056 auto complete = model::packets::LeConnectCompleteView::Create(incoming);
4057 ASSERT(complete.IsValid());
4058
4059 AddressWithType advertising_address{
4060 incoming.GetSourceAddress(), static_cast<bluetooth::hci::AddressType>(
4061 complete.GetAdvertisingAddressType())};
4062
4063 LOG_INFO(
4064 "Received LE Connect complete response with advertising address %s(%hhx)",
4065 advertising_address.ToString().c_str(),
4066 advertising_address.GetAddressType());
4067
4068 HandleLeConnection(
4069 advertising_address,
4070 AddressWithType(incoming.GetDestinationAddress(),
4071 static_cast<bluetooth::hci::AddressType>(
4072 complete.GetInitiatingAddressType())),
4073 bluetooth::hci::Role::CENTRAL, complete.GetLeConnectionInterval(),
4074 complete.GetLeConnectionLatency(),
4075 complete.GetLeConnectionSupervisionTimeout(), ExtendedAdvertising());
4076
4077 initiator_.pending_connect_request = {};
4078 initiator_.Disable();
4079 }
4080
IncomingLeConnectionParameterRequest(model::packets::LinkLayerPacketView incoming)4081 void LinkLayerController::IncomingLeConnectionParameterRequest(
4082 model::packets::LinkLayerPacketView incoming) {
4083 auto request =
4084 model::packets::LeConnectionParameterRequestView::Create(incoming);
4085 ASSERT(request.IsValid());
4086 Address peer = incoming.GetSourceAddress();
4087 uint16_t handle = connections_.GetHandleOnlyAddress(peer);
4088 if (handle == kReservedHandle) {
4089 LOG_INFO("@%s: Unknown connection @%s",
4090 incoming.GetDestinationAddress().ToString().c_str(),
4091 peer.ToString().c_str());
4092 return;
4093 }
4094
4095 if (IsLeEventUnmasked(SubeventCode::REMOTE_CONNECTION_PARAMETER_REQUEST)) {
4096 send_event_(
4097 bluetooth::hci::LeRemoteConnectionParameterRequestBuilder::Create(
4098 handle, request.GetIntervalMin(), request.GetIntervalMax(),
4099 request.GetLatency(), request.GetTimeout()));
4100 } else {
4101 // If the request is being indicated to the Host and the event to the Host
4102 // is masked, then the Link Layer shall issue an LL_REJECT_EXT_IND PDU with
4103 // the ErrorCode set to Unsupported Remote Feature (0x1A).
4104 SendLeLinkLayerPacket(
4105 model::packets::LeConnectionParameterUpdateBuilder::Create(
4106 request.GetDestinationAddress(), request.GetSourceAddress(),
4107 static_cast<uint8_t>(ErrorCode::UNSUPPORTED_REMOTE_OR_LMP_FEATURE),
4108 0, 0, 0));
4109 }
4110 }
4111
IncomingLeConnectionParameterUpdate(model::packets::LinkLayerPacketView incoming)4112 void LinkLayerController::IncomingLeConnectionParameterUpdate(
4113 model::packets::LinkLayerPacketView incoming) {
4114 auto update =
4115 model::packets::LeConnectionParameterUpdateView::Create(incoming);
4116 ASSERT(update.IsValid());
4117 Address peer = incoming.GetSourceAddress();
4118 uint16_t handle = connections_.GetHandleOnlyAddress(peer);
4119 if (handle == kReservedHandle) {
4120 LOG_INFO("@%s: Unknown connection @%s",
4121 incoming.GetDestinationAddress().ToString().c_str(),
4122 peer.ToString().c_str());
4123 return;
4124 }
4125 if (IsLeEventUnmasked(SubeventCode::CONNECTION_UPDATE_COMPLETE)) {
4126 send_event_(bluetooth::hci::LeConnectionUpdateCompleteBuilder::Create(
4127 static_cast<ErrorCode>(update.GetStatus()), handle,
4128 update.GetInterval(), update.GetLatency(), update.GetTimeout()));
4129 }
4130 }
4131
IncomingLeEncryptConnection(model::packets::LinkLayerPacketView incoming)4132 void LinkLayerController::IncomingLeEncryptConnection(
4133 model::packets::LinkLayerPacketView incoming) {
4134 LOG_INFO("IncomingLeEncryptConnection");
4135
4136 Address peer = incoming.GetSourceAddress();
4137 uint16_t handle = connections_.GetHandleOnlyAddress(peer);
4138 if (handle == kReservedHandle) {
4139 LOG_INFO("@%s: Unknown connection @%s",
4140 incoming.GetDestinationAddress().ToString().c_str(),
4141 peer.ToString().c_str());
4142 return;
4143 }
4144 auto le_encrypt = model::packets::LeEncryptConnectionView::Create(incoming);
4145 ASSERT(le_encrypt.IsValid());
4146
4147 // TODO: Save keys to check
4148
4149 if (IsEventUnmasked(EventCode::LE_META_EVENT)) {
4150 send_event_(bluetooth::hci::LeLongTermKeyRequestBuilder::Create(
4151 handle, le_encrypt.GetRand(), le_encrypt.GetEdiv()));
4152 }
4153 }
4154
IncomingLeEncryptConnectionResponse(model::packets::LinkLayerPacketView incoming)4155 void LinkLayerController::IncomingLeEncryptConnectionResponse(
4156 model::packets::LinkLayerPacketView incoming) {
4157 LOG_INFO("IncomingLeEncryptConnectionResponse");
4158 // TODO: Check keys
4159 uint16_t handle =
4160 connections_.GetHandleOnlyAddress(incoming.GetSourceAddress());
4161 if (handle == kReservedHandle) {
4162 LOG_INFO("@%s: Unknown connection @%s",
4163 incoming.GetDestinationAddress().ToString().c_str(),
4164 incoming.GetSourceAddress().ToString().c_str());
4165 return;
4166 }
4167 ErrorCode status = ErrorCode::SUCCESS;
4168 auto response =
4169 model::packets::LeEncryptConnectionResponseView::Create(incoming);
4170 ASSERT(response.IsValid());
4171
4172 // Zero LTK is a rejection
4173 if (response.GetLtk() == std::array<uint8_t, 16>()) {
4174 status = ErrorCode::AUTHENTICATION_FAILURE;
4175 }
4176
4177 if (connections_.IsEncrypted(handle)) {
4178 if (IsEventUnmasked(EventCode::ENCRYPTION_KEY_REFRESH_COMPLETE)) {
4179 send_event_(bluetooth::hci::EncryptionKeyRefreshCompleteBuilder::Create(
4180 status, handle));
4181 }
4182 } else {
4183 connections_.Encrypt(handle);
4184 if (IsEventUnmasked(EventCode::ENCRYPTION_CHANGE)) {
4185 send_event_(bluetooth::hci::EncryptionChangeBuilder::Create(
4186 status, handle, bluetooth::hci::EncryptionEnabled::ON));
4187 }
4188 }
4189 }
4190
IncomingLeReadRemoteFeatures(model::packets::LinkLayerPacketView incoming)4191 void LinkLayerController::IncomingLeReadRemoteFeatures(
4192 model::packets::LinkLayerPacketView incoming) {
4193 uint16_t handle =
4194 connections_.GetHandleOnlyAddress(incoming.GetSourceAddress());
4195 ErrorCode status = ErrorCode::SUCCESS;
4196 if (handle == kReservedHandle) {
4197 LOG_WARN("@%s: Unknown connection @%s",
4198 incoming.GetDestinationAddress().ToString().c_str(),
4199 incoming.GetSourceAddress().ToString().c_str());
4200 }
4201 SendLeLinkLayerPacket(
4202 model::packets::LeReadRemoteFeaturesResponseBuilder::Create(
4203 incoming.GetDestinationAddress(), incoming.GetSourceAddress(),
4204 GetLeSupportedFeatures(), static_cast<uint8_t>(status)));
4205 }
4206
IncomingLeReadRemoteFeaturesResponse(model::packets::LinkLayerPacketView incoming)4207 void LinkLayerController::IncomingLeReadRemoteFeaturesResponse(
4208 model::packets::LinkLayerPacketView incoming) {
4209 uint16_t handle =
4210 connections_.GetHandleOnlyAddress(incoming.GetSourceAddress());
4211 ErrorCode status = ErrorCode::SUCCESS;
4212 auto response =
4213 model::packets::LeReadRemoteFeaturesResponseView::Create(incoming);
4214 ASSERT(response.IsValid());
4215 if (handle == kReservedHandle) {
4216 LOG_INFO("@%s: Unknown connection @%s",
4217 incoming.GetDestinationAddress().ToString().c_str(),
4218 incoming.GetSourceAddress().ToString().c_str());
4219 status = ErrorCode::UNKNOWN_CONNECTION;
4220 } else {
4221 status = static_cast<ErrorCode>(response.GetStatus());
4222 }
4223 if (IsEventUnmasked(EventCode::LE_META_EVENT)) {
4224 send_event_(bluetooth::hci::LeReadRemoteFeaturesCompleteBuilder::Create(
4225 status, handle, response.GetFeatures()));
4226 }
4227 }
4228
ProcessIncomingLegacyScanRequest(AddressWithType scanning_address,AddressWithType resolved_scanning_address,AddressWithType advertising_address)4229 void LinkLayerController::ProcessIncomingLegacyScanRequest(
4230 AddressWithType scanning_address, AddressWithType resolved_scanning_address,
4231 AddressWithType advertising_address) {
4232 // Check if the advertising addresses matches the legacy
4233 // advertising address.
4234 if (!legacy_advertiser_.IsEnabled()) {
4235 return;
4236 }
4237 if (!legacy_advertiser_.IsScannable()) {
4238 LOG_VERB(
4239 "LE Scan request ignored by legacy advertiser because it is not "
4240 "scannable");
4241 return;
4242 }
4243
4244 if (advertising_address != legacy_advertiser_.advertising_address) {
4245 LOG_VERB(
4246 "LE Scan request ignored by legacy advertiser because the advertising "
4247 "address %s(%hhx) does not match %s(%hhx)",
4248 advertising_address.ToString().c_str(),
4249 advertising_address.GetAddressType(),
4250 legacy_advertiser_.GetAdvertisingAddress().ToString().c_str(),
4251 legacy_advertiser_.GetAdvertisingAddress().GetAddressType());
4252 return;
4253 }
4254
4255 // Check if scanner address is in the filter accept list
4256 // for this advertiser.
4257 switch (legacy_advertiser_.advertising_filter_policy) {
4258 case bluetooth::hci::AdvertisingFilterPolicy::ALL_DEVICES:
4259 case bluetooth::hci::AdvertisingFilterPolicy::LISTED_CONNECT:
4260 break;
4261 case bluetooth::hci::AdvertisingFilterPolicy::LISTED_SCAN:
4262 case bluetooth::hci::AdvertisingFilterPolicy::LISTED_SCAN_AND_CONNECT:
4263 if (!LeFilterAcceptListContainsDevice(resolved_scanning_address)) {
4264 LOG_VERB(
4265 "LE Scan request ignored by legacy advertiser because the scanning "
4266 "address %s(%hhx) is not in the filter accept list",
4267 resolved_scanning_address.ToString().c_str(),
4268 resolved_scanning_address.GetAddressType());
4269 return;
4270 }
4271 break;
4272 }
4273
4274 LOG_INFO(
4275 "Accepting LE Scan request to legacy advertiser from scanning address "
4276 "%s(%hhx)",
4277 resolved_scanning_address.ToString().c_str(),
4278 resolved_scanning_address.GetAddressType());
4279
4280 // Generate the SCAN_RSP packet.
4281 // Note: If the advertiser processes the scan request, the advertiser’s
4282 // device address (AdvA field) in the SCAN_RSP PDU shall be the same as
4283 // the advertiser’s device address (AdvA field) in the SCAN_REQ PDU to
4284 // which it is responding.
4285 SendLeLinkLayerPacketWithRssi(
4286 advertising_address.GetAddress(), scanning_address.GetAddress(),
4287 properties_.le_advertising_physical_channel_tx_power,
4288 model::packets::LeScanResponseBuilder::Create(
4289 advertising_address.GetAddress(), scanning_address.GetAddress(),
4290 static_cast<model::packets::AddressType>(
4291 advertising_address.GetAddressType()),
4292 legacy_advertiser_.scan_response_data));
4293 }
4294
ProcessIncomingExtendedScanRequest(ExtendedAdvertiser const & advertiser,AddressWithType scanning_address,AddressWithType resolved_scanning_address,AddressWithType advertising_address)4295 void LinkLayerController::ProcessIncomingExtendedScanRequest(
4296 ExtendedAdvertiser const& advertiser, AddressWithType scanning_address,
4297 AddressWithType resolved_scanning_address,
4298 AddressWithType advertising_address) {
4299 // Check if the advertising addresses matches the legacy
4300 // advertising address.
4301 if (!advertiser.IsEnabled()) {
4302 return;
4303 }
4304 if (!advertiser.IsScannable()) {
4305 LOG_VERB(
4306 "LE Scan request ignored by extended advertiser %d because it is not "
4307 "scannable",
4308 advertiser.advertising_handle);
4309 return;
4310 }
4311
4312 if (advertising_address != advertiser.advertising_address) {
4313 LOG_VERB(
4314 "LE Scan request ignored by extended advertiser %d because the "
4315 "advertising address %s(%hhx) does not match %s(%hhx)",
4316 advertiser.advertising_handle, advertising_address.ToString().c_str(),
4317 advertising_address.GetAddressType(),
4318 advertiser.GetAdvertisingAddress().ToString().c_str(),
4319 advertiser.GetAdvertisingAddress().GetAddressType());
4320 return;
4321 }
4322
4323 // Check if scanner address is in the filter accept list
4324 // for this advertiser.
4325 switch (advertiser.advertising_filter_policy) {
4326 case bluetooth::hci::AdvertisingFilterPolicy::ALL_DEVICES:
4327 case bluetooth::hci::AdvertisingFilterPolicy::LISTED_CONNECT:
4328 break;
4329 case bluetooth::hci::AdvertisingFilterPolicy::LISTED_SCAN:
4330 case bluetooth::hci::AdvertisingFilterPolicy::LISTED_SCAN_AND_CONNECT:
4331 if (!LeFilterAcceptListContainsDevice(resolved_scanning_address)) {
4332 LOG_VERB(
4333 "LE Scan request ignored by extended advertiser %d because the "
4334 "scanning address %s(%hhx) is not in the filter accept list",
4335 advertiser.advertising_handle,
4336 resolved_scanning_address.ToString().c_str(),
4337 resolved_scanning_address.GetAddressType());
4338 return;
4339 }
4340 break;
4341 }
4342
4343 // Check if the scanner address is the target address in the case of
4344 // scannable directed event types.
4345 if (advertiser.IsDirected() &&
4346 advertiser.target_address != resolved_scanning_address) {
4347 LOG_VERB(
4348 "LE Scan request ignored by extended advertiser %d because the "
4349 "scanning address %s(%hhx) does not match the target address %s(%hhx)",
4350 advertiser.advertising_handle,
4351 resolved_scanning_address.ToString().c_str(),
4352 resolved_scanning_address.GetAddressType(),
4353 advertiser.GetTargetAddress().ToString().c_str(),
4354 advertiser.GetTargetAddress().GetAddressType());
4355 return;
4356 }
4357
4358 LOG_INFO(
4359 "Accepting LE Scan request to extended advertiser %d from scanning "
4360 "address %s(%hhx)",
4361 advertiser.advertising_handle,
4362 resolved_scanning_address.ToString().c_str(),
4363 resolved_scanning_address.GetAddressType());
4364
4365 // Generate the SCAN_RSP packet.
4366 // Note: If the advertiser processes the scan request, the advertiser’s
4367 // device address (AdvA field) in the SCAN_RSP PDU shall be the same as
4368 // the advertiser’s device address (AdvA field) in the SCAN_REQ PDU to
4369 // which it is responding.
4370 SendLeLinkLayerPacketWithRssi(
4371 advertising_address.GetAddress(), scanning_address.GetAddress(),
4372 advertiser.advertising_tx_power,
4373 model::packets::LeScanResponseBuilder::Create(
4374 advertising_address.GetAddress(), scanning_address.GetAddress(),
4375 static_cast<model::packets::AddressType>(
4376 advertising_address.GetAddressType()),
4377 advertiser.scan_response_data));
4378 }
4379
IncomingLeScanPacket(model::packets::LinkLayerPacketView incoming)4380 void LinkLayerController::IncomingLeScanPacket(
4381 model::packets::LinkLayerPacketView incoming) {
4382 auto scan_request = model::packets::LeScanView::Create(incoming);
4383 ASSERT(scan_request.IsValid());
4384
4385 AddressWithType scanning_address{
4386 scan_request.GetSourceAddress(),
4387 static_cast<AddressType>(scan_request.GetScanningAddressType())};
4388
4389 AddressWithType advertising_address{
4390 scan_request.GetDestinationAddress(),
4391 static_cast<AddressType>(scan_request.GetAdvertisingAddressType())};
4392
4393 // Note: Vol 6, Part B § 6.2 Privacy in the Advertising State.
4394 //
4395 // When an advertiser receives a scan request that contains a resolvable
4396 // private address for the scanner’s device address (ScanA field) and
4397 // address resolution is enabled, the Link Layer shall resolve the private
4398 // address. The advertising filter policy shall then determine if
4399 // the advertiser processes the scan request.
4400 AddressWithType resolved_scanning_address =
4401 ResolvePrivateAddress(scanning_address, IrkSelection::Peer)
4402 .value_or(scanning_address);
4403
4404 if (resolved_scanning_address != scanning_address) {
4405 LOG_VERB("Resolved the scanning address %s(%hhx) to %s(%hhx)",
4406 scanning_address.ToString().c_str(),
4407 scanning_address.GetAddressType(),
4408 resolved_scanning_address.ToString().c_str(),
4409 resolved_scanning_address.GetAddressType());
4410 }
4411
4412 ProcessIncomingLegacyScanRequest(scanning_address, resolved_scanning_address,
4413 advertising_address);
4414 for (auto& [_, advertiser] : extended_advertisers_) {
4415 ProcessIncomingExtendedScanRequest(advertiser, scanning_address,
4416 resolved_scanning_address,
4417 advertising_address);
4418 }
4419 }
4420
IncomingLeScanResponsePacket(model::packets::LinkLayerPacketView incoming,uint8_t rssi)4421 void LinkLayerController::IncomingLeScanResponsePacket(
4422 model::packets::LinkLayerPacketView incoming, uint8_t rssi) {
4423 auto scan_response = model::packets::LeScanResponseView::Create(incoming);
4424 ASSERT(scan_response.IsValid());
4425
4426 if (!scanner_.IsEnabled()) {
4427 return;
4428 }
4429
4430 if (!scanner_.pending_scan_request) {
4431 LOG_VERB(
4432 "LE Scan response ignored by scanner because no request is currently "
4433 "pending");
4434 return;
4435 }
4436
4437 AddressWithType advertising_address{
4438 scan_response.GetSourceAddress(),
4439 static_cast<AddressType>(scan_response.GetAdvertisingAddressType())};
4440
4441 // If the advertiser processes the scan request, the advertiser’s device
4442 // address (AdvA field) in the scan response PDU shall be the same as the
4443 // advertiser’s device address (AdvA field) in the scan request PDU to which
4444 // it is responding.
4445 if (advertising_address != scanner_.pending_scan_request) {
4446 LOG_VERB(
4447 "LE Scan response ignored by scanner because the advertising address "
4448 "%s(%hhx) does not match the pending request %s(%hhx)",
4449 advertising_address.ToString().c_str(),
4450 advertising_address.GetAddressType(),
4451 scanner_.pending_scan_request.value().ToString().c_str(),
4452 scanner_.pending_scan_request.value().GetAddressType());
4453 return;
4454 }
4455
4456 AddressWithType resolved_advertising_address =
4457 ResolvePrivateAddress(advertising_address, IrkSelection::Peer)
4458 .value_or(advertising_address);
4459
4460 if (advertising_address != resolved_advertising_address) {
4461 LOG_VERB("Resolved the advertising address %s(%hhx) to %s(%hhx)",
4462 advertising_address.ToString().c_str(),
4463 advertising_address.GetAddressType(),
4464 resolved_advertising_address.ToString().c_str(),
4465 resolved_advertising_address.GetAddressType());
4466 return;
4467 }
4468
4469 LOG_INFO("Accepting LE Scan response from advertising address %s(%hhx)",
4470 resolved_advertising_address.ToString().c_str(),
4471 resolved_advertising_address.GetAddressType());
4472
4473 scanner_.pending_scan_request = {};
4474
4475 bool should_send_advertising_report = true;
4476 if (scanner_.filter_duplicates !=
4477 bluetooth::hci::FilterDuplicates::DISABLED) {
4478 if (scanner_.IsPacketInHistory(incoming)) {
4479 should_send_advertising_report = false;
4480 } else {
4481 scanner_.AddPacketToHistory(incoming);
4482 }
4483 }
4484
4485 if (LegacyAdvertising() && should_send_advertising_report &&
4486 IsLeEventUnmasked(SubeventCode::ADVERTISING_REPORT)) {
4487 bluetooth::hci::LeAdvertisingResponseRaw response;
4488 response.event_type_ = bluetooth::hci::AdvertisingEventType::SCAN_RESPONSE;
4489 response.address_ = resolved_advertising_address.GetAddress();
4490 response.address_type_ = resolved_advertising_address.GetAddressType();
4491 response.advertising_data_ = scan_response.GetScanResponseData();
4492 response.rssi_ = rssi;
4493 send_event_(
4494 bluetooth::hci::LeAdvertisingReportRawBuilder::Create({response}));
4495 }
4496
4497 if (ExtendedAdvertising() && should_send_advertising_report &&
4498 IsLeEventUnmasked(SubeventCode::EXTENDED_ADVERTISING_REPORT)) {
4499 bluetooth::hci::LeExtendedAdvertisingResponseRaw response;
4500 response.address_ = resolved_advertising_address.GetAddress();
4501 response.address_type_ =
4502 static_cast<bluetooth::hci::DirectAdvertisingAddressType>(
4503 resolved_advertising_address.GetAddressType());
4504 response.connectable_ = scanner_.connectable_scan_response;
4505 response.scannable_ = true;
4506 response.legacy_ = true;
4507 response.scan_response_ = true;
4508 response.primary_phy_ = bluetooth::hci::PrimaryPhyType::LE_1M;
4509 response.advertising_sid_ = 0xFF;
4510 response.tx_power_ = 0x7F;
4511 response.advertising_data_ = scan_response.GetScanResponseData();
4512 response.rssi_ = rssi;
4513 send_event_(bluetooth::hci::LeExtendedAdvertisingReportRawBuilder::Create(
4514 {response}));
4515 }
4516 }
4517
LeScanning()4518 void LinkLayerController::LeScanning() {
4519 if (!scanner_.IsEnabled()) {
4520 return;
4521 }
4522
4523 std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now();
4524
4525 // Extended Scanning Timeout
4526
4527 // Generate HCI Connection Complete or Enhanced HCI Connection Complete
4528 // events with Advertising Timeout error code when the advertising
4529 // type is ADV_DIRECT_IND and the connection failed to be established.
4530
4531 if (scanner_.timeout.has_value() &&
4532 !scanner_.periodical_timeout.has_value() &&
4533 now >= scanner_.timeout.value()) {
4534 // At the end of a single scan (Duration non-zero but Period zero),
4535 // an HCI_LE_Scan_Timeout event shall be generated.
4536 LOG_INFO("Extended Scan Timeout");
4537 scanner_.scan_enable = false;
4538 scanner_.history.clear();
4539 if (IsLeEventUnmasked(SubeventCode::SCAN_TIMEOUT)) {
4540 send_event_(bluetooth::hci::LeScanTimeoutBuilder::Create());
4541 }
4542 }
4543
4544 // End of duration with scan enabled
4545 if (scanner_.timeout.has_value() && scanner_.periodical_timeout.has_value() &&
4546 now >= scanner_.timeout.value()) {
4547 scanner_.timeout = {};
4548 }
4549
4550 // End of period
4551 if (!scanner_.timeout.has_value() &&
4552 scanner_.periodical_timeout.has_value() &&
4553 now >= scanner_.periodical_timeout.value()) {
4554 if (scanner_.filter_duplicates == FilterDuplicates::RESET_EACH_PERIOD) {
4555 scanner_.history.clear();
4556 }
4557 scanner_.timeout = now + scanner_.duration;
4558 scanner_.periodical_timeout = now + scanner_.period;
4559 }
4560 }
4561
4562 #ifndef ROOTCANAL_LMP
IncomingPasskeyPacket(model::packets::LinkLayerPacketView incoming)4563 void LinkLayerController::IncomingPasskeyPacket(
4564 model::packets::LinkLayerPacketView incoming) {
4565 auto passkey = model::packets::PasskeyView::Create(incoming);
4566 ASSERT(passkey.IsValid());
4567 SaveKeyAndAuthenticate('P', incoming.GetSourceAddress());
4568 }
4569
IncomingPasskeyFailedPacket(model::packets::LinkLayerPacketView incoming)4570 void LinkLayerController::IncomingPasskeyFailedPacket(
4571 model::packets::LinkLayerPacketView incoming) {
4572 auto failed = model::packets::PasskeyFailedView::Create(incoming);
4573 ASSERT(failed.IsValid());
4574 auto current_peer = incoming.GetSourceAddress();
4575 security_manager_.AuthenticationRequestFinished();
4576 ScheduleTask(kNoDelayMs, [this, current_peer]() {
4577 if (IsEventUnmasked(EventCode::SIMPLE_PAIRING_COMPLETE)) {
4578 send_event_(bluetooth::hci::SimplePairingCompleteBuilder::Create(
4579 ErrorCode::AUTHENTICATION_FAILURE, current_peer));
4580 }
4581 });
4582 }
4583
IncomingPinRequestPacket(model::packets::LinkLayerPacketView incoming)4584 void LinkLayerController::IncomingPinRequestPacket(
4585 model::packets::LinkLayerPacketView incoming) {
4586 auto request = model::packets::PinRequestView::Create(incoming);
4587 ASSERT(request.IsValid());
4588 auto peer = incoming.GetSourceAddress();
4589 auto handle = connections_.GetHandle(AddressWithType(
4590 peer, bluetooth::hci::AddressType::PUBLIC_DEVICE_ADDRESS));
4591 if (handle == kReservedHandle) {
4592 LOG_INFO("Dropping %s request (no connection)", peer.ToString().c_str());
4593 auto wrong_pin = request.GetPinCode();
4594 wrong_pin[0] = wrong_pin[0]++;
4595 SendLinkLayerPacket(model::packets::PinResponseBuilder::Create(
4596 GetAddress(), peer, wrong_pin));
4597 return;
4598 }
4599 if (security_manager_.AuthenticationInProgress()) {
4600 auto current_peer = security_manager_.GetAuthenticationAddress();
4601 if (current_peer != peer) {
4602 LOG_INFO("Dropping %s request (%s in progress)", peer.ToString().c_str(),
4603 current_peer.ToString().c_str());
4604 auto wrong_pin = request.GetPinCode();
4605 wrong_pin[0] = wrong_pin[0]++;
4606 SendLinkLayerPacket(model::packets::PinResponseBuilder::Create(
4607 GetAddress(), peer, wrong_pin));
4608 return;
4609 }
4610 } else {
4611 LOG_INFO("Incoming authentication request %s", peer.ToString().c_str());
4612 security_manager_.AuthenticationRequest(peer, handle, false);
4613 }
4614 auto current_peer = security_manager_.GetAuthenticationAddress();
4615 security_manager_.SetRemotePin(peer, request.GetPinCode());
4616 if (security_manager_.GetPinRequested(peer)) {
4617 if (security_manager_.GetLocalPinResponseReceived(peer)) {
4618 SendLinkLayerPacket(model::packets::PinResponseBuilder::Create(
4619 GetAddress(), peer, request.GetPinCode()));
4620 if (security_manager_.PinCompare()) {
4621 LOG_INFO("Authenticating %s", peer.ToString().c_str());
4622 SaveKeyAndAuthenticate('L', peer); // Legacy
4623 } else {
4624 security_manager_.AuthenticationRequestFinished();
4625 ScheduleTask(kNoDelayMs, [this, peer]() {
4626 if (IsEventUnmasked(EventCode::SIMPLE_PAIRING_COMPLETE)) {
4627 send_event_(bluetooth::hci::SimplePairingCompleteBuilder::Create(
4628 ErrorCode::AUTHENTICATION_FAILURE, peer));
4629 }
4630 });
4631 }
4632 }
4633 } else {
4634 LOG_INFO("PIN pairing %s", GetAddress().ToString().c_str());
4635 ScheduleTask(kNoDelayMs, [this, peer]() {
4636 security_manager_.SetPinRequested(peer);
4637 if (IsEventUnmasked(EventCode::PIN_CODE_REQUEST)) {
4638 send_event_(bluetooth::hci::PinCodeRequestBuilder::Create(peer));
4639 }
4640 });
4641 }
4642 }
4643
IncomingPinResponsePacket(model::packets::LinkLayerPacketView incoming)4644 void LinkLayerController::IncomingPinResponsePacket(
4645 model::packets::LinkLayerPacketView incoming) {
4646 auto request = model::packets::PinResponseView::Create(incoming);
4647 ASSERT(request.IsValid());
4648 auto peer = incoming.GetSourceAddress();
4649 auto handle = connections_.GetHandle(AddressWithType(
4650 peer, bluetooth::hci::AddressType::PUBLIC_DEVICE_ADDRESS));
4651 if (handle == kReservedHandle) {
4652 LOG_INFO("Dropping %s request (no connection)", peer.ToString().c_str());
4653 return;
4654 }
4655 if (security_manager_.AuthenticationInProgress()) {
4656 auto current_peer = security_manager_.GetAuthenticationAddress();
4657 if (current_peer != peer) {
4658 LOG_INFO("Dropping %s request (%s in progress)", peer.ToString().c_str(),
4659 current_peer.ToString().c_str());
4660 return;
4661 }
4662 } else {
4663 LOG_INFO("Dropping response without authentication request %s",
4664 peer.ToString().c_str());
4665 return;
4666 }
4667 auto current_peer = security_manager_.GetAuthenticationAddress();
4668 security_manager_.SetRemotePin(peer, request.GetPinCode());
4669 if (security_manager_.GetPinRequested(peer)) {
4670 if (security_manager_.GetLocalPinResponseReceived(peer)) {
4671 SendLinkLayerPacket(model::packets::PinResponseBuilder::Create(
4672 GetAddress(), peer, request.GetPinCode()));
4673 if (security_manager_.PinCompare()) {
4674 LOG_INFO("Authenticating %s", peer.ToString().c_str());
4675 SaveKeyAndAuthenticate('L', peer); // Legacy
4676 } else {
4677 security_manager_.AuthenticationRequestFinished();
4678 ScheduleTask(kNoDelayMs, [this, peer]() {
4679 if (IsEventUnmasked(EventCode::SIMPLE_PAIRING_COMPLETE)) {
4680 send_event_(bluetooth::hci::SimplePairingCompleteBuilder::Create(
4681 ErrorCode::AUTHENTICATION_FAILURE, peer));
4682 }
4683 });
4684 }
4685 }
4686 } else {
4687 LOG_INFO("PIN pairing %s", GetAddress().ToString().c_str());
4688 ScheduleTask(kNoDelayMs, [this, peer]() {
4689 security_manager_.SetPinRequested(peer);
4690 if (IsEventUnmasked(EventCode::PIN_CODE_REQUEST)) {
4691 send_event_(bluetooth::hci::PinCodeRequestBuilder::Create(peer));
4692 }
4693 });
4694 }
4695 }
4696 #endif /* !ROOTCANAL_LMP */
4697
IncomingPagePacket(model::packets::LinkLayerPacketView incoming)4698 void LinkLayerController::IncomingPagePacket(
4699 model::packets::LinkLayerPacketView incoming) {
4700 auto page = model::packets::PageView::Create(incoming);
4701 ASSERT(page.IsValid());
4702 LOG_INFO("from %s", incoming.GetSourceAddress().ToString().c_str());
4703
4704 if (!connections_.CreatePendingConnection(
4705 incoming.GetSourceAddress(),
4706 authentication_enable_ == AuthenticationEnable::REQUIRED)) {
4707 // Send a response to indicate that we're busy, or drop the packet?
4708 LOG_WARN("Failed to create a pending connection for %s",
4709 incoming.GetSourceAddress().ToString().c_str());
4710 }
4711
4712 bluetooth::hci::Address source_address{};
4713 bluetooth::hci::Address::FromString(page.GetSourceAddress().ToString(),
4714 source_address);
4715
4716 if (IsEventUnmasked(EventCode::CONNECTION_REQUEST)) {
4717 send_event_(bluetooth::hci::ConnectionRequestBuilder::Create(
4718 source_address, page.GetClassOfDevice(),
4719 bluetooth::hci::ConnectionRequestLinkType::ACL));
4720 }
4721 }
4722
IncomingPageRejectPacket(model::packets::LinkLayerPacketView incoming)4723 void LinkLayerController::IncomingPageRejectPacket(
4724 model::packets::LinkLayerPacketView incoming) {
4725 LOG_INFO("%s", incoming.GetSourceAddress().ToString().c_str());
4726 auto reject = model::packets::PageRejectView::Create(incoming);
4727 ASSERT(reject.IsValid());
4728 LOG_INFO("Sending CreateConnectionComplete");
4729 if (IsEventUnmasked(EventCode::CONNECTION_COMPLETE)) {
4730 send_event_(bluetooth::hci::ConnectionCompleteBuilder::Create(
4731 static_cast<ErrorCode>(reject.GetReason()), 0x0eff,
4732 incoming.GetSourceAddress(), bluetooth::hci::LinkType::ACL,
4733 bluetooth::hci::Enable::DISABLED));
4734 }
4735 }
4736
IncomingPageResponsePacket(model::packets::LinkLayerPacketView incoming)4737 void LinkLayerController::IncomingPageResponsePacket(
4738 model::packets::LinkLayerPacketView incoming) {
4739 Address peer = incoming.GetSourceAddress();
4740 LOG_INFO("%s", peer.ToString().c_str());
4741 #ifndef ROOTCANAL_LMP
4742 bool awaiting_authentication = connections_.AuthenticatePendingConnection();
4743 #endif /* !ROOTCANAL_LMP */
4744 uint16_t handle =
4745 connections_.CreateConnection(peer, incoming.GetDestinationAddress());
4746 if (handle == kReservedHandle) {
4747 LOG_WARN("No free handles");
4748 return;
4749 }
4750 CancelScheduledTask(page_timeout_task_id_);
4751 #ifdef ROOTCANAL_LMP
4752 ASSERT(link_manager_add_link(
4753 lm_.get(), reinterpret_cast<const uint8_t(*)[6]>(peer.data())));
4754 #endif /* ROOTCANAL_LMP */
4755
4756 CheckExpiringConnection(handle);
4757
4758 if (IsEventUnmasked(EventCode::CONNECTION_COMPLETE)) {
4759 send_event_(bluetooth::hci::ConnectionCompleteBuilder::Create(
4760 ErrorCode::SUCCESS, handle, incoming.GetSourceAddress(),
4761 bluetooth::hci::LinkType::ACL, bluetooth::hci::Enable::DISABLED));
4762 }
4763
4764 #ifndef ROOTCANAL_LMP
4765 if (awaiting_authentication) {
4766 ScheduleTask(kNoDelayMs, [this, peer, handle]() {
4767 HandleAuthenticationRequest(peer, handle);
4768 });
4769 }
4770 #endif /* !ROOTCANAL_LMP */
4771 }
4772
TimerTick()4773 void LinkLayerController::TimerTick() {
4774 if (inquiry_timer_task_id_ != kInvalidTaskId) Inquiry();
4775 LeAdvertising();
4776 LeScanning();
4777 #ifdef ROOTCANAL_LMP
4778 link_manager_tick(lm_.get());
4779 #endif /* ROOTCANAL_LMP */
4780 }
4781
Close()4782 void LinkLayerController::Close() {
4783 for (auto handle : connections_.GetAclHandles()) {
4784 Disconnect(handle, ErrorCode::CONNECTION_TIMEOUT);
4785 }
4786 }
4787
RegisterEventChannel(const std::function<void (std::shared_ptr<bluetooth::hci::EventBuilder>)> & callback)4788 void LinkLayerController::RegisterEventChannel(
4789 const std::function<void(std::shared_ptr<bluetooth::hci::EventBuilder>)>&
4790 callback) {
4791 send_event_ = callback;
4792 }
4793
RegisterAclChannel(const std::function<void (std::shared_ptr<bluetooth::hci::AclBuilder>)> & callback)4794 void LinkLayerController::RegisterAclChannel(
4795 const std::function<void(std::shared_ptr<bluetooth::hci::AclBuilder>)>&
4796 callback) {
4797 send_acl_ = callback;
4798 }
4799
RegisterScoChannel(const std::function<void (std::shared_ptr<bluetooth::hci::ScoBuilder>)> & callback)4800 void LinkLayerController::RegisterScoChannel(
4801 const std::function<void(std::shared_ptr<bluetooth::hci::ScoBuilder>)>&
4802 callback) {
4803 send_sco_ = callback;
4804 }
4805
RegisterIsoChannel(const std::function<void (std::shared_ptr<bluetooth::hci::IsoBuilder>)> & callback)4806 void LinkLayerController::RegisterIsoChannel(
4807 const std::function<void(std::shared_ptr<bluetooth::hci::IsoBuilder>)>&
4808 callback) {
4809 send_iso_ = callback;
4810 }
4811
RegisterRemoteChannel(const std::function<void (std::shared_ptr<model::packets::LinkLayerPacketBuilder>,Phy::Type)> & callback)4812 void LinkLayerController::RegisterRemoteChannel(
4813 const std::function<void(
4814 std::shared_ptr<model::packets::LinkLayerPacketBuilder>, Phy::Type)>&
4815 callback) {
4816 send_to_remote_ = callback;
4817 }
4818
RegisterTaskScheduler(std::function<AsyncTaskId (milliseconds,const TaskCallback &)> event_scheduler)4819 void LinkLayerController::RegisterTaskScheduler(
4820 std::function<AsyncTaskId(milliseconds, const TaskCallback&)>
4821 event_scheduler) {
4822 schedule_task_ = event_scheduler;
4823 }
4824
ScheduleTask(milliseconds delay_ms,const TaskCallback & callback)4825 AsyncTaskId LinkLayerController::ScheduleTask(milliseconds delay_ms,
4826 const TaskCallback& callback) {
4827 if (schedule_task_) {
4828 return schedule_task_(delay_ms, callback);
4829 } else if (delay_ms == milliseconds::zero()) {
4830 callback();
4831 return 0;
4832 } else {
4833 LOG_ERROR("Unable to schedule task on delay");
4834 return 0;
4835 }
4836 }
4837
SchedulePeriodicTask(milliseconds delay_ms,milliseconds period_ms,const TaskCallback & callback)4838 AsyncTaskId LinkLayerController::SchedulePeriodicTask(
4839 milliseconds delay_ms, milliseconds period_ms,
4840 const TaskCallback& callback) {
4841 if (schedule_periodic_task_) {
4842 return schedule_periodic_task_(delay_ms, period_ms, callback);
4843 } else {
4844 LOG_ERROR("Unable to schedule task on delay");
4845 return 0;
4846 }
4847 }
4848
RegisterPeriodicTaskScheduler(std::function<AsyncTaskId (milliseconds,milliseconds,const TaskCallback &)> periodic_event_scheduler)4849 void LinkLayerController::RegisterPeriodicTaskScheduler(
4850 std::function<AsyncTaskId(milliseconds, milliseconds, const TaskCallback&)>
4851 periodic_event_scheduler) {
4852 schedule_periodic_task_ = periodic_event_scheduler;
4853 }
4854
CancelScheduledTask(AsyncTaskId task_id)4855 void LinkLayerController::CancelScheduledTask(AsyncTaskId task_id) {
4856 if (schedule_task_ && cancel_task_) {
4857 cancel_task_(task_id);
4858 }
4859 }
4860
RegisterTaskCancel(std::function<void (AsyncTaskId)> task_cancel)4861 void LinkLayerController::RegisterTaskCancel(
4862 std::function<void(AsyncTaskId)> task_cancel) {
4863 cancel_task_ = task_cancel;
4864 }
4865
4866 #ifdef ROOTCANAL_LMP
ForwardToLm(bluetooth::hci::CommandView command)4867 void LinkLayerController::ForwardToLm(bluetooth::hci::CommandView command) {
4868 auto packet = std::vector(command.begin(), command.end());
4869 ASSERT(link_manager_ingest_hci(lm_.get(), packet.data(), packet.size()));
4870 }
4871 #else
StartSimplePairing(const Address & address)4872 void LinkLayerController::StartSimplePairing(const Address& address) {
4873 // IO Capability Exchange (See the Diagram in the Spec)
4874 if (IsEventUnmasked(EventCode::IO_CAPABILITY_REQUEST)) {
4875 send_event_(bluetooth::hci::IoCapabilityRequestBuilder::Create(address));
4876 }
4877
4878 // Get a Key, then authenticate
4879 // PublicKeyExchange(address);
4880 // AuthenticateRemoteStage1(address);
4881 // AuthenticateRemoteStage2(address);
4882 }
4883
AuthenticateRemoteStage1(const Address & peer,PairingType pairing_type)4884 void LinkLayerController::AuthenticateRemoteStage1(const Address& peer,
4885 PairingType pairing_type) {
4886 ASSERT(security_manager_.GetAuthenticationAddress() == peer);
4887 // TODO: Public key exchange first?
4888 switch (pairing_type) {
4889 case PairingType::AUTO_CONFIRMATION:
4890 if (IsEventUnmasked(EventCode::USER_CONFIRMATION_REQUEST)) {
4891 send_event_(bluetooth::hci::UserConfirmationRequestBuilder::Create(
4892 peer, 123456));
4893 }
4894 break;
4895 case PairingType::CONFIRM_Y_N:
4896 if (IsEventUnmasked(EventCode::USER_CONFIRMATION_REQUEST)) {
4897 send_event_(bluetooth::hci::UserConfirmationRequestBuilder::Create(
4898 peer, 123456));
4899 }
4900 break;
4901 case PairingType::DISPLAY_PIN:
4902 if (IsEventUnmasked(EventCode::USER_PASSKEY_NOTIFICATION)) {
4903 send_event_(bluetooth::hci::UserPasskeyNotificationBuilder::Create(
4904 peer, 123456));
4905 }
4906 break;
4907 case PairingType::DISPLAY_AND_CONFIRM:
4908 if (IsEventUnmasked(EventCode::USER_CONFIRMATION_REQUEST)) {
4909 send_event_(bluetooth::hci::UserConfirmationRequestBuilder::Create(
4910 peer, 123456));
4911 }
4912 break;
4913 case PairingType::INPUT_PIN:
4914 if (IsEventUnmasked(EventCode::USER_PASSKEY_REQUEST)) {
4915 send_event_(bluetooth::hci::UserPasskeyRequestBuilder::Create(peer));
4916 }
4917 break;
4918 case PairingType::OUT_OF_BAND:
4919 LOG_INFO("Oob data request for %s", peer.ToString().c_str());
4920 if (IsEventUnmasked(EventCode::REMOTE_OOB_DATA_REQUEST)) {
4921 send_event_(bluetooth::hci::RemoteOobDataRequestBuilder::Create(peer));
4922 }
4923 break;
4924 case PairingType::PEER_HAS_OUT_OF_BAND:
4925 LOG_INFO("Trusting that %s has OOB data", peer.ToString().c_str());
4926 SaveKeyAndAuthenticate('P', peer);
4927 break;
4928 default:
4929 LOG_ALWAYS_FATAL("Invalid PairingType %d",
4930 static_cast<int>(pairing_type));
4931 }
4932 }
4933
AuthenticateRemoteStage2(const Address & peer)4934 void LinkLayerController::AuthenticateRemoteStage2(const Address& peer) {
4935 uint16_t handle = security_manager_.GetAuthenticationHandle();
4936 ASSERT(security_manager_.GetAuthenticationAddress() == peer);
4937 // Check key in security_manager_ ?
4938 if (security_manager_.IsInitiator()) {
4939 if (IsEventUnmasked(EventCode::AUTHENTICATION_COMPLETE)) {
4940 send_event_(bluetooth::hci::AuthenticationCompleteBuilder::Create(
4941 ErrorCode::SUCCESS, handle));
4942 }
4943 }
4944 }
4945
LinkKeyRequestReply(const Address & peer,const std::array<uint8_t,16> & key)4946 ErrorCode LinkLayerController::LinkKeyRequestReply(
4947 const Address& peer, const std::array<uint8_t, 16>& key) {
4948 security_manager_.WriteKey(peer, key);
4949 security_manager_.AuthenticationRequestFinished();
4950
4951 ScheduleTask(kNoDelayMs, [this, peer]() { AuthenticateRemoteStage2(peer); });
4952
4953 return ErrorCode::SUCCESS;
4954 }
4955
LinkKeyRequestNegativeReply(const Address & address)4956 ErrorCode LinkLayerController::LinkKeyRequestNegativeReply(
4957 const Address& address) {
4958 security_manager_.DeleteKey(address);
4959 // Simple pairing to get a key
4960 uint16_t handle = connections_.GetHandleOnlyAddress(address);
4961 if (handle == kReservedHandle) {
4962 LOG_INFO("Device not connected %s", address.ToString().c_str());
4963 return ErrorCode::UNKNOWN_CONNECTION;
4964 }
4965
4966 if (secure_simple_pairing_host_support_) {
4967 if (!security_manager_.AuthenticationInProgress()) {
4968 security_manager_.AuthenticationRequest(address, handle, false);
4969 }
4970
4971 ScheduleTask(kNoDelayMs,
4972 [this, address]() { StartSimplePairing(address); });
4973 } else {
4974 LOG_INFO("PIN pairing %s", GetAddress().ToString().c_str());
4975 ScheduleTask(kNoDelayMs, [this, address]() {
4976 security_manager_.SetPinRequested(address);
4977 if (IsEventUnmasked(EventCode::PIN_CODE_REQUEST)) {
4978 send_event_(bluetooth::hci::PinCodeRequestBuilder::Create(address));
4979 }
4980 });
4981 }
4982 return ErrorCode::SUCCESS;
4983 }
4984
IoCapabilityRequestReply(const Address & peer,uint8_t io_capability,uint8_t oob_data_present_flag,uint8_t authentication_requirements)4985 ErrorCode LinkLayerController::IoCapabilityRequestReply(
4986 const Address& peer, uint8_t io_capability, uint8_t oob_data_present_flag,
4987 uint8_t authentication_requirements) {
4988 security_manager_.SetLocalIoCapability(
4989 peer, io_capability, oob_data_present_flag, authentication_requirements);
4990
4991 PairingType pairing_type = security_manager_.GetSimplePairingType();
4992
4993 if (pairing_type != PairingType::INVALID) {
4994 ScheduleTask(kNoDelayMs, [this, peer, pairing_type]() {
4995 AuthenticateRemoteStage1(peer, pairing_type);
4996 });
4997 SendLinkLayerPacket(model::packets::IoCapabilityResponseBuilder::Create(
4998 GetAddress(), peer, io_capability, oob_data_present_flag,
4999 authentication_requirements));
5000 } else {
5001 LOG_INFO("Requesting remote capability");
5002
5003 SendLinkLayerPacket(model::packets::IoCapabilityRequestBuilder::Create(
5004 GetAddress(), peer, io_capability, oob_data_present_flag,
5005 authentication_requirements));
5006 }
5007
5008 return ErrorCode::SUCCESS;
5009 }
5010
IoCapabilityRequestNegativeReply(const Address & peer,ErrorCode reason)5011 ErrorCode LinkLayerController::IoCapabilityRequestNegativeReply(
5012 const Address& peer, ErrorCode reason) {
5013 if (security_manager_.GetAuthenticationAddress() != peer) {
5014 return ErrorCode::AUTHENTICATION_FAILURE;
5015 }
5016
5017 security_manager_.InvalidateIoCapabilities();
5018
5019 SendLinkLayerPacket(
5020 model::packets::IoCapabilityNegativeResponseBuilder::Create(
5021 GetAddress(), peer, static_cast<uint8_t>(reason)));
5022
5023 return ErrorCode::SUCCESS;
5024 }
5025
SaveKeyAndAuthenticate(uint8_t key_type,const Address & peer)5026 void LinkLayerController::SaveKeyAndAuthenticate(uint8_t key_type,
5027 const Address& peer) {
5028 std::array<uint8_t, 16> key_vec{'k',
5029 'e',
5030 'y',
5031 ' ',
5032 key_type,
5033 5,
5034 6,
5035 7,
5036 8,
5037 9,
5038 10,
5039 11,
5040 12,
5041 13,
5042 static_cast<uint8_t>(key_id_ >> 8u),
5043 static_cast<uint8_t>(key_id_)};
5044 key_id_ += 1;
5045 security_manager_.WriteKey(peer, key_vec);
5046
5047 security_manager_.AuthenticationRequestFinished();
5048
5049 if (key_type == 'L') {
5050 // Legacy
5051 ScheduleTask(kNoDelayMs, [this, peer, key_vec]() {
5052 if (IsEventUnmasked(EventCode::LINK_KEY_NOTIFICATION)) {
5053 send_event_(bluetooth::hci::LinkKeyNotificationBuilder::Create(
5054 peer, key_vec, bluetooth::hci::KeyType::AUTHENTICATED_P192));
5055 }
5056 });
5057 } else {
5058 ScheduleTask(kNoDelayMs, [this, peer]() {
5059 if (IsEventUnmasked(EventCode::SIMPLE_PAIRING_COMPLETE)) {
5060 send_event_(bluetooth::hci::SimplePairingCompleteBuilder::Create(
5061 ErrorCode::SUCCESS, peer));
5062 }
5063 });
5064
5065 ScheduleTask(kNoDelayMs, [this, peer, key_vec]() {
5066 if (IsEventUnmasked(EventCode::LINK_KEY_NOTIFICATION)) {
5067 send_event_(bluetooth::hci::LinkKeyNotificationBuilder::Create(
5068 peer, key_vec, bluetooth::hci::KeyType::AUTHENTICATED_P256));
5069 }
5070 });
5071 }
5072
5073 ScheduleTask(kNoDelayMs, [this, peer]() { AuthenticateRemoteStage2(peer); });
5074 }
5075
PinCodeRequestReply(const Address & peer,std::vector<uint8_t> pin)5076 ErrorCode LinkLayerController::PinCodeRequestReply(const Address& peer,
5077 std::vector<uint8_t> pin) {
5078 LOG_INFO("%s", GetAddress().ToString().c_str());
5079 auto current_peer = security_manager_.GetAuthenticationAddress();
5080 if (peer != current_peer) {
5081 LOG_INFO("%s: %s != %s", GetAddress().ToString().c_str(),
5082 peer.ToString().c_str(), current_peer.ToString().c_str());
5083 security_manager_.AuthenticationRequestFinished();
5084 ScheduleTask(kNoDelayMs, [this, current_peer]() {
5085 if (IsEventUnmasked(EventCode::SIMPLE_PAIRING_COMPLETE)) {
5086 send_event_(bluetooth::hci::SimplePairingCompleteBuilder::Create(
5087 ErrorCode::AUTHENTICATION_FAILURE, current_peer));
5088 }
5089 });
5090 return ErrorCode::UNKNOWN_CONNECTION;
5091 }
5092 if (!security_manager_.GetPinRequested(peer)) {
5093 LOG_INFO("No Pin Requested for %s", peer.ToString().c_str());
5094 return ErrorCode::COMMAND_DISALLOWED;
5095 }
5096 security_manager_.SetLocalPin(peer, pin);
5097 if (security_manager_.GetRemotePinResponseReceived(peer)) {
5098 if (security_manager_.PinCompare()) {
5099 LOG_INFO("Authenticating %s", peer.ToString().c_str());
5100 SaveKeyAndAuthenticate('L', peer); // Legacy
5101 } else {
5102 security_manager_.AuthenticationRequestFinished();
5103 ScheduleTask(kNoDelayMs, [this, peer]() {
5104 if (IsEventUnmasked(EventCode::SIMPLE_PAIRING_COMPLETE)) {
5105 send_event_(bluetooth::hci::SimplePairingCompleteBuilder::Create(
5106 ErrorCode::AUTHENTICATION_FAILURE, peer));
5107 }
5108 });
5109 }
5110 } else {
5111 SendLinkLayerPacket(
5112 model::packets::PinRequestBuilder::Create(GetAddress(), peer, pin));
5113 }
5114 return ErrorCode::SUCCESS;
5115 }
5116
PinCodeRequestNegativeReply(const Address & peer)5117 ErrorCode LinkLayerController::PinCodeRequestNegativeReply(
5118 const Address& peer) {
5119 auto current_peer = security_manager_.GetAuthenticationAddress();
5120 security_manager_.AuthenticationRequestFinished();
5121 ScheduleTask(kNoDelayMs, [this, current_peer]() {
5122 if (IsEventUnmasked(EventCode::SIMPLE_PAIRING_COMPLETE)) {
5123 send_event_(bluetooth::hci::SimplePairingCompleteBuilder::Create(
5124 ErrorCode::AUTHENTICATION_FAILURE, current_peer));
5125 }
5126 });
5127 if (peer != current_peer) {
5128 return ErrorCode::UNKNOWN_CONNECTION;
5129 }
5130 if (!security_manager_.GetPinRequested(peer)) {
5131 LOG_INFO("No Pin Requested for %s", peer.ToString().c_str());
5132 return ErrorCode::COMMAND_DISALLOWED;
5133 }
5134 return ErrorCode::SUCCESS;
5135 }
5136
UserConfirmationRequestReply(const Address & peer)5137 ErrorCode LinkLayerController::UserConfirmationRequestReply(
5138 const Address& peer) {
5139 if (security_manager_.GetAuthenticationAddress() != peer) {
5140 return ErrorCode::AUTHENTICATION_FAILURE;
5141 }
5142 SaveKeyAndAuthenticate('U', peer);
5143 return ErrorCode::SUCCESS;
5144 }
5145
UserConfirmationRequestNegativeReply(const Address & peer)5146 ErrorCode LinkLayerController::UserConfirmationRequestNegativeReply(
5147 const Address& peer) {
5148 auto current_peer = security_manager_.GetAuthenticationAddress();
5149 security_manager_.AuthenticationRequestFinished();
5150 ScheduleTask(kNoDelayMs, [this, current_peer]() {
5151 if (IsEventUnmasked(EventCode::SIMPLE_PAIRING_COMPLETE)) {
5152 send_event_(bluetooth::hci::SimplePairingCompleteBuilder::Create(
5153 ErrorCode::AUTHENTICATION_FAILURE, current_peer));
5154 }
5155 });
5156 if (peer != current_peer) {
5157 return ErrorCode::UNKNOWN_CONNECTION;
5158 }
5159 return ErrorCode::SUCCESS;
5160 }
5161
UserPasskeyRequestReply(const Address & peer,uint32_t numeric_value)5162 ErrorCode LinkLayerController::UserPasskeyRequestReply(const Address& peer,
5163 uint32_t numeric_value) {
5164 if (security_manager_.GetAuthenticationAddress() != peer) {
5165 return ErrorCode::AUTHENTICATION_FAILURE;
5166 }
5167 SendLinkLayerPacket(model::packets::PasskeyBuilder::Create(GetAddress(), peer,
5168 numeric_value));
5169 SaveKeyAndAuthenticate('P', peer);
5170
5171 return ErrorCode::SUCCESS;
5172 }
5173
UserPasskeyRequestNegativeReply(const Address & peer)5174 ErrorCode LinkLayerController::UserPasskeyRequestNegativeReply(
5175 const Address& peer) {
5176 auto current_peer = security_manager_.GetAuthenticationAddress();
5177 security_manager_.AuthenticationRequestFinished();
5178 ScheduleTask(kNoDelayMs, [this, current_peer]() {
5179 if (IsEventUnmasked(EventCode::SIMPLE_PAIRING_COMPLETE)) {
5180 send_event_(bluetooth::hci::SimplePairingCompleteBuilder::Create(
5181 ErrorCode::AUTHENTICATION_FAILURE, current_peer));
5182 }
5183 });
5184 if (peer != current_peer) {
5185 return ErrorCode::UNKNOWN_CONNECTION;
5186 }
5187 return ErrorCode::SUCCESS;
5188 }
5189
RemoteOobDataRequestReply(const Address & peer,const std::array<uint8_t,16> & c,const std::array<uint8_t,16> & r)5190 ErrorCode LinkLayerController::RemoteOobDataRequestReply(
5191 const Address& peer, const std::array<uint8_t, 16>& c,
5192 const std::array<uint8_t, 16>& r) {
5193 if (security_manager_.GetAuthenticationAddress() != peer) {
5194 return ErrorCode::AUTHENTICATION_FAILURE;
5195 }
5196 LOG_INFO("TODO:Do something with the OOB data c=%d r=%d", c[0], r[0]);
5197 SaveKeyAndAuthenticate('o', peer);
5198
5199 return ErrorCode::SUCCESS;
5200 }
5201
RemoteOobDataRequestNegativeReply(const Address & peer)5202 ErrorCode LinkLayerController::RemoteOobDataRequestNegativeReply(
5203 const Address& peer) {
5204 auto current_peer = security_manager_.GetAuthenticationAddress();
5205 security_manager_.AuthenticationRequestFinished();
5206 ScheduleTask(kNoDelayMs, [this, current_peer]() {
5207 if (IsEventUnmasked(EventCode::SIMPLE_PAIRING_COMPLETE)) {
5208 send_event_(bluetooth::hci::SimplePairingCompleteBuilder::Create(
5209 ErrorCode::AUTHENTICATION_FAILURE, current_peer));
5210 }
5211 });
5212 if (peer != current_peer) {
5213 return ErrorCode::UNKNOWN_CONNECTION;
5214 }
5215 return ErrorCode::SUCCESS;
5216 }
5217
RemoteOobExtendedDataRequestReply(const Address & peer,const std::array<uint8_t,16> & c192,const std::array<uint8_t,16> & r192,const std::array<uint8_t,16> & c256,const std::array<uint8_t,16> & r256)5218 ErrorCode LinkLayerController::RemoteOobExtendedDataRequestReply(
5219 const Address& peer, const std::array<uint8_t, 16>& c192,
5220 const std::array<uint8_t, 16>& r192, const std::array<uint8_t, 16>& c256,
5221 const std::array<uint8_t, 16>& r256) {
5222 if (security_manager_.GetAuthenticationAddress() != peer) {
5223 return ErrorCode::AUTHENTICATION_FAILURE;
5224 }
5225 LOG_INFO(
5226 "TODO:Do something with the OOB data c192=%d r192=%d c256=%d r256=%d",
5227 c192[0], r192[0], c256[0], r256[0]);
5228 SaveKeyAndAuthenticate('O', peer);
5229
5230 return ErrorCode::SUCCESS;
5231 }
5232
SendKeypressNotification(const Address & peer,bluetooth::hci::KeypressNotificationType notification_type)5233 ErrorCode LinkLayerController::SendKeypressNotification(
5234 const Address& peer,
5235 bluetooth::hci::KeypressNotificationType notification_type) {
5236 if (notification_type >
5237 bluetooth::hci::KeypressNotificationType::ENTRY_COMPLETED) {
5238 return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
5239 }
5240
5241 SendLinkLayerPacket(model::packets::KeypressNotificationBuilder::Create(
5242 GetAddress(), peer,
5243 static_cast<model::packets::PasskeyNotificationType>(notification_type)));
5244 return ErrorCode::SUCCESS;
5245 }
5246
HandleAuthenticationRequest(const Address & address,uint16_t handle)5247 void LinkLayerController::HandleAuthenticationRequest(const Address& address,
5248 uint16_t handle) {
5249 security_manager_.AuthenticationRequest(address, handle, true);
5250 if (IsEventUnmasked(EventCode::LINK_KEY_REQUEST)) {
5251 send_event_(bluetooth::hci::LinkKeyRequestBuilder::Create(address));
5252 }
5253 }
5254
AuthenticationRequested(uint16_t handle)5255 ErrorCode LinkLayerController::AuthenticationRequested(uint16_t handle) {
5256 if (!connections_.HasHandle(handle)) {
5257 LOG_INFO("Authentication Requested for unknown handle %04x", handle);
5258 return ErrorCode::UNKNOWN_CONNECTION;
5259 }
5260
5261 AddressWithType remote = connections_.GetAddress(handle);
5262
5263 ScheduleTask(kNoDelayMs, [this, remote, handle]() {
5264 HandleAuthenticationRequest(remote.GetAddress(), handle);
5265 });
5266
5267 return ErrorCode::SUCCESS;
5268 }
5269
HandleSetConnectionEncryption(const Address & peer,uint16_t handle,uint8_t encryption_enable)5270 void LinkLayerController::HandleSetConnectionEncryption(
5271 const Address& peer, uint16_t handle, uint8_t encryption_enable) {
5272 // TODO: Block ACL traffic or at least guard against it
5273
5274 if (connections_.IsEncrypted(handle) && encryption_enable) {
5275 if (IsEventUnmasked(EventCode::ENCRYPTION_CHANGE)) {
5276 send_event_(bluetooth::hci::EncryptionChangeBuilder::Create(
5277 ErrorCode::SUCCESS, handle,
5278 static_cast<bluetooth::hci::EncryptionEnabled>(encryption_enable)));
5279 }
5280 return;
5281 }
5282
5283 uint16_t count = security_manager_.ReadKey(peer);
5284 if (count == 0) {
5285 LOG_ERROR("NO KEY HERE for %s", peer.ToString().c_str());
5286 return;
5287 }
5288 auto array = security_manager_.GetKey(peer);
5289 std::vector<uint8_t> key_vec{array.begin(), array.end()};
5290 SendLinkLayerPacket(model::packets::EncryptConnectionBuilder::Create(
5291 GetAddress(), peer, key_vec));
5292 }
5293
SetConnectionEncryption(uint16_t handle,uint8_t encryption_enable)5294 ErrorCode LinkLayerController::SetConnectionEncryption(
5295 uint16_t handle, uint8_t encryption_enable) {
5296 if (!connections_.HasHandle(handle)) {
5297 LOG_INFO("Set Connection Encryption for unknown handle %04x", handle);
5298 return ErrorCode::UNKNOWN_CONNECTION;
5299 }
5300
5301 if (connections_.IsEncrypted(handle) && !encryption_enable) {
5302 return ErrorCode::ENCRYPTION_MODE_NOT_ACCEPTABLE;
5303 }
5304 AddressWithType remote = connections_.GetAddress(handle);
5305
5306 if (security_manager_.ReadKey(remote.GetAddress()) == 0) {
5307 return ErrorCode::PIN_OR_KEY_MISSING;
5308 }
5309
5310 ScheduleTask(kNoDelayMs, [this, remote, handle, encryption_enable]() {
5311 HandleSetConnectionEncryption(remote.GetAddress(), handle,
5312 encryption_enable);
5313 });
5314 return ErrorCode::SUCCESS;
5315 }
5316 #endif /* ROOTCANAL_LMP */
5317
ReadCurrentIacLap() const5318 std::vector<bluetooth::hci::Lap> const& LinkLayerController::ReadCurrentIacLap()
5319 const {
5320 return current_iac_lap_list_;
5321 }
5322
WriteCurrentIacLap(std::vector<bluetooth::hci::Lap> iac_lap)5323 void LinkLayerController::WriteCurrentIacLap(
5324 std::vector<bluetooth::hci::Lap> iac_lap) {
5325 current_iac_lap_list_.swap(iac_lap);
5326
5327 // If Num_Current_IAC is greater than Num_Supported_IAC then only the first
5328 // Num_Supported_IAC shall be stored in the Controller
5329 if (current_iac_lap_list_.size() > properties_.num_supported_iac) {
5330 current_iac_lap_list_.resize(properties_.num_supported_iac);
5331 }
5332 }
5333
AcceptConnectionRequest(const Address & bd_addr,bool try_role_switch)5334 ErrorCode LinkLayerController::AcceptConnectionRequest(const Address& bd_addr,
5335 bool try_role_switch) {
5336 if (connections_.HasPendingConnection(bd_addr)) {
5337 LOG_INFO("Accepting connection request from %s",
5338 bd_addr.ToString().c_str());
5339 ScheduleTask(kNoDelayMs, [this, bd_addr, try_role_switch]() {
5340 LOG_INFO("Accepted connection from %s", bd_addr.ToString().c_str());
5341 MakePeripheralConnection(bd_addr, try_role_switch);
5342 });
5343
5344 return ErrorCode::SUCCESS;
5345 }
5346
5347 // The HCI command Accept Connection may be used to accept incoming SCO
5348 // connection requests.
5349 if (connections_.HasPendingScoConnection(bd_addr)) {
5350 ErrorCode status = ErrorCode::SUCCESS;
5351 uint16_t sco_handle = 0;
5352 ScoLinkParameters link_parameters = {};
5353 ScoConnectionParameters connection_parameters =
5354 connections_.GetScoConnectionParameters(bd_addr);
5355
5356 if (!connections_.AcceptPendingScoConnection(
5357 bd_addr, connection_parameters, [this, bd_addr] {
5358 return LinkLayerController::StartScoStream(bd_addr);
5359 })) {
5360 connections_.CancelPendingScoConnection(bd_addr);
5361 status = ErrorCode::SCO_INTERVAL_REJECTED; // TODO: proper status code
5362 } else {
5363 sco_handle = connections_.GetScoHandle(bd_addr);
5364 link_parameters = connections_.GetScoLinkParameters(bd_addr);
5365 }
5366
5367 // Send eSCO connection response to peer.
5368 SendLinkLayerPacket(model::packets::ScoConnectionResponseBuilder::Create(
5369 GetAddress(), bd_addr, (uint8_t)status,
5370 link_parameters.transmission_interval,
5371 link_parameters.retransmission_window, link_parameters.rx_packet_length,
5372 link_parameters.tx_packet_length, link_parameters.air_mode,
5373 link_parameters.extended));
5374
5375 // Schedule HCI Connection Complete event.
5376 ScheduleTask(kNoDelayMs, [this, status, sco_handle, bd_addr]() {
5377 send_event_(bluetooth::hci::ConnectionCompleteBuilder::Create(
5378 ErrorCode(status), sco_handle, bd_addr, bluetooth::hci::LinkType::SCO,
5379 bluetooth::hci::Enable::DISABLED));
5380 });
5381
5382 return ErrorCode::SUCCESS;
5383 }
5384
5385 LOG_INFO("No pending connection for %s", bd_addr.ToString().c_str());
5386 return ErrorCode::UNKNOWN_CONNECTION;
5387 }
5388
MakePeripheralConnection(const Address & addr,bool try_role_switch)5389 void LinkLayerController::MakePeripheralConnection(const Address& addr,
5390 bool try_role_switch) {
5391 LOG_INFO("Sending page response to %s", addr.ToString().c_str());
5392 SendLinkLayerPacket(model::packets::PageResponseBuilder::Create(
5393 GetAddress(), addr, try_role_switch));
5394
5395 uint16_t handle = connections_.CreateConnection(addr, GetAddress());
5396 if (handle == kReservedHandle) {
5397 LOG_INFO("CreateConnection failed");
5398 return;
5399 }
5400 #ifdef ROOTCANAL_LMP
5401 ASSERT(link_manager_add_link(
5402 lm_.get(), reinterpret_cast<const uint8_t(*)[6]>(addr.data())));
5403 #endif /* ROOTCANAL_LMP */
5404
5405 CheckExpiringConnection(handle);
5406
5407 LOG_INFO("CreateConnection returned handle 0x%x", handle);
5408 if (IsEventUnmasked(EventCode::CONNECTION_COMPLETE)) {
5409 send_event_(bluetooth::hci::ConnectionCompleteBuilder::Create(
5410 ErrorCode::SUCCESS, handle, addr, bluetooth::hci::LinkType::ACL,
5411 bluetooth::hci::Enable::DISABLED));
5412 }
5413 }
5414
RejectConnectionRequest(const Address & addr,uint8_t reason)5415 ErrorCode LinkLayerController::RejectConnectionRequest(const Address& addr,
5416 uint8_t reason) {
5417 if (!connections_.HasPendingConnection(addr)) {
5418 LOG_INFO("No pending connection for %s", addr.ToString().c_str());
5419 return ErrorCode::UNKNOWN_CONNECTION;
5420 }
5421
5422 ScheduleTask(kNoDelayMs, [this, addr, reason]() {
5423 RejectPeripheralConnection(addr, reason);
5424 });
5425
5426 return ErrorCode::SUCCESS;
5427 }
5428
RejectPeripheralConnection(const Address & addr,uint8_t reason)5429 void LinkLayerController::RejectPeripheralConnection(const Address& addr,
5430 uint8_t reason) {
5431 LOG_INFO("Sending page reject to %s (reason 0x%02hhx)",
5432 addr.ToString().c_str(), reason);
5433 SendLinkLayerPacket(
5434 model::packets::PageRejectBuilder::Create(GetAddress(), addr, reason));
5435
5436 if (IsEventUnmasked(EventCode::CONNECTION_COMPLETE)) {
5437 send_event_(bluetooth::hci::ConnectionCompleteBuilder::Create(
5438 static_cast<ErrorCode>(reason), 0xeff, addr,
5439 bluetooth::hci::LinkType::ACL, bluetooth::hci::Enable::DISABLED));
5440 }
5441 }
5442
CreateConnection(const Address & addr,uint16_t,uint8_t,uint16_t,uint8_t allow_role_switch)5443 ErrorCode LinkLayerController::CreateConnection(const Address& addr, uint16_t,
5444 uint8_t, uint16_t,
5445 uint8_t allow_role_switch) {
5446 if (!connections_.CreatePendingConnection(
5447 addr, authentication_enable_ == AuthenticationEnable::REQUIRED)) {
5448 return ErrorCode::CONTROLLER_BUSY;
5449 }
5450
5451 page_timeout_task_id_ = ScheduleTask(
5452 duration_cast<milliseconds>(page_timeout_ * microseconds(625)),
5453 [this, addr] {
5454 send_event_(bluetooth::hci::ConnectionCompleteBuilder::Create(
5455 ErrorCode::PAGE_TIMEOUT, 0xeff, addr, bluetooth::hci::LinkType::ACL,
5456 bluetooth::hci::Enable::DISABLED));
5457 });
5458
5459 SendLinkLayerPacket(model::packets::PageBuilder::Create(
5460 GetAddress(), addr, class_of_device_, allow_role_switch));
5461
5462 return ErrorCode::SUCCESS;
5463 }
5464
CreateConnectionCancel(const Address & addr)5465 ErrorCode LinkLayerController::CreateConnectionCancel(const Address& addr) {
5466 if (!connections_.CancelPendingConnection(addr)) {
5467 return ErrorCode::UNKNOWN_CONNECTION;
5468 }
5469 CancelScheduledTask(page_timeout_task_id_);
5470 return ErrorCode::SUCCESS;
5471 }
5472
SendDisconnectionCompleteEvent(uint16_t handle,ErrorCode reason)5473 void LinkLayerController::SendDisconnectionCompleteEvent(uint16_t handle,
5474 ErrorCode reason) {
5475 if (IsEventUnmasked(EventCode::DISCONNECTION_COMPLETE)) {
5476 ScheduleTask(kNoDelayMs, [this, handle, reason]() {
5477 send_event_(bluetooth::hci::DisconnectionCompleteBuilder::Create(
5478 ErrorCode::SUCCESS, handle, reason));
5479 });
5480 }
5481 }
5482
Disconnect(uint16_t handle,ErrorCode reason)5483 ErrorCode LinkLayerController::Disconnect(uint16_t handle, ErrorCode reason) {
5484 if (connections_.HasScoHandle(handle)) {
5485 const Address remote = connections_.GetScoAddress(handle);
5486 LOG_INFO("Disconnecting eSCO connection with %s",
5487 remote.ToString().c_str());
5488
5489 SendLinkLayerPacket(model::packets::ScoDisconnectBuilder::Create(
5490 GetAddress(), remote, static_cast<uint8_t>(reason)));
5491
5492 connections_.Disconnect(handle, cancel_task_);
5493 SendDisconnectionCompleteEvent(handle, reason);
5494 return ErrorCode::SUCCESS;
5495 }
5496
5497 if (!connections_.HasHandle(handle)) {
5498 return ErrorCode::UNKNOWN_CONNECTION;
5499 }
5500
5501 const AddressWithType remote = connections_.GetAddress(handle);
5502 auto is_br_edr = connections_.GetPhyType(handle) == Phy::Type::BR_EDR;
5503
5504 if (is_br_edr) {
5505 LOG_INFO("Disconnecting ACL connection with %s", remote.ToString().c_str());
5506
5507 uint16_t sco_handle = connections_.GetScoHandle(remote.GetAddress());
5508 if (sco_handle != kReservedHandle) {
5509 SendLinkLayerPacket(model::packets::ScoDisconnectBuilder::Create(
5510 GetAddress(), remote.GetAddress(), static_cast<uint8_t>(reason)));
5511
5512 connections_.Disconnect(sco_handle, cancel_task_);
5513 SendDisconnectionCompleteEvent(sco_handle, reason);
5514 }
5515
5516 SendLinkLayerPacket(model::packets::DisconnectBuilder::Create(
5517 GetAddress(), remote.GetAddress(), static_cast<uint8_t>(reason)));
5518 } else {
5519 LOG_INFO("Disconnecting LE connection with %s", remote.ToString().c_str());
5520
5521 SendLeLinkLayerPacket(model::packets::DisconnectBuilder::Create(
5522 connections_.GetOwnAddress(handle).GetAddress(), remote.GetAddress(),
5523 static_cast<uint8_t>(reason)));
5524 }
5525
5526 connections_.Disconnect(handle, cancel_task_);
5527 SendDisconnectionCompleteEvent(handle, ErrorCode(reason));
5528 #ifdef ROOTCANAL_LMP
5529 if (is_br_edr) {
5530 ASSERT(link_manager_remove_link(
5531 lm_.get(),
5532 reinterpret_cast<uint8_t(*)[6]>(remote.GetAddress().data())));
5533 }
5534 #endif
5535 return ErrorCode::SUCCESS;
5536 }
5537
ChangeConnectionPacketType(uint16_t handle,uint16_t types)5538 ErrorCode LinkLayerController::ChangeConnectionPacketType(uint16_t handle,
5539 uint16_t types) {
5540 if (!connections_.HasHandle(handle)) {
5541 return ErrorCode::UNKNOWN_CONNECTION;
5542 }
5543
5544 ScheduleTask(kNoDelayMs, [this, handle, types]() {
5545 if (IsEventUnmasked(EventCode::CONNECTION_PACKET_TYPE_CHANGED)) {
5546 send_event_(bluetooth::hci::ConnectionPacketTypeChangedBuilder::Create(
5547 ErrorCode::SUCCESS, handle, types));
5548 }
5549 });
5550
5551 return ErrorCode::SUCCESS;
5552 }
5553
ChangeConnectionLinkKey(uint16_t handle)5554 ErrorCode LinkLayerController::ChangeConnectionLinkKey(uint16_t handle) {
5555 if (!connections_.HasHandle(handle)) {
5556 return ErrorCode::UNKNOWN_CONNECTION;
5557 }
5558
5559 // TODO: implement real logic
5560 return ErrorCode::COMMAND_DISALLOWED;
5561 }
5562
CentralLinkKey(uint8_t)5563 ErrorCode LinkLayerController::CentralLinkKey(uint8_t /* key_flag */) {
5564 // TODO: implement real logic
5565 return ErrorCode::COMMAND_DISALLOWED;
5566 }
5567
HoldMode(uint16_t handle,uint16_t hold_mode_max_interval,uint16_t hold_mode_min_interval)5568 ErrorCode LinkLayerController::HoldMode(uint16_t handle,
5569 uint16_t hold_mode_max_interval,
5570 uint16_t hold_mode_min_interval) {
5571 if (!connections_.HasHandle(handle)) {
5572 return ErrorCode::UNKNOWN_CONNECTION;
5573 }
5574
5575 if (hold_mode_max_interval < hold_mode_min_interval) {
5576 return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
5577 }
5578
5579 // TODO: implement real logic
5580 return ErrorCode::COMMAND_DISALLOWED;
5581 }
5582
SniffMode(uint16_t handle,uint16_t sniff_max_interval,uint16_t sniff_min_interval,uint16_t sniff_attempt,uint16_t sniff_timeout)5583 ErrorCode LinkLayerController::SniffMode(uint16_t handle,
5584 uint16_t sniff_max_interval,
5585 uint16_t sniff_min_interval,
5586 uint16_t sniff_attempt,
5587 uint16_t sniff_timeout) {
5588 if (!connections_.HasHandle(handle)) {
5589 return ErrorCode::UNKNOWN_CONNECTION;
5590 }
5591
5592 if (sniff_max_interval < sniff_min_interval || sniff_attempt < 0x0001 ||
5593 sniff_attempt > 0x7FFF || sniff_timeout > 0x7FFF) {
5594 return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
5595 }
5596
5597 // TODO: implement real logic
5598 return ErrorCode::COMMAND_DISALLOWED;
5599 }
5600
ExitSniffMode(uint16_t handle)5601 ErrorCode LinkLayerController::ExitSniffMode(uint16_t handle) {
5602 if (!connections_.HasHandle(handle)) {
5603 return ErrorCode::UNKNOWN_CONNECTION;
5604 }
5605
5606 // TODO: implement real logic
5607 return ErrorCode::COMMAND_DISALLOWED;
5608 }
5609
QosSetup(uint16_t handle,uint8_t service_type,uint32_t,uint32_t,uint32_t,uint32_t)5610 ErrorCode LinkLayerController::QosSetup(uint16_t handle, uint8_t service_type,
5611 uint32_t /* token_rate */,
5612 uint32_t /* peak_bandwidth */,
5613 uint32_t /* latency */,
5614 uint32_t /* delay_variation */) {
5615 if (!connections_.HasHandle(handle)) {
5616 return ErrorCode::UNKNOWN_CONNECTION;
5617 }
5618
5619 if (service_type > 0x02) {
5620 return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
5621 }
5622
5623 // TODO: implement real logic
5624 return ErrorCode::COMMAND_DISALLOWED;
5625 }
5626
RoleDiscovery(uint16_t handle,bluetooth::hci::Role * role)5627 ErrorCode LinkLayerController::RoleDiscovery(uint16_t handle,
5628 bluetooth::hci::Role* role) {
5629 if (!connections_.HasHandle(handle)) {
5630 return ErrorCode::UNKNOWN_CONNECTION;
5631 }
5632 *role = connections_.GetAclRole(handle);
5633 return ErrorCode::SUCCESS;
5634 }
5635
SwitchRole(Address addr,bluetooth::hci::Role role)5636 ErrorCode LinkLayerController::SwitchRole(Address addr,
5637 bluetooth::hci::Role role) {
5638 auto handle = connections_.GetHandleOnlyAddress(addr);
5639 if (handle == rootcanal::kReservedHandle) {
5640 return ErrorCode::UNKNOWN_CONNECTION;
5641 }
5642 connections_.SetAclRole(handle, role);
5643 ScheduleTask(kNoDelayMs, [this, addr, role]() {
5644 send_event_(bluetooth::hci::RoleChangeBuilder::Create(ErrorCode::SUCCESS,
5645 addr, role));
5646 });
5647 return ErrorCode::SUCCESS;
5648 }
5649
ReadLinkPolicySettings(uint16_t handle,uint16_t * settings)5650 ErrorCode LinkLayerController::ReadLinkPolicySettings(uint16_t handle,
5651 uint16_t* settings) {
5652 if (!connections_.HasHandle(handle)) {
5653 return ErrorCode::UNKNOWN_CONNECTION;
5654 }
5655 *settings = connections_.GetAclLinkPolicySettings(handle);
5656 return ErrorCode::SUCCESS;
5657 }
5658
WriteLinkPolicySettings(uint16_t handle,uint16_t settings)5659 ErrorCode LinkLayerController::WriteLinkPolicySettings(uint16_t handle,
5660 uint16_t settings) {
5661 if (!connections_.HasHandle(handle)) {
5662 return ErrorCode::UNKNOWN_CONNECTION;
5663 }
5664 if (settings > 7 /* Sniff + Hold + Role switch */) {
5665 return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
5666 }
5667 connections_.SetAclLinkPolicySettings(handle, settings);
5668 return ErrorCode::SUCCESS;
5669 }
5670
WriteDefaultLinkPolicySettings(uint16_t settings)5671 ErrorCode LinkLayerController::WriteDefaultLinkPolicySettings(
5672 uint16_t settings) {
5673 if (settings > 7 /* Sniff + Hold + Role switch */) {
5674 return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
5675 }
5676 default_link_policy_settings_ = settings;
5677 return ErrorCode::SUCCESS;
5678 }
5679
ReadDefaultLinkPolicySettings()5680 uint16_t LinkLayerController::ReadDefaultLinkPolicySettings() {
5681 return default_link_policy_settings_;
5682 }
5683
ReadLocalOobData()5684 void LinkLayerController::ReadLocalOobData() {
5685 std::array<uint8_t, 16> c_array(
5686 {'c', ' ', 'a', 'r', 'r', 'a', 'y', ' ', '0', '0', '0', '0', '0', '0',
5687 static_cast<uint8_t>((oob_id_ % 0x10000) >> 8u),
5688 static_cast<uint8_t>(oob_id_ % 0x100)});
5689
5690 std::array<uint8_t, 16> r_array(
5691 {'r', ' ', 'a', 'r', 'r', 'a', 'y', ' ', '0', '0', '0', '0', '0', '0',
5692 static_cast<uint8_t>((oob_id_ % 0x10000) >> 8u),
5693 static_cast<uint8_t>(oob_id_ % 0x100)});
5694
5695 send_event_(bluetooth::hci::ReadLocalOobDataCompleteBuilder::Create(
5696 1, ErrorCode::SUCCESS, c_array, r_array));
5697 oob_id_ += 1;
5698 }
5699
ReadLocalOobExtendedData()5700 void LinkLayerController::ReadLocalOobExtendedData() {
5701 std::array<uint8_t, 16> c_192_array(
5702 {'c', ' ', 'a', 'r', 'r', 'a', 'y', ' ', '1', '9', '2', '0', '0', '0',
5703 static_cast<uint8_t>((oob_id_ % 0x10000) >> 8u),
5704 static_cast<uint8_t>(oob_id_ % 0x100)});
5705
5706 std::array<uint8_t, 16> r_192_array(
5707 {'r', ' ', 'a', 'r', 'r', 'a', 'y', ' ', '1', '9', '2', '0', '0', '0',
5708 static_cast<uint8_t>((oob_id_ % 0x10000) >> 8u),
5709 static_cast<uint8_t>(oob_id_ % 0x100)});
5710
5711 std::array<uint8_t, 16> c_256_array(
5712 {'c', ' ', 'a', 'r', 'r', 'a', 'y', ' ', '2', '5', '6', '0', '0', '0',
5713 static_cast<uint8_t>((oob_id_ % 0x10000) >> 8u),
5714 static_cast<uint8_t>(oob_id_ % 0x100)});
5715
5716 std::array<uint8_t, 16> r_256_array(
5717 {'r', ' ', 'a', 'r', 'r', 'a', 'y', ' ', '2', '5', '6', '0', '0', '0',
5718 static_cast<uint8_t>((oob_id_ % 0x10000) >> 8u),
5719 static_cast<uint8_t>(oob_id_ % 0x100)});
5720
5721 send_event_(bluetooth::hci::ReadLocalOobExtendedDataCompleteBuilder::Create(
5722 1, ErrorCode::SUCCESS, c_192_array, r_192_array, c_256_array,
5723 r_256_array));
5724 oob_id_ += 1;
5725 }
5726
FlowSpecification(uint16_t handle,uint8_t flow_direction,uint8_t service_type,uint32_t,uint32_t,uint32_t,uint32_t)5727 ErrorCode LinkLayerController::FlowSpecification(
5728 uint16_t handle, uint8_t flow_direction, uint8_t service_type,
5729 uint32_t /* token_rate */, uint32_t /* token_bucket_size */,
5730 uint32_t /* peak_bandwidth */, uint32_t /* access_latency */) {
5731 if (!connections_.HasHandle(handle)) {
5732 return ErrorCode::UNKNOWN_CONNECTION;
5733 }
5734
5735 if (flow_direction > 0x01 || service_type > 0x02) {
5736 return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
5737 }
5738
5739 // TODO: implement real logic
5740 return ErrorCode::COMMAND_DISALLOWED;
5741 }
5742
WriteLinkSupervisionTimeout(uint16_t handle,uint16_t)5743 ErrorCode LinkLayerController::WriteLinkSupervisionTimeout(uint16_t handle,
5744 uint16_t) {
5745 if (!connections_.HasHandle(handle)) {
5746 return ErrorCode::UNKNOWN_CONNECTION;
5747 }
5748 return ErrorCode::SUCCESS;
5749 }
5750
LeConnectionUpdateComplete(uint16_t handle,uint16_t interval_min,uint16_t interval_max,uint16_t latency,uint16_t supervision_timeout)5751 void LinkLayerController::LeConnectionUpdateComplete(
5752 uint16_t handle, uint16_t interval_min, uint16_t interval_max,
5753 uint16_t latency, uint16_t supervision_timeout) {
5754 ErrorCode status = ErrorCode::SUCCESS;
5755 if (!connections_.HasHandle(handle)) {
5756 status = ErrorCode::UNKNOWN_CONNECTION;
5757 }
5758
5759 if (interval_min < 6 || interval_max > 0xC80 || interval_min > interval_max ||
5760 interval_max < interval_min || latency > 0x1F3 ||
5761 supervision_timeout < 0xA || supervision_timeout > 0xC80 ||
5762 // The Supervision_Timeout in milliseconds (*10) shall be larger than (1 +
5763 // Connection_Latency) * Connection_Interval_Max (* 5/4) * 2
5764 supervision_timeout <= ((((1 + latency) * interval_max * 10) / 4) / 10)) {
5765 status = ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
5766 }
5767 uint16_t interval = (interval_min + interval_max) / 2;
5768
5769 SendLeLinkLayerPacket(LeConnectionParameterUpdateBuilder::Create(
5770 connections_.GetOwnAddress(handle).GetAddress(),
5771 connections_.GetAddress(handle).GetAddress(),
5772 static_cast<uint8_t>(ErrorCode::SUCCESS), interval, latency,
5773 supervision_timeout));
5774
5775 if (IsLeEventUnmasked(SubeventCode::CONNECTION_UPDATE_COMPLETE)) {
5776 send_event_(bluetooth::hci::LeConnectionUpdateCompleteBuilder::Create(
5777 status, handle, interval, latency, supervision_timeout));
5778 }
5779 }
5780
LeConnectionUpdate(uint16_t handle,uint16_t interval_min,uint16_t interval_max,uint16_t latency,uint16_t supervision_timeout)5781 ErrorCode LinkLayerController::LeConnectionUpdate(
5782 uint16_t handle, uint16_t interval_min, uint16_t interval_max,
5783 uint16_t latency, uint16_t supervision_timeout) {
5784 if (!connections_.HasHandle(handle)) {
5785 return ErrorCode::UNKNOWN_CONNECTION;
5786 }
5787
5788 bluetooth::hci::Role role = connections_.GetAclRole(handle);
5789
5790 if (role == bluetooth::hci::Role::CENTRAL) {
5791 // As Central, it is allowed to directly send
5792 // LL_CONNECTION_PARAM_UPDATE_IND to update the parameters.
5793 SendLeLinkLayerPacket(LeConnectionParameterUpdateBuilder::Create(
5794 connections_.GetOwnAddress(handle).GetAddress(),
5795 connections_.GetAddress(handle).GetAddress(),
5796 static_cast<uint8_t>(ErrorCode::SUCCESS), interval_max, latency,
5797 supervision_timeout));
5798
5799 if (IsLeEventUnmasked(SubeventCode::CONNECTION_UPDATE_COMPLETE)) {
5800 send_event_(bluetooth::hci::LeConnectionUpdateCompleteBuilder::Create(
5801 ErrorCode::SUCCESS, handle, interval_max, latency,
5802 supervision_timeout));
5803 }
5804 } else {
5805 // Send LL_CONNECTION_PARAM_REQ and wait for LL_CONNECTION_PARAM_RSP
5806 // in return.
5807 SendLeLinkLayerPacket(LeConnectionParameterRequestBuilder::Create(
5808 connections_.GetOwnAddress(handle).GetAddress(),
5809 connections_.GetAddress(handle).GetAddress(), interval_min,
5810 interval_max, latency, supervision_timeout));
5811 }
5812
5813 return ErrorCode::SUCCESS;
5814 }
5815
LeRemoteConnectionParameterRequestReply(uint16_t connection_handle,uint16_t interval_min,uint16_t interval_max,uint16_t timeout,uint16_t latency,uint16_t minimum_ce_length,uint16_t maximum_ce_length)5816 ErrorCode LinkLayerController::LeRemoteConnectionParameterRequestReply(
5817 uint16_t connection_handle, uint16_t interval_min, uint16_t interval_max,
5818 uint16_t timeout, uint16_t latency, uint16_t minimum_ce_length,
5819 uint16_t maximum_ce_length) {
5820 if (!connections_.HasHandle(connection_handle)) {
5821 return ErrorCode::UNKNOWN_CONNECTION;
5822 }
5823
5824 if ((interval_min > interval_max) ||
5825 (minimum_ce_length > maximum_ce_length)) {
5826 return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
5827 }
5828
5829 ScheduleTask(kNoDelayMs, [this, connection_handle, interval_min, interval_max,
5830 latency, timeout]() {
5831 LeConnectionUpdateComplete(connection_handle, interval_min, interval_max,
5832 latency, timeout);
5833 });
5834 return ErrorCode::SUCCESS;
5835 }
5836
LeRemoteConnectionParameterRequestNegativeReply(uint16_t connection_handle,bluetooth::hci::ErrorCode reason)5837 ErrorCode LinkLayerController::LeRemoteConnectionParameterRequestNegativeReply(
5838 uint16_t connection_handle, bluetooth::hci::ErrorCode reason) {
5839 if (!connections_.HasHandle(connection_handle)) {
5840 return ErrorCode::UNKNOWN_CONNECTION;
5841 }
5842
5843 uint16_t interval = 0;
5844 uint16_t latency = 0;
5845 uint16_t timeout = 0;
5846 SendLeLinkLayerPacket(LeConnectionParameterUpdateBuilder::Create(
5847 connections_.GetOwnAddress(connection_handle).GetAddress(),
5848 connections_.GetAddress(connection_handle).GetAddress(),
5849 static_cast<uint8_t>(reason), interval, latency, timeout));
5850 return ErrorCode::SUCCESS;
5851 }
5852
HasAclConnection()5853 bool LinkLayerController::HasAclConnection() {
5854 return (connections_.GetAclHandles().size() > 0);
5855 }
5856
LeReadIsoTxSync(uint16_t)5857 void LinkLayerController::LeReadIsoTxSync(uint16_t /* handle */) {}
5858
LeSetCigParameters(uint8_t cig_id,uint32_t sdu_interval_m_to_s,uint32_t sdu_interval_s_to_m,bluetooth::hci::ClockAccuracy clock_accuracy,bluetooth::hci::Packing packing,bluetooth::hci::Enable framing,uint16_t max_transport_latency_m_to_s,uint16_t max_transport_latency_s_to_m,std::vector<bluetooth::hci::CisParametersConfig> cis_config)5859 void LinkLayerController::LeSetCigParameters(
5860 uint8_t cig_id, uint32_t sdu_interval_m_to_s, uint32_t sdu_interval_s_to_m,
5861 bluetooth::hci::ClockAccuracy clock_accuracy,
5862 bluetooth::hci::Packing packing, bluetooth::hci::Enable framing,
5863 uint16_t max_transport_latency_m_to_s,
5864 uint16_t max_transport_latency_s_to_m,
5865 std::vector<bluetooth::hci::CisParametersConfig> cis_config) {
5866 if (IsEventUnmasked(EventCode::LE_META_EVENT)) {
5867 send_event_(connections_.SetCigParameters(
5868 cig_id, sdu_interval_m_to_s, sdu_interval_s_to_m, clock_accuracy,
5869 packing, framing, max_transport_latency_m_to_s,
5870 max_transport_latency_s_to_m, cis_config));
5871 }
5872 }
5873
LeCreateCis(std::vector<bluetooth::hci::CreateCisConfig> cis_config)5874 ErrorCode LinkLayerController::LeCreateCis(
5875 std::vector<bluetooth::hci::CreateCisConfig> cis_config) {
5876 if (connections_.HasPendingCis()) {
5877 return ErrorCode::COMMAND_DISALLOWED;
5878 }
5879 for (auto& config : cis_config) {
5880 if (!connections_.HasHandle(config.acl_connection_handle_)) {
5881 LOG_INFO("Unknown ACL handle %04x", config.acl_connection_handle_);
5882 return ErrorCode::UNKNOWN_CONNECTION;
5883 }
5884 if (!connections_.HasCisHandle(config.cis_connection_handle_)) {
5885 LOG_INFO("Unknown CIS handle %04x", config.cis_connection_handle_);
5886 return ErrorCode::UNKNOWN_CONNECTION;
5887 }
5888 }
5889 for (auto& config : cis_config) {
5890 connections_.CreatePendingCis(config);
5891 auto own_address =
5892 connections_.GetOwnAddress(config.acl_connection_handle_);
5893 auto peer_address = connections_.GetAddress(config.acl_connection_handle_);
5894 StreamParameters stream_parameters =
5895 connections_.GetStreamParameters(config.cis_connection_handle_);
5896 GroupParameters group_parameters =
5897 connections_.GetGroupParameters(stream_parameters.group_id);
5898
5899 SendLeLinkLayerPacket(model::packets::IsoConnectionRequestBuilder::Create(
5900 own_address.GetAddress(), peer_address.GetAddress(),
5901 stream_parameters.group_id, group_parameters.sdu_interval_m_to_s,
5902 group_parameters.sdu_interval_s_to_m, group_parameters.interleaved,
5903 group_parameters.framed, group_parameters.max_transport_latency_m_to_s,
5904 group_parameters.max_transport_latency_s_to_m,
5905 stream_parameters.stream_id, stream_parameters.max_sdu_m_to_s,
5906 stream_parameters.max_sdu_s_to_m, config.cis_connection_handle_,
5907 config.acl_connection_handle_));
5908 }
5909 return ErrorCode::SUCCESS;
5910 }
5911
LeRemoveCig(uint8_t cig_id)5912 ErrorCode LinkLayerController::LeRemoveCig(uint8_t cig_id) {
5913 return connections_.RemoveCig(cig_id);
5914 }
5915
LeAcceptCisRequest(uint16_t cis_handle)5916 ErrorCode LinkLayerController::LeAcceptCisRequest(uint16_t cis_handle) {
5917 if (!connections_.HasPendingCisConnection(cis_handle)) {
5918 return ErrorCode::UNKNOWN_CONNECTION;
5919 }
5920 auto acl_handle = connections_.GetPendingAclHandle(cis_handle);
5921
5922 connections_.ConnectCis(cis_handle);
5923
5924 SendLeLinkLayerPacket(model::packets::IsoConnectionResponseBuilder::Create(
5925 connections_.GetOwnAddress(acl_handle).GetAddress(),
5926 connections_.GetAddress(acl_handle).GetAddress(),
5927 static_cast<uint8_t>(ErrorCode::SUCCESS), cis_handle, acl_handle,
5928 connections_.GetRemoteCisHandleForCisHandle(cis_handle)));
5929
5930 // Both sides have to send LeCisEstablished event
5931
5932 uint32_t cig_sync_delay = 0x100;
5933 uint32_t cis_sync_delay = 0x200;
5934 uint32_t latency_m_to_s = 0x200;
5935 uint32_t latency_s_to_m = 0x200;
5936 uint8_t nse = 1;
5937 uint8_t bn_m_to_s = 0;
5938 uint8_t bn_s_to_m = 0;
5939 uint8_t ft_m_to_s = 0;
5940 uint8_t ft_s_to_m = 0;
5941 uint8_t max_pdu_m_to_s = 0x40;
5942 uint8_t max_pdu_s_to_m = 0x40;
5943 uint16_t iso_interval = 0x100;
5944 if (IsEventUnmasked(EventCode::LE_META_EVENT)) {
5945 send_event_(bluetooth::hci::LeCisEstablishedBuilder::Create(
5946 ErrorCode::SUCCESS, cis_handle, cig_sync_delay, cis_sync_delay,
5947 latency_m_to_s, latency_s_to_m,
5948 bluetooth::hci::SecondaryPhyType::NO_PACKETS,
5949 bluetooth::hci::SecondaryPhyType::NO_PACKETS, nse, bn_m_to_s, bn_s_to_m,
5950 ft_m_to_s, ft_s_to_m, max_pdu_m_to_s, max_pdu_s_to_m, iso_interval));
5951 }
5952 return ErrorCode::SUCCESS;
5953 }
5954
LeRejectCisRequest(uint16_t cis_handle,ErrorCode reason)5955 ErrorCode LinkLayerController::LeRejectCisRequest(uint16_t cis_handle,
5956 ErrorCode reason) {
5957 if (!connections_.HasPendingCisConnection(cis_handle)) {
5958 return ErrorCode::UNKNOWN_CONNECTION;
5959 }
5960 auto acl_handle = connections_.GetPendingAclHandle(cis_handle);
5961
5962 SendLeLinkLayerPacket(model::packets::IsoConnectionResponseBuilder::Create(
5963 connections_.GetOwnAddress(acl_handle).GetAddress(),
5964 connections_.GetAddress(acl_handle).GetAddress(),
5965 static_cast<uint8_t>(reason), acl_handle, cis_handle, kReservedHandle));
5966 connections_.RejectCis(cis_handle);
5967 return ErrorCode::SUCCESS;
5968 }
5969
LeCreateBig(uint8_t,uint8_t,uint8_t,uint32_t,uint16_t,uint16_t,uint8_t,bluetooth::hci::SecondaryPhyType,bluetooth::hci::Packing,bluetooth::hci::Enable,bluetooth::hci::Enable,std::array<uint8_t,16>)5970 ErrorCode LinkLayerController::LeCreateBig(
5971 uint8_t /* big_handle */, uint8_t /* advertising_handle */,
5972 uint8_t /* num_bis */, uint32_t /* sdu_interval */, uint16_t /* max_sdu */,
5973 uint16_t /* max_transport_latency */, uint8_t /* rtn */,
5974 bluetooth::hci::SecondaryPhyType /* phy */,
5975 bluetooth::hci::Packing /* packing */, bluetooth::hci::Enable /* framing */,
5976 bluetooth::hci::Enable /* encryption */,
5977 std::array<uint8_t, 16> /* broadcast_code */) {
5978 return ErrorCode::SUCCESS;
5979 }
5980
LeTerminateBig(uint8_t,ErrorCode)5981 ErrorCode LinkLayerController::LeTerminateBig(uint8_t /* big_handle */,
5982 ErrorCode /* reason */) {
5983 return ErrorCode::SUCCESS;
5984 }
5985
LeBigCreateSync(uint8_t,uint16_t,bluetooth::hci::Enable,std::array<uint8_t,16>,uint8_t,uint16_t,std::vector<uint8_t>)5986 ErrorCode LinkLayerController::LeBigCreateSync(
5987 uint8_t /* big_handle */, uint16_t /* sync_handle */,
5988 bluetooth::hci::Enable /* encryption */,
5989 std::array<uint8_t, 16> /* broadcast_code */, uint8_t /* mse */,
5990 uint16_t /* big_sync_timeout */, std::vector<uint8_t> /* bis */) {
5991 return ErrorCode::SUCCESS;
5992 }
5993
LeBigTerminateSync(uint8_t)5994 void LinkLayerController::LeBigTerminateSync(uint8_t /* big_handle */) {}
5995
LeRequestPeerSca(uint16_t)5996 ErrorCode LinkLayerController::LeRequestPeerSca(uint16_t /* request_handle */) {
5997 return ErrorCode::SUCCESS;
5998 }
5999
LeSetupIsoDataPath(uint16_t,bluetooth::hci::DataPathDirection,uint8_t,uint64_t,uint32_t,std::vector<uint8_t>)6000 void LinkLayerController::LeSetupIsoDataPath(
6001 uint16_t /* connection_handle */,
6002 bluetooth::hci::DataPathDirection /* data_path_direction */,
6003 uint8_t /* data_path_id */, uint64_t /* codec_id */,
6004 uint32_t /* controller_Delay */,
6005 std::vector<uint8_t> /* codec_configuration */) {}
6006
LeRemoveIsoDataPath(uint16_t,bluetooth::hci::RemoveDataPathDirection)6007 void LinkLayerController::LeRemoveIsoDataPath(
6008 uint16_t /* connection_handle */,
6009 bluetooth::hci::RemoveDataPathDirection /* remove_data_path_direction */) {}
6010
HandleLeEnableEncryption(uint16_t handle,std::array<uint8_t,8> rand,uint16_t ediv,std::array<uint8_t,16> ltk)6011 void LinkLayerController::HandleLeEnableEncryption(
6012 uint16_t handle, std::array<uint8_t, 8> rand, uint16_t ediv,
6013 std::array<uint8_t, 16> ltk) {
6014 // TODO: Check keys
6015 // TODO: Block ACL traffic or at least guard against it
6016 if (!connections_.HasHandle(handle)) {
6017 return;
6018 }
6019 SendLeLinkLayerPacket(model::packets::LeEncryptConnectionBuilder::Create(
6020 connections_.GetOwnAddress(handle).GetAddress(),
6021 connections_.GetAddress(handle).GetAddress(), rand, ediv, ltk));
6022 }
6023
LeEnableEncryption(uint16_t handle,std::array<uint8_t,8> rand,uint16_t ediv,std::array<uint8_t,16> ltk)6024 ErrorCode LinkLayerController::LeEnableEncryption(uint16_t handle,
6025 std::array<uint8_t, 8> rand,
6026 uint16_t ediv,
6027 std::array<uint8_t, 16> ltk) {
6028 if (!connections_.HasHandle(handle)) {
6029 LOG_INFO("Unknown handle %04x", handle);
6030 return ErrorCode::UNKNOWN_CONNECTION;
6031 }
6032
6033 ScheduleTask(kNoDelayMs, [this, handle, rand, ediv, ltk]() {
6034 HandleLeEnableEncryption(handle, rand, ediv, ltk);
6035 });
6036 return ErrorCode::SUCCESS;
6037 }
6038
LeLongTermKeyRequestReply(uint16_t handle,std::array<uint8_t,16> ltk)6039 ErrorCode LinkLayerController::LeLongTermKeyRequestReply(
6040 uint16_t handle, std::array<uint8_t, 16> ltk) {
6041 if (!connections_.HasHandle(handle)) {
6042 LOG_INFO("Unknown handle %04x", handle);
6043 return ErrorCode::UNKNOWN_CONNECTION;
6044 }
6045
6046 // TODO: Check keys
6047 if (connections_.IsEncrypted(handle)) {
6048 if (IsEventUnmasked(EventCode::ENCRYPTION_KEY_REFRESH_COMPLETE)) {
6049 send_event_(bluetooth::hci::EncryptionKeyRefreshCompleteBuilder::Create(
6050 ErrorCode::SUCCESS, handle));
6051 }
6052 } else {
6053 connections_.Encrypt(handle);
6054 if (IsEventUnmasked(EventCode::ENCRYPTION_CHANGE)) {
6055 send_event_(bluetooth::hci::EncryptionChangeBuilder::Create(
6056 ErrorCode::SUCCESS, handle, bluetooth::hci::EncryptionEnabled::ON));
6057 }
6058 }
6059 SendLeLinkLayerPacket(
6060 model::packets::LeEncryptConnectionResponseBuilder::Create(
6061 connections_.GetOwnAddress(handle).GetAddress(),
6062 connections_.GetAddress(handle).GetAddress(),
6063 std::array<uint8_t, 8>(), uint16_t(), ltk));
6064
6065 return ErrorCode::SUCCESS;
6066 }
6067
LeLongTermKeyRequestNegativeReply(uint16_t handle)6068 ErrorCode LinkLayerController::LeLongTermKeyRequestNegativeReply(
6069 uint16_t handle) {
6070 if (!connections_.HasHandle(handle)) {
6071 LOG_INFO("Unknown handle %04x", handle);
6072 return ErrorCode::UNKNOWN_CONNECTION;
6073 }
6074
6075 SendLeLinkLayerPacket(
6076 model::packets::LeEncryptConnectionResponseBuilder::Create(
6077 connections_.GetOwnAddress(handle).GetAddress(),
6078 connections_.GetAddress(handle).GetAddress(),
6079 std::array<uint8_t, 8>(), uint16_t(), std::array<uint8_t, 16>()));
6080 return ErrorCode::SUCCESS;
6081 }
6082
Reset()6083 void LinkLayerController::Reset() {
6084 host_supported_features_ = 0;
6085 le_host_support_ = false;
6086 secure_simple_pairing_host_support_ = false;
6087 secure_connections_host_support_ = false;
6088 le_host_supported_features_ = 0;
6089 connected_isochronous_stream_host_support_ = false;
6090 connection_subrating_host_support_ = false;
6091 random_address_ = Address::kEmpty;
6092 page_scan_enable_ = false;
6093 inquiry_scan_enable_ = false;
6094 inquiry_scan_interval_ = 0x1000;
6095 inquiry_scan_window_ = 0x0012;
6096 page_timeout_ = 0x2000;
6097 connection_accept_timeout_ = 0x1FA0;
6098 page_scan_interval_ = 0x0800;
6099 page_scan_window_ = 0x0012;
6100 voice_setting_ = 0x0060;
6101 authentication_enable_ = AuthenticationEnable::NOT_REQUIRED;
6102 default_link_policy_settings_ = 0x0000;
6103 sco_flow_control_enable_ = false;
6104 local_name_.fill(0);
6105 extended_inquiry_response_.fill(0);
6106 class_of_device_ = ClassOfDevice({0, 0, 0});
6107 min_encryption_key_size_ = 16;
6108 event_mask_ = 0x00001fffffffffff;
6109 event_mask_page_2_ = 0x0;
6110 le_event_mask_ = 0x01f;
6111 le_suggested_max_tx_octets_ = 0x001b;
6112 le_suggested_max_tx_time_ = 0x0148;
6113 resolvable_private_address_timeout_ = std::chrono::seconds(0x0384);
6114 page_scan_repetition_mode_ = PageScanRepetitionMode::R0;
6115 connections_ = AclConnectionHandler();
6116 oob_id_ = 1;
6117 key_id_ = 1;
6118 le_filter_accept_list_.clear();
6119 le_resolving_list_.clear();
6120 le_resolving_list_enabled_ = false;
6121 legacy_advertising_in_use_ = false;
6122 extended_advertising_in_use_ = false;
6123 legacy_advertiser_ = LegacyAdvertiser{};
6124 extended_advertisers_.clear();
6125 scanner_ = Scanner{};
6126 initiator_ = Initiator{};
6127 last_inquiry_ = steady_clock::now();
6128 inquiry_mode_ = InquiryType::STANDARD;
6129 inquiry_lap_ = 0;
6130 inquiry_max_responses_ = 0;
6131
6132 bluetooth::hci::Lap general_iac;
6133 general_iac.lap_ = 0x33; // 0x9E8B33
6134 current_iac_lap_list_.clear();
6135 current_iac_lap_list_.emplace_back(general_iac);
6136
6137 if (inquiry_timer_task_id_ != kInvalidTaskId) {
6138 CancelScheduledTask(inquiry_timer_task_id_);
6139 inquiry_timer_task_id_ = kInvalidTaskId;
6140 }
6141
6142 if (page_timeout_task_id_ != kInvalidTaskId) {
6143 CancelScheduledTask(page_timeout_task_id_);
6144 page_timeout_task_id_ = kInvalidTaskId;
6145 }
6146
6147 #ifdef ROOTCANAL_LMP
6148 lm_.reset(link_manager_create(ops_));
6149 #else
6150 security_manager_ = SecurityManager(10);
6151 #endif
6152 }
6153
StartInquiry(milliseconds timeout)6154 void LinkLayerController::StartInquiry(milliseconds timeout) {
6155 inquiry_timer_task_id_ = ScheduleTask(milliseconds(timeout), [this]() {
6156 LinkLayerController::InquiryTimeout();
6157 });
6158 }
6159
InquiryCancel()6160 void LinkLayerController::InquiryCancel() {
6161 ASSERT(inquiry_timer_task_id_ != kInvalidTaskId);
6162 CancelScheduledTask(inquiry_timer_task_id_);
6163 inquiry_timer_task_id_ = kInvalidTaskId;
6164 }
6165
InquiryTimeout()6166 void LinkLayerController::InquiryTimeout() {
6167 if (inquiry_timer_task_id_ != kInvalidTaskId) {
6168 inquiry_timer_task_id_ = kInvalidTaskId;
6169 if (IsEventUnmasked(EventCode::INQUIRY_COMPLETE)) {
6170 send_event_(
6171 bluetooth::hci::InquiryCompleteBuilder::Create(ErrorCode::SUCCESS));
6172 }
6173 }
6174 }
6175
SetInquiryMode(uint8_t mode)6176 void LinkLayerController::SetInquiryMode(uint8_t mode) {
6177 inquiry_mode_ = static_cast<model::packets::InquiryType>(mode);
6178 }
6179
SetInquiryLAP(uint64_t lap)6180 void LinkLayerController::SetInquiryLAP(uint64_t lap) { inquiry_lap_ = lap; }
6181
SetInquiryMaxResponses(uint8_t max)6182 void LinkLayerController::SetInquiryMaxResponses(uint8_t max) {
6183 inquiry_max_responses_ = max;
6184 }
6185
Inquiry()6186 void LinkLayerController::Inquiry() {
6187 steady_clock::time_point now = steady_clock::now();
6188 if (duration_cast<milliseconds>(now - last_inquiry_) < milliseconds(2000)) {
6189 return;
6190 }
6191
6192 SendLinkLayerPacket(model::packets::InquiryBuilder::Create(
6193 GetAddress(), Address::kEmpty, inquiry_mode_, inquiry_lap_));
6194 last_inquiry_ = now;
6195 }
6196
SetInquiryScanEnable(bool enable)6197 void LinkLayerController::SetInquiryScanEnable(bool enable) {
6198 inquiry_scan_enable_ = enable;
6199 }
6200
SetPageScanEnable(bool enable)6201 void LinkLayerController::SetPageScanEnable(bool enable) {
6202 page_scan_enable_ = enable;
6203 }
6204
GetPageTimeout()6205 uint16_t LinkLayerController::GetPageTimeout() { return page_timeout_; }
6206
SetPageTimeout(uint16_t page_timeout)6207 void LinkLayerController::SetPageTimeout(uint16_t page_timeout) {
6208 page_timeout_ = page_timeout;
6209 }
6210
AddScoConnection(uint16_t connection_handle,uint16_t packet_type,ScoDatapath datapath)6211 ErrorCode LinkLayerController::AddScoConnection(uint16_t connection_handle,
6212 uint16_t packet_type,
6213 ScoDatapath datapath) {
6214 if (!connections_.HasHandle(connection_handle)) {
6215 return ErrorCode::UNKNOWN_CONNECTION;
6216 }
6217
6218 Address bd_addr = connections_.GetAddress(connection_handle).GetAddress();
6219 if (connections_.HasPendingScoConnection(bd_addr)) {
6220 return ErrorCode::COMMAND_DISALLOWED;
6221 }
6222
6223 LOG_INFO("Creating SCO connection with %s", bd_addr.ToString().c_str());
6224
6225 // Save connection parameters.
6226 ScoConnectionParameters connection_parameters = {
6227 8000,
6228 8000,
6229 0xffff,
6230 0x60 /* 16bit CVSD */,
6231 (uint8_t)bluetooth::hci::RetransmissionEffort::NO_RETRANSMISSION,
6232 (uint16_t)((uint16_t)((packet_type >> 5) & 0x7u) |
6233 (uint16_t)bluetooth::hci::SynchronousPacketTypeBits::
6234 NO_2_EV3_ALLOWED |
6235 (uint16_t)bluetooth::hci::SynchronousPacketTypeBits::
6236 NO_3_EV3_ALLOWED |
6237 (uint16_t)bluetooth::hci::SynchronousPacketTypeBits::
6238 NO_2_EV5_ALLOWED |
6239 (uint16_t)bluetooth::hci::SynchronousPacketTypeBits::
6240 NO_3_EV5_ALLOWED)};
6241 connections_.CreateScoConnection(
6242 connections_.GetAddress(connection_handle).GetAddress(),
6243 connection_parameters, SCO_STATE_PENDING, datapath, true);
6244
6245 // Send SCO connection request to peer.
6246 SendLinkLayerPacket(model::packets::ScoConnectionRequestBuilder::Create(
6247 GetAddress(), bd_addr, connection_parameters.transmit_bandwidth,
6248 connection_parameters.receive_bandwidth,
6249 connection_parameters.max_latency, connection_parameters.voice_setting,
6250 connection_parameters.retransmission_effort,
6251 connection_parameters.packet_type, class_of_device_));
6252 return ErrorCode::SUCCESS;
6253 }
6254
SetupSynchronousConnection(uint16_t connection_handle,uint32_t transmit_bandwidth,uint32_t receive_bandwidth,uint16_t max_latency,uint16_t voice_setting,uint8_t retransmission_effort,uint16_t packet_types,ScoDatapath datapath)6255 ErrorCode LinkLayerController::SetupSynchronousConnection(
6256 uint16_t connection_handle, uint32_t transmit_bandwidth,
6257 uint32_t receive_bandwidth, uint16_t max_latency, uint16_t voice_setting,
6258 uint8_t retransmission_effort, uint16_t packet_types,
6259 ScoDatapath datapath) {
6260 if (!connections_.HasHandle(connection_handle)) {
6261 return ErrorCode::UNKNOWN_CONNECTION;
6262 }
6263
6264 Address bd_addr = connections_.GetAddress(connection_handle).GetAddress();
6265 if (connections_.HasPendingScoConnection(bd_addr)) {
6266 // This command may be used to modify an exising eSCO link.
6267 // Skip for now. TODO: should return an event
6268 // HCI_Synchronous_Connection_Changed on both sides.
6269 return ErrorCode::COMMAND_DISALLOWED;
6270 }
6271
6272 LOG_INFO("Creating eSCO connection with %s", bd_addr.ToString().c_str());
6273
6274 // Save connection parameters.
6275 ScoConnectionParameters connection_parameters = {
6276 transmit_bandwidth, receive_bandwidth, max_latency,
6277 voice_setting, retransmission_effort, packet_types};
6278 connections_.CreateScoConnection(
6279 connections_.GetAddress(connection_handle).GetAddress(),
6280 connection_parameters, SCO_STATE_PENDING, datapath);
6281
6282 // Send eSCO connection request to peer.
6283 SendLinkLayerPacket(model::packets::ScoConnectionRequestBuilder::Create(
6284 GetAddress(), bd_addr, transmit_bandwidth, receive_bandwidth, max_latency,
6285 voice_setting, retransmission_effort, packet_types, class_of_device_));
6286 return ErrorCode::SUCCESS;
6287 }
6288
AcceptSynchronousConnection(Address bd_addr,uint32_t transmit_bandwidth,uint32_t receive_bandwidth,uint16_t max_latency,uint16_t voice_setting,uint8_t retransmission_effort,uint16_t packet_types)6289 ErrorCode LinkLayerController::AcceptSynchronousConnection(
6290 Address bd_addr, uint32_t transmit_bandwidth, uint32_t receive_bandwidth,
6291 uint16_t max_latency, uint16_t voice_setting, uint8_t retransmission_effort,
6292 uint16_t packet_types) {
6293 LOG_INFO("Accepting eSCO connection request from %s",
6294 bd_addr.ToString().c_str());
6295
6296 if (!connections_.HasPendingScoConnection(bd_addr)) {
6297 LOG_INFO("No pending eSCO connection for %s", bd_addr.ToString().c_str());
6298 return ErrorCode::COMMAND_DISALLOWED;
6299 }
6300
6301 ErrorCode status = ErrorCode::SUCCESS;
6302 uint16_t sco_handle = 0;
6303 ScoLinkParameters link_parameters = {};
6304 ScoConnectionParameters connection_parameters = {
6305 transmit_bandwidth, receive_bandwidth, max_latency,
6306 voice_setting, retransmission_effort, packet_types};
6307
6308 if (!connections_.AcceptPendingScoConnection(
6309 bd_addr, connection_parameters, [this, bd_addr] {
6310 return LinkLayerController::StartScoStream(bd_addr);
6311 })) {
6312 connections_.CancelPendingScoConnection(bd_addr);
6313 status = ErrorCode::STATUS_UNKNOWN; // TODO: proper status code
6314 } else {
6315 sco_handle = connections_.GetScoHandle(bd_addr);
6316 link_parameters = connections_.GetScoLinkParameters(bd_addr);
6317 }
6318
6319 // Send eSCO connection response to peer.
6320 SendLinkLayerPacket(model::packets::ScoConnectionResponseBuilder::Create(
6321 GetAddress(), bd_addr, (uint8_t)status,
6322 link_parameters.transmission_interval,
6323 link_parameters.retransmission_window, link_parameters.rx_packet_length,
6324 link_parameters.tx_packet_length, link_parameters.air_mode,
6325 link_parameters.extended));
6326
6327 // Schedule HCI Synchronous Connection Complete event.
6328 ScheduleTask(kNoDelayMs, [this, status, sco_handle, bd_addr,
6329 link_parameters]() {
6330 send_event_(bluetooth::hci::SynchronousConnectionCompleteBuilder::Create(
6331 ErrorCode(status), sco_handle, bd_addr,
6332 link_parameters.extended ? bluetooth::hci::ScoLinkType::ESCO
6333 : bluetooth::hci::ScoLinkType::SCO,
6334 link_parameters.extended ? link_parameters.transmission_interval : 0,
6335 link_parameters.extended ? link_parameters.retransmission_window : 0,
6336 link_parameters.extended ? link_parameters.rx_packet_length : 0,
6337 link_parameters.extended ? link_parameters.tx_packet_length : 0,
6338 bluetooth::hci::ScoAirMode(link_parameters.air_mode)));
6339 });
6340
6341 return ErrorCode::SUCCESS;
6342 }
6343
RejectSynchronousConnection(Address bd_addr,uint16_t reason)6344 ErrorCode LinkLayerController::RejectSynchronousConnection(Address bd_addr,
6345 uint16_t reason) {
6346 LOG_INFO("Rejecting eSCO connection request from %s",
6347 bd_addr.ToString().c_str());
6348
6349 if (reason == (uint8_t)ErrorCode::SUCCESS) {
6350 reason = (uint8_t)ErrorCode::REMOTE_USER_TERMINATED_CONNECTION;
6351 }
6352 if (!connections_.HasPendingScoConnection(bd_addr)) {
6353 return ErrorCode::COMMAND_DISALLOWED;
6354 }
6355
6356 connections_.CancelPendingScoConnection(bd_addr);
6357
6358 // Send eSCO connection response to peer.
6359 SendLinkLayerPacket(model::packets::ScoConnectionResponseBuilder::Create(
6360 GetAddress(), bd_addr, reason, 0, 0, 0, 0, 0, 0));
6361
6362 // Schedule HCI Synchronous Connection Complete event.
6363 ScheduleTask(kNoDelayMs, [this, reason, bd_addr]() {
6364 send_event_(bluetooth::hci::SynchronousConnectionCompleteBuilder::Create(
6365 ErrorCode(reason), 0, bd_addr, bluetooth::hci::ScoLinkType::ESCO, 0, 0,
6366 0, 0, bluetooth::hci::ScoAirMode::TRANSPARENT));
6367 });
6368
6369 return ErrorCode::SUCCESS;
6370 }
6371
CheckExpiringConnection(uint16_t handle)6372 void LinkLayerController::CheckExpiringConnection(uint16_t handle) {
6373 if (!connections_.HasHandle(handle)) {
6374 return;
6375 }
6376
6377 if (connections_.HasLinkExpired(handle)) {
6378 Disconnect(handle, ErrorCode::CONNECTION_TIMEOUT);
6379 return;
6380 }
6381
6382 if (connections_.IsLinkNearExpiring(handle)) {
6383 AddressWithType my_address = connections_.GetOwnAddress(handle);
6384 AddressWithType destination = connections_.GetAddress(handle);
6385 SendLinkLayerPacket(model::packets::PingRequestBuilder::Create(
6386 my_address.GetAddress(), destination.GetAddress()));
6387 ScheduleTask(std::chrono::duration_cast<milliseconds>(
6388 connections_.TimeUntilLinkExpired(handle)),
6389 [this, handle] { CheckExpiringConnection(handle); });
6390 return;
6391 }
6392
6393 ScheduleTask(std::chrono::duration_cast<milliseconds>(
6394 connections_.TimeUntilLinkNearExpiring(handle)),
6395 [this, handle] { CheckExpiringConnection(handle); });
6396 }
6397
IncomingPingRequest(model::packets::LinkLayerPacketView packet)6398 void LinkLayerController::IncomingPingRequest(
6399 model::packets::LinkLayerPacketView packet) {
6400 auto view = model::packets::PingRequestView::Create(packet);
6401 ASSERT(view.IsValid());
6402 SendLinkLayerPacket(model::packets::PingResponseBuilder::Create(
6403 packet.GetDestinationAddress(), packet.GetSourceAddress()));
6404 }
6405
StartScoStream(Address address)6406 AsyncTaskId LinkLayerController::StartScoStream(Address address) {
6407 auto sco_builder = bluetooth::hci::ScoBuilder::Create(
6408 connections_.GetScoHandle(address), PacketStatusFlag::CORRECTLY_RECEIVED,
6409 {0, 0, 0, 0, 0});
6410
6411 auto bytes = std::make_shared<std::vector<uint8_t>>();
6412 bluetooth::packet::BitInserter bit_inserter(*bytes);
6413 sco_builder->Serialize(bit_inserter);
6414 auto raw_view =
6415 bluetooth::hci::PacketView<bluetooth::hci::kLittleEndian>(bytes);
6416 auto sco_view = bluetooth::hci::ScoView::Create(raw_view);
6417 ASSERT(sco_view.IsValid());
6418
6419 return SchedulePeriodicTask(0ms, 20ms, [this, address, sco_view]() {
6420 LOG_INFO("SCO sending...");
6421 SendScoToRemote(sco_view);
6422 });
6423 }
6424 } // namespace rootcanal
6425