1 /*
2  * Copyright 2020 HIMSA II K/S - www.himsa.com. Represented by EHIMA -
3  * www.ehima.com
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #pragma once
19 
20 #include <bluetooth/log.h>
21 #include <com_android_bluetooth_flags.h>
22 
23 #include <map>
24 #include <memory>
25 #include <utility>
26 #include <vector>
27 
28 #include "hci/controller_interface.h"
29 #include "include/bind_helpers.h"
30 #include "internal_include/stack_config.h"
31 #include "main/shim/entry.h"
32 #include "osi/include/alarm.h"
33 #include "osi/include/allocator.h"
34 #include "stack/btm/btm_sec.h"
35 #include "stack/eatt/eatt.h"
36 #include "stack/gatt/gatt_int.h"
37 #include "stack/include/bt_hdr.h"
38 #include "stack/include/bt_psm_types.h"
39 #include "stack/include/btm_sec_api.h"
40 #include "stack/include/l2cap_interface.h"
41 #include "stack/include/l2cdefs.h"
42 #include "stack/include/main_thread.h"
43 
44 namespace bluetooth {
45 namespace eatt {
46 
47 #define BLE_GATT_SVR_SUP_FEAT_EATT_BITMASK 0x01
48 
49 class eatt_device {
50 public:
51   RawAddress bda_;
52   uint16_t rx_mtu_;
53   uint16_t rx_mps_;
54 
55   tGATT_TCB* eatt_tcb_;
56 
57   std::map<uint16_t, std::shared_ptr<EattChannel>> eatt_channels;
58   bool collision;
eatt_device(const RawAddress & bd_addr,uint16_t mtu,uint16_t mps)59   eatt_device(const RawAddress& bd_addr, uint16_t mtu, uint16_t mps)
60       : rx_mtu_(mtu), rx_mps_(mps), eatt_tcb_(nullptr), collision(false) {
61     bda_ = bd_addr;
62   }
63 };
64 
65 struct eatt_impl {
66   std::vector<eatt_device> devices_;
67   uint16_t psm_;
68   uint16_t default_mtu_;
69   uint16_t max_mps_;
70   tL2CAP_APPL_INFO reg_info_;
71 
72   base::WeakPtrFactory<eatt_impl> weak_factory_{this};
73 
eatt_impleatt_impl74   eatt_impl() {
75     default_mtu_ = EATT_DEFAULT_MTU;
76     max_mps_ = EATT_MIN_MTU_MPS;
77     psm_ = BT_PSM_EATT;
78   }
79 
80   ~eatt_impl() = default;
81 
find_device_by_cideatt_impl82   eatt_device* find_device_by_cid(uint16_t lcid) {
83     /* This works only because Android CIDs are unique across the ACL
84      * connections */
85     auto iter = find_if(devices_.begin(), devices_.end(), [&lcid](const eatt_device& ed) {
86       auto it = ed.eatt_channels.find(lcid);
87       return it != ed.eatt_channels.end();
88     });
89 
90     return (iter == devices_.end()) ? nullptr : &(*iter);
91   }
92 
find_channel_by_cideatt_impl93   EattChannel* find_channel_by_cid(uint16_t lcid) {
94     eatt_device* eatt_dev = find_device_by_cid(lcid);
95     if (!eatt_dev) {
96       return nullptr;
97     }
98 
99     auto it = eatt_dev->eatt_channels.find(lcid);
100     return (it == eatt_dev->eatt_channels.end()) ? nullptr : it->second.get();
101   }
102 
is_channel_connection_pendingeatt_impl103   bool is_channel_connection_pending(eatt_device* eatt_dev) {
104     for (const std::pair<uint16_t, std::shared_ptr<EattChannel>>& el : eatt_dev->eatt_channels) {
105       if (el.second->state_ == EattChannelState::EATT_CHANNEL_PENDING) {
106         return true;
107       }
108     }
109     return false;
110   }
111 
find_channel_by_cideatt_impl112   EattChannel* find_channel_by_cid(const RawAddress& bdaddr, uint16_t lcid) {
113     eatt_device* eatt_dev = find_device_by_address(bdaddr);
114     if (!eatt_dev) {
115       return nullptr;
116     }
117 
118     auto it = eatt_dev->eatt_channels.find(lcid);
119     return (it == eatt_dev->eatt_channels.end()) ? nullptr : it->second.get();
120   }
121 
remove_channel_by_cideatt_impl122   void remove_channel_by_cid(eatt_device* eatt_dev, uint16_t lcid) {
123     auto channel = eatt_dev->eatt_channels[lcid];
124     if (!channel->cl_cmd_q_.empty()) {
125       log::warn("Channel {:c}, for device {} is not empty on disconnection.", lcid, channel->bda_);
126       channel->cl_cmd_q_.clear();
127     }
128 
129     eatt_dev->eatt_channels.erase(lcid);
130 
131     if (eatt_dev->eatt_channels.size() == 0) {
132       eatt_dev->eatt_tcb_ = NULL;
133     }
134   }
135 
remove_channel_by_cideatt_impl136   void remove_channel_by_cid(uint16_t lcid) {
137     eatt_device* eatt_dev = find_device_by_cid(lcid);
138     if (!eatt_dev) {
139       return;
140     }
141 
142     remove_channel_by_cid(eatt_dev, lcid);
143   }
144 
eatt_l2cap_connect_ind_commoneatt_impl145   bool eatt_l2cap_connect_ind_common(const RawAddress& bda, std::vector<uint16_t>& lcids,
146                                      uint16_t /* psm */, uint16_t peer_mtu, uint8_t identifier) {
147     /* The assumption is that L2CAP layer already check parameters etc.
148      * Get our capabilities and accept all the channels.
149      */
150     eatt_device* eatt_dev = this->find_device_by_address(bda);
151     if (!eatt_dev) {
152       /* If there is no device it means, Android did not read yet Server
153        * supported features, but according to Core 5.3, Vol 3,  Part G, 6.2.1,
154        * for LE case it is not necessary to read it before establish connection.
155        * Therefore assume, device supports EATT since we got request to create
156        * EATT channels. Just create device here. */
157       log::info("Adding device: {} on incoming EATT creation request", bda);
158       eatt_dev = add_eatt_device(bda);
159     }
160 
161     uint16_t max_mps = shim::GetController()->GetLeBufferSize().le_data_packet_length_;
162 
163     tL2CAP_LE_CFG_INFO local_coc_cfg = {
164             .result = tL2CAP_CFG_RESULT::L2CAP_CFG_OK,
165             .mtu = eatt_dev->rx_mtu_,
166             .mps = eatt_dev->rx_mps_ < max_mps ? eatt_dev->rx_mps_ : max_mps,
167             .credits = L2CA_LeCreditDefault(),
168     };
169 
170     if (!stack::l2cap::get_interface().L2CA_ConnectCreditBasedRsp(
171                 bda, identifier, lcids, tL2CAP_LE_RESULT_CODE::L2CAP_LE_RESULT_CONN_OK,
172                 &local_coc_cfg)) {
173       log::warn("Unable to respond L2CAP le_coc credit indication peer:{}", bda);
174       return false;
175     }
176 
177     if (!eatt_dev->eatt_tcb_) {
178       eatt_dev->eatt_tcb_ = gatt_find_tcb_by_addr(eatt_dev->bda_, BT_TRANSPORT_LE);
179       log::assert_that(eatt_dev->eatt_tcb_ != nullptr,
180                        "assert failed: eatt_dev->eatt_tcb_ != nullptr");
181     }
182 
183     for (uint16_t cid : lcids) {
184       EattChannel* channel = find_eatt_channel_by_cid(bda, cid);
185       log::assert_that(channel == nullptr, "assert failed: channel == nullptr");
186 
187       auto chan = std::make_shared<EattChannel>(eatt_dev->bda_, cid, peer_mtu, eatt_dev->rx_mtu_);
188       eatt_dev->eatt_channels.insert({cid, chan});
189 
190       chan->EattChannelSetState(EattChannelState::EATT_CHANNEL_OPENED);
191       eatt_dev->eatt_tcb_->eatt++;
192 
193       log::info("Channel connected CID 0x{:x}", cid);
194     }
195 
196     return true;
197   }
198 
199   /* This is for the L2CAP ECoC Testing. */
200   void upper_tester_send_data_if_needed(const RawAddress& bda, uint16_t cid = 0) {
201     eatt_device* eatt_dev = find_device_by_address(bda);
202     auto num_of_sdu = stack_config_get_interface()->get_pts_l2cap_ecoc_send_num_of_sdu();
203     log::info("device {}, num: {}", eatt_dev->bda_, num_of_sdu);
204 
205     if (num_of_sdu <= 0) {
206       return;
207     }
208 
209     uint16_t mtu = 0;
210     if (cid != 0) {
211       auto chan = find_channel_by_cid(cid);
212       mtu = chan->tx_mtu_;
213     } else {
214       for (const std::pair<uint16_t, std::shared_ptr<EattChannel>>& el : eatt_dev->eatt_channels) {
215         if (el.second->state_ == EattChannelState::EATT_CHANNEL_OPENED) {
216           cid = el.first;
217           mtu = el.second->tx_mtu_;
218           break;
219         }
220       }
221     }
222 
223     if (cid == 0 || mtu == 0) {
224       log::error("There is no OPEN cid or MTU is 0");
225       return;
226     }
227 
228     for (int i = 0; i < num_of_sdu; i++) {
229       BT_HDR* p_buf = (BT_HDR*)osi_malloc(mtu + sizeof(BT_HDR));
230       p_buf->offset = L2CAP_MIN_OFFSET;
231       p_buf->len = mtu;
232 
233       auto status = stack::l2cap::get_interface().L2CA_DataWrite(cid, p_buf);
234       log::info("Data num: {} sent with status {}", i, static_cast<int>(status));
235     }
236   }
237 
238   /* This is for the L2CAP ECoC Testing. */
upper_tester_delay_connect_cbeatt_impl239   void upper_tester_delay_connect_cb(const RawAddress& bda) {
240     log::info("device {}", bda);
241     eatt_device* eatt_dev = find_device_by_address(bda);
242     if (eatt_dev == nullptr) {
243       log::error("device is not available");
244       return;
245     }
246 
247     connect_eatt_wrap(eatt_dev);
248   }
249 
upper_tester_delay_connecteatt_impl250   void upper_tester_delay_connect(const RawAddress& bda, int timeout_ms) {
251     bt_status_t status =
252             do_in_main_thread_delayed(base::BindOnce(&eatt_impl::upper_tester_delay_connect_cb,
253                                                      weak_factory_.GetWeakPtr(), bda),
254                                       std::chrono::milliseconds(timeout_ms));
255 
256     log::info("Scheduled peripheral connect eatt for device with status: {}", (int)status);
257   }
258 
upper_tester_l2cap_connect_indeatt_impl259   void upper_tester_l2cap_connect_ind(const RawAddress& bda, std::vector<uint16_t>& lcids,
260                                       uint16_t psm, uint16_t peer_mtu, uint8_t identifier) {
261     /* This is just for L2CAP PTS test cases*/
262     auto min_key_size = stack_config_get_interface()->get_pts_l2cap_ecoc_min_key_size();
263     if (min_key_size > 0 && (min_key_size >= 7 && min_key_size <= 16)) {
264       auto key_size = btm_ble_read_sec_key_size(bda);
265       if (key_size < min_key_size) {
266         std::vector<uint16_t> empty;
267         log::error("Insufficient key size ({}<{}) for device {}", key_size, min_key_size, bda);
268         if (!stack::l2cap::get_interface().L2CA_ConnectCreditBasedRsp(
269                     bda, identifier, empty,
270                     tL2CAP_LE_RESULT_CODE::L2CAP_LE_RESULT_INSUFFICIENT_ENCRYP_KEY_SIZE, nullptr)) {
271           log::warn("Unable to respond L2CAP le_coc credit indication peer:{}", bda);
272         }
273         return;
274       }
275     }
276 
277     if (!eatt_l2cap_connect_ind_common(bda, lcids, psm, peer_mtu, identifier)) {
278       log::debug("Reject L2CAP Connection request.");
279       return;
280     }
281 
282     /* Android let Central to create EATT (PTS initiates EATT). Some PTS test
283      * cases wants Android to do it anyway (Android initiates EATT).
284      */
285     if (stack_config_get_interface()->get_pts_eatt_peripheral_collision_support()) {
286       upper_tester_delay_connect(bda, 500);
287       return;
288     }
289 
290     upper_tester_send_data_if_needed(bda);
291 
292     if (stack_config_get_interface()->get_pts_l2cap_ecoc_reconfigure()) {
293       bt_status_t status = do_in_main_thread_delayed(
294               base::BindOnce(&eatt_impl::reconfigure_all, weak_factory_.GetWeakPtr(), bda, 300),
295               std::chrono::seconds(4));
296       log::info("Scheduled ECOC reconfiguration with status: {}", (int)status);
297     }
298   }
299 
eatt_l2cap_connect_indeatt_impl300   void eatt_l2cap_connect_ind(const RawAddress& bda, std::vector<uint16_t>& lcids, uint16_t psm,
301                               uint16_t peer_mtu, uint8_t identifier) {
302     log::info("Device {}, num of cids: {}, psm 0x{:04x}, peer_mtu {}", bda,
303               static_cast<int>(lcids.size()), psm, peer_mtu);
304 
305     if (!stack_config_get_interface()->get_pts_connect_eatt_before_encryption() &&
306         !BTM_IsEncrypted(bda, BT_TRANSPORT_LE)) {
307       /* If Link is not encrypted, we shall not accept EATT channel creation. */
308       std::vector<uint16_t> empty;
309       tL2CAP_LE_RESULT_CODE result =
310               tL2CAP_LE_RESULT_CODE::L2CAP_LE_RESULT_INSUFFICIENT_AUTHENTICATION;
311       if (BTM_IsLinkKeyKnown(bda, BT_TRANSPORT_LE)) {
312         result = tL2CAP_LE_RESULT_CODE::L2CAP_LE_RESULT_INSUFFICIENT_ENCRYP;
313       }
314       log::error("ACL to device {} is unencrypted.", bda);
315       if (!stack::l2cap::get_interface().L2CA_ConnectCreditBasedRsp(bda, identifier, empty, result,
316                                                                     nullptr)) {
317         log::warn("Unable to respond L2CAP le_coc credit indication peer:{}", bda);
318       }
319       return;
320     }
321 
322     if (stack_config_get_interface()->get_pts_l2cap_ecoc_upper_tester()) {
323       log::info("Upper tester for the L2CAP ECoC enabled");
324       return upper_tester_l2cap_connect_ind(bda, lcids, psm, peer_mtu, identifier);
325     }
326 
327     eatt_l2cap_connect_ind_common(bda, lcids, psm, peer_mtu, identifier);
328   }
329 
eatt_retry_after_collision_if_neededeatt_impl330   void eatt_retry_after_collision_if_needed(eatt_device* eatt_dev) {
331     if (!eatt_dev->collision) {
332       log::debug("No collision.");
333       return;
334     }
335     /* We are here, because remote device wanted to create channels when
336      * Android proceed its own EATT creation. How to handle it is described
337      * here: BT Core 5.3, Volume 3, Part G, 5.4
338      */
339     log::info("EATT collision detected. If we are Central we will retry right away");
340 
341     eatt_dev->collision = false;
342     uint8_t role = stack::l2cap::get_interface().L2CA_GetBleConnRole(eatt_dev->bda_);
343     if (role == HCI_ROLE_CENTRAL) {
344       log::info("Retrying EATT setup due to previous collision for device {}", eatt_dev->bda_);
345       connect_eatt_wrap(eatt_dev);
346     } else if (stack_config_get_interface()->get_pts_eatt_peripheral_collision_support()) {
347       /* This is only for the PTS. Android does not setup EATT when is a
348        * peripheral.
349        */
350       upper_tester_delay_connect(eatt_dev->bda_, 500);
351     }
352   }
353 
354   /* This is for the L2CAP ECoC Testing. */
upper_tester_l2cap_connect_cfmeatt_impl355   void upper_tester_l2cap_connect_cfm(eatt_device* eatt_dev) {
356     log::info("Upper tester for L2CAP Ecoc {}", eatt_dev->bda_);
357     if (is_channel_connection_pending(eatt_dev)) {
358       log::info("Waiting for all channels to be connected");
359       return;
360     }
361 
362     if (stack_config_get_interface()->get_pts_l2cap_ecoc_connect_remaining() &&
363         (static_cast<int>(eatt_dev->eatt_channels.size()) < L2CAP_CREDIT_BASED_MAX_CIDS)) {
364       log::info("Connecting remaining channels {}",
365                 L2CAP_CREDIT_BASED_MAX_CIDS - static_cast<int>(eatt_dev->eatt_channels.size()));
366       upper_tester_delay_connect(eatt_dev->bda_, 1000);
367       return;
368     }
369     upper_tester_send_data_if_needed(eatt_dev->bda_);
370   }
371 
eatt_l2cap_connect_cfmeatt_impl372   void eatt_l2cap_connect_cfm(const RawAddress& bda, uint16_t lcid, uint16_t peer_mtu,
373                               tL2CAP_LE_RESULT_CODE result) {
374     log::info("bda: {} cid: {}peer mtu: {} result {}", bda, lcid, peer_mtu, result);
375 
376     eatt_device* eatt_dev = find_device_by_address(bda);
377     if (!eatt_dev) {
378       log::error("unknown device");
379       return;
380     }
381 
382     EattChannel* channel = this->find_channel_by_cid(bda, lcid);
383     if (!channel) {
384       log::error("unknown cid: 0x{:x}", lcid);
385       return;
386     }
387 
388     if (result != tL2CAP_LE_RESULT_CODE::L2CAP_LE_RESULT_CONN_OK) {
389       log::error("Could not connect CoC result: 0x{:x}", result);
390       remove_channel_by_cid(eatt_dev, lcid);
391 
392       /* If there is no channels connected, check if there was collision */
393       if (!is_channel_connection_pending(eatt_dev)) {
394         eatt_retry_after_collision_if_needed(eatt_dev);
395       }
396       return;
397     }
398 
399     channel->EattChannelSetState(EattChannelState::EATT_CHANNEL_OPENED);
400     channel->EattChannelSetTxMTU(peer_mtu);
401 
402     log::assert_that(eatt_dev->eatt_tcb_ != nullptr,
403                      "assert failed: eatt_dev->eatt_tcb_ != nullptr");
404     log::assert_that(eatt_dev->bda_ == channel->bda_,
405                      "assert failed: eatt_dev->bda_ == channel->bda_");
406     eatt_dev->eatt_tcb_->eatt++;
407 
408     log::info("Channel connected CID 0x{:04x}", lcid);
409 
410     if (stack_config_get_interface()->get_pts_l2cap_ecoc_upper_tester()) {
411       upper_tester_l2cap_connect_cfm(eatt_dev);
412     }
413   }
414 
eatt_l2cap_reconfig_completedeatt_impl415   void eatt_l2cap_reconfig_completed(const RawAddress& bda, uint16_t lcid, bool is_local_cfg,
416                                      tL2CAP_LE_CFG_INFO* p_cfg) {
417     log::info("lcid: 0x{:x} local cfg?: {}", lcid, is_local_cfg);
418 
419     EattChannel* channel = find_channel_by_cid(bda, lcid);
420     if (!channel) {
421       return;
422     }
423 
424     // regardless of success result, we have finished reconfiguration
425     channel->EattChannelSetState(EattChannelState::EATT_CHANNEL_OPENED);
426 
427     if (p_cfg->result != tL2CAP_CFG_RESULT::L2CAP_CFG_OK) {
428       log::info("reconfig failed lcid: 0x{:x} result:{}", lcid,
429                 l2cap_cfg_result_text(p_cfg->result));
430       return;
431     }
432 
433     /* On this layer we don't care about mps as this is handled in L2CAP layer
434      */
435     if (is_local_cfg) {
436       channel->rx_mtu_ = p_cfg->mtu;
437     } else {
438       channel->EattChannelSetTxMTU(p_cfg->mtu);
439     }
440 
441     if (stack_config_get_interface()->get_pts_l2cap_ecoc_reconfigure()) {
442       /* Upper tester for L2CAP - schedule sending data */
443       do_in_main_thread_delayed(base::BindOnce(&eatt_impl::upper_tester_send_data_if_needed,
444                                                weak_factory_.GetWeakPtr(), bda, lcid),
445                                 std::chrono::seconds(1));
446     }
447   }
448 
eatt_l2cap_collision_indeatt_impl449   void eatt_l2cap_collision_ind(const RawAddress& bda) {
450     eatt_device* eatt_dev = find_device_by_address(bda);
451     if (!eatt_dev) {
452       log::error("Device {} not available anymore:", bda);
453       return;
454     }
455     /* Remote wanted to setup channels as well. Let's retry remote's request
456      * when we are done with ours.*/
457     eatt_dev->collision = true;
458   }
459 
eatt_l2cap_error_cbeatt_impl460   void eatt_l2cap_error_cb(uint16_t lcid, uint16_t reason) {
461     EattChannel* channel = find_channel_by_cid(lcid);
462     if (!channel) {
463       log::error("Unknown cid: 0x{:x}, reason: 0x{:x}", lcid, reason);
464       return;
465     }
466 
467     eatt_device* eatt_dev = find_device_by_address(channel->bda_);
468     switch (channel->state_) {
469       case EattChannelState::EATT_CHANNEL_PENDING:
470         log::warn("Channel for cid: 0x{:x} is not extablished, reason: 0x{:x}", lcid, reason);
471         remove_channel_by_cid(eatt_dev, lcid);
472         break;
473       case EattChannelState::EATT_CHANNEL_RECONFIGURING:
474         /* Just go back to open state */
475         log::error("Reconfig failed fo cid: 0x{:x}, reason: 0x{:x}", lcid, reason);
476         channel->EattChannelSetState(EattChannelState::EATT_CHANNEL_OPENED);
477         break;
478       default:
479         log::error("cid: 0x{:x}, reason: 0x{:x}, invalid state: {}", lcid, reason,
480                    static_cast<uint8_t>(channel->state_));
481         break;
482     }
483 
484     if (!is_channel_connection_pending(eatt_dev)) {
485       eatt_retry_after_collision_if_needed(eatt_dev);
486     }
487   }
488 
eatt_l2cap_disconnect_indeatt_impl489   void eatt_l2cap_disconnect_ind(uint16_t lcid, bool /* please_confirm */) {
490     log::info("cid: 0x{:x}", lcid);
491     eatt_device* eatt_dev = find_device_by_cid(lcid);
492     if (!eatt_dev) {
493       log::error("unknown cid: 0x{:x}", lcid);
494       return;
495     }
496 
497     eatt_dev->eatt_tcb_->eatt--;
498     remove_channel_by_cid(eatt_dev, lcid);
499   }
500 
eatt_l2cap_data_indeatt_impl501   void eatt_l2cap_data_ind(uint16_t lcid, BT_HDR* data_p) {
502     log::info("cid: 0x{:x}", lcid);
503     eatt_device* eatt_dev = find_device_by_cid(lcid);
504     if (!eatt_dev) {
505       log::error("unknown cid: 0x{:x}", lcid);
506       return;
507     }
508 
509     EattChannel* channel = find_channel_by_cid(eatt_dev->bda_, lcid);
510     if (!channel) {
511       log::error("Received data on closed channel 0x{:x}", lcid);
512       return;
513     }
514 
515     gatt_data_process(*eatt_dev->eatt_tcb_, channel->cid_, data_p);
516     osi_free(data_p);
517   }
518 
is_eatt_supported_by_peereatt_impl519   bool is_eatt_supported_by_peer(const RawAddress& bd_addr) {
520     return gatt_profile_get_eatt_support(bd_addr);
521   }
522 
find_device_by_addresseatt_impl523   eatt_device* find_device_by_address(const RawAddress& bd_addr) {
524     auto iter = find_if(devices_.begin(), devices_.end(),
525                         [&bd_addr](const eatt_device& ed) { return ed.bda_ == bd_addr; });
526 
527     return iter == devices_.end() ? nullptr : &(*iter);
528   }
529 
add_eatt_deviceeatt_impl530   eatt_device* add_eatt_device(const RawAddress& bd_addr) {
531     devices_.push_back(eatt_device(bd_addr, default_mtu_, max_mps_));
532     eatt_device* eatt_dev = &devices_.back();
533     return eatt_dev;
534   }
535 
connect_eatt_wrapeatt_impl536   void connect_eatt_wrap(eatt_device* eatt_dev) {
537     if (stack_config_get_interface()->get_pts_eatt_peripheral_collision_support()) {
538       /* For PTS case, lets assume we support only 5 channels */
539       log::info("Number of existing channels {}", (int)eatt_dev->eatt_channels.size());
540       connect_eatt(eatt_dev, L2CAP_CREDIT_BASED_MAX_CIDS - (int)eatt_dev->eatt_channels.size());
541       return;
542     }
543 
544     connect_eatt(eatt_dev);
545   }
546 
547   void connect_eatt(eatt_device* eatt_dev, uint8_t num_of_channels = L2CAP_CREDIT_BASED_MAX_CIDS) {
548     /* Let us use maximum possible mps */
549     if (eatt_dev->rx_mps_ == EATT_MIN_MTU_MPS) {
550       eatt_dev->rx_mps_ = shim::GetController()->GetLeBufferSize().le_data_packet_length_;
551     }
552 
553     tL2CAP_LE_CFG_INFO local_coc_cfg = {
554             .result = tL2CAP_CFG_RESULT::L2CAP_CFG_OK,
555             .mtu = eatt_dev->rx_mtu_,
556             .mps = eatt_dev->rx_mps_,
557             .credits = L2CA_LeCreditDefault(),
558             .number_of_channels = num_of_channels,
559     };
560 
561     log::info("Connecting device {}, cnt count {}", eatt_dev->bda_, num_of_channels);
562 
563     /* Warning! CIDs in Android are unique across the ACL connections */
564     std::vector<uint16_t> connecting_cids =
565             stack::l2cap::get_interface().L2CA_ConnectCreditBasedReq(psm_, eatt_dev->bda_,
566                                                                      &local_coc_cfg);
567 
568     if (connecting_cids.size() == 0) {
569       log::error("Unable to get cid");
570       return;
571     }
572 
573     log::info("Successfully sent CoC request, number of channel: {}", connecting_cids.size());
574 
575     for (uint16_t cid : connecting_cids) {
576       log::info("\t cid: 0x{:x}", cid);
577 
578       auto chan = std::make_shared<EattChannel>(eatt_dev->bda_, cid, 0, eatt_dev->rx_mtu_);
579       eatt_dev->eatt_channels.insert({cid, chan});
580     }
581 
582     if (eatt_dev->eatt_tcb_) {
583       log::info("has tcb ? {}", eatt_dev->eatt_tcb_ == nullptr);
584       return;
585     }
586 
587     eatt_dev->eatt_tcb_ = gatt_find_tcb_by_addr(eatt_dev->bda_, BT_TRANSPORT_LE);
588     log::assert_that(eatt_dev->eatt_tcb_ != nullptr,
589                      "assert failed: eatt_dev->eatt_tcb_ != nullptr");
590   }
591 
find_eatt_channel_by_cideatt_impl592   EattChannel* find_eatt_channel_by_cid(const RawAddress& bd_addr, uint16_t cid) {
593     eatt_device* eatt_dev = find_device_by_address(bd_addr);
594     if (!eatt_dev) {
595       return nullptr;
596     }
597 
598     auto iter = find_if(eatt_dev->eatt_channels.begin(), eatt_dev->eatt_channels.end(),
599                         [&cid](const std::pair<uint16_t, std::shared_ptr<EattChannel>>& el) {
600                           return el.first == cid;
601                         });
602 
603     return iter == eatt_dev->eatt_channels.end() ? nullptr : iter->second.get();
604   }
605 
find_eatt_channel_by_transideatt_impl606   EattChannel* find_eatt_channel_by_transid(const RawAddress& bd_addr, uint32_t trans_id) {
607     eatt_device* eatt_dev = find_device_by_address(bd_addr);
608     if (!eatt_dev) {
609       return nullptr;
610     }
611 
612     auto iter = find_if(eatt_dev->eatt_channels.begin(), eatt_dev->eatt_channels.end(),
613                         [&trans_id](const std::pair<uint16_t, std::shared_ptr<EattChannel>>& el) {
614                           return el.second->server_outstanding_cmd_.trans_id == trans_id;
615                         });
616 
617     return iter == eatt_dev->eatt_channels.end() ? nullptr : iter->second.get();
618   }
619 
is_indication_pendingeatt_impl620   bool is_indication_pending(const RawAddress& bd_addr, uint16_t indication_handle) {
621     eatt_device* eatt_dev = find_device_by_address(bd_addr);
622     if (!eatt_dev) {
623       return false;
624     }
625 
626     auto iter = find_if(
627             eatt_dev->eatt_channels.begin(), eatt_dev->eatt_channels.end(),
628             [&indication_handle](const std::pair<uint16_t, std::shared_ptr<EattChannel>>& el) {
629               return el.second->indicate_handle_ == indication_handle;
630             });
631 
632     return iter != eatt_dev->eatt_channels.end();
633   }
634 
get_channel_available_for_indicationeatt_impl635   EattChannel* get_channel_available_for_indication(const RawAddress& bd_addr) {
636     eatt_device* eatt_dev = find_device_by_address(bd_addr);
637     auto iter = find_if(eatt_dev->eatt_channels.begin(), eatt_dev->eatt_channels.end(),
638                         [](const std::pair<uint16_t, std::shared_ptr<EattChannel>>& el) {
639                           return el.second->state_ == EattChannelState::EATT_CHANNEL_OPENED &&
640                                  !GATT_HANDLE_IS_VALID(el.second->indicate_handle_);
641                         });
642 
643     return (iter == eatt_dev->eatt_channels.end()) ? nullptr : iter->second.get();
644   }
645 
get_channel_available_for_client_requesteatt_impl646   EattChannel* get_channel_available_for_client_request(const RawAddress& bd_addr) {
647     eatt_device* eatt_dev = find_device_by_address(bd_addr);
648     if (!eatt_dev) {
649       return nullptr;
650     }
651 
652     auto iter = find_if(eatt_dev->eatt_channels.begin(), eatt_dev->eatt_channels.end(),
653                         [](const std::pair<uint16_t, std::shared_ptr<EattChannel>>& el) {
654                           return el.second->state_ == EattChannelState::EATT_CHANNEL_OPENED &&
655                                  el.second->cl_cmd_q_.empty();
656                         });
657 
658     return (iter == eatt_dev->eatt_channels.end()) ? nullptr : iter->second.get();
659   }
660 
free_gatt_resourceseatt_impl661   void free_gatt_resources(const RawAddress& bd_addr) {
662     eatt_device* eatt_dev = find_device_by_address(bd_addr);
663     if (!eatt_dev) {
664       return;
665     }
666 
667     auto iter = eatt_dev->eatt_channels.begin();
668     while (iter != eatt_dev->eatt_channels.end()) {
669       EattChannel* channel = iter->second.get();
670 
671       fixed_queue_free(channel->server_outstanding_cmd_.multi_rsp_q, NULL);
672       channel->server_outstanding_cmd_.multi_rsp_q = NULL;
673       iter++;
674     }
675   }
676 
is_outstanding_msg_in_send_queueeatt_impl677   bool is_outstanding_msg_in_send_queue(const RawAddress& bd_addr) {
678     eatt_device* eatt_dev = find_device_by_address(bd_addr);
679     if (!eatt_dev) {
680       return false;
681     }
682 
683     auto iter = find_if(eatt_dev->eatt_channels.begin(), eatt_dev->eatt_channels.end(),
684                         [](const std::pair<uint16_t, std::shared_ptr<EattChannel>>& el) {
685                           if (el.second->cl_cmd_q_.empty()) {
686                             return false;
687                           }
688 
689                           tGATT_CMD_Q& cmd = el.second->cl_cmd_q_.front();
690                           return cmd.to_send;
691                         });
692     return iter != eatt_dev->eatt_channels.end();
693   }
694 
get_channel_with_queued_dataeatt_impl695   EattChannel* get_channel_with_queued_data(const RawAddress& bd_addr) {
696     eatt_device* eatt_dev = find_device_by_address(bd_addr);
697     if (!eatt_dev) {
698       return nullptr;
699     }
700 
701     auto iter = find_if(eatt_dev->eatt_channels.begin(), eatt_dev->eatt_channels.end(),
702                         [](const std::pair<uint16_t, std::shared_ptr<EattChannel>>& el) {
703                           if (el.second->cl_cmd_q_.empty()) {
704                             return false;
705                           }
706 
707                           tGATT_CMD_Q& cmd = el.second->cl_cmd_q_.front();
708                           return cmd.to_send;
709                         });
710     return (iter == eatt_dev->eatt_channels.end()) ? nullptr : iter->second.get();
711   }
712 
eatt_ind_ack_timeouteatt_impl713   static void eatt_ind_ack_timeout(void* data) {
714     EattChannel* channel = (EattChannel*)data;
715     tGATT_TCB* p_tcb = gatt_find_tcb_by_addr(channel->bda_, BT_TRANSPORT_LE);
716 
717     log::warn("send ack now");
718     attp_send_cl_confirmation_msg(*p_tcb, channel->cid_);
719   }
720 
eatt_ind_confirmation_timeouteatt_impl721   static void eatt_ind_confirmation_timeout(void* data) {
722     EattChannel* channel = (EattChannel*)data;
723     tGATT_TCB* p_tcb = gatt_find_tcb_by_addr(channel->bda_, BT_TRANSPORT_LE);
724 
725     log::warn("disconnecting channel {:#x} for {}", channel->cid_, channel->bda_);
726     if (com::android::bluetooth::flags::gatt_disconnect_fix()) {
727       EattExtension::GetInstance()->Disconnect(channel->bda_, channel->cid_);
728     } else {
729       gatt_disconnect(p_tcb);
730     }
731   }
732 
start_indication_confirm_timereatt_impl733   void start_indication_confirm_timer(const RawAddress& bd_addr, uint16_t cid) {
734     EattChannel* channel = find_eatt_channel_by_cid(bd_addr, cid);
735     if (!channel) {
736       log::error("Unknown cid: 0x{:x} or device {}", cid, bd_addr);
737       return;
738     }
739 
740     alarm_set_on_mloop(channel->ind_confirmation_timer_, GATT_WAIT_FOR_RSP_TIMEOUT_MS,
741                        eatt_ind_confirmation_timeout, channel);
742   }
743 
stop_indication_confirm_timereatt_impl744   void stop_indication_confirm_timer(const RawAddress& bd_addr, uint16_t cid) {
745     EattChannel* channel = find_eatt_channel_by_cid(bd_addr, cid);
746     if (!channel) {
747       log::error("Unknown cid: 0x{:x} or device {}", cid, bd_addr);
748       return;
749     }
750 
751     alarm_cancel(channel->ind_confirmation_timer_);
752   }
753 
start_app_indication_timereatt_impl754   void start_app_indication_timer(const RawAddress& bd_addr, uint16_t cid) {
755     EattChannel* channel = find_eatt_channel_by_cid(bd_addr, cid);
756     if (!channel) {
757       log::error("Unknown cid: 0x{:x} or device {}", cid, bd_addr);
758       return;
759     }
760 
761     alarm_set_on_mloop(channel->ind_ack_timer_, GATT_WAIT_FOR_RSP_TIMEOUT_MS, eatt_ind_ack_timeout,
762                        channel);
763   }
764 
stop_app_indication_timereatt_impl765   void stop_app_indication_timer(const RawAddress& bd_addr, uint16_t cid) {
766     EattChannel* channel = find_eatt_channel_by_cid(bd_addr, cid);
767     if (!channel) {
768       log::error("Unknown cid: 0x{:x} or device {}", cid, bd_addr);
769       return;
770     }
771 
772     alarm_cancel(channel->ind_ack_timer_);
773   }
774 
reconfigureeatt_impl775   void reconfigure(const RawAddress& bd_addr, uint16_t cid, uint16_t new_mtu) {
776     eatt_device* eatt_dev = find_device_by_address(bd_addr);
777     if (!eatt_dev) {
778       log::error("Unknown device {}", bd_addr);
779       return;
780     }
781 
782     EattChannel* channel = find_eatt_channel_by_cid(bd_addr, cid);
783     if (!channel) {
784       log::error("Unknown cid: 0x{:x} or device {}", cid, bd_addr);
785       return;
786     }
787 
788     if (new_mtu <= channel->rx_mtu_) {
789       log::error("Invalid mtu: 0x{:x}", new_mtu);
790       return;
791     }
792 
793     std::vector<uint16_t> cids = {cid};
794 
795     tL2CAP_LE_CFG_INFO cfg = {
796             .result = tL2CAP_CFG_RESULT::L2CAP_CFG_OK,
797             .mtu = new_mtu,
798             .mps = eatt_dev->rx_mps_,
799     };
800 
801     if (!stack::l2cap::get_interface().L2CA_ReconfigCreditBasedConnsReq(eatt_dev->bda_, cids,
802                                                                         &cfg)) {
803       log::error("Could not start reconfig cid: 0x{:x} or device {}", cid, bd_addr);
804       return;
805     }
806 
807     channel->EattChannelSetState(EattChannelState::EATT_CHANNEL_RECONFIGURING);
808   }
809 
reconfigure_alleatt_impl810   void reconfigure_all(const RawAddress& bd_addr, uint16_t new_mtu) {
811     log::info("Device {}, new mtu {}", bd_addr, new_mtu);
812     eatt_device* eatt_dev = find_device_by_address(bd_addr);
813     if (!eatt_dev) {
814       log::error("Unknown device {}", bd_addr);
815       return;
816     }
817 
818     uint8_t num_of_channels = eatt_dev->eatt_channels.size();
819     if (num_of_channels == 0) {
820       log::error("No channels for device {}", bd_addr);
821       return;
822     }
823 
824     std::vector<uint16_t> cids;
825 
826     auto iter = eatt_dev->eatt_channels.begin();
827     while (iter != eatt_dev->eatt_channels.end()) {
828       uint16_t cid = iter->first;
829       cids.push_back(cid);
830       iter++;
831     }
832 
833     if (new_mtu <= EATT_MIN_MTU_MPS) {
834       log::error("Invalid mtu: 0x{:x}", new_mtu);
835       return;
836     }
837 
838     tL2CAP_LE_CFG_INFO cfg = {
839             .result = tL2CAP_CFG_RESULT::L2CAP_CFG_OK, .mtu = new_mtu, .mps = eatt_dev->rx_mps_};
840 
841     if (!stack::l2cap::get_interface().L2CA_ReconfigCreditBasedConnsReq(eatt_dev->bda_, cids,
842                                                                         &cfg)) {
843       log::error("Could not start reconfig for device {}", bd_addr);
844       return;
845     }
846 
847     for (auto& channel : eatt_dev->eatt_channels) {
848       channel.second->EattChannelSetState(EattChannelState::EATT_CHANNEL_RECONFIGURING);
849     }
850   }
851 
supported_features_cbeatt_impl852   void supported_features_cb(uint8_t role, const RawAddress& bd_addr, uint8_t features) {
853     bool is_eatt_supported = features & BLE_GATT_SVR_SUP_FEAT_EATT_BITMASK;
854 
855     log::info("{} is_eatt_supported = {}", bd_addr, int(is_eatt_supported));
856     if (!is_eatt_supported) {
857       return;
858     }
859 
860     eatt_device* eatt_dev = this->find_device_by_address(bd_addr);
861     if (!eatt_dev) {
862       log::info("Adding device: {} on supported features callback.", bd_addr);
863       eatt_dev = add_eatt_device(bd_addr);
864     }
865 
866     if (role != HCI_ROLE_CENTRAL) {
867       /* TODO For now do nothing, we could run a timer here and start EATT if
868        * not started by central */
869       log::info("EATT Should be connected by the central. Let's wait for it.");
870       return;
871     }
872 
873     connect_eatt_wrap(eatt_dev);
874   }
875 
disconnect_channeleatt_impl876   void disconnect_channel(uint16_t cid) {
877     if (!stack::l2cap::get_interface().L2CA_DisconnectReq(cid)) {
878       log::warn("Unable to request L2CAP disconnect cid:{}", cid);
879     }
880   }
881 
disconnecteatt_impl882   void disconnect(const RawAddress& bd_addr, uint16_t cid) {
883     log::info("Device: {}, cid: 0x{:04x}", bd_addr, cid);
884 
885     eatt_device* eatt_dev = find_device_by_address(bd_addr);
886     if (!eatt_dev) {
887       log::warn("no eatt device found");
888       return;
889     }
890 
891     if (!eatt_dev->eatt_tcb_) {
892       log::assert_that(eatt_dev->eatt_channels.size() == 0,
893                        "assert failed: eatt_dev->eatt_channels.size() == 0");
894       log::warn("no eatt channels found");
895       return;
896     }
897 
898     if (cid != EATT_ALL_CIDS) {
899       auto chan = find_channel_by_cid(cid);
900       if (!chan) {
901         log::warn("Cid {} not found for device {}", cid, bd_addr);
902         return;
903       }
904       log::info("Disconnecting cid {}", cid);
905       disconnect_channel(cid);
906       remove_channel_by_cid(cid);
907       return;
908     }
909 
910     auto iter = eatt_dev->eatt_channels.begin();
911     while (iter != eatt_dev->eatt_channels.end()) {
912       uint16_t cid = iter->first;
913       disconnect_channel(cid);
914       /* When initiating disconnection, stack will not notify us that it is
915        * done. We need to assume success
916        */
917       iter = eatt_dev->eatt_channels.erase(iter);
918     }
919     eatt_dev->eatt_tcb_->eatt = 0;
920     eatt_dev->eatt_tcb_ = nullptr;
921     eatt_dev->collision = false;
922   }
923 
upper_tester_connecteatt_impl924   void upper_tester_connect(const RawAddress& bd_addr, eatt_device* eatt_dev, uint8_t role) {
925     log::info("L2CAP Upper tester enabled, {} ({}), role: {}({})", bd_addr,
926               std::format_ptr(eatt_dev),
927               role == HCI_ROLE_CENTRAL ? "HCI_ROLE_CENTRAL" : "HCI_ROLE_PERIPHERAL", role);
928 
929     auto num_of_chan = stack_config_get_interface()->get_pts_l2cap_ecoc_initial_chan_cnt();
930     if (num_of_chan <= 0) {
931       num_of_chan = L2CAP_CREDIT_BASED_MAX_CIDS;
932     }
933 
934     /* This is needed for L2CAP test cases */
935     if (stack_config_get_interface()->get_pts_connect_eatt_unconditionally()) {
936       /* Normally eatt_dev exist only if EATT is supported by remote device.
937        * Here it is created unconditionally */
938       if (eatt_dev == nullptr) {
939         eatt_dev = add_eatt_device(bd_addr);
940       }
941       /* For PTS just start connecting EATT right away */
942       connect_eatt(eatt_dev, num_of_chan);
943       return;
944     }
945 
946     if (eatt_dev != nullptr && role == HCI_ROLE_CENTRAL) {
947       connect_eatt(eatt_dev, num_of_chan);
948       return;
949     }
950 
951     /* If we don't know yet, read GATT server supported features. */
952     if (gatt_cl_read_sr_supp_feat_req(bd_addr, base::BindOnce(&eatt_impl::supported_features_cb,
953                                                               weak_factory_.GetWeakPtr(), role)) ==
954         false) {
955       log::info("Read server supported features failed for device {}", bd_addr);
956     }
957   }
958 
connecteatt_impl959   void connect(const RawAddress& bd_addr) {
960     eatt_device* eatt_dev = find_device_by_address(bd_addr);
961 
962     uint8_t role = stack::l2cap::get_interface().L2CA_GetBleConnRole(bd_addr);
963     if (role == HCI_ROLE_UNKNOWN) {
964       log::error("Could not get device role{}", bd_addr);
965       return;
966     }
967 
968     if (stack_config_get_interface()->get_pts_l2cap_ecoc_upper_tester()) {
969       upper_tester_connect(bd_addr, eatt_dev, role);
970       return;
971     }
972 
973     log::info("Device {}, role {}", bd_addr, role == HCI_ROLE_CENTRAL ? "central" : "peripheral");
974 
975     if (eatt_dev) {
976       /* We are reconnecting device we know that support EATT.
977        * Just connect CoC
978        */
979       log::info("Known device, connect eCoC");
980 
981       if (role != HCI_ROLE_CENTRAL) {
982         log::info("EATT Should be connected by the central. Let's wait for it.");
983         return;
984       }
985 
986       connect_eatt_wrap(eatt_dev);
987       return;
988     }
989 
990     if (role != HCI_ROLE_CENTRAL) {
991       return;
992     }
993 
994     if (gatt_profile_get_eatt_support(bd_addr)) {
995       log::debug("Eatt is supported for device {}", bd_addr);
996       supported_features_cb(role, bd_addr, BLE_GATT_SVR_SUP_FEAT_EATT_BITMASK);
997       return;
998     }
999 
1000     /* If we don't know yet, read GATT server supported features. */
1001     if (gatt_cl_read_sr_supp_feat_req(bd_addr, base::BindOnce(&eatt_impl::supported_features_cb,
1002                                                               weak_factory_.GetWeakPtr(), role)) ==
1003         false) {
1004       log::info("Read server supported features failed for device {}", bd_addr);
1005     }
1006   }
1007 
add_from_storageeatt_impl1008   void add_from_storage(const RawAddress& bd_addr) {
1009     eatt_device* eatt_dev = find_device_by_address(bd_addr);
1010 
1011     log::info("restoring: {}", bd_addr);
1012 
1013     if (!eatt_dev) {
1014       add_eatt_device(bd_addr);
1015     }
1016   }
1017 };
1018 
1019 }  // namespace eatt
1020 }  // namespace bluetooth
1021