1 /******************************************************************************
2  *
3  *  Copyright 2009-2012 Broadcom Corporation
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 
19 /******************************************************************************
20  *
21  *  this file contains functions relating to BLE management.
22  *
23  ******************************************************************************/
24 
25 #define LOG_TAG "l2c_ble"
26 
27 #include <base/strings/stringprintf.h>
28 #include <bluetooth/log.h>
29 #include <com_android_bluetooth_flags.h>
30 
31 #ifdef __ANDROID__
32 #include <android/sysprop/BluetoothProperties.sysprop.h>
33 #endif
34 
35 #include "btif/include/core_callbacks.h"
36 #include "btif/include/stack_manager_t.h"
37 #include "hci/controller_interface.h"
38 #include "hci/hci_layer.h"
39 #include "internal_include/bt_target.h"
40 #include "main/shim/entry.h"
41 #include "osi/include/allocator.h"
42 #include "osi/include/properties.h"
43 #include "stack/btm/btm_ble_sec.h"
44 #include "stack/btm/btm_int_types.h"
45 #include "stack/btm/btm_sec.h"
46 #include "stack/btm/btm_sec_int_types.h"
47 #include "stack/include/acl_api.h"
48 #include "stack/include/bt_psm_types.h"
49 #include "stack/include/bt_types.h"
50 #include "stack/include/btm_ble_api.h"
51 #include "stack/include/btm_log_history.h"
52 #include "stack/include/l2c_api.h"
53 #include "stack/include/l2cap_acl_interface.h"
54 #include "stack/include/l2cdefs.h"
55 #include "stack/include/main_thread.h"
56 #include "stack/l2cap/l2c_int.h"
57 #include "types/raw_address.h"
58 
59 using namespace bluetooth;
60 
61 namespace {
62 
63 constexpr char kBtmLogTag[] = "L2CAP";
64 
65 }
66 
67 extern tBTM_CB btm_cb;
68 
69 using base::StringPrintf;
70 
71 void l2cble_start_conn_update(tL2C_LCB* p_lcb);
72 
L2CA_Consolidate(const RawAddress & identity_addr,const RawAddress & rpa)73 void L2CA_Consolidate(const RawAddress& identity_addr, const RawAddress& rpa) {
74   tL2C_LCB* p_lcb = l2cu_find_lcb_by_bd_addr(rpa, BT_TRANSPORT_LE);
75   if (p_lcb == nullptr) {
76     return;
77   }
78 
79   log::info("consolidating l2c_lcb record {} -> {}", rpa, identity_addr);
80   p_lcb->remote_bd_addr = identity_addr;
81 }
82 
L2CA_GetBleConnRole(const RawAddress & bd_addr)83 hci_role_t L2CA_GetBleConnRole(const RawAddress& bd_addr) {
84   tL2C_LCB* p_lcb = l2cu_find_lcb_by_bd_addr(bd_addr, BT_TRANSPORT_LE);
85   if (p_lcb == nullptr) {
86     return HCI_ROLE_UNKNOWN;
87   }
88   return p_lcb->LinkRole();
89 }
90 
91 /*******************************************************************************
92  *
93  * Function l2cble_notify_le_connection
94  *
95  * Description This function notifiy the l2cap connection to the app layer
96  *
97  * Returns none
98  *
99  ******************************************************************************/
l2cble_notify_le_connection(const RawAddress & bda)100 void l2cble_notify_le_connection(const RawAddress& bda) {
101   tL2C_LCB* p_lcb = l2cu_find_lcb_by_bd_addr(bda, BT_TRANSPORT_LE);
102   if (p_lcb == nullptr) {
103     log::warn("Received notification for le connection but no lcb found");
104     return;
105   }
106 
107   if (BTM_IsAclConnectionUp(bda, BT_TRANSPORT_LE) &&
108       p_lcb->link_state != LST_CONNECTED) {
109     /* update link status */
110     // TODO Move this back into acl layer
111     btm_establish_continue_from_address(bda, BT_TRANSPORT_LE);
112     /* update l2cap link status and send callback */
113     p_lcb->link_state = LST_CONNECTED;
114     l2cu_process_fixed_chnl_resp(p_lcb);
115   }
116 
117   /* For all channels, send the event through their FSMs */
118   for (tL2C_CCB* p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb;
119        p_ccb = p_ccb->p_next_ccb) {
120     if (p_ccb->chnl_state == CST_CLOSED)
121       l2c_csm_execute(p_ccb, L2CEVT_LP_CONNECT_CFM, NULL);
122   }
123 }
124 
125 /** This function is called when an HCI Connection Complete event is received.
126  */
l2cble_conn_comp(uint16_t handle,tHCI_ROLE role,const RawAddress & bda,tBLE_ADDR_TYPE,uint16_t conn_interval,uint16_t conn_latency,uint16_t conn_timeout)127 bool l2cble_conn_comp(uint16_t handle, tHCI_ROLE role, const RawAddress& bda,
128                       tBLE_ADDR_TYPE /* type */, uint16_t conn_interval,
129                       uint16_t conn_latency, uint16_t conn_timeout) {
130   // role == HCI_ROLE_CENTRAL => scanner completed connection
131   // role == HCI_ROLE_PERIPHERAL => advertiser completed connection
132 
133   /* See if we have a link control block for the remote device */
134   tL2C_LCB* p_lcb = l2cu_find_lcb_by_bd_addr(bda, BT_TRANSPORT_LE);
135 
136   /* If we do not have one, create one. this is auto connection complete. */
137   if (!p_lcb) {
138     p_lcb = l2cu_allocate_lcb(bda, false, BT_TRANSPORT_LE);
139     if (!p_lcb) {
140       log::error("Unable to allocate link resource for le acl connection");
141       return false;
142     } else {
143       if (!l2cu_initialize_fixed_ccb(p_lcb, L2CAP_ATT_CID)) {
144         log::error("Unable to allocate channel resource for le acl connection");
145         return false;
146       }
147     }
148     p_lcb->link_state = LST_CONNECTING;
149   } else if (role == HCI_ROLE_CENTRAL && p_lcb->link_state != LST_CONNECTING) {
150     log::error(
151         "Received le acl connection as role central but not in connecting "
152         "state");
153     return false;
154   }
155 
156   if (role == HCI_ROLE_CENTRAL) alarm_cancel(p_lcb->l2c_lcb_timer);
157 
158   /* Save the handle */
159   l2cu_set_lcb_handle(*p_lcb, handle);
160 
161   /* Connected OK. Change state to connected, we were scanning so we are central
162    */
163   if (role == HCI_ROLE_CENTRAL) {
164     p_lcb->SetLinkRoleAsCentral();
165   } else {
166     p_lcb->SetLinkRoleAsPeripheral();
167   }
168 
169   p_lcb->transport = BT_TRANSPORT_LE;
170 
171   /* update link parameter, set peripheral link as non-spec default upon link up
172    */
173   p_lcb->min_interval = p_lcb->max_interval = conn_interval;
174   p_lcb->timeout = conn_timeout;
175   p_lcb->latency = conn_latency;
176   p_lcb->conn_update_mask = L2C_BLE_NOT_DEFAULT_PARAM;
177   p_lcb->conn_update_blocked_by_profile_connection = false;
178   p_lcb->conn_update_blocked_by_service_discovery = false;
179 
180   p_lcb->subrate_req_mask = 0;
181   p_lcb->subrate_min = 1;
182   p_lcb->subrate_max = 1;
183   p_lcb->max_latency = 0;
184   p_lcb->cont_num = 0;
185   p_lcb->supervision_tout = 0;
186 
187   p_lcb->peer_chnl_mask[0] = L2CAP_FIXED_CHNL_ATT_BIT |
188                              L2CAP_FIXED_CHNL_BLE_SIG_BIT |
189                              L2CAP_FIXED_CHNL_SMP_BIT;
190 
191   if (role == HCI_ROLE_PERIPHERAL) {
192     if (!bluetooth::shim::GetController()
193              ->SupportsBlePeripheralInitiatedFeaturesExchange()) {
194       p_lcb->link_state = LST_CONNECTED;
195       l2cu_process_fixed_chnl_resp(p_lcb);
196     }
197   }
198   return true;
199 }
200 
201 /*******************************************************************************
202  *
203  * Function         l2cble_handle_connect_rsp_neg
204  *
205  * Description      This function sends error message to all the
206  *                  outstanding channels
207  *
208  * Returns          void
209  *
210  ******************************************************************************/
l2cble_handle_connect_rsp_neg(tL2C_LCB * p_lcb,tL2C_CONN_INFO * con_info)211 static void l2cble_handle_connect_rsp_neg(tL2C_LCB* p_lcb,
212                                           tL2C_CONN_INFO* con_info) {
213   tL2C_CCB* temp_p_ccb = NULL;
214   for (int i = 0; i < p_lcb->pending_ecoc_conn_cnt; i++) {
215     uint16_t cid = p_lcb->pending_ecoc_connection_cids[i];
216     temp_p_ccb = l2cu_find_ccb_by_cid(p_lcb, cid);
217     l2c_csm_execute(temp_p_ccb, L2CEVT_L2CAP_CREDIT_BASED_CONNECT_RSP_NEG,
218                     con_info);
219   }
220 
221   p_lcb->pending_ecoc_conn_cnt = 0;
222   memset(p_lcb->pending_ecoc_connection_cids, 0, L2CAP_CREDIT_BASED_MAX_CIDS);
223 }
224 
225 /*******************************************************************************
226  *
227  * Function         l2cble_process_sig_cmd
228  *
229  * Description      This function is called when a signalling packet is received
230  *                  on the BLE signalling CID
231  *
232  * Returns          void
233  *
234  ******************************************************************************/
l2cble_process_sig_cmd(tL2C_LCB * p_lcb,uint8_t * p,uint16_t pkt_len)235 void l2cble_process_sig_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) {
236   uint8_t* p_pkt_end;
237   uint8_t cmd_code, id;
238   uint16_t cmd_len;
239   uint16_t min_interval, max_interval, latency, timeout;
240   tL2C_CONN_INFO con_info;
241   uint16_t lcid = 0, rcid = 0, mtu = 0, mps = 0, initial_credit = 0;
242   tL2C_CCB *p_ccb = NULL, *temp_p_ccb = NULL;
243   tL2C_RCB* p_rcb;
244   uint16_t credit;
245   uint8_t num_of_channels;
246 
247   p_pkt_end = p + pkt_len;
248 
249   if (p + 4 > p_pkt_end) {
250     log::error("invalid read");
251     return;
252   }
253 
254   STREAM_TO_UINT8(cmd_code, p);
255   STREAM_TO_UINT8(id, p);
256   STREAM_TO_UINT16(cmd_len, p);
257 
258   /* Check command length does not exceed packet length */
259   if ((p + cmd_len) > p_pkt_end) {
260     log::warn("L2CAP - LE - format error, pkt_len: {}  cmd_len: {}  code: {}",
261               pkt_len, cmd_len, cmd_code);
262     return;
263   }
264 
265   switch (cmd_code) {
266     case L2CAP_CMD_REJECT: {
267       uint16_t reason;
268 
269       if (p + 2 > p_pkt_end) {
270         log::error(
271             "invalid L2CAP_CMD_REJECT packet, not containing enough data for "
272             "`reason` field");
273         return;
274       }
275 
276       STREAM_TO_UINT16(reason, p);
277 
278       if (reason == L2CAP_CMD_REJ_NOT_UNDERSTOOD &&
279           p_lcb->pending_ecoc_conn_cnt > 0) {
280         con_info.l2cap_result = L2CAP_LE_RESULT_NO_PSM;
281         l2cble_handle_connect_rsp_neg(p_lcb, &con_info);
282       }
283     } break;
284 
285     case L2CAP_CMD_ECHO_REQ:
286     case L2CAP_CMD_ECHO_RSP:
287     case L2CAP_CMD_INFO_RSP:
288     case L2CAP_CMD_INFO_REQ:
289       l2cu_send_peer_cmd_reject(p_lcb, L2CAP_CMD_REJ_NOT_UNDERSTOOD, id, 0, 0);
290       break;
291 
292     case L2CAP_CMD_BLE_UPDATE_REQ:
293       if (p + 8 > p_pkt_end) {
294         log::error("invalid read");
295         return;
296       }
297 
298       STREAM_TO_UINT16(min_interval, p); /* 0x0006 - 0x0C80 */
299       STREAM_TO_UINT16(max_interval, p); /* 0x0006 - 0x0C80 */
300       STREAM_TO_UINT16(latency, p);      /* 0x0000 - 0x03E8 */
301       STREAM_TO_UINT16(timeout, p);      /* 0x000A - 0x0C80 */
302       /* If we are a central, the peripheral wants to update the parameters */
303       if (p_lcb->IsLinkRoleCentral()) {
304         L2CA_AdjustConnectionIntervals(
305             &min_interval, &max_interval,
306             osi_property_get_int32("bluetooth.core.le.min_connection_interval",
307                                    BTM_BLE_CONN_INT_MIN_LIMIT));
308 
309         if (min_interval < BTM_BLE_CONN_INT_MIN ||
310             min_interval > BTM_BLE_CONN_INT_MAX ||
311             max_interval < BTM_BLE_CONN_INT_MIN ||
312             max_interval > BTM_BLE_CONN_INT_MAX ||
313             latency > BTM_BLE_CONN_LATENCY_MAX ||
314             /*(timeout >= max_interval && latency > (timeout * 10/(max_interval
315                * 1.25) - 1)) ||*/
316             timeout < BTM_BLE_CONN_SUP_TOUT_MIN ||
317             timeout > BTM_BLE_CONN_SUP_TOUT_MAX ||
318             max_interval < min_interval) {
319           l2cu_send_peer_ble_par_rsp(p_lcb, L2CAP_CFG_UNACCEPTABLE_PARAMS, id);
320         } else {
321           l2cu_send_peer_ble_par_rsp(p_lcb, L2CAP_CFG_OK, id);
322 
323           p_lcb->min_interval = min_interval;
324           p_lcb->max_interval = max_interval;
325           p_lcb->latency = latency;
326           p_lcb->timeout = timeout;
327           p_lcb->conn_update_mask |= L2C_BLE_NEW_CONN_PARAM;
328 
329           l2cble_start_conn_update(p_lcb);
330         }
331       } else
332         l2cu_send_peer_cmd_reject(p_lcb, L2CAP_CMD_REJ_NOT_UNDERSTOOD, id, 0,
333                                   0);
334       break;
335 
336     case L2CAP_CMD_BLE_UPDATE_RSP:
337       p += 2;
338       break;
339 
340     case L2CAP_CMD_CREDIT_BASED_CONN_REQ: {
341       if (p + 10 > p_pkt_end) {
342         log::error("invalid L2CAP_CMD_CREDIT_BASED_CONN_REQ len");
343         return;
344       }
345 
346       STREAM_TO_UINT16(con_info.psm, p);
347       STREAM_TO_UINT16(mtu, p);
348       STREAM_TO_UINT16(mps, p);
349       STREAM_TO_UINT16(initial_credit, p);
350 
351       /* Check how many channels remote side wants. */
352       num_of_channels = (p_pkt_end - p) / sizeof(uint16_t);
353       if (num_of_channels > L2CAP_CREDIT_BASED_MAX_CIDS) {
354         log::warn("L2CAP - invalid number of channels requested: {}",
355                   num_of_channels);
356         l2cu_reject_credit_based_conn_req(p_lcb, id,
357                                           L2CAP_CREDIT_BASED_MAX_CIDS,
358                                           L2CAP_LE_RESULT_INVALID_PARAMETERS);
359         return;
360       }
361 
362       log::debug(
363           "Recv L2CAP_CMD_CREDIT_BASED_CONN_REQ with mtu = {}, mps = {}, "
364           "initial credit = {}num_of_channels = {}",
365           mtu, mps, initial_credit, num_of_channels);
366 
367       /* Check PSM Support */
368       p_rcb = l2cu_find_ble_rcb_by_psm(con_info.psm);
369       if (p_rcb == NULL) {
370         log::warn("L2CAP - rcvd conn req for unknown PSM: 0x{:04x}",
371                   con_info.psm);
372         l2cu_reject_credit_based_conn_req(p_lcb, id, num_of_channels,
373                                           L2CAP_LE_RESULT_NO_PSM);
374         return;
375       }
376 
377       if (p_lcb->pending_ecoc_conn_cnt > 0) {
378         log::warn("L2CAP - L2CAP_CMD_CREDIT_BASED_CONN_REQ collision:");
379         if (p_rcb->api.pL2CA_CreditBasedCollisionInd_Cb &&
380             con_info.psm == BT_PSM_EATT) {
381           (*p_rcb->api.pL2CA_CreditBasedCollisionInd_Cb)(p_lcb->remote_bd_addr);
382         }
383         l2cu_reject_credit_based_conn_req(p_lcb, id, num_of_channels,
384                                           L2CAP_LE_RESULT_NO_RESOURCES);
385         return;
386       }
387 
388       p_lcb->pending_ecoc_conn_cnt = num_of_channels;
389 
390       if (!p_rcb->api.pL2CA_CreditBasedConnectInd_Cb) {
391         log::warn("L2CAP - rcvd conn req for outgoing-only connection PSM: {}",
392                   con_info.psm);
393         l2cu_reject_credit_based_conn_req(p_lcb, id, num_of_channels,
394                                           L2CAP_CONN_NO_PSM);
395         return;
396       }
397 
398       /* validate the parameters */
399       if (mtu < L2CAP_CREDIT_BASED_MIN_MTU ||
400           mps < L2CAP_CREDIT_BASED_MIN_MPS || mps > L2CAP_LE_MAX_MPS) {
401         log::error("L2CAP don't like the params");
402         l2cu_reject_credit_based_conn_req(p_lcb, id, num_of_channels,
403                                           L2CAP_LE_RESULT_INVALID_PARAMETERS);
404         return;
405       }
406 
407       bool lead_cid_set = false;
408 
409       for (int i = 0; i < num_of_channels; i++) {
410         STREAM_TO_UINT16(rcid, p);
411         temp_p_ccb = l2cu_find_ccb_by_remote_cid(p_lcb, rcid);
412         if (temp_p_ccb) {
413           log::warn("L2CAP - rcvd conn req for duplicated cid: 0x{:04x}", rcid);
414           p_lcb->pending_ecoc_connection_cids[i] = 0;
415           p_lcb->pending_l2cap_result =
416               L2CAP_LE_RESULT_SOURCE_CID_ALREADY_ALLOCATED;
417         } else {
418           /* Allocate a ccb for this.*/
419           temp_p_ccb = l2cu_allocate_ccb(
420               p_lcb, 0, con_info.psm == BT_PSM_EATT /* is_eatt */);
421           if (temp_p_ccb == NULL) {
422             log::error("L2CAP - unable to allocate CCB");
423             p_lcb->pending_ecoc_connection_cids[i] = 0;
424             p_lcb->pending_l2cap_result = L2CAP_LE_RESULT_NO_RESOURCES;
425             continue;
426           }
427 
428           temp_p_ccb->ecoc = true;
429           temp_p_ccb->remote_id = id;
430           temp_p_ccb->p_rcb = p_rcb;
431           temp_p_ccb->remote_cid = rcid;
432 
433           temp_p_ccb->peer_conn_cfg.mtu = mtu;
434           temp_p_ccb->peer_conn_cfg.mps = mps;
435           temp_p_ccb->peer_conn_cfg.credits = initial_credit;
436 
437           temp_p_ccb->tx_mps = mps;
438           temp_p_ccb->ble_sdu = NULL;
439           temp_p_ccb->ble_sdu_length = 0;
440           temp_p_ccb->is_first_seg = true;
441           temp_p_ccb->peer_cfg.fcr.mode = L2CAP_FCR_LE_COC_MODE;
442 
443           /* This list will be used to prepare response */
444           p_lcb->pending_ecoc_connection_cids[i] = temp_p_ccb->local_cid;
445 
446           /*This is going to be our lead p_ccb for state machine */
447           if (!lead_cid_set) {
448             p_ccb = temp_p_ccb;
449             p_ccb->local_conn_cfg.mtu = L2CAP_SDU_LENGTH_LE_MAX;
450             p_ccb->local_conn_cfg.mps = bluetooth::shim::GetController()
451                                             ->GetLeBufferSize()
452                                             .le_data_packet_length_;
453             p_lcb->pending_lead_cid = p_ccb->local_cid;
454             lead_cid_set = true;
455           }
456         }
457       }
458 
459       if (!lead_cid_set) {
460         log::error("L2CAP - unable to allocate CCB");
461         l2cu_reject_credit_based_conn_req(p_lcb, id, num_of_channels,
462                                           p_lcb->pending_l2cap_result);
463         return;
464       }
465 
466       log::debug("L2CAP - processing peer credit based connect request");
467       l2c_csm_execute(p_ccb, L2CEVT_L2CAP_CREDIT_BASED_CONNECT_REQ, NULL);
468       break;
469     }
470     case L2CAP_CMD_CREDIT_BASED_CONN_RES:
471       if (p + 8 > p_pkt_end) {
472         log::error("invalid L2CAP_CMD_CREDIT_BASED_CONN_RES len");
473         return;
474       }
475 
476       log::verbose("Recv L2CAP_CMD_CREDIT_BASED_CONN_RES");
477       /* For all channels, see whose identifier matches this id */
478       for (temp_p_ccb = p_lcb->ccb_queue.p_first_ccb; temp_p_ccb;
479            temp_p_ccb = temp_p_ccb->p_next_ccb) {
480         if (temp_p_ccb->local_id == id) {
481           p_ccb = temp_p_ccb;
482           break;
483         }
484       }
485 
486       if (!p_ccb) {
487         log::verbose("Cannot find matching connection req");
488         con_info.l2cap_result = L2CAP_LE_RESULT_INVALID_SOURCE_CID;
489         l2c_csm_execute(p_ccb, L2CEVT_L2CAP_CONNECT_RSP_NEG, &con_info);
490         return;
491       }
492 
493       STREAM_TO_UINT16(mtu, p);
494       STREAM_TO_UINT16(mps, p);
495       STREAM_TO_UINT16(initial_credit, p);
496       STREAM_TO_UINT16(con_info.l2cap_result, p);
497 
498       /* When one of these result is sent back that means,
499        * all the channels has been rejected
500        */
501       if (con_info.l2cap_result == L2CAP_LE_RESULT_NO_PSM ||
502           con_info.l2cap_result ==
503               L2CAP_LE_RESULT_INSUFFICIENT_AUTHENTICATION ||
504           con_info.l2cap_result == L2CAP_LE_RESULT_INSUFFICIENT_ENCRYP ||
505           con_info.l2cap_result == L2CAP_LE_RESULT_INSUFFICIENT_AUTHORIZATION ||
506           con_info.l2cap_result == L2CAP_LE_RESULT_UNACCEPTABLE_PARAMETERS ||
507           con_info.l2cap_result == L2CAP_LE_RESULT_INVALID_PARAMETERS) {
508         log::error("L2CAP - not accepted. Status {}", con_info.l2cap_result);
509         l2cble_handle_connect_rsp_neg(p_lcb, &con_info);
510         return;
511       }
512 
513       /* validate the parameters */
514       if (mtu < L2CAP_CREDIT_BASED_MIN_MTU ||
515           mps < L2CAP_CREDIT_BASED_MIN_MPS || mps > L2CAP_LE_MAX_MPS) {
516         log::error("L2CAP - invalid params");
517         con_info.l2cap_result = L2CAP_LE_RESULT_INVALID_PARAMETERS;
518         l2cble_handle_connect_rsp_neg(p_lcb, &con_info);
519         return;
520       }
521 
522       /* At least some of the channels has been created and parameters are
523        * good*/
524       num_of_channels = (p_pkt_end - p) / sizeof(uint16_t);
525       if (num_of_channels != p_lcb->pending_ecoc_conn_cnt) {
526         log::error(
527             "Incorrect response.expected num of channels = {} received num of "
528             "channels = {}",
529             num_of_channels, p_lcb->pending_ecoc_conn_cnt);
530         return;
531       }
532 
533       log::verbose(
534           "mtu = {}, mps = {}, initial_credit = {}, con_info.l2cap_result = "
535           "{} num_of_channels = {}",
536           mtu, mps, initial_credit, con_info.l2cap_result, num_of_channels);
537 
538       con_info.peer_mtu = mtu;
539 
540       /* Copy request data and clear it so user can perform another connect if
541        * needed in the callback. */
542       p_lcb->pending_ecoc_conn_cnt = 0;
543       uint16_t cids[L2CAP_CREDIT_BASED_MAX_CIDS];
544       std::copy_n(p_lcb->pending_ecoc_connection_cids,
545                   L2CAP_CREDIT_BASED_MAX_CIDS, cids);
546       std::fill_n(p_lcb->pending_ecoc_connection_cids,
547                   L2CAP_CREDIT_BASED_MAX_CIDS, 0);
548 
549       for (int i = 0; i < num_of_channels; i++) {
550         uint16_t cid = cids[i];
551         STREAM_TO_UINT16(rcid, p);
552 
553         if (rcid != 0) {
554           /* If remote cid is duplicated then disconnect original channel
555            * and current channel by sending event to upper layer
556            */
557           temp_p_ccb = l2cu_find_ccb_by_remote_cid(p_lcb, rcid);
558           if (temp_p_ccb != nullptr) {
559             log::error(
560                 "Already Allocated Destination cid. rcid = {} send "
561                 "peer_disc_req",
562                 rcid);
563 
564             l2cu_send_peer_disc_req(temp_p_ccb);
565 
566             temp_p_ccb = l2cu_find_ccb_by_cid(p_lcb, cid);
567             con_info.l2cap_result = L2CAP_LE_RESULT_UNACCEPTABLE_PARAMETERS;
568             l2c_csm_execute(temp_p_ccb,
569                             L2CEVT_L2CAP_CREDIT_BASED_CONNECT_RSP_NEG,
570                             &con_info);
571             continue;
572           }
573         }
574 
575         temp_p_ccb = l2cu_find_ccb_by_cid(p_lcb, cid);
576         temp_p_ccb->remote_cid = rcid;
577 
578         log::verbose("local cid = {} remote cid = {}", cid,
579                      temp_p_ccb->remote_cid);
580 
581         /* Check if peer accepted channel, if not release the one not
582          * created
583          */
584         if (temp_p_ccb->remote_cid == 0) {
585           l2c_csm_execute(temp_p_ccb, L2CEVT_L2CAP_CREDIT_BASED_CONNECT_RSP_NEG,
586                           &con_info);
587         } else {
588           temp_p_ccb->tx_mps = mps;
589           temp_p_ccb->ble_sdu = NULL;
590           temp_p_ccb->ble_sdu_length = 0;
591           temp_p_ccb->is_first_seg = true;
592           temp_p_ccb->peer_cfg.fcr.mode = L2CAP_FCR_LE_COC_MODE;
593           temp_p_ccb->peer_conn_cfg.mtu = mtu;
594           temp_p_ccb->peer_conn_cfg.mps = mps;
595           temp_p_ccb->peer_conn_cfg.credits = initial_credit;
596 
597           l2c_csm_execute(temp_p_ccb, L2CEVT_L2CAP_CREDIT_BASED_CONNECT_RSP,
598                           &con_info);
599         }
600       }
601 
602       break;
603     case L2CAP_CMD_CREDIT_BASED_RECONFIG_REQ: {
604       if (p + 6 > p_pkt_end) {
605         l2cu_send_ble_reconfig_rsp(p_lcb, id, L2CAP_RECONFIG_UNACCAPTED_PARAM);
606         return;
607       }
608 
609       STREAM_TO_UINT16(mtu, p);
610       STREAM_TO_UINT16(mps, p);
611 
612       /* validate the parameters */
613       if (mtu < L2CAP_CREDIT_BASED_MIN_MTU ||
614           mps < L2CAP_CREDIT_BASED_MIN_MPS || mps > L2CAP_LE_MAX_MPS) {
615         log::error("L2CAP - invalid params");
616         l2cu_send_ble_reconfig_rsp(p_lcb, id, L2CAP_RECONFIG_UNACCAPTED_PARAM);
617         return;
618       }
619 
620       /* Check how many channels remote side wants to reconfigure */
621       num_of_channels = (p_pkt_end - p) / sizeof(uint16_t);
622 
623       log::verbose(
624           "Recv L2CAP_CMD_CREDIT_BASED_RECONFIG_REQ with mtu = {}, mps = {}, "
625           "num_of_channels = {}",
626           mtu, mps, num_of_channels);
627 
628       uint8_t* p_tmp = p;
629       for (int i = 0; i < num_of_channels; i++) {
630         STREAM_TO_UINT16(rcid, p_tmp);
631         p_ccb = l2cu_find_ccb_by_remote_cid(p_lcb, rcid);
632         if (!p_ccb) {
633           log::warn("L2CAP - rcvd config req for non existing cid: 0x{:04x}",
634                     rcid);
635           l2cu_send_ble_reconfig_rsp(p_lcb, id, L2CAP_RECONFIG_INVALID_DCID);
636           return;
637         }
638 
639         if (p_ccb->peer_conn_cfg.mtu > mtu) {
640           log::warn(
641               "L2CAP - rcvd config req mtu reduction new mtu < mtu ({} < {})",
642               mtu, p_ccb->peer_conn_cfg.mtu);
643           l2cu_send_ble_reconfig_rsp(p_lcb, id,
644                                      L2CAP_RECONFIG_REDUCTION_MTU_NO_ALLOWED);
645           return;
646         }
647 
648         if (p_ccb->peer_conn_cfg.mps > mps && num_of_channels > 1) {
649           log::warn(
650               "L2CAP - rcvd config req mps reduction new mps < mps ({} < {})",
651               mtu, p_ccb->peer_conn_cfg.mtu);
652           l2cu_send_ble_reconfig_rsp(p_lcb, id,
653                                      L2CAP_RECONFIG_REDUCTION_MPS_NO_ALLOWED);
654           return;
655         }
656       }
657 
658       for (int i = 0; i < num_of_channels; i++) {
659         STREAM_TO_UINT16(rcid, p);
660 
661         /* Store new values */
662         p_ccb = l2cu_find_ccb_by_remote_cid(p_lcb, rcid);
663         p_ccb->peer_conn_cfg.mtu = mtu;
664         p_ccb->peer_conn_cfg.mps = mps;
665         p_ccb->tx_mps = mps;
666 
667         tL2CAP_LE_CFG_INFO le_cfg;
668         le_cfg.mps = mps;
669         le_cfg.mtu = mtu;
670 
671         l2c_csm_execute(p_ccb, L2CEVT_L2CAP_CREDIT_BASED_RECONFIG_REQ, &le_cfg);
672       }
673 
674       l2cu_send_ble_reconfig_rsp(p_lcb, id, L2CAP_RECONFIG_SUCCEED);
675 
676       break;
677     }
678 
679     case L2CAP_CMD_CREDIT_BASED_RECONFIG_RES: {
680       uint16_t result;
681       if (p + sizeof(uint16_t) > p_pkt_end) {
682         log::error("invalid read");
683         return;
684       }
685       STREAM_TO_UINT16(result, p);
686 
687       log::verbose(
688           "Recv L2CAP_CMD_CREDIT_BASED_RECONFIG_RES for result = 0x{:04x}",
689           result);
690 
691       p_lcb->pending_ecoc_reconfig_cfg.result = result;
692 
693       /* All channels which are in reconfiguration state are marked with
694        * reconfig_started flag. Find it and send response
695        */
696       for (temp_p_ccb = p_lcb->ccb_queue.p_first_ccb; temp_p_ccb;
697            temp_p_ccb = temp_p_ccb->p_next_ccb) {
698         if ((temp_p_ccb->in_use) && (temp_p_ccb->reconfig_started)) {
699           l2c_csm_execute(temp_p_ccb, L2CEVT_L2CAP_CREDIT_BASED_RECONFIG_RSP,
700                           &p_lcb->pending_ecoc_reconfig_cfg);
701 
702           temp_p_ccb->reconfig_started = false;
703           if (result == L2CAP_CFG_OK) {
704             temp_p_ccb->local_conn_cfg = p_lcb->pending_ecoc_reconfig_cfg;
705           }
706         }
707       }
708 
709       break;
710     }
711 
712     case L2CAP_CMD_BLE_CREDIT_BASED_CONN_REQ:
713       if (p + 10 > p_pkt_end) {
714         log::error("invalid read");
715         return;
716       }
717 
718       STREAM_TO_UINT16(con_info.psm, p);
719       STREAM_TO_UINT16(rcid, p);
720       STREAM_TO_UINT16(mtu, p);
721       STREAM_TO_UINT16(mps, p);
722       STREAM_TO_UINT16(initial_credit, p);
723 
724       log::verbose(
725           "Recv L2CAP_CMD_BLE_CREDIT_BASED_CONN_REQ with mtu = {}, mps = {}, "
726           "initial credit = {}",
727           mtu, mps, initial_credit);
728 
729       p_ccb = l2cu_find_ccb_by_remote_cid(p_lcb, rcid);
730       if (p_ccb) {
731         log::warn("L2CAP - rcvd conn req for duplicated cid: 0x{:04x}", rcid);
732         l2cu_reject_ble_coc_connection(
733             p_lcb, id, L2CAP_LE_RESULT_SOURCE_CID_ALREADY_ALLOCATED);
734         break;
735       }
736 
737       p_rcb = l2cu_find_ble_rcb_by_psm(con_info.psm);
738       if (p_rcb == NULL) {
739         log::warn("L2CAP - rcvd conn req for unknown PSM: 0x{:04x}",
740                   con_info.psm);
741         l2cu_reject_ble_coc_connection(p_lcb, id, L2CAP_LE_RESULT_NO_PSM);
742         break;
743       } else {
744         if (!p_rcb->api.pL2CA_ConnectInd_Cb) {
745           log::warn(
746               "L2CAP - rcvd conn req for outgoing-only connection PSM: {}",
747               con_info.psm);
748           l2cu_reject_ble_coc_connection(p_lcb, id, L2CAP_CONN_NO_PSM);
749           break;
750         }
751       }
752 
753       /* Allocate a ccb for this.*/
754       p_ccb = l2cu_allocate_ccb(p_lcb, 0,
755                                 con_info.psm == BT_PSM_EATT /* is_eatt */);
756       if (p_ccb == NULL) {
757         log::error("L2CAP - unable to allocate CCB");
758         l2cu_reject_ble_connection(p_ccb, id, L2CAP_CONN_NO_RESOURCES);
759         break;
760       }
761 
762       /* validate the parameters */
763       if (mtu < L2CAP_LE_MIN_MTU || mps < L2CAP_LE_MIN_MPS ||
764           mps > L2CAP_LE_MAX_MPS) {
765         log::error("L2CAP do not like the params");
766         l2cu_reject_ble_connection(p_ccb, id, L2CAP_CONN_NO_RESOURCES);
767         break;
768       }
769 
770       p_ccb->remote_id = id;
771       p_ccb->p_rcb = p_rcb;
772       p_ccb->remote_cid = rcid;
773 
774       p_ccb->local_conn_cfg.mtu = L2CAP_SDU_LENGTH_LE_MAX;
775       p_ccb->local_conn_cfg.mps = bluetooth::shim::GetController()
776                                       ->GetLeBufferSize()
777                                       .le_data_packet_length_;
778       p_ccb->local_conn_cfg.credits = L2CA_LeCreditDefault();
779       p_ccb->remote_credit_count = L2CA_LeCreditDefault();
780 
781       p_ccb->peer_conn_cfg.mtu = mtu;
782       p_ccb->peer_conn_cfg.mps = mps;
783       p_ccb->peer_conn_cfg.credits = initial_credit;
784 
785       p_ccb->tx_mps = mps;
786       p_ccb->ble_sdu = NULL;
787       p_ccb->ble_sdu_length = 0;
788       p_ccb->is_first_seg = true;
789       p_ccb->peer_cfg.fcr.mode = L2CAP_FCR_LE_COC_MODE;
790 
791       p_ccb->connection_initiator = L2CAP_INITIATOR_REMOTE;
792 
793       l2c_csm_execute(p_ccb, L2CEVT_L2CAP_CONNECT_REQ, &con_info);
794       break;
795 
796     case L2CAP_CMD_BLE_CREDIT_BASED_CONN_RES:
797       log::verbose("Recv L2CAP_CMD_BLE_CREDIT_BASED_CONN_RES");
798       /* For all channels, see whose identifier matches this id */
799       for (temp_p_ccb = p_lcb->ccb_queue.p_first_ccb; temp_p_ccb;
800            temp_p_ccb = temp_p_ccb->p_next_ccb) {
801         if (temp_p_ccb->local_id == id) {
802           p_ccb = temp_p_ccb;
803           break;
804         }
805       }
806       if (p_ccb) {
807         log::verbose("I remember the connection req");
808         if (p + 10 > p_pkt_end) {
809           log::error("invalid read");
810           return;
811         }
812 
813         STREAM_TO_UINT16(p_ccb->remote_cid, p);
814         STREAM_TO_UINT16(p_ccb->peer_conn_cfg.mtu, p);
815         STREAM_TO_UINT16(p_ccb->peer_conn_cfg.mps, p);
816         STREAM_TO_UINT16(p_ccb->peer_conn_cfg.credits, p);
817         STREAM_TO_UINT16(con_info.l2cap_result, p);
818         con_info.remote_cid = p_ccb->remote_cid;
819 
820         log::verbose(
821             "remote_cid = {}, mtu = {}, mps = {}, initial_credit = {}, "
822             "con_info.l2cap_result = {}",
823             p_ccb->remote_cid, p_ccb->peer_conn_cfg.mtu,
824             p_ccb->peer_conn_cfg.mps, p_ccb->peer_conn_cfg.credits,
825             con_info.l2cap_result);
826 
827         /* validate the parameters */
828         if (p_ccb->peer_conn_cfg.mtu < L2CAP_LE_MIN_MTU ||
829             p_ccb->peer_conn_cfg.mps < L2CAP_LE_MIN_MPS ||
830             p_ccb->peer_conn_cfg.mps > L2CAP_LE_MAX_MPS) {
831           log::error("L2CAP do not like the params");
832           con_info.l2cap_result = L2CAP_LE_RESULT_NO_RESOURCES;
833           l2c_csm_execute(p_ccb, L2CEVT_L2CAP_CONNECT_RSP_NEG, &con_info);
834           break;
835         }
836 
837         p_ccb->tx_mps = p_ccb->peer_conn_cfg.mps;
838         p_ccb->ble_sdu = NULL;
839         p_ccb->ble_sdu_length = 0;
840         p_ccb->is_first_seg = true;
841         p_ccb->peer_cfg.fcr.mode = L2CAP_FCR_LE_COC_MODE;
842 
843         if (con_info.l2cap_result == L2CAP_LE_RESULT_CONN_OK)
844           l2c_csm_execute(p_ccb, L2CEVT_L2CAP_CONNECT_RSP, &con_info);
845         else
846           l2c_csm_execute(p_ccb, L2CEVT_L2CAP_CONNECT_RSP_NEG, &con_info);
847       } else {
848         log::verbose("I DO NOT remember the connection req");
849         con_info.l2cap_result = L2CAP_LE_RESULT_INVALID_SOURCE_CID;
850         l2c_csm_execute(p_ccb, L2CEVT_L2CAP_CONNECT_RSP_NEG, &con_info);
851       }
852       break;
853 
854     case L2CAP_CMD_BLE_FLOW_CTRL_CREDIT:
855       if (p + 4 > p_pkt_end) {
856         log::error("invalid read");
857         return;
858       }
859 
860       STREAM_TO_UINT16(lcid, p);
861       p_ccb = l2cu_find_ccb_by_remote_cid(p_lcb, lcid);
862       if (p_ccb == NULL) {
863         log::verbose("Credit received for unknown channel id {}", lcid);
864         break;
865       }
866 
867       STREAM_TO_UINT16(credit, p);
868       l2c_csm_execute(p_ccb, L2CEVT_L2CAP_RECV_FLOW_CONTROL_CREDIT, &credit);
869       log::verbose("Credit received");
870       break;
871 
872     case L2CAP_CMD_DISC_REQ:
873       if (p + 4 > p_pkt_end) {
874         return;
875       }
876       STREAM_TO_UINT16(lcid, p);
877       STREAM_TO_UINT16(rcid, p);
878 
879       p_ccb = l2cu_find_ccb_by_cid(p_lcb, lcid);
880       if (p_ccb != NULL) {
881         if (p_ccb->remote_cid == rcid) {
882           p_ccb->remote_id = id;
883           l2c_csm_execute(p_ccb, L2CEVT_L2CAP_DISCONNECT_REQ, NULL);
884         }
885       } else
886         l2cu_send_peer_cmd_reject(p_lcb, L2CAP_CMD_REJ_INVALID_CID, id, 0, 0);
887 
888       break;
889 
890     case L2CAP_CMD_DISC_RSP:
891       if (p + 4 > p_pkt_end) {
892         log::error("invalid read");
893         return;
894       }
895       STREAM_TO_UINT16(rcid, p);
896       STREAM_TO_UINT16(lcid, p);
897 
898       p_ccb = l2cu_find_ccb_by_cid(p_lcb, lcid);
899       if (p_ccb != NULL) {
900         if ((p_ccb->remote_cid == rcid) && (p_ccb->local_id == id))
901           l2c_csm_execute(p_ccb, L2CEVT_L2CAP_DISCONNECT_RSP, NULL);
902       }
903       break;
904 
905     default:
906       log::warn("L2CAP - LE - unknown cmd code: {}", cmd_code);
907       l2cu_send_peer_cmd_reject(p_lcb, L2CAP_CMD_REJ_NOT_UNDERSTOOD, id, 0, 0);
908       break;
909   }
910 }
911 
912 /** This function is to initate a direct connection. Returns true if connection
913  * initiated, false otherwise. */
l2cble_create_conn(tL2C_LCB * p_lcb)914 bool l2cble_create_conn(tL2C_LCB* p_lcb) {
915   if (!acl_create_le_connection(p_lcb->remote_bd_addr)) {
916     return false;
917   }
918 
919   p_lcb->link_state = LST_CONNECTING;
920 
921   // TODO: we should not need this timer at all, the connection failure should
922   // be reported from lower layer
923   alarm_set_on_mloop(p_lcb->l2c_lcb_timer, L2CAP_BLE_LINK_CONNECT_TIMEOUT_MS,
924                      l2c_lcb_timer_timeout, p_lcb);
925   return true;
926 }
927 
928 /*******************************************************************************
929  *
930  * Function         l2c_link_processs_ble_num_bufs
931  *
932  * Description      This function is called when a "controller buffer size"
933  *                  event is first received from the controller. It updates
934  *                  the L2CAP values.
935  *
936  * Returns          void
937  *
938  ******************************************************************************/
l2c_link_processs_ble_num_bufs(uint16_t num_lm_ble_bufs)939 void l2c_link_processs_ble_num_bufs(uint16_t num_lm_ble_bufs) {
940   if (num_lm_ble_bufs == 0) {
941     num_lm_ble_bufs = L2C_DEF_NUM_BLE_BUF_SHARED;
942     l2cb.num_lm_acl_bufs -= L2C_DEF_NUM_BLE_BUF_SHARED;
943   }
944 
945   l2cb.num_lm_ble_bufs = num_lm_ble_bufs;
946   l2cb.controller_le_xmit_window = num_lm_ble_bufs;
947 }
948 
949 /*******************************************************************************
950  *
951  * Function         l2c_ble_link_adjust_allocation
952  *
953  * Description      This function is called when a link is created or removed
954  *                  to calculate the amount of packets each link may send to
955  *                  the HCI without an ack coming back.
956  *
957  *                  Currently, this is a simple allocation, dividing the
958  *                  number of Controller Packets by the number of links. In
959  *                  the future, QOS configuration should be examined.
960  *
961  * Returns          void
962  *
963  ******************************************************************************/
l2c_ble_link_adjust_allocation(void)964 void l2c_ble_link_adjust_allocation(void) {
965   uint16_t qq, yy, qq_remainder;
966   tL2C_LCB* p_lcb;
967   uint16_t hi_quota, low_quota;
968   uint16_t num_lowpri_links = 0;
969   uint16_t num_hipri_links = 0;
970   uint16_t controller_xmit_quota = l2cb.num_lm_ble_bufs;
971   uint16_t high_pri_link_quota = L2CAP_HIGH_PRI_MIN_XMIT_QUOTA_A;
972 
973   /* If no links active, reset buffer quotas and controller buffers */
974   if (l2cb.num_ble_links_active == 0) {
975     l2cb.controller_le_xmit_window = l2cb.num_lm_ble_bufs;
976     l2cb.ble_round_robin_quota = l2cb.ble_round_robin_unacked = 0;
977     return;
978   }
979 
980   /* First, count the links */
981   for (yy = 0, p_lcb = &l2cb.lcb_pool[0]; yy < MAX_L2CAP_LINKS; yy++, p_lcb++) {
982     if (p_lcb->in_use && p_lcb->transport == BT_TRANSPORT_LE) {
983       if (p_lcb->acl_priority == L2CAP_PRIORITY_HIGH)
984         num_hipri_links++;
985       else
986         num_lowpri_links++;
987     }
988   }
989 
990   /* now adjust high priority link quota */
991   low_quota = num_lowpri_links ? 1 : 0;
992   while ((num_hipri_links * high_pri_link_quota + low_quota) >
993          controller_xmit_quota)
994     high_pri_link_quota--;
995 
996   /* Work out the xmit quota and buffer quota high and low priorities */
997   hi_quota = num_hipri_links * high_pri_link_quota;
998   low_quota =
999       (hi_quota < controller_xmit_quota) ? controller_xmit_quota - hi_quota : 1;
1000 
1001   /* Work out and save the HCI xmit quota for each low priority link */
1002 
1003   /* If each low priority link cannot have at least one buffer */
1004   if (num_lowpri_links > low_quota) {
1005     l2cb.ble_round_robin_quota = low_quota;
1006     qq = qq_remainder = 0;
1007   }
1008   /* If each low priority link can have at least one buffer */
1009   else if (num_lowpri_links > 0) {
1010     l2cb.ble_round_robin_quota = 0;
1011     l2cb.ble_round_robin_unacked = 0;
1012     qq = low_quota / num_lowpri_links;
1013     qq_remainder = low_quota % num_lowpri_links;
1014   }
1015   /* If no low priority link */
1016   else {
1017     l2cb.ble_round_robin_quota = 0;
1018     l2cb.ble_round_robin_unacked = 0;
1019     qq = qq_remainder = 0;
1020   }
1021   log::verbose(
1022       "l2c_ble_link_adjust_allocation  num_hipri: {}  num_lowpri: {}  "
1023       "low_quota: {}  round_robin_quota: {}  qq: {}",
1024       num_hipri_links, num_lowpri_links, low_quota, l2cb.ble_round_robin_quota,
1025       qq);
1026 
1027   /* Now, assign the quotas to each link */
1028   for (yy = 0, p_lcb = &l2cb.lcb_pool[0]; yy < MAX_L2CAP_LINKS; yy++, p_lcb++) {
1029     if (p_lcb->in_use && p_lcb->transport == BT_TRANSPORT_LE) {
1030       if (p_lcb->acl_priority == L2CAP_PRIORITY_HIGH) {
1031         p_lcb->link_xmit_quota = high_pri_link_quota;
1032       } else {
1033         /* Safety check in case we switched to round-robin with something
1034          * outstanding */
1035         /* if sent_not_acked is added into round_robin_unacked then do not add
1036          * it again */
1037         /* l2cap keeps updating sent_not_acked for exiting from round robin */
1038         if ((p_lcb->link_xmit_quota > 0) && (qq == 0))
1039           l2cb.ble_round_robin_unacked += p_lcb->sent_not_acked;
1040 
1041         p_lcb->link_xmit_quota = qq;
1042         if (qq_remainder > 0) {
1043           p_lcb->link_xmit_quota++;
1044           qq_remainder--;
1045         }
1046       }
1047 
1048       log::verbose(
1049           "l2c_ble_link_adjust_allocation LCB {}   Priority: {}  XmitQuota: {}",
1050           yy, p_lcb->acl_priority, p_lcb->link_xmit_quota);
1051 
1052       log::verbose("SentNotAcked: {}  RRUnacked: {}", p_lcb->sent_not_acked,
1053                    l2cb.round_robin_unacked);
1054 
1055       /* There is a special case where we have readjusted the link quotas and */
1056       /* this link may have sent anything but some other link sent packets so */
1057       /* so we may need a timer to kick off this link's transmissions. */
1058       if ((p_lcb->link_state == LST_CONNECTED) &&
1059           (!list_is_empty(p_lcb->link_xmit_data_q)) &&
1060           (p_lcb->sent_not_acked < p_lcb->link_xmit_quota)) {
1061         alarm_set_on_mloop(p_lcb->l2c_lcb_timer,
1062                            L2CAP_LINK_FLOW_CONTROL_TIMEOUT_MS,
1063                            l2c_lcb_timer_timeout, p_lcb);
1064       }
1065     }
1066   }
1067 }
1068 
1069 /*******************************************************************************
1070  *
1071  * Function         l2cble_update_data_length
1072  *
1073  * Description      This function update link tx data length if applicable
1074  *
1075  * Returns          void
1076  *
1077  ******************************************************************************/
l2cble_update_data_length(tL2C_LCB * p_lcb)1078 void l2cble_update_data_length(tL2C_LCB* p_lcb) {
1079   uint16_t tx_mtu = 0;
1080   uint16_t i = 0;
1081 
1082   log::verbose("");
1083 
1084   /* See if we have a link control block for the connection */
1085   if (p_lcb == NULL) return;
1086 
1087   for (i = 0; i < L2CAP_NUM_FIXED_CHNLS; i++) {
1088     if (i + L2CAP_FIRST_FIXED_CHNL != L2CAP_BLE_SIGNALLING_CID) {
1089       if ((p_lcb->p_fixed_ccbs[i] != NULL) &&
1090           (tx_mtu < (p_lcb->p_fixed_ccbs[i]->tx_data_len + L2CAP_PKT_OVERHEAD)))
1091         tx_mtu = p_lcb->p_fixed_ccbs[i]->tx_data_len + L2CAP_PKT_OVERHEAD;
1092     }
1093   }
1094 
1095   if (tx_mtu > BTM_BLE_DATA_SIZE_MAX) tx_mtu = BTM_BLE_DATA_SIZE_MAX;
1096 
1097   /* update TX data length if changed */
1098   if (p_lcb->tx_data_len != tx_mtu)
1099     BTM_SetBleDataLength(p_lcb->remote_bd_addr, tx_mtu);
1100 }
1101 
1102 /*******************************************************************************
1103  *
1104  * Function         l2cble_process_data_length_change_evt
1105  *
1106  * Description      This function process the data length change event
1107  *
1108  * Returns          void
1109  *
1110  ******************************************************************************/
is_legal_tx_data_len(const uint16_t & tx_data_len)1111 static bool is_legal_tx_data_len(const uint16_t& tx_data_len) {
1112   return (tx_data_len >= 0x001B && tx_data_len <= 0x00FB);
1113 }
1114 
l2cble_process_data_length_change_event(uint16_t handle,uint16_t tx_data_len,uint16_t)1115 void l2cble_process_data_length_change_event(uint16_t handle,
1116                                              uint16_t tx_data_len,
1117                                              uint16_t /* rx_data_len */) {
1118   tL2C_LCB* p_lcb = l2cu_find_lcb_by_handle(handle);
1119   if (p_lcb == nullptr) {
1120     log::warn(
1121         "Received data length change event for unknown ACL handle:0x{:04x}",
1122         handle);
1123     return;
1124   }
1125 
1126   if (is_legal_tx_data_len(tx_data_len)) {
1127     if (p_lcb->tx_data_len != tx_data_len) {
1128       log::debug(
1129           "Received data length change event for device:{} tx_data_len:{} => "
1130           "{}",
1131           p_lcb->remote_bd_addr, p_lcb->tx_data_len, tx_data_len);
1132       BTM_LogHistory(kBtmLogTag, p_lcb->remote_bd_addr, "LE Data length change",
1133                      base::StringPrintf("tx_octets:%hu => %hu",
1134                                         p_lcb->tx_data_len, tx_data_len));
1135       p_lcb->tx_data_len = tx_data_len;
1136     } else {
1137       log::debug(
1138           "Received duplicated data length change event for device:{} "
1139           "tx_data_len:{}",
1140           p_lcb->remote_bd_addr, tx_data_len);
1141     }
1142   } else {
1143     log::warn(
1144         "Received illegal data length change event for device:{} "
1145         "tx_data_len:{}",
1146         p_lcb->remote_bd_addr, tx_data_len);
1147   }
1148   /* ignore rx_data len for now */
1149 }
1150 
1151 /*******************************************************************************
1152  *
1153  * Function         l2cble_credit_based_conn_req
1154  *
1155  * Description      This function sends LE Credit Based Connection Request for
1156  *                  LE connection oriented channels.
1157  *
1158  * Returns          void
1159  *
1160  ******************************************************************************/
l2cble_credit_based_conn_req(tL2C_CCB * p_ccb)1161 void l2cble_credit_based_conn_req(tL2C_CCB* p_ccb) {
1162   if (!p_ccb) return;
1163 
1164   if (p_ccb->p_lcb && p_ccb->p_lcb->transport != BT_TRANSPORT_LE) {
1165     log::warn("LE link doesn't exist");
1166     return;
1167   }
1168 
1169   if (p_ccb->ecoc) {
1170     l2cu_send_peer_credit_based_conn_req(p_ccb);
1171   } else {
1172     l2cu_send_peer_ble_credit_based_conn_req(p_ccb);
1173   }
1174   return;
1175 }
1176 
1177 /*******************************************************************************
1178  *
1179  * Function         l2cble_credit_based_conn_res
1180  *
1181  * Description      This function sends LE Credit Based Connection Response for
1182  *                  LE connection oriented channels.
1183  *
1184  * Returns          void
1185  *
1186  ******************************************************************************/
l2cble_credit_based_conn_res(tL2C_CCB * p_ccb,uint16_t result)1187 void l2cble_credit_based_conn_res(tL2C_CCB* p_ccb, uint16_t result) {
1188   if (!p_ccb) return;
1189 
1190   if (p_ccb->p_lcb && p_ccb->p_lcb->transport != BT_TRANSPORT_LE) {
1191     log::warn("LE link doesn't exist");
1192     return;
1193   }
1194 
1195   l2cu_send_peer_ble_credit_based_conn_res(p_ccb, result);
1196   return;
1197 }
1198 
1199 /*******************************************************************************
1200  *
1201  * Function         l2cble_send_flow_control_credit
1202  *
1203  * Description      This function sends flow control credits for
1204  *                  LE connection oriented channels.
1205  *
1206  * Returns          void
1207  *
1208  ******************************************************************************/
l2cble_send_flow_control_credit(tL2C_CCB * p_ccb,uint16_t credit_value)1209 void l2cble_send_flow_control_credit(tL2C_CCB* p_ccb, uint16_t credit_value) {
1210   if (!p_ccb) return;
1211 
1212   if (p_ccb->p_lcb && p_ccb->p_lcb->transport != BT_TRANSPORT_LE) {
1213     log::warn("LE link doesn't exist");
1214     return;
1215   }
1216 
1217   l2cu_send_peer_ble_flow_control_credit(p_ccb, credit_value);
1218   return;
1219 }
1220 
1221 /*******************************************************************************
1222  *
1223  * Function         l2cble_send_peer_disc_req
1224  *
1225  * Description      This function sends disconnect request
1226  *                  to the peer LE device
1227  *
1228  * Returns          void
1229  *
1230  ******************************************************************************/
l2cble_send_peer_disc_req(tL2C_CCB * p_ccb)1231 void l2cble_send_peer_disc_req(tL2C_CCB* p_ccb) {
1232   log::verbose("");
1233   if (!p_ccb) return;
1234 
1235   if (p_ccb->p_lcb && p_ccb->p_lcb->transport != BT_TRANSPORT_LE) {
1236     log::warn("LE link doesn't exist");
1237     return;
1238   }
1239 
1240   l2cu_send_peer_ble_credit_based_disconn_req(p_ccb);
1241   return;
1242 }
1243 
1244 /*******************************************************************************
1245  *
1246  * Function         l2cble_sec_comp
1247  *
1248  * Description      This function is called when security procedure for an LE
1249  *                  COC link is done
1250  *
1251  * Returns          void
1252  *
1253  ******************************************************************************/
l2cble_sec_comp(RawAddress bda,tBT_TRANSPORT transport,void *,tBTM_STATUS status)1254 void l2cble_sec_comp(RawAddress bda, tBT_TRANSPORT transport,
1255                      void* /* p_ref_data */, tBTM_STATUS status) {
1256   tL2C_LCB* p_lcb = l2cu_find_lcb_by_bd_addr(bda, BT_TRANSPORT_LE);
1257   tL2CAP_SEC_DATA* p_buf = NULL;
1258   uint8_t sec_act;
1259 
1260   if (!p_lcb) {
1261     log::warn("security complete for unknown device. bda={}", bda);
1262     return;
1263   }
1264 
1265   sec_act = p_lcb->sec_act;
1266   p_lcb->sec_act = 0;
1267 
1268   if (!fixed_queue_is_empty(p_lcb->le_sec_pending_q)) {
1269     p_buf = (tL2CAP_SEC_DATA*)fixed_queue_dequeue(p_lcb->le_sec_pending_q);
1270     if (!p_buf) {
1271       log::warn("Security complete for request not initiated from L2CAP");
1272       return;
1273     }
1274 
1275     if (status != BTM_SUCCESS) {
1276       (*(p_buf->p_callback))(bda, BT_TRANSPORT_LE, p_buf->p_ref_data, status);
1277       osi_free(p_buf);
1278     } else {
1279       if (sec_act == BTM_SEC_ENCRYPT_MITM) {
1280         if (BTM_IsLinkKeyAuthed(bda, transport))
1281           (*(p_buf->p_callback))(bda, BT_TRANSPORT_LE, p_buf->p_ref_data,
1282                                  status);
1283         else {
1284           log::verbose("MITM Protection Not present");
1285           (*(p_buf->p_callback))(bda, BT_TRANSPORT_LE, p_buf->p_ref_data,
1286                                  BTM_FAILED_ON_SECURITY);
1287         }
1288       } else {
1289         log::verbose("MITM Protection not required sec_act = {}",
1290                      p_lcb->sec_act);
1291 
1292         (*(p_buf->p_callback))(bda, BT_TRANSPORT_LE, p_buf->p_ref_data, status);
1293       }
1294       osi_free(p_buf);
1295     }
1296   } else {
1297     log::warn("Security complete for request not initiated from L2CAP");
1298     return;
1299   }
1300 
1301   while (!fixed_queue_is_empty(p_lcb->le_sec_pending_q)) {
1302     p_buf = (tL2CAP_SEC_DATA*)fixed_queue_dequeue(p_lcb->le_sec_pending_q);
1303 
1304     if (status != BTM_SUCCESS) {
1305       (*(p_buf->p_callback))(bda, BT_TRANSPORT_LE, p_buf->p_ref_data, status);
1306       osi_free(p_buf);
1307     }
1308     else {
1309       l2ble_sec_access_req(bda, p_buf->psm, p_buf->is_originator,
1310                            p_buf->p_callback, p_buf->p_ref_data);
1311 
1312       osi_free(p_buf);
1313       break;
1314     }
1315   }
1316 }
1317 
1318 /*******************************************************************************
1319  *
1320  * Function         l2ble_sec_access_req
1321  *
1322  * Description      This function is called by LE COC link to meet the
1323  *                  security requirement for the link
1324  *
1325  * Returns          Returns  - L2CAP LE Connection Response Result Code.
1326  *
1327  ******************************************************************************/
l2ble_sec_access_req(const RawAddress & bd_addr,uint16_t psm,bool is_originator,tBTM_SEC_CALLBACK * p_callback,void * p_ref_data)1328 tL2CAP_LE_RESULT_CODE l2ble_sec_access_req(const RawAddress& bd_addr,
1329                                            uint16_t psm, bool is_originator,
1330                                            tBTM_SEC_CALLBACK* p_callback,
1331                                            void* p_ref_data) {
1332   tL2C_LCB* p_lcb = NULL;
1333 
1334   if (!p_callback) {
1335     log::error("No callback function");
1336     return L2CAP_LE_RESULT_NO_RESOURCES;
1337   }
1338 
1339   p_lcb = l2cu_find_lcb_by_bd_addr(bd_addr, BT_TRANSPORT_LE);
1340 
1341   if (!p_lcb) {
1342     log::error("Security check for unknown device");
1343     p_callback(bd_addr, BT_TRANSPORT_LE, p_ref_data, BTM_UNKNOWN_ADDR);
1344     return L2CAP_LE_RESULT_NO_RESOURCES;
1345   }
1346 
1347   tL2CAP_SEC_DATA* p_buf =
1348       (tL2CAP_SEC_DATA*)osi_malloc((uint16_t)sizeof(tL2CAP_SEC_DATA));
1349   if (!p_buf) {
1350     log::error("No resources for connection");
1351     p_callback(bd_addr, BT_TRANSPORT_LE, p_ref_data, BTM_NO_RESOURCES);
1352     return L2CAP_LE_RESULT_NO_RESOURCES;
1353   }
1354 
1355   p_buf->psm = psm;
1356   p_buf->is_originator = is_originator;
1357   p_buf->p_callback = p_callback;
1358   p_buf->p_ref_data = p_ref_data;
1359   fixed_queue_enqueue(p_lcb->le_sec_pending_q, p_buf);
1360   tBTM_STATUS result = btm_ble_start_sec_check(bd_addr, psm, is_originator,
1361                                                &l2cble_sec_comp, p_ref_data);
1362 
1363   switch (result) {
1364     case BTM_SUCCESS:
1365       return L2CAP_LE_RESULT_CONN_OK;
1366     case BTM_ILLEGAL_VALUE:
1367       return L2CAP_LE_RESULT_NO_PSM;
1368     case BTM_NOT_AUTHENTICATED:
1369       return L2CAP_LE_RESULT_INSUFFICIENT_AUTHENTICATION;
1370     case BTM_NOT_ENCRYPTED:
1371       return L2CAP_LE_RESULT_INSUFFICIENT_ENCRYP;
1372     case BTM_NOT_AUTHORIZED:
1373       return L2CAP_LE_RESULT_INSUFFICIENT_AUTHORIZATION;
1374     case BTM_INSUFFICIENT_ENCRYPT_KEY_SIZE:
1375       return L2CAP_LE_RESULT_INSUFFICIENT_ENCRYP_KEY_SIZE;
1376     default:
1377       log::error("unexpected return value: {}", btm_status_text(result));
1378       return L2CAP_LE_RESULT_INVALID_PARAMETERS;
1379   }
1380 }
1381 
1382 /* This function is called to adjust the connection intervals based on various
1383  * constraints. For example, when there is at least one Hearing Aid device
1384  * bonded, the minimum interval is raised. On return, min_interval and
1385  * max_interval are updated. */
L2CA_AdjustConnectionIntervals(uint16_t * min_interval,uint16_t * max_interval,uint16_t floor_interval)1386 void L2CA_AdjustConnectionIntervals(uint16_t* min_interval,
1387                                     uint16_t* max_interval,
1388                                     uint16_t floor_interval) {
1389   // Allow for customization by systemprops for mainline
1390   uint16_t phone_min_interval = floor_interval;
1391 #ifdef __ANDROID__
1392   phone_min_interval =
1393       android::sysprop::BluetoothProperties::getGapLeConnMinLimit().value_or(
1394           floor_interval);
1395 #else
1396   phone_min_interval = (uint16_t)osi_property_get_int32(
1397       "bluetooth.core.gap.le.conn.min.limit", (int32_t)floor_interval);
1398 #endif
1399 
1400   if (GetInterfaceToProfiles()
1401           ->profileSpecific_HACK->GetHearingAidDeviceCount()) {
1402     // When there are bonded Hearing Aid devices, we will constrained this
1403     // minimum interval.
1404     phone_min_interval = BTM_BLE_CONN_INT_MIN_HEARINGAID;
1405     log::verbose("Have Hearing Aids. Min. interval is set to {}",
1406                  phone_min_interval);
1407   }
1408 
1409   if (!com::android::bluetooth::flags::l2cap_le_do_not_adjust_min_interval() &&
1410       *min_interval < phone_min_interval) {
1411     log::verbose("requested min_interval={} too small. Set to {}",
1412                  *min_interval, phone_min_interval);
1413     *min_interval = phone_min_interval;
1414   }
1415 
1416   // While this could result in connection parameters that fall
1417   // outside fo the range requested, this will allow the connection
1418   // to remain established.
1419   // In other words, this is a workaround for certain peripherals.
1420   if (*max_interval < phone_min_interval) {
1421     log::verbose("requested max_interval={} too small. Set to {}",
1422                  *max_interval, phone_min_interval);
1423     *max_interval = phone_min_interval;
1424   }
1425 }
1426 
L2CA_SetEcosystemBaseInterval(uint32_t base_interval)1427 void L2CA_SetEcosystemBaseInterval(uint32_t base_interval) {
1428   if (!com::android::bluetooth::flags::le_audio_base_ecosystem_interval()) {
1429     return;
1430   }
1431 
1432   log::info("base_interval: {}ms", base_interval);
1433   bluetooth::shim::GetHciLayer()->EnqueueCommand(
1434       bluetooth::hci::SetEcosystemBaseIntervalBuilder::Create(base_interval),
1435       get_main_thread()->BindOnce([](bluetooth::hci::CommandCompleteView view) {
1436         ASSERT(view.IsValid());
1437         auto status_view =
1438             bluetooth::hci::SetEcosystemBaseIntervalCompleteView::Create(
1439                 bluetooth::hci::SetEcosystemBaseIntervalCompleteView::Create(
1440                     view));
1441         ASSERT(status_view.IsValid());
1442 
1443         if (status_view.GetStatus() != bluetooth::hci::ErrorCode::SUCCESS) {
1444           log::warn("Set Ecosystem Base Interval status {}",
1445                     ErrorCodeText(status_view.GetStatus()));
1446           return;
1447         }
1448       }));
1449 }
1450