1 /*
2 * Copyright 2019 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 #define LOG_TAG "bt_shim_l2cap"
18
19 #include <future>
20 #include <unordered_map>
21 #include <unordered_set>
22
23 #include "bta/include/bta_dm_acl.h"
24 #include "gd/l2cap/classic/l2cap_classic_module.h"
25 #include "gd/l2cap/le/l2cap_le_module.h"
26 #include "gd/os/log.h"
27 #include "gd/os/queue.h"
28 #include "main/shim/acl_api.h"
29 #include "main/shim/btm.h"
30 #include "main/shim/entry.h"
31 #include "main/shim/helpers.h"
32 #include "main/shim/l2c_api.h"
33 #include "main/shim/stack.h"
34 #include "osi/include/allocator.h"
35 #include "stack/btm/btm_ble_int.h"
36 #include "stack/btm/btm_sec.h"
37 #include "stack/include/acl_hci_link_interface.h"
38 #include "stack/include/ble_acl_interface.h"
39 #include "stack/include/btm_api.h"
40 #include "stack/include/btu.h"
41 #include "stack/include/gatt_api.h"
42 #include "stack/include/sco_hci_link_interface.h"
43
44 extern void gatt_notify_conn_update(const RawAddress& remote, uint16_t interval,
45 uint16_t latency, uint16_t timeout,
46 tHCI_STATUS status);
47 extern void gatt_notify_phy_updated(tGATT_STATUS status, uint16_t handle,
48 uint8_t tx_phy, uint8_t rx_phy);
49
50 void process_ssr_event(tHCI_STATUS status, uint16_t handle, uint16_t max_tx_lat,
51 uint16_t max_rx_lat);
52
53 namespace bluetooth {
54 namespace shim {
55
56 using bluetooth::hci::AddressWithType;
57 using namespace bluetooth::l2cap;
58
59 // Classic Dynamic Channel Shim Helper
60
61 namespace {
62 uint16_t classic_cid_token_counter_ = 0x41;
63 constexpr uint64_t kBrEdrNotSupportedMask = 0x0000002000000000; // Bit 37
64 constexpr uint64_t kLeSupportedControllerMask = 0x0000004000000000; // Bit 38
65 constexpr uint64_t kLeSupportedHostMask = 0x0000000000000002; // Bit 1
66
67 std::unordered_map<uint16_t /* token */, uint16_t /* psm */>
68 classic_cid_token_to_channel_map_;
69
add_classic_cid_token_entry(uint16_t psm)70 uint16_t add_classic_cid_token_entry(uint16_t psm) {
71 uint16_t new_token = classic_cid_token_counter_;
72 classic_cid_token_to_channel_map_[new_token] = psm;
73 classic_cid_token_counter_++;
74 if (classic_cid_token_counter_ == 0) classic_cid_token_counter_ = 0x41;
75 return new_token;
76 }
77
remove_classic_cid_token_entry(uint16_t cid_token)78 void remove_classic_cid_token_entry(uint16_t cid_token) {
79 classic_cid_token_to_channel_map_.erase(cid_token);
80 }
81
82 void remove_classic_dynamic_channel_helper(uint16_t psm);
83
84 struct ClassicDynamicChannelHelper {
ClassicDynamicChannelHelperbluetooth::shim::__anon71e10d460110::ClassicDynamicChannelHelper85 ClassicDynamicChannelHelper(uint16_t psm, tL2CAP_APPL_INFO appl_info,
86 classic::DynamicChannelConfigurationOption config,
87 classic::SecurityPolicy policy)
88 : psm_(psm), appl_info_(appl_info), config_(config), policy_(policy) {}
89
90 uint16_t psm_;
91 tL2CAP_APPL_INFO appl_info_;
92 classic::DynamicChannelConfigurationOption config_;
93 classic::SecurityPolicy policy_;
94
Registerbluetooth::shim::__anon71e10d460110::ClassicDynamicChannelHelper95 void Register() {
96 GetL2capClassicModule()->GetDynamicChannelManager()->RegisterService(
97 psm_, config_, policy_,
98 GetGdShimHandler()->BindOnceOn(
99 this, &ClassicDynamicChannelHelper::on_registration_complete),
100 GetGdShimHandler()->BindOn(
101 this, &ClassicDynamicChannelHelper::on_channel_open, 0));
102 }
103
on_registration_completebluetooth::shim::__anon71e10d460110::ClassicDynamicChannelHelper104 void on_registration_complete(
105 classic::DynamicChannelManager::RegistrationResult result,
106 std::unique_ptr<classic::DynamicChannelService> service) {
107 if (result != classic::DynamicChannelManager::RegistrationResult::SUCCESS) {
108 LOG(ERROR) << "Channel is not registered. psm=" << +psm_ << (int)result;
109 return;
110 }
111 channel_service_ = std::move(service);
112 }
113
114 std::unique_ptr<classic::DynamicChannelService> channel_service_ = nullptr;
115
Connectbluetooth::shim::__anon71e10d460110::ClassicDynamicChannelHelper116 void Connect(uint16_t cid_token, bluetooth::hci::AddressWithType device) {
117 if (channel_service_ == nullptr) {
118 return;
119 }
120 initiated_by_us_[cid_token] = true;
121 GetL2capClassicModule()->GetDynamicChannelManager()->ConnectChannel(
122 device.GetAddress(), config_, psm_,
123 GetGdShimHandler()->BindOn(
124 this, &ClassicDynamicChannelHelper::on_channel_open, cid_token),
125 GetGdShimHandler()->BindOnceOn(
126 this, &ClassicDynamicChannelHelper::on_outgoing_connection_fail));
127 }
128
Disconnectbluetooth::shim::__anon71e10d460110::ClassicDynamicChannelHelper129 void Disconnect(uint16_t cid_token) {
130 if (channel_service_ == nullptr) {
131 return;
132 }
133 if (channels_.count(cid_token) == 0) {
134 return;
135 }
136 channels_[cid_token]->Close();
137 }
138
Unregisterbluetooth::shim::__anon71e10d460110::ClassicDynamicChannelHelper139 void Unregister() {
140 if (channel_service_ != nullptr) {
141 channel_service_->Unregister(GetGdShimHandler()->BindOnceOn(
142 this, &ClassicDynamicChannelHelper::on_unregistered));
143 channel_service_ = nullptr;
144 }
145 }
146
on_unregisteredbluetooth::shim::__anon71e10d460110::ClassicDynamicChannelHelper147 void on_unregistered() {
148 for (const auto& device : channels_) {
149 device.second->Close();
150 }
151 remove_classic_dynamic_channel_helper(psm_);
152 }
153
on_channel_closebluetooth::shim::__anon71e10d460110::ClassicDynamicChannelHelper154 void on_channel_close(uint16_t cid_token,
155 bluetooth::hci::ErrorCode error_code) {
156 channel_enqueue_buffer_[cid_token] = nullptr;
157 channel_enqueue_buffer_.erase(cid_token);
158 channels_[cid_token]->GetQueueUpEnd()->UnregisterDequeue();
159 channels_.erase(cid_token);
160 do_in_main_thread(FROM_HERE, base::Bind(appl_info_.pL2CA_DisconnectInd_Cb,
161 cid_token, false));
162
163 remove_classic_cid_token_entry(cid_token);
164 initiated_by_us_.erase(cid_token);
165
166 if (channel_service_ == nullptr && channels_.empty()) {
167 // Try again
168 L2CA_Deregister(psm_);
169 }
170 }
171
on_channel_openbluetooth::shim::__anon71e10d460110::ClassicDynamicChannelHelper172 void on_channel_open(uint16_t cid_token,
173 std::unique_ptr<classic::DynamicChannel> channel) {
174 auto device = channel->GetDevice();
175 auto address = bluetooth::ToRawAddress(device.GetAddress());
176 bool initiator_local = (cid_token != 0);
177 if (cid_token == 0) {
178 cid_token = add_classic_cid_token_entry(psm_);
179 }
180
181 channel->RegisterOnCloseCallback(GetGdShimHandler()->BindOnceOn(
182 this, &ClassicDynamicChannelHelper::on_channel_close, cid_token));
183
184 channel_enqueue_buffer_[cid_token] = std::make_unique<
185 bluetooth::os::EnqueueBuffer<bluetooth::packet::BasePacketBuilder>>(
186 channel->GetQueueUpEnd());
187
188 if (initiator_local) {
189 do_in_main_thread(
190 FROM_HERE, base::Bind(appl_info_.pL2CA_ConnectCfm_Cb, cid_token, 0));
191
192 tL2CAP_CFG_INFO cfg_info{};
193 do_in_main_thread(FROM_HERE, base::Bind(appl_info_.pL2CA_ConfigCfm_Cb,
194 cid_token, L2CAP_INITIATOR_LOCAL,
195 base::Unretained(&cfg_info)));
196 } else {
197 if (appl_info_.pL2CA_ConnectInd_Cb == nullptr) {
198 Disconnect(cid_token);
199 return;
200 }
201 do_in_main_thread(FROM_HERE, base::Bind(appl_info_.pL2CA_ConnectInd_Cb,
202 address, cid_token, psm_, 0));
203
204 tL2CAP_CFG_INFO cfg_info{};
205 do_in_main_thread(FROM_HERE, base::Bind(appl_info_.pL2CA_ConfigCfm_Cb,
206 cid_token, L2CAP_INITIATOR_LOCAL,
207 base::Unretained(&cfg_info)));
208 }
209
210 channel->GetQueueUpEnd()->RegisterDequeue(
211 GetGdShimHandler(),
212 bluetooth::common::Bind(&ClassicDynamicChannelHelper::on_incoming_data,
213 bluetooth::common::Unretained(this),
214 cid_token));
215
216 channels_[cid_token] = std::move(channel);
217 }
218
on_incoming_databluetooth::shim::__anon71e10d460110::ClassicDynamicChannelHelper219 void on_incoming_data(uint16_t cid_token) {
220 auto channel = channels_.find(cid_token);
221 if (channel == channels_.end()) {
222 LOG_ERROR("Channel is not open");
223 return;
224 }
225 auto packet = channel->second->GetQueueUpEnd()->TryDequeue();
226 std::vector<uint8_t> packet_vector(packet->begin(), packet->end());
227 BT_HDR* buffer =
228 static_cast<BT_HDR*>(osi_calloc(packet_vector.size() + sizeof(BT_HDR)));
229 std::copy(packet_vector.begin(), packet_vector.end(), buffer->data);
230 buffer->len = packet_vector.size();
231 if (do_in_main_thread(FROM_HERE,
232 base::Bind(appl_info_.pL2CA_DataInd_Cb, cid_token,
233 base::Unretained(buffer))) !=
234 BT_STATUS_SUCCESS) {
235 osi_free(buffer);
236 }
237 }
238
on_outgoing_connection_failbluetooth::shim::__anon71e10d460110::ClassicDynamicChannelHelper239 void on_outgoing_connection_fail(
240 classic::DynamicChannelManager::ConnectionResult result) {
241 LOG(ERROR) << "Outgoing connection failed: "
242 << static_cast<int>(result.connection_result_code);
243 }
244
sendbluetooth::shim::__anon71e10d460110::ClassicDynamicChannelHelper245 bool send(uint16_t cid,
246 std::unique_ptr<bluetooth::packet::BasePacketBuilder> packet) {
247 auto buffer = channel_enqueue_buffer_.find(cid);
248 if (buffer == channel_enqueue_buffer_.end() || buffer->second == nullptr) {
249 LOG(ERROR) << "Channel is not open";
250 return false;
251 }
252 buffer->second->Enqueue(std::move(packet), GetGdShimHandler());
253 return true;
254 }
255
GetRemoteCidbluetooth::shim::__anon71e10d460110::ClassicDynamicChannelHelper256 uint16_t GetRemoteCid(uint16_t cid) {
257 auto channel = channels_.find(cid);
258 if (channel == channels_.end()) {
259 LOG_ERROR("Channel is not open");
260 return 0;
261 }
262 return channel->second->HACK_GetRemoteCid();
263 }
264
SetChannelTxPrioritybluetooth::shim::__anon71e10d460110::ClassicDynamicChannelHelper265 bool SetChannelTxPriority(uint16_t cid, bool high_priority) {
266 auto channel = channels_.find(cid);
267 if (channel == channels_.end()) {
268 LOG_ERROR("Channel is not open");
269 return false;
270 }
271 channel->second->HACK_SetChannelTxPriority(high_priority);
272 return true;
273 }
274
FlushChannelbluetooth::shim::__anon71e10d460110::ClassicDynamicChannelHelper275 void FlushChannel(uint16_t cid) {
276 auto buffer = channel_enqueue_buffer_.find(cid);
277 if (buffer == channel_enqueue_buffer_.end()) {
278 LOG_ERROR("Channel is not open");
279 return;
280 }
281 buffer->second->Clear();
282 }
283
GetNumBufferedPacketsbluetooth::shim::__anon71e10d460110::ClassicDynamicChannelHelper284 uint16_t GetNumBufferedPackets(uint16_t cid) {
285 auto buffer = channel_enqueue_buffer_.find(cid);
286 if (buffer == channel_enqueue_buffer_.end()) {
287 LOG_ERROR("Channel is not open");
288 return 0;
289 }
290 return buffer->second->Size();
291 }
292
293 std::unordered_map<uint16_t, std::unique_ptr<classic::DynamicChannel>>
294 channels_;
295 std::unordered_map<uint16_t, std::unique_ptr<bluetooth::os::EnqueueBuffer<
296 bluetooth::packet::BasePacketBuilder>>>
297 channel_enqueue_buffer_;
298 std::unordered_map<uint16_t, bool> initiated_by_us_;
299 };
300
301 std::unordered_map<uint16_t, std::unique_ptr<ClassicDynamicChannelHelper>>
302 classic_dynamic_channel_helper_map_;
303
remove_classic_dynamic_channel_helper(uint16_t psm)304 void remove_classic_dynamic_channel_helper(uint16_t psm) {
305 if (classic_dynamic_channel_helper_map_.count(psm) != 0 &&
306 classic_dynamic_channel_helper_map_[psm]->channels_.empty()) {
307 classic_dynamic_channel_helper_map_.erase(psm);
308 }
309 }
310
311 // Helper: L2cap security enforcement shim
312
313 std::unordered_map<intptr_t,
314 bluetooth::common::ContextualOnceCallback<void(bool)>>
315 security_enforce_callback_map = {};
316
317 class ClassicSecurityEnforcementShim
318 : public bluetooth::l2cap::classic::SecurityEnforcementInterface {
319 public:
security_enforce_result_callback(const RawAddress * bd_addr,tBT_TRANSPORT trasnport,void * p_ref_data,tBTM_STATUS result)320 static void security_enforce_result_callback(const RawAddress* bd_addr,
321 tBT_TRANSPORT trasnport,
322 void* p_ref_data,
323 tBTM_STATUS result) {
324 intptr_t counter = (intptr_t)p_ref_data;
325 if (security_enforce_callback_map.count(counter) == 0) {
326 LOG_ERROR("Received unexpected callback");
327 return;
328 }
329
330 auto& callback = security_enforce_callback_map[counter];
331 std::move(callback).Invoke(result == BTM_SUCCESS);
332 security_enforce_callback_map.erase(counter);
333 }
334
Enforce(bluetooth::hci::AddressWithType remote,bluetooth::l2cap::classic::SecurityPolicy policy,ResultCallback result_callback)335 void Enforce(bluetooth::hci::AddressWithType remote,
336 bluetooth::l2cap::classic::SecurityPolicy policy,
337 ResultCallback result_callback) override {
338 uint16_t sec_mask = 0;
339 switch (policy) {
340 case bluetooth::l2cap::classic::SecurityPolicy::
341 _SDP_ONLY_NO_SECURITY_WHATSOEVER_PLAINTEXT_TRANSPORT_OK:
342 result_callback.Invoke(true);
343 return;
344 case bluetooth::l2cap::classic::SecurityPolicy::ENCRYPTED_TRANSPORT:
345 sec_mask = BTM_SEC_IN_AUTHENTICATE | BTM_SEC_IN_ENCRYPT |
346 BTM_SEC_OUT_AUTHENTICATE | BTM_SEC_OUT_ENCRYPT;
347 break;
348 case bluetooth::l2cap::classic::SecurityPolicy::BEST:
349 case bluetooth::l2cap::classic::SecurityPolicy::
350 AUTHENTICATED_ENCRYPTED_TRANSPORT:
351 sec_mask = BTM_SEC_IN_AUTHENTICATE | BTM_SEC_IN_ENCRYPT |
352 BTM_SEC_IN_MITM | BTM_SEC_OUT_AUTHENTICATE |
353 BTM_SEC_OUT_ENCRYPT | BTM_SEC_OUT_MITM;
354 break;
355 }
356 auto bd_addr = bluetooth::ToRawAddress(remote.GetAddress());
357 security_enforce_callback_map[security_enforce_callback_counter_] =
358 std::move(result_callback);
359 btm_sec_l2cap_access_req_by_requirement(
360 bd_addr, sec_mask, true, security_enforce_result_callback,
361 (void*)security_enforce_callback_counter_);
362 security_enforce_callback_counter_++;
363 }
364
365 intptr_t security_enforce_callback_counter_ = 100;
366 } security_enforcement_shim_;
367
368 struct RemoteFeature {
369 uint8_t lmp_version = 0;
370 uint16_t manufacturer_name = 0;
371 uint16_t sub_version = 0;
372 uint8_t raw_remote_features[8];
373 bool version_info_received = false;
374 bool role_switch_supported = false;
375 bool br_edr_supported = false;
376 bool le_supported_controller = false;
377 bool le_supported_host = false;
378 bool ssp_supported = false;
379 bool sc_supported = false;
380 bool received_page_0 = false;
381 bool received_page_1 = false;
382 };
383
384 std::unordered_map<RawAddress, RemoteFeature> remote_feature_map_;
385
386 struct LinkPropertyListenerShim
387 : public bluetooth::l2cap::classic::LinkPropertyListener {
388 std::unordered_map<hci::Address, uint16_t> address_to_handle_;
389
OnLinkConnectedbluetooth::shim::__anon71e10d460110::LinkPropertyListenerShim390 void OnLinkConnected(hci::Address remote, uint16_t handle) override {
391 address_to_handle_[remote] = handle;
392 }
393
OnLinkDisconnectedbluetooth::shim::__anon71e10d460110::LinkPropertyListenerShim394 void OnLinkDisconnected(hci::Address remote) override {
395 address_to_handle_.erase(remote);
396 }
397
OnReadRemoteVersionInformationbluetooth::shim::__anon71e10d460110::LinkPropertyListenerShim398 void OnReadRemoteVersionInformation(hci::ErrorCode error_code,
399 hci::Address remote, uint8_t lmp_version,
400 uint16_t manufacturer_name,
401 uint16_t sub_version) override {
402 auto bda = bluetooth::ToRawAddress(remote);
403 auto& entry = remote_feature_map_[bda];
404 entry.lmp_version = lmp_version;
405 entry.manufacturer_name = manufacturer_name;
406 entry.sub_version = sub_version;
407 entry.version_info_received = true;
408 }
409
OnReadRemoteExtendedFeaturesbluetooth::shim::__anon71e10d460110::LinkPropertyListenerShim410 void OnReadRemoteExtendedFeatures(hci::Address remote, uint8_t page_number,
411 uint8_t max_page_number,
412 uint64_t features) override {
413 auto bda = bluetooth::ToRawAddress(remote);
414 auto& entry = remote_feature_map_[bda];
415 if (page_number == 0) {
416 entry.received_page_0 = true;
417 if (features & 0x20) entry.role_switch_supported = true;
418 entry.br_edr_supported = !(features & kBrEdrNotSupportedMask);
419 entry.le_supported_controller = features & kLeSupportedControllerMask;
420 std::memcpy(entry.raw_remote_features, &features, 8);
421 }
422 if (page_number == 1) {
423 entry.received_page_1 = true;
424 if (features & 0x01) entry.ssp_supported = true;
425 entry.le_supported_host = features & kLeSupportedHostMask;
426 }
427 if (entry.received_page_0 && entry.received_page_1) {
428 const bool le_supported =
429 entry.le_supported_controller && entry.le_supported_host;
430 btm_sec_set_peer_sec_caps(address_to_handle_[remote], entry.ssp_supported,
431 false, entry.role_switch_supported,
432 entry.br_edr_supported, le_supported);
433 }
434 }
435
OnRoleChangebluetooth::shim::__anon71e10d460110::LinkPropertyListenerShim436 void OnRoleChange(hci::ErrorCode error_code, hci::Address remote,
437 hci::Role role) override {
438 btm_rejectlist_role_change_device(ToRawAddress(remote),
439 ToLegacyHciErrorCode(error_code));
440 btm_acl_role_changed(ToLegacyHciErrorCode(error_code), ToRawAddress(remote),
441 ToLegacyRole(role));
442 }
443
OnReadClockOffsetbluetooth::shim::__anon71e10d460110::LinkPropertyListenerShim444 void OnReadClockOffset(hci::Address remote, uint16_t clock_offset) override {
445 btm_sec_update_clock_offset(address_to_handle_[remote], clock_offset);
446 }
447
OnModeChangebluetooth::shim::__anon71e10d460110::LinkPropertyListenerShim448 void OnModeChange(hci::ErrorCode error_code, hci::Address remote,
449 hci::Mode mode, uint16_t interval) override {
450 btm_sco_chk_pend_unpark(ToLegacyHciErrorCode(error_code),
451 address_to_handle_[remote]);
452 btm_pm_proc_mode_change(ToLegacyHciErrorCode(error_code),
453 address_to_handle_[remote], ToLegacyHciMode(mode),
454 interval);
455 }
456
OnSniffSubratingbluetooth::shim::__anon71e10d460110::LinkPropertyListenerShim457 void OnSniffSubrating(hci::ErrorCode error_code, hci::Address remote,
458 uint16_t max_tx_lat, uint16_t max_rx_lat,
459 uint16_t min_remote_timeout,
460 uint16_t min_local_timeout) override {
461 process_ssr_event(ToLegacyHciErrorCode(error_code),
462 address_to_handle_[remote], max_tx_lat, max_rx_lat);
463 }
464
465 } link_property_listener_shim_;
466
467 class SecurityListenerShim
468 : public bluetooth::l2cap::classic::LinkSecurityInterfaceListener {
469 public:
OnLinkConnected(std::unique_ptr<bluetooth::l2cap::classic::LinkSecurityInterface> interface)470 void OnLinkConnected(
471 std::unique_ptr<bluetooth::l2cap::classic::LinkSecurityInterface>
472 interface) override {
473 auto bda = bluetooth::ToRawAddress(interface->GetRemoteAddress());
474
475 uint16_t handle = interface->GetAclHandle();
476 address_to_handle_[bda] = handle;
477 btm_sec_connected(bda, handle, HCI_SUCCESS, 0);
478 BTM_PM_OnConnected(handle, bda);
479 BTA_dm_acl_up(bda, BT_TRANSPORT_BR_EDR);
480 address_to_interface_[bda] = std::move(interface);
481 }
482
OnAuthenticationComplete(hci::ErrorCode hci_status,bluetooth::hci::Address remote)483 void OnAuthenticationComplete(hci::ErrorCode hci_status,
484 bluetooth::hci::Address remote) override {
485 // Note: if gd security is not enabled, we should use btu_hcif.cc path
486 auto bda = bluetooth::ToRawAddress(remote);
487 uint16_t handle = address_to_handle_[bda];
488 btm_sec_auth_complete(handle, ToLegacyHciErrorCode(hci_status));
489 }
490
OnLinkDisconnected(bluetooth::hci::Address remote)491 void OnLinkDisconnected(bluetooth::hci::Address remote) override {
492 auto bda = bluetooth::ToRawAddress(remote);
493 uint16_t handle = address_to_handle_[bda];
494 address_to_handle_.erase(bda);
495 address_to_interface_.erase(bda);
496 btm_sec_disconnected(handle, HCI_ERR_PEER_USER);
497 BTA_dm_acl_down(bda, BT_TRANSPORT_BR_EDR);
498 BTM_PM_OnDisconnected(handle);
499 }
500
OnEncryptionChange(bluetooth::hci::Address remote,bool encrypted)501 void OnEncryptionChange(bluetooth::hci::Address remote,
502 bool encrypted) override {
503 // Note: if gd security is not enabled, we should use btu_hcif.cc path
504 auto bda = bluetooth::ToRawAddress(remote);
505 uint16_t handle = address_to_handle_[bda];
506 btm_sec_encrypt_change(handle, HCI_SUCCESS, encrypted);
507 }
508
UpdateLinkHoldForSecurity(RawAddress remote,bool is_bonding)509 void UpdateLinkHoldForSecurity(RawAddress remote, bool is_bonding) {
510 if (address_to_interface_.count(remote) == 0) {
511 return;
512 }
513 if (is_bonding) {
514 address_to_interface_[remote]->Hold();
515 } else {
516 address_to_interface_[remote]->Release();
517 }
518 }
519
IsRoleCentral(RawAddress remote)520 bool IsRoleCentral(RawAddress remote) {
521 if (address_to_interface_.count(remote) == 0) {
522 return false;
523 }
524 return address_to_interface_[remote]->GetRole() ==
525 bluetooth::hci::Role::CENTRAL;
526 }
527
Disconnect(RawAddress remote)528 void Disconnect(RawAddress remote) {
529 if (address_to_interface_.count(remote) == 0) {
530 return;
531 }
532 return address_to_interface_[remote]->Disconnect();
533 }
534
GetNumAclLinks()535 uint16_t GetNumAclLinks() { return address_to_handle_.size(); }
536
IsLinkUp(RawAddress remote)537 bool IsLinkUp(RawAddress remote) {
538 return address_to_interface_.count(remote) != 0;
539 }
540
541 std::unordered_map<RawAddress, uint16_t> address_to_handle_;
542 std::unordered_map<
543 RawAddress,
544 std::unique_ptr<bluetooth::l2cap::classic::LinkSecurityInterface>>
545 address_to_interface_;
546 } security_listener_shim_;
547
548 bluetooth::l2cap::classic::SecurityInterface* security_interface_ = nullptr;
549
550 struct LeLinkPropertyListenerShim
551 : public bluetooth::l2cap::le::LinkPropertyListener {
552 struct ConnectionInfo {
553 uint16_t handle;
554 hci::Role role;
555 AddressWithType address_with_type;
556 };
557 std::unordered_map<hci::Address, ConnectionInfo> info_;
558
OnLinkConnectedbluetooth::shim::__anon71e10d460110::LeLinkPropertyListenerShim559 void OnLinkConnected(AddressWithType remote, uint16_t handle,
560 hci::Role role) override {
561 info_[remote.GetAddress()] = {handle, role, remote};
562 btm_ble_connected(ToRawAddress(remote.GetAddress()), handle,
563 HCI_ENCRYPT_MODE_DISABLED, static_cast<uint8_t>(role),
564 static_cast<tBLE_ADDR_TYPE>(remote.GetAddressType()),
565 false);
566 }
567
OnLinkDisconnectedbluetooth::shim::__anon71e10d460110::LeLinkPropertyListenerShim568 void OnLinkDisconnected(hci::AddressWithType remote) override {
569 info_.erase(remote.GetAddress());
570 }
571
OnReadRemoteVersionInformationbluetooth::shim::__anon71e10d460110::LeLinkPropertyListenerShim572 void OnReadRemoteVersionInformation(hci::ErrorCode hci_status,
573 hci::AddressWithType remote,
574 uint8_t lmp_version,
575 uint16_t manufacturer_name,
576 uint16_t sub_version) override {
577 auto bda = bluetooth::ToRawAddress(remote.GetAddress());
578 auto& entry = remote_feature_map_[bda];
579 entry.lmp_version = lmp_version;
580 entry.manufacturer_name = manufacturer_name;
581 entry.sub_version = sub_version;
582 entry.version_info_received = true;
583 }
584
OnConnectionUpdatebluetooth::shim::__anon71e10d460110::LeLinkPropertyListenerShim585 void OnConnectionUpdate(hci::AddressWithType remote,
586 uint16_t connection_interval,
587 uint16_t connection_latency,
588 uint16_t supervision_timeout) override {
589 acl_ble_update_event_received(
590 HCI_SUCCESS, info_[remote.GetAddress()].handle, connection_interval,
591 connection_latency, supervision_timeout);
592 }
593
OnPhyUpdatebluetooth::shim::__anon71e10d460110::LeLinkPropertyListenerShim594 void OnPhyUpdate(hci::AddressWithType remote, uint8_t tx_phy,
595 uint8_t rx_phy) override {
596 gatt_notify_phy_updated(GATT_SUCCESS, info_[remote.GetAddress()].handle,
597 tx_phy, rx_phy);
598 }
599
OnDataLengthChangebluetooth::shim::__anon71e10d460110::LeLinkPropertyListenerShim600 void OnDataLengthChange(hci::AddressWithType remote, uint16_t tx_octets,
601 uint16_t tx_time, uint16_t rx_octets,
602 uint16_t rx_time) override {
603 // Used by L2cap internal only.
604 }
605 } le_link_property_listener_shim_;
606
607 std::unordered_map<intptr_t,
608 bluetooth::common::ContextualOnceCallback<void(bool)>>
609 le_security_enforce_callback_map = {};
610
611 class LeSecurityEnforcementShim
612 : public bluetooth::l2cap::le::SecurityEnforcementInterface {
613 public:
le_security_enforce_result_callback(const RawAddress * bd_addr,tBT_TRANSPORT trasnport,void * p_ref_data,tBTM_STATUS result)614 static void le_security_enforce_result_callback(const RawAddress* bd_addr,
615 tBT_TRANSPORT trasnport,
616 void* p_ref_data,
617 tBTM_STATUS result) {
618 intptr_t counter = (intptr_t)p_ref_data;
619 if (le_security_enforce_callback_map.count(counter) == 0) {
620 LOG_ERROR("Received unexpected callback");
621 return;
622 }
623 auto& callback = le_security_enforce_callback_map[counter];
624 std::move(callback).Invoke(result == BTM_SUCCESS);
625 le_security_enforce_callback_map.erase(counter);
626 }
627
Enforce(bluetooth::hci::AddressWithType remote,bluetooth::l2cap::le::SecurityPolicy policy,ResultCallback result_callback)628 void Enforce(bluetooth::hci::AddressWithType remote,
629 bluetooth::l2cap::le::SecurityPolicy policy,
630 ResultCallback result_callback) override {
631 tBTM_BLE_SEC_ACT sec_act = BTM_BLE_SEC_NONE;
632 switch (policy) {
633 case bluetooth::l2cap::le::SecurityPolicy::
634 NO_SECURITY_WHATSOEVER_PLAINTEXT_TRANSPORT_OK:
635 result_callback.Invoke(true);
636 return;
637 case bluetooth::l2cap::le::SecurityPolicy::ENCRYPTED_TRANSPORT:
638 sec_act = BTM_BLE_SEC_ENCRYPT;
639 break;
640 case bluetooth::l2cap::le::SecurityPolicy::BEST:
641 case bluetooth::l2cap::le::SecurityPolicy::
642 AUTHENTICATED_ENCRYPTED_TRANSPORT:
643 sec_act = BTM_BLE_SEC_ENCRYPT_MITM;
644 break;
645 default:
646 result_callback.Invoke(false);
647 }
648 auto bd_addr = bluetooth::ToRawAddress(remote.GetAddress());
649 le_security_enforce_callback_map[security_enforce_callback_counter_] =
650 std::move(result_callback);
651 BTM_SetEncryption(bd_addr, BT_TRANSPORT_LE,
652 le_security_enforce_result_callback,
653 (void*)security_enforce_callback_counter_, sec_act);
654 security_enforce_callback_counter_++;
655 }
656
657 intptr_t security_enforce_callback_counter_ = 100;
658 } le_security_enforcement_shim_;
659 } // namespace
660
L2CA_ReadRemoteVersion(const RawAddress & addr,uint8_t * lmp_version,uint16_t * manufacturer,uint16_t * lmp_sub_version)661 bool L2CA_ReadRemoteVersion(const RawAddress& addr, uint8_t* lmp_version,
662 uint16_t* manufacturer, uint16_t* lmp_sub_version) {
663 auto& entry = remote_feature_map_[addr];
664 if (!entry.version_info_received) {
665 return false;
666 }
667 if (lmp_version != nullptr) *lmp_version = entry.lmp_version;
668 if (manufacturer != nullptr) *manufacturer = entry.manufacturer_name;
669 if (lmp_sub_version != nullptr) *lmp_sub_version = entry.sub_version;
670 return true;
671 }
672
L2CA_ReadRemoteFeatures(const RawAddress & addr)673 uint8_t* L2CA_ReadRemoteFeatures(const RawAddress& addr) {
674 auto& entry = remote_feature_map_[addr];
675 if (!entry.received_page_0) {
676 return nullptr;
677 }
678 return entry.raw_remote_features;
679 }
680
on_sco_disconnect(uint16_t handle,uint8_t reason)681 static void on_sco_disconnect(uint16_t handle, uint8_t reason) {
682 GetGdShimHandler()->Post(base::BindOnce(base::IgnoreResult(&btm_sco_removed),
683 handle,
684 static_cast<tHCI_REASON>(reason)));
685 }
686
L2CA_UseLegacySecurityModule()687 void L2CA_UseLegacySecurityModule() {
688 LOG_INFO("GD L2cap is using legacy security module");
689 GetL2capClassicModule()->SetLinkPropertyListener(
690 GetGdShimHandler(), &link_property_listener_shim_);
691
692 GetL2capClassicModule()->InjectSecurityEnforcementInterface(
693 &security_enforcement_shim_);
694 security_interface_ = GetL2capClassicModule()->GetSecurityInterface(
695 GetGdShimHandler(), &security_listener_shim_);
696
697 GetL2capLeModule()->SetLinkPropertyListener(GetGdShimHandler(),
698 &le_link_property_listener_shim_);
699 GetL2capLeModule()->InjectSecurityEnforcementInterface(
700 &le_security_enforcement_shim_);
701
702 GetAclManager()->HACK_SetScoDisconnectCallback(on_sco_disconnect);
703 }
704
705 /**
706 * Classic Service Registration APIs
707 */
L2CA_Register(uint16_t client_psm,const tL2CAP_APPL_INFO & callbacks,bool enable_snoop,tL2CAP_ERTM_INFO * p_ertm_info,uint16_t my_mtu,uint16_t required_remote_mtu,uint16_t sec_level)708 uint16_t L2CA_Register(uint16_t client_psm, const tL2CAP_APPL_INFO& callbacks,
709 bool enable_snoop, tL2CAP_ERTM_INFO* p_ertm_info,
710 uint16_t my_mtu, uint16_t required_remote_mtu,
711 uint16_t sec_level) {
712 if (classic_dynamic_channel_helper_map_.count(client_psm) != 0) {
713 LOG(ERROR) << __func__ << "Already registered psm: " << client_psm;
714 return 0;
715 }
716
717 classic::DynamicChannelConfigurationOption config;
718 config.minimal_remote_mtu = std::max<uint16_t>(required_remote_mtu, 48);
719 config.incoming_mtu = my_mtu;
720 config.channel_mode =
721 (p_ertm_info != nullptr &&
722 p_ertm_info->preferred_mode == L2CAP_FCR_ERTM_MODE
723 ? classic::DynamicChannelConfigurationOption::
724 RetransmissionAndFlowControlMode::ENHANCED_RETRANSMISSION
725 : classic::DynamicChannelConfigurationOption::
726 RetransmissionAndFlowControlMode::L2CAP_BASIC);
727
728 classic::SecurityPolicy policy =
729 (client_psm == 1
730 ? classic::SecurityPolicy::
731 _SDP_ONLY_NO_SECURITY_WHATSOEVER_PLAINTEXT_TRANSPORT_OK
732 : classic::SecurityPolicy::ENCRYPTED_TRANSPORT);
733 if (sec_level & (BTM_SEC_IN_AUTHENTICATE | BTM_SEC_OUT_AUTHENTICATE)) {
734 policy = classic::SecurityPolicy::BEST;
735 }
736
737 classic_dynamic_channel_helper_map_[client_psm] =
738 std::make_unique<ClassicDynamicChannelHelper>(client_psm, callbacks,
739 config, policy);
740
741 classic_dynamic_channel_helper_map_[client_psm]->Register();
742 return client_psm;
743 }
744
L2CA_Deregister(uint16_t psm)745 void L2CA_Deregister(uint16_t psm) {
746 if (classic_dynamic_channel_helper_map_.count(psm) == 0) {
747 LOG(ERROR) << __func__ << "Not registered psm: " << psm;
748 return;
749 }
750 classic_dynamic_channel_helper_map_[psm]->Unregister();
751 }
752
753 /**
754 * Classic Connection Oriented Channel APIS
755 */
L2CA_ConnectReq(uint16_t psm,const RawAddress & raw_address)756 uint16_t L2CA_ConnectReq(uint16_t psm, const RawAddress& raw_address) {
757 if (classic_dynamic_channel_helper_map_.count(psm) == 0) {
758 LOG(ERROR) << __func__ << "Not registered psm: " << psm;
759 return 0;
760 }
761 uint16_t cid_token = add_classic_cid_token_entry(psm);
762 classic_dynamic_channel_helper_map_[psm]->Connect(
763 cid_token, ToAddressWithType(raw_address, BLE_ADDR_PUBLIC));
764 return cid_token;
765 }
766
L2CA_DisconnectReq(uint16_t cid)767 bool L2CA_DisconnectReq(uint16_t cid) {
768 auto psm = classic_cid_token_to_channel_map_[cid];
769 if (classic_dynamic_channel_helper_map_.count(psm) == 0) {
770 LOG(ERROR) << __func__ << "Not registered psm: " << psm;
771 return false;
772 }
773 classic_dynamic_channel_helper_map_[psm]->Disconnect(cid);
774 return true;
775 }
776
L2CA_DataWrite(uint16_t cid,BT_HDR * p_data)777 uint8_t L2CA_DataWrite(uint16_t cid, BT_HDR* p_data) {
778 if (classic_cid_token_to_channel_map_.count(cid) == 0) {
779 LOG(ERROR) << __func__ << "Invalid cid: " << cid;
780 osi_free(p_data);
781 return 0;
782 }
783 auto psm = classic_cid_token_to_channel_map_[cid];
784 if (classic_dynamic_channel_helper_map_.count(psm) == 0) {
785 LOG(ERROR) << __func__ << "Not registered psm: " << psm;
786 osi_free(p_data);
787 return 0;
788 }
789 auto len = p_data->len;
790 auto* data = p_data->data + p_data->offset;
791 uint8_t sent_length =
792 classic_dynamic_channel_helper_map_[psm]->send(
793 cid, MakeUniquePacket(data, len, IsPacketFlushable(p_data))) *
794 len;
795 osi_free(p_data);
796 return sent_length;
797 }
798
L2CA_ReconfigCreditBasedConnsReq(const RawAddress & bd_addr,std::vector<uint16_t> & lcids,tL2CAP_LE_CFG_INFO * p_cfg)799 bool L2CA_ReconfigCreditBasedConnsReq(const RawAddress& bd_addr,
800 std::vector<uint16_t>& lcids,
801 tL2CAP_LE_CFG_INFO* p_cfg) {
802 LOG_INFO("UNIMPLEMENTED %s addr: %s cfg:%p", __func__,
803 bd_addr.ToString().c_str(), p_cfg);
804 return false;
805 }
806
L2CA_ConnectCreditBasedReq(uint16_t psm,const RawAddress & p_bd_addr,tL2CAP_LE_CFG_INFO * p_cfg)807 std::vector<uint16_t> L2CA_ConnectCreditBasedReq(uint16_t psm,
808 const RawAddress& p_bd_addr,
809 tL2CAP_LE_CFG_INFO* p_cfg) {
810 LOG_INFO("UNIMPLEMENTED %s addr:%s", __func__, p_bd_addr.ToString().c_str());
811 std::vector<uint16_t> result;
812 return result;
813 }
814
L2CA_ConnectCreditBasedRsp(const RawAddress & bd_addr,uint8_t id,std::vector<uint16_t> & accepted_lcids,uint16_t result,tL2CAP_LE_CFG_INFO * p_cfg)815 bool L2CA_ConnectCreditBasedRsp(const RawAddress& bd_addr, uint8_t id,
816 std::vector<uint16_t>& accepted_lcids,
817 uint16_t result, tL2CAP_LE_CFG_INFO* p_cfg) {
818 LOG_INFO("UNIMPLEMENTED %s addr:%s", __func__, bd_addr.ToString().c_str());
819 return false;
820 }
821
822 /**
823 * Link APIs
824 */
L2CA_SetIdleTimeoutByBdAddr(const RawAddress & bd_addr,uint16_t timeout,tBT_TRANSPORT transport)825 bool L2CA_SetIdleTimeoutByBdAddr(const RawAddress& bd_addr, uint16_t timeout,
826 tBT_TRANSPORT transport) {
827 if (transport == BT_TRANSPORT_BR_EDR) {
828 LOG_INFO("UNIMPLEMENTED %s", __func__);
829 return false;
830 }
831 if (timeout == 0 || timeout == GATT_LINK_IDLE_TIMEOUT_WHEN_NO_APP) {
832 bluetooth::shim::L2CA_RemoveFixedChnl(kLeAttributeCid, bd_addr);
833 return true;
834 } else {
835 LOG_INFO("UNIMPLEMENTED %s", __func__);
836 return false;
837 }
838 }
839
L2CA_SetAclPriority(uint16_t handle,bool high_priority)840 bool L2CA_SetAclPriority(uint16_t handle, bool high_priority) {
841 GetAclManager()->HACK_SetAclTxPriority(handle, high_priority);
842 return true;
843 }
844
L2CA_SetAclPriority(const RawAddress & bd_addr,tL2CAP_PRIORITY priority)845 bool L2CA_SetAclPriority(const RawAddress& bd_addr, tL2CAP_PRIORITY priority) {
846 uint16_t handle = security_listener_shim_.address_to_handle_[bd_addr];
847 return L2CA_SetAclPriority(handle, priority == L2CAP_PRIORITY_HIGH);
848 }
849
L2CA_GetPeerFeatures(const RawAddress & bd_addr,uint32_t * p_ext_feat,uint8_t * p_chnl_mask)850 bool L2CA_GetPeerFeatures(const RawAddress& bd_addr, uint32_t* p_ext_feat,
851 uint8_t* p_chnl_mask) {
852 LOG_INFO("UNIMPLEMENTED %s", __func__);
853 return false;
854 }
855
856 static constexpr uint16_t kAttCid = 4;
857
858 struct LeFixedChannelHelper {
LeFixedChannelHelperbluetooth::shim::LeFixedChannelHelper859 LeFixedChannelHelper(uint16_t cid) : cid_(cid) {}
860
861 uint16_t cid_;
862
on_registration_completebluetooth::shim::LeFixedChannelHelper863 void on_registration_complete(
864 le::FixedChannelManager::RegistrationResult result,
865 std::unique_ptr<le::FixedChannelService> service) {
866 if (result != le::FixedChannelManager::RegistrationResult::SUCCESS) {
867 LOG(ERROR) << "Channel is not registered. cid=" << +cid_;
868 return;
869 }
870 channel_service_ = std::move(service);
871 }
872
873 std::unique_ptr<le::FixedChannelService> channel_service_ = nullptr;
874
on_channel_closebluetooth::shim::LeFixedChannelHelper875 void on_channel_close(bluetooth::hci::Address device,
876 bluetooth::hci::ErrorCode error_code) {
877 auto address = bluetooth::ToRawAddress(device);
878 channel_enqueue_buffer_[device] = nullptr;
879 channels_[device]->GetQueueUpEnd()->UnregisterDequeue();
880 channels_[device] = nullptr;
881 conn_parameters_.erase(device);
882 uint8_t error = static_cast<uint8_t>(error_code);
883 (freg_.pL2CA_FixedConn_Cb)(cid_, address, false, error, BT_TRANSPORT_LE);
884 }
885
on_channel_openbluetooth::shim::LeFixedChannelHelper886 void on_channel_open(std::unique_ptr<le::FixedChannel> channel) {
887 auto remote = channel->GetDevice();
888 auto device = remote.GetAddress();
889 channel->RegisterOnCloseCallback(
890 GetGdShimHandler(), bluetooth::common::BindOnce(
891 &LeFixedChannelHelper::on_channel_close,
892 bluetooth::common::Unretained(this), device));
893 if (cid_ == kAttCid) {
894 channel->Acquire();
895 }
896 channel_enqueue_buffer_[device] = std::make_unique<
897 bluetooth::os::EnqueueBuffer<bluetooth::packet::BasePacketBuilder>>(
898 channel->GetQueueUpEnd());
899 channel->GetQueueUpEnd()->RegisterDequeue(
900 GetGdShimHandler(),
901 bluetooth::common::Bind(&LeFixedChannelHelper::on_incoming_data,
902 bluetooth::common::Unretained(this), device));
903 channels_[device] = std::move(channel);
904 conn_parameters_[device] = {};
905
906 auto address = bluetooth::ToRawAddress(device);
907
908 (freg_.pL2CA_FixedConn_Cb)(cid_, address, true, 0, BT_TRANSPORT_LE);
909 }
910
on_incoming_databluetooth::shim::LeFixedChannelHelper911 void on_incoming_data(bluetooth::hci::Address device) {
912 auto channel = channels_.find(device);
913 if (channel == channels_.end()) {
914 LOG_ERROR("Channel is not open");
915 return;
916 }
917 auto packet = channel->second->GetQueueUpEnd()->TryDequeue();
918 std::vector<uint8_t> packet_vector(packet->begin(), packet->end());
919 BT_HDR* buffer =
920 static_cast<BT_HDR*>(osi_calloc(packet_vector.size() + sizeof(BT_HDR)));
921 std::copy(packet_vector.begin(), packet_vector.end(), buffer->data);
922 buffer->len = packet_vector.size();
923 auto address = bluetooth::ToRawAddress(device);
924 freg_.pL2CA_FixedData_Cb(cid_, address, buffer);
925 }
926
on_outgoing_connection_failbluetooth::shim::LeFixedChannelHelper927 void on_outgoing_connection_fail(
928 RawAddress remote, le::FixedChannelManager::ConnectionResult result) {
929 LOG(ERROR) << "Outgoing connection failed";
930 freg_.pL2CA_FixedConn_Cb(cid_, remote, true, 0, BT_TRANSPORT_LE);
931 }
932
sendbluetooth::shim::LeFixedChannelHelper933 bool send(hci::Address remote,
934 std::unique_ptr<bluetooth::packet::BasePacketBuilder> packet) {
935 auto buffer = channel_enqueue_buffer_.find(remote);
936 if (buffer == channel_enqueue_buffer_.end() || buffer->second == nullptr) {
937 LOG(ERROR) << "Channel is not open for cid " << cid_;
938 return false;
939 }
940 buffer->second->Enqueue(std::move(packet), GetGdShimHandler());
941 return true;
942 }
943
944 std::unordered_map<hci::Address, std::unique_ptr<le::FixedChannel>> channels_;
945 std::unordered_map<hci::Address, std::unique_ptr<bluetooth::os::EnqueueBuffer<
946 bluetooth::packet::BasePacketBuilder>>>
947 channel_enqueue_buffer_;
948
949 struct ConnectionParameter {
950 // Default values are from GD HCI_ACL le_impl.
951 uint16_t min_int = 0x0018;
952 uint16_t max_int = 0x0028;
953 uint16_t latency = 0x0000;
954 uint16_t timeout = 0x001f4;
955 uint16_t min_ce_len = 0x0000;
956 uint16_t max_ce_len = 0x0000;
957 bool update_allowed = true;
958 };
959 std::unordered_map<hci::Address, ConnectionParameter> conn_parameters_;
960 tL2CAP_FIXED_CHNL_REG freg_;
961 };
962
963 static LeFixedChannelHelper att_helper{4};
964 static LeFixedChannelHelper smp_helper{6};
965 static std::unordered_map<uint16_t, LeFixedChannelHelper&>
966 le_fixed_channel_helper_{
967 {4, att_helper},
968 {6, smp_helper},
969 };
970
971 /**
972 * Fixed Channel APIs. Note: Classic fixed channel (connectionless and BR SMP)
973 * is not supported
974 */
L2CA_RegisterFixedChannel(uint16_t cid,tL2CAP_FIXED_CHNL_REG * p_freg)975 bool L2CA_RegisterFixedChannel(uint16_t cid, tL2CAP_FIXED_CHNL_REG* p_freg) {
976 if (cid != kAttCid && cid != kSmpCid) {
977 LOG(ERROR) << "Invalid cid: " << cid;
978 return false;
979 }
980 auto* helper = &le_fixed_channel_helper_.find(cid)->second;
981 if (helper == nullptr) {
982 LOG(ERROR) << "Can't register cid " << cid;
983 return false;
984 }
985 GetL2capLeModule()->GetFixedChannelManager()->RegisterService(
986 cid,
987 common::BindOnce(&LeFixedChannelHelper::on_registration_complete,
988 common::Unretained(helper)),
989 common::Bind(&LeFixedChannelHelper::on_channel_open,
990 common::Unretained(helper)),
991 GetGdShimHandler());
992 helper->freg_ = *p_freg;
993 return true;
994 }
995
L2CA_ConnectFixedChnl(uint16_t cid,const RawAddress & rem_bda)996 bool L2CA_ConnectFixedChnl(uint16_t cid, const RawAddress& rem_bda) {
997 if (cid != kAttCid && cid != kSmpCid) {
998 LOG(ERROR) << "Invalid cid " << cid;
999 return false;
1000 }
1001
1002 auto* helper = &le_fixed_channel_helper_.find(cid)->second;
1003 auto remote = Btm::GetAddressAndType(rem_bda);
1004 auto record =
1005 le_link_property_listener_shim_.info_.find(ToGdAddress(rem_bda));
1006 if (record != le_link_property_listener_shim_.info_.end()) {
1007 remote = record->second.address_with_type;
1008 }
1009 LOG(ERROR) << __func__ << remote.ToString();
1010 auto manager = GetL2capLeModule()->GetFixedChannelManager();
1011 manager->ConnectServices(
1012 remote,
1013 common::BindOnce(&LeFixedChannelHelper::on_outgoing_connection_fail,
1014 common::Unretained(helper), rem_bda),
1015 GetGdShimHandler());
1016 return true;
1017 }
1018
L2CA_SendFixedChnlData(uint16_t cid,const RawAddress & rem_bda,BT_HDR * p_buf)1019 uint16_t L2CA_SendFixedChnlData(uint16_t cid, const RawAddress& rem_bda,
1020 BT_HDR* p_buf) {
1021 if (cid != kAttCid && cid != kSmpCid) {
1022 LOG(ERROR) << "Invalid cid " << cid;
1023 osi_free(p_buf);
1024 return L2CAP_DW_FAILED;
1025 }
1026 auto* helper = &le_fixed_channel_helper_.find(cid)->second;
1027 auto len = p_buf->len;
1028 auto* data = p_buf->data + p_buf->offset;
1029 bool sent =
1030 helper->send(ToGdAddress(rem_bda),
1031 MakeUniquePacket(data, len, IsPacketFlushable(p_buf)));
1032 osi_free(p_buf);
1033 return sent ? L2CAP_DW_SUCCESS : L2CAP_DW_FAILED;
1034 }
1035
L2CA_RemoveFixedChnl(uint16_t cid,const RawAddress & rem_bda)1036 bool L2CA_RemoveFixedChnl(uint16_t cid, const RawAddress& rem_bda) {
1037 if (cid != kAttCid && cid != kSmpCid) {
1038 LOG(ERROR) << "Invalid cid " << cid;
1039 return false;
1040 }
1041 auto* helper = &le_fixed_channel_helper_.find(cid)->second;
1042 auto channel = helper->channels_.find(ToGdAddress(rem_bda));
1043 if (channel == helper->channels_.end() || channel->second == nullptr) {
1044 LOG(ERROR) << "Channel is not open";
1045 return false;
1046 }
1047 channel->second->Release();
1048 return true;
1049 }
1050
L2CA_GetLeHandle(const RawAddress & rem_bda)1051 uint16_t L2CA_GetLeHandle(const RawAddress& rem_bda) {
1052 auto addr = ToGdAddress(rem_bda);
1053 if (le_link_property_listener_shim_.info_.count(addr) == 0) {
1054 return 0;
1055 }
1056 return le_link_property_listener_shim_.info_[addr].handle;
1057 }
1058
L2CA_LeConnectionUpdate(const RawAddress & rem_bda,uint16_t min_int,uint16_t max_int,uint16_t latency,uint16_t timeout,uint16_t min_ce_len,uint16_t max_ce_len)1059 void L2CA_LeConnectionUpdate(const RawAddress& rem_bda, uint16_t min_int,
1060 uint16_t max_int, uint16_t latency,
1061 uint16_t timeout, uint16_t min_ce_len,
1062 uint16_t max_ce_len) {
1063 auto* helper = &le_fixed_channel_helper_.find(kAttCid)->second;
1064 auto channel = helper->channels_.find(ToGdAddress(rem_bda));
1065 if (channel == helper->channels_.end() || channel->second == nullptr) {
1066 LOG(ERROR) << "Channel is not open";
1067 return;
1068 }
1069
1070 auto& parameter = helper->conn_parameters_[ToGdAddress(rem_bda)];
1071
1072 parameter.min_int = min_int;
1073 parameter.max_int = max_int;
1074 parameter.latency = latency;
1075 parameter.timeout = timeout;
1076 parameter.min_ce_len = min_ce_len;
1077 parameter.max_ce_len = max_ce_len;
1078
1079 if (parameter.update_allowed) {
1080 channel->second->GetLinkOptions()->UpdateConnectionParameter(
1081 min_int, max_int, latency, timeout, min_ce_len, max_ce_len);
1082 }
1083 // If update not allowed, don't update; instead cache the value, and update
1084 // when update is allowed.
1085 }
1086
L2CA_EnableUpdateBleConnParams(const RawAddress & rem_bda,bool enable)1087 bool L2CA_EnableUpdateBleConnParams(const RawAddress& rem_bda, bool enable) {
1088 // When enable is false, we disallow remote connection update request, and
1089 // we use default parameters temporarily.
1090 auto* helper = &le_fixed_channel_helper_.find(kAttCid)->second;
1091 auto channel = helper->channels_.find(ToGdAddress(rem_bda));
1092 if (channel == helper->channels_.end() || channel->second == nullptr) {
1093 LOG(ERROR) << "Channel is not open";
1094 return false;
1095 }
1096
1097 auto& parameter = helper->conn_parameters_[ToGdAddress(rem_bda)];
1098 parameter.update_allowed = enable;
1099 // TODO(hsz): Notify HCI_ACL LE to allow/disallow remote request.
1100
1101 if (parameter.update_allowed) {
1102 // Use cached values
1103 uint16_t min_int = parameter.min_int;
1104 uint16_t max_int = parameter.max_int;
1105 uint16_t latency = parameter.latency;
1106 uint16_t timeout = parameter.timeout;
1107 uint16_t min_ce_len = parameter.min_ce_len;
1108 uint16_t max_ce_len = parameter.max_ce_len;
1109 channel->second->GetLinkOptions()->UpdateConnectionParameter(
1110 min_int, max_int, latency, timeout, min_ce_len, max_ce_len);
1111 } else {
1112 // Use the value from legacy l2cble_start_conn_update
1113 uint16_t min_int = BTM_BLE_CONN_INT_MIN;
1114 uint16_t max_int = BTM_BLE_CONN_INT_MIN;
1115 L2CA_AdjustConnectionIntervals(&min_int, &max_int, BTM_BLE_CONN_INT_MIN);
1116 uint16_t latency = BTM_BLE_CONN_PERIPHERAL_LATENCY_DEF;
1117 uint16_t timeout = BTM_BLE_CONN_TIMEOUT_DEF;
1118 uint16_t min_ce_len = 0x0000;
1119 uint16_t max_ce_len = 0x0000;
1120 channel->second->GetLinkOptions()->UpdateConnectionParameter(
1121 min_int, max_int, latency, timeout, min_ce_len, max_ce_len);
1122 }
1123 return true;
1124 }
1125
1126 /**
1127 * Channel hygiene APIs
1128 */
L2CA_GetRemoteCid(uint16_t lcid,uint16_t * rcid)1129 bool L2CA_GetRemoteCid(uint16_t lcid, uint16_t* rcid) {
1130 auto psm = classic_cid_token_to_channel_map_[lcid];
1131 if (classic_dynamic_channel_helper_map_.count(psm) == 0) {
1132 LOG(ERROR) << __func__ << "Not registered psm: " << psm;
1133 return false;
1134 }
1135 *rcid = classic_dynamic_channel_helper_map_[psm]->GetRemoteCid(lcid);
1136 return *rcid != 0;
1137 }
1138
L2CA_SetTxPriority(uint16_t cid,tL2CAP_CHNL_PRIORITY priority)1139 bool L2CA_SetTxPriority(uint16_t cid, tL2CAP_CHNL_PRIORITY priority) {
1140 auto psm = classic_cid_token_to_channel_map_[cid];
1141 if (classic_dynamic_channel_helper_map_.count(psm) == 0) {
1142 LOG(ERROR) << __func__ << "Not registered psm: " << psm;
1143 return false;
1144 }
1145 bool high_priority = priority == L2CAP_CHNL_PRIORITY_HIGH;
1146 return classic_dynamic_channel_helper_map_[psm]->SetChannelTxPriority(
1147 cid, high_priority);
1148 }
1149
L2CA_SetLeGattTimeout(const RawAddress & rem_bda,uint16_t idle_tout)1150 bool L2CA_SetLeGattTimeout(const RawAddress& rem_bda, uint16_t idle_tout) {
1151 if (idle_tout == 0xffff) {
1152 bluetooth::shim::L2CA_ConnectFixedChnl(kLeAttributeCid, rem_bda);
1153 } else {
1154 bluetooth::shim::L2CA_RemoveFixedChnl(kLeAttributeCid, rem_bda);
1155 }
1156 return true;
1157 }
1158
L2CA_SetChnlFlushability(uint16_t cid,bool is_flushable)1159 bool L2CA_SetChnlFlushability(uint16_t cid, bool is_flushable) {
1160 LOG_INFO("UNIMPLEMENTED %s", __func__);
1161 return false;
1162 }
1163
L2CA_FlushChannel(uint16_t lcid,uint16_t num_to_flush)1164 uint16_t L2CA_FlushChannel(uint16_t lcid, uint16_t num_to_flush) {
1165 auto psm = classic_cid_token_to_channel_map_[lcid];
1166 if (classic_dynamic_channel_helper_map_.count(psm) == 0) {
1167 LOG(ERROR) << __func__ << "Not registered psm: " << psm;
1168 return 0;
1169 }
1170 if (num_to_flush == L2CAP_FLUSH_CHANS_GET) {
1171 return classic_dynamic_channel_helper_map_[psm]->GetNumBufferedPackets(
1172 lcid);
1173 } else {
1174 classic_dynamic_channel_helper_map_[psm]->FlushChannel(lcid);
1175 return 1; // Client doesn't care
1176 }
1177 // TODO: Implement LE part
1178 }
1179
L2CA_IsLinkEstablished(const RawAddress & bd_addr,tBT_TRANSPORT transport)1180 bool L2CA_IsLinkEstablished(const RawAddress& bd_addr,
1181 tBT_TRANSPORT transport) {
1182 if (transport == BT_TRANSPORT_BR_EDR) {
1183 return security_listener_shim_.IsLinkUp(bd_addr);
1184 } else {
1185 return bluetooth::shim::L2CA_GetLeHandle(bd_addr) != 0;
1186 }
1187 }
1188
L2CA_IsLeLink(uint16_t acl_handle)1189 bool L2CA_IsLeLink(uint16_t acl_handle) {
1190 for (const auto& entry : le_link_property_listener_shim_.info_) {
1191 if (entry.second.handle == acl_handle) return true;
1192 }
1193 return false;
1194 }
1195
L2CA_ReadConnectionAddr(const RawAddress & pseudo_addr,RawAddress & conn_addr,uint8_t * p_addr_type)1196 void L2CA_ReadConnectionAddr(const RawAddress& pseudo_addr,
1197 RawAddress& conn_addr, uint8_t* p_addr_type) {
1198 auto* helper = &le_fixed_channel_helper_.find(kSmpCid)->second;
1199 auto channel = helper->channels_.find(ToGdAddress(pseudo_addr));
1200 if (channel == helper->channels_.end() || channel->second == nullptr) {
1201 LOG(ERROR) << "Channel is not open!";
1202 return;
1203 }
1204 auto local = channel->second->GetLinkOptions()->GetLocalAddress();
1205 conn_addr = ToRawAddress(local.GetAddress());
1206 *p_addr_type = static_cast<uint8_t>(local.GetAddressType());
1207 }
1208
L2CA_ReadRemoteConnectionAddr(const RawAddress & pseudo_addr,RawAddress & conn_addr,uint8_t * p_addr_type)1209 bool L2CA_ReadRemoteConnectionAddr(const RawAddress& pseudo_addr,
1210 RawAddress& conn_addr,
1211 uint8_t* p_addr_type) {
1212 auto remote = ToGdAddress(pseudo_addr);
1213 if (le_link_property_listener_shim_.info_.count(remote) == 0) {
1214 LOG(ERROR) << __func__ << ": Unknown address";
1215 return false;
1216 }
1217 auto info = le_link_property_listener_shim_.info_[remote].address_with_type;
1218 conn_addr = ToRawAddress(info.GetAddress());
1219 *p_addr_type = static_cast<tBLE_ADDR_TYPE>(info.GetAddressType());
1220 return true;
1221 }
1222
L2CA_GetBleConnRole(const RawAddress & bd_addr)1223 hci_role_t L2CA_GetBleConnRole(const RawAddress& bd_addr) {
1224 auto remote = ToGdAddress(bd_addr);
1225 if (le_link_property_listener_shim_.info_.count(remote) == 0) {
1226 return HCI_ROLE_UNKNOWN;
1227 }
1228 return static_cast<hci_role_t>(
1229 le_link_property_listener_shim_.info_[remote].role);
1230 }
1231
L2CA_ConnectForSecurity(const RawAddress & bd_addr)1232 void L2CA_ConnectForSecurity(const RawAddress& bd_addr) {
1233 security_interface_->InitiateConnectionForSecurity(
1234 bluetooth::ToGdAddress(bd_addr));
1235 }
1236
L2CA_SetBondingState(const RawAddress & bd_addr,bool is_bonding)1237 void L2CA_SetBondingState(const RawAddress& bd_addr, bool is_bonding) {
1238 security_listener_shim_.UpdateLinkHoldForSecurity(bd_addr, is_bonding);
1239 }
1240
L2CA_DisconnectLink(const RawAddress & remote)1241 void L2CA_DisconnectLink(const RawAddress& remote) {
1242 security_listener_shim_.Disconnect(remote);
1243 }
1244
L2CA_GetNumLinks()1245 uint16_t L2CA_GetNumLinks() { return security_listener_shim_.GetNumAclLinks(); }
1246
1247 // LE COC Shim Helper
1248
1249 namespace {
1250
1251 uint16_t le_cid_token_counter_ = 0x41;
1252
1253 std::unordered_map<uint16_t /* token */, uint16_t /* psm */>
1254 le_cid_token_to_channel_map_;
1255
add_le_cid_token_entry(uint16_t psm)1256 uint16_t add_le_cid_token_entry(uint16_t psm) {
1257 uint16_t new_token = le_cid_token_counter_;
1258 le_cid_token_to_channel_map_[new_token] = psm;
1259 le_cid_token_counter_++;
1260 if (le_cid_token_counter_ == 0) le_cid_token_counter_ = 0x41;
1261 return new_token;
1262 }
1263
remove_le_cid_token_entry(uint16_t cid_token)1264 void remove_le_cid_token_entry(uint16_t cid_token) {
1265 le_cid_token_to_channel_map_.erase(cid_token);
1266 }
1267
1268 void remove_le_dynamic_channel_helper(uint16_t psm);
1269
1270 struct LeDynamicChannelHelper {
LeDynamicChannelHelperbluetooth::shim::__anon71e10d460210::LeDynamicChannelHelper1271 LeDynamicChannelHelper(uint16_t psm, tL2CAP_APPL_INFO appl_info,
1272 le::DynamicChannelConfigurationOption config,
1273 le::SecurityPolicy policy)
1274 : psm_(psm), appl_info_(appl_info), config_(config), policy_(policy) {}
1275
1276 uint16_t psm_;
1277 tL2CAP_APPL_INFO appl_info_;
1278 le::DynamicChannelConfigurationOption config_;
1279 le::SecurityPolicy policy_;
1280
Registerbluetooth::shim::__anon71e10d460210::LeDynamicChannelHelper1281 void Register() {
1282 std::promise<void> promise;
1283 auto future = promise.get_future();
1284 GetL2capLeModule()->GetDynamicChannelManager()->RegisterService(
1285 psm_, config_, policy_,
1286 base::BindOnce(&LeDynamicChannelHelper::on_registration_complete,
1287 base::Unretained(this), std::move(promise)),
1288 base::Bind(&LeDynamicChannelHelper::on_channel_open,
1289 base::Unretained(this), 0),
1290 GetGdShimHandler());
1291 future.wait_for(std::chrono::milliseconds(300));
1292 }
1293
on_registration_completebluetooth::shim::__anon71e10d460210::LeDynamicChannelHelper1294 void on_registration_complete(
1295 std::promise<void> promise,
1296 le::DynamicChannelManager::RegistrationResult result,
1297 std::unique_ptr<le::DynamicChannelService> service) {
1298 if (result != le::DynamicChannelManager::RegistrationResult::SUCCESS) {
1299 LOG(ERROR) << "Channel is not registered. psm=" << +psm_ << (int)result;
1300 promise.set_value();
1301 return;
1302 }
1303 channel_service_ = std::move(service);
1304 promise.set_value();
1305 }
1306
1307 std::unique_ptr<le::DynamicChannelService> channel_service_ = nullptr;
1308
Connectbluetooth::shim::__anon71e10d460210::LeDynamicChannelHelper1309 void Connect(uint16_t cid_token, bluetooth::hci::AddressWithType device) {
1310 if (channel_service_ == nullptr) {
1311 LOG(ERROR) << __func__ << "Not registered";
1312 return;
1313 }
1314 initiated_by_us_[cid_token] = true;
1315 GetL2capLeModule()->GetDynamicChannelManager()->ConnectChannel(
1316 device, config_, psm_,
1317 base::Bind(&LeDynamicChannelHelper::on_channel_open,
1318 base::Unretained(this), cid_token),
1319 base::BindOnce(&LeDynamicChannelHelper::on_outgoing_connection_fail,
1320 base::Unretained(this)),
1321 GetGdShimHandler());
1322 }
1323
Disconnectbluetooth::shim::__anon71e10d460210::LeDynamicChannelHelper1324 void Disconnect(uint16_t cid_token) {
1325 if (channel_service_ == nullptr) {
1326 return;
1327 }
1328 if (channels_.count(cid_token) == 0) {
1329 return;
1330 }
1331 channels_[cid_token]->Close();
1332 }
1333
Unregisterbluetooth::shim::__anon71e10d460210::LeDynamicChannelHelper1334 void Unregister() {
1335 if (channel_service_ != nullptr) {
1336 channel_service_->Unregister(
1337 base::BindOnce(&LeDynamicChannelHelper::on_unregistered,
1338 base::Unretained(this)),
1339 GetGdShimHandler());
1340 channel_service_ = nullptr;
1341 }
1342 }
1343
on_unregisteredbluetooth::shim::__anon71e10d460210::LeDynamicChannelHelper1344 void on_unregistered() {
1345 for (const auto& device : channels_) {
1346 device.second->Close();
1347 }
1348 remove_le_dynamic_channel_helper(psm_);
1349 }
1350
on_channel_closebluetooth::shim::__anon71e10d460210::LeDynamicChannelHelper1351 void on_channel_close(uint16_t cid_token,
1352 bluetooth::hci::ErrorCode error_code) {
1353 channel_enqueue_buffer_[cid_token] = nullptr;
1354 channel_enqueue_buffer_.erase(cid_token);
1355 channels_[cid_token]->GetQueueUpEnd()->UnregisterDequeue();
1356 channels_.erase(cid_token);
1357 do_in_main_thread(FROM_HERE, base::Bind(appl_info_.pL2CA_DisconnectInd_Cb,
1358 cid_token, false));
1359
1360 remove_le_cid_token_entry(cid_token);
1361 initiated_by_us_.erase(cid_token);
1362
1363 if (channel_service_ == nullptr && channels_.empty()) {
1364 // Try again
1365 L2CA_Deregister(psm_);
1366 }
1367 }
1368
on_channel_openbluetooth::shim::__anon71e10d460210::LeDynamicChannelHelper1369 void on_channel_open(uint16_t cid_token,
1370 std::unique_ptr<le::DynamicChannel> channel) {
1371 auto device = channel->GetDevice();
1372 auto address = bluetooth::ToRawAddress(device.GetAddress());
1373 bool initiator_local = (cid_token != 0);
1374 if (cid_token == 0) {
1375 cid_token = add_le_cid_token_entry(psm_);
1376 }
1377
1378 channel->RegisterOnCloseCallback(GetGdShimHandler()->BindOnceOn(
1379 this, &LeDynamicChannelHelper::on_channel_close, cid_token));
1380
1381 channel->GetQueueUpEnd()->RegisterDequeue(
1382 GetGdShimHandler(),
1383 bluetooth::common::Bind(&LeDynamicChannelHelper::on_incoming_data,
1384 bluetooth::common::Unretained(this),
1385 cid_token));
1386
1387 channel_enqueue_buffer_[cid_token] = std::make_unique<
1388 bluetooth::os::EnqueueBuffer<bluetooth::packet::BasePacketBuilder>>(
1389 channel->GetQueueUpEnd());
1390
1391 channels_[cid_token] = std::move(channel);
1392
1393 if (initiator_local) {
1394 do_in_main_thread(
1395 FROM_HERE, base::Bind(appl_info_.pL2CA_ConnectCfm_Cb, cid_token, 0));
1396
1397 } else {
1398 if (appl_info_.pL2CA_ConnectInd_Cb == nullptr) {
1399 Disconnect(cid_token);
1400 return;
1401 }
1402 do_in_main_thread(FROM_HERE, base::Bind(appl_info_.pL2CA_ConnectInd_Cb,
1403 address, cid_token, psm_, 0));
1404 }
1405 }
1406
on_incoming_databluetooth::shim::__anon71e10d460210::LeDynamicChannelHelper1407 void on_incoming_data(uint16_t cid_token) {
1408 auto channel = channels_.find(cid_token);
1409 if (channel == channels_.end()) {
1410 LOG_ERROR("Channel is not open");
1411 return;
1412 }
1413 auto packet = channel->second->GetQueueUpEnd()->TryDequeue();
1414 std::vector<uint8_t> packet_vector(packet->begin(), packet->end());
1415 BT_HDR* buffer =
1416 static_cast<BT_HDR*>(osi_calloc(packet_vector.size() + sizeof(BT_HDR)));
1417 std::copy(packet_vector.begin(), packet_vector.end(), buffer->data);
1418 buffer->len = packet_vector.size();
1419 if (do_in_main_thread(FROM_HERE,
1420 base::Bind(appl_info_.pL2CA_DataInd_Cb, cid_token,
1421 base::Unretained(buffer))) !=
1422 BT_STATUS_SUCCESS) {
1423 osi_free(buffer);
1424 }
1425 }
1426
on_outgoing_connection_failbluetooth::shim::__anon71e10d460210::LeDynamicChannelHelper1427 void on_outgoing_connection_fail(
1428 le::DynamicChannelManager::ConnectionResult result) {
1429 LOG(ERROR) << "Outgoing connection failed";
1430 }
1431
sendbluetooth::shim::__anon71e10d460210::LeDynamicChannelHelper1432 bool send(uint16_t cid,
1433 std::unique_ptr<bluetooth::packet::BasePacketBuilder> packet) {
1434 auto buffer = channel_enqueue_buffer_.find(cid);
1435 if (buffer == channel_enqueue_buffer_.end() || buffer->second == nullptr) {
1436 LOG(ERROR) << "Channel is not open";
1437 return false;
1438 }
1439 buffer->second->Enqueue(std::move(packet), GetGdShimHandler());
1440 return true;
1441 }
1442
GetMtubluetooth::shim::__anon71e10d460210::LeDynamicChannelHelper1443 uint16_t GetMtu(uint16_t cid_token) {
1444 if (channels_.count(cid_token) == 0) {
1445 return 0;
1446 }
1447 return static_cast<uint16_t>(channels_[cid_token]->GetMtu());
1448 }
1449
1450 std::unordered_map<uint16_t, std::unique_ptr<le::DynamicChannel>> channels_;
1451 std::unordered_map<uint16_t, std::unique_ptr<bluetooth::os::EnqueueBuffer<
1452 bluetooth::packet::BasePacketBuilder>>>
1453 channel_enqueue_buffer_;
1454 std::unordered_map<uint16_t, bool> initiated_by_us_;
1455 };
1456
1457 std::unordered_map<uint16_t, std::unique_ptr<LeDynamicChannelHelper>>
1458 le_dynamic_channel_helper_map_;
1459
remove_le_dynamic_channel_helper(uint16_t psm)1460 void remove_le_dynamic_channel_helper(uint16_t psm) {
1461 if (le_dynamic_channel_helper_map_.count(psm) != 0 &&
1462 le_dynamic_channel_helper_map_[psm]->channels_.empty()) {
1463 le_dynamic_channel_helper_map_.erase(psm);
1464 }
1465 }
1466
1467 std::unordered_set<uint16_t> assigned_dynamic_le_psm_;
1468 uint16_t next_assigned_dynamic_le_psm_ = 0x80;
1469 } // namespace
1470
1471 /**
1472 * Le Connection Oriented Channel APIs
1473 */
1474
L2CA_AllocateLePSM()1475 uint16_t L2CA_AllocateLePSM() {
1476 if (le_dynamic_channel_helper_map_.size() > 100) {
1477 LOG_ERROR("Why do we need more than 100 dynamic channel PSMs?");
1478 return 0;
1479 }
1480 while (le_dynamic_channel_helper_map_.count(next_assigned_dynamic_le_psm_)) {
1481 next_assigned_dynamic_le_psm_++;
1482 if (next_assigned_dynamic_le_psm_ > 0xff) {
1483 next_assigned_dynamic_le_psm_ = 0x80;
1484 }
1485 }
1486 assigned_dynamic_le_psm_.emplace(next_assigned_dynamic_le_psm_);
1487 return next_assigned_dynamic_le_psm_;
1488 }
1489
L2CA_FreeLePSM(uint16_t psm)1490 void L2CA_FreeLePSM(uint16_t psm) { assigned_dynamic_le_psm_.erase(psm); }
1491
L2CA_RegisterLECoc(uint16_t psm,const tL2CAP_APPL_INFO & callbacks,uint16_t sec_level,tL2CAP_LE_CFG_INFO cfg)1492 uint16_t L2CA_RegisterLECoc(uint16_t psm, const tL2CAP_APPL_INFO& callbacks,
1493 uint16_t sec_level, tL2CAP_LE_CFG_INFO cfg) {
1494 if (le_dynamic_channel_helper_map_.count(psm) != 0) {
1495 LOG(ERROR) << __func__ << "Already registered psm: " << psm;
1496 return 0;
1497 }
1498
1499 le::DynamicChannelConfigurationOption config;
1500 config.mtu = cfg.mtu;
1501 le::SecurityPolicy policy =
1502 le::SecurityPolicy::NO_SECURITY_WHATSOEVER_PLAINTEXT_TRANSPORT_OK;
1503 if (sec_level & (BTM_SEC_IN_AUTHENTICATE | BTM_SEC_OUT_AUTHENTICATE)) {
1504 policy = le::SecurityPolicy::AUTHENTICATED_ENCRYPTED_TRANSPORT;
1505 }
1506
1507 le_dynamic_channel_helper_map_[psm] =
1508 std::make_unique<LeDynamicChannelHelper>(psm, callbacks, config, policy);
1509 le_dynamic_channel_helper_map_[psm]->Register();
1510 return psm;
1511 }
1512
L2CA_DeregisterLECoc(uint16_t psm)1513 void L2CA_DeregisterLECoc(uint16_t psm) {
1514 if (le_dynamic_channel_helper_map_.count(psm) == 0) {
1515 LOG(ERROR) << __func__ << "Not registered psm: " << psm;
1516 return;
1517 }
1518 le_dynamic_channel_helper_map_[psm]->Unregister();
1519 }
1520
L2CA_ConnectLECocReq(uint16_t psm,const RawAddress & p_bd_addr,tL2CAP_LE_CFG_INFO * p_cfg)1521 uint16_t L2CA_ConnectLECocReq(uint16_t psm, const RawAddress& p_bd_addr,
1522 tL2CAP_LE_CFG_INFO* p_cfg) {
1523 if (le_dynamic_channel_helper_map_.count(psm) == 0) {
1524 LOG(ERROR) << __func__ << "Not registered psm: " << psm;
1525 return 0;
1526 }
1527 uint16_t cid_token = add_le_cid_token_entry(psm);
1528 auto remote = Btm::GetAddressAndType(p_bd_addr);
1529 auto record =
1530 le_link_property_listener_shim_.info_.find(ToGdAddress(p_bd_addr));
1531 if (record != le_link_property_listener_shim_.info_.end()) {
1532 remote = record->second.address_with_type;
1533 }
1534 le_dynamic_channel_helper_map_[psm]->Connect(cid_token, remote);
1535 return cid_token;
1536 }
1537
L2CA_GetPeerLECocConfig(uint16_t cid,tL2CAP_LE_CFG_INFO * peer_cfg)1538 bool L2CA_GetPeerLECocConfig(uint16_t cid, tL2CAP_LE_CFG_INFO* peer_cfg) {
1539 if (le_cid_token_to_channel_map_.count(cid) == 0) {
1540 LOG(ERROR) << __func__ << "Invalid cid: " << cid;
1541 return false;
1542 }
1543 auto psm = le_cid_token_to_channel_map_[cid];
1544 if (le_dynamic_channel_helper_map_.count(psm) == 0) {
1545 LOG(ERROR) << __func__ << "Not registered psm: " << psm;
1546 return false;
1547 }
1548 auto mtu = le_dynamic_channel_helper_map_[psm]->GetMtu(cid);
1549 peer_cfg->mtu = mtu;
1550 return mtu;
1551 }
1552
L2CA_DisconnectLECocReq(uint16_t cid)1553 bool L2CA_DisconnectLECocReq(uint16_t cid) {
1554 if (le_cid_token_to_channel_map_.count(cid) == 0) {
1555 LOG(ERROR) << __func__ << "Invalid cid: " << cid;
1556 return false;
1557 }
1558 auto psm = le_cid_token_to_channel_map_[cid];
1559 if (le_dynamic_channel_helper_map_.count(psm) == 0) {
1560 LOG(ERROR) << __func__ << "Not registered psm: " << psm;
1561 return false;
1562 }
1563 le_dynamic_channel_helper_map_[psm]->Disconnect(cid);
1564 return true;
1565 }
1566
L2CA_LECocDataWrite(uint16_t cid,BT_HDR * p_data)1567 uint8_t L2CA_LECocDataWrite(uint16_t cid, BT_HDR* p_data) {
1568 if (le_cid_token_to_channel_map_.count(cid) == 0) {
1569 LOG(ERROR) << __func__ << "Invalid cid: " << cid;
1570 osi_free(p_data);
1571 return 0;
1572 }
1573 auto psm = le_cid_token_to_channel_map_[cid];
1574 if (le_dynamic_channel_helper_map_.count(psm) == 0) {
1575 LOG(ERROR) << __func__ << "Not registered psm: " << psm;
1576 osi_free(p_data);
1577 return 0;
1578 }
1579 auto len = p_data->len;
1580 auto* data = p_data->data + p_data->offset;
1581 uint8_t sent_length =
1582 le_dynamic_channel_helper_map_[psm]->send(
1583 cid, MakeUniquePacket(data, len, IsPacketFlushable(p_data))) *
1584 len;
1585 osi_free(p_data);
1586 return sent_length;
1587 }
1588
L2CA_SwitchRoleToCentral(const RawAddress & addr)1589 void L2CA_SwitchRoleToCentral(const RawAddress& addr) {
1590 GetAclManager()->SwitchRole(ToGdAddress(addr), bluetooth::hci::Role::CENTRAL);
1591 }
1592
1593 } // namespace shim
1594 } // namespace bluetooth
1595