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