• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 + 2 > 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       STREAM_TO_UINT16(result, p);
815 
816       L2CAP_TRACE_DEBUG(
817           "Recv L2CAP_CMD_CREDIT_BASED_RECONFIG_RES for "
818           "result = 0x%04x",
819           result);
820 
821       p_lcb->pending_ecoc_reconfig_cfg.result = result;
822 
823       /* All channels which are in reconfiguration state are marked with
824        * reconfig_started flag. Find it and send response
825        */
826       for (temp_p_ccb = p_lcb->ccb_queue.p_first_ccb; temp_p_ccb;
827            temp_p_ccb = temp_p_ccb->p_next_ccb) {
828         if ((temp_p_ccb->in_use) && (temp_p_ccb->reconfig_started)) {
829           l2c_csm_execute(temp_p_ccb, L2CEVT_L2CAP_CREDIT_BASED_RECONFIG_RSP,
830                           &p_lcb->pending_ecoc_reconfig_cfg);
831 
832           temp_p_ccb->reconfig_started = false;
833           if (result == L2CAP_CFG_OK) {
834             temp_p_ccb->local_conn_cfg = p_lcb->pending_ecoc_reconfig_cfg;
835           }
836         }
837       }
838 
839       break;
840     }
841 
842     case L2CAP_CMD_BLE_CREDIT_BASED_CONN_REQ:
843       if (p + 10 > p_pkt_end) {
844         android_errorWriteLog(0x534e4554, "80261585");
845         LOG(ERROR) << "invalid read";
846         return;
847       }
848 
849       STREAM_TO_UINT16(con_info.psm, p);
850       STREAM_TO_UINT16(rcid, p);
851       STREAM_TO_UINT16(mtu, p);
852       STREAM_TO_UINT16(mps, p);
853       STREAM_TO_UINT16(initial_credit, p);
854 
855       L2CAP_TRACE_DEBUG(
856           "Recv L2CAP_CMD_BLE_CREDIT_BASED_CONN_REQ with "
857           "mtu = %d, "
858           "mps = %d, "
859           "initial credit = %d",
860           mtu, mps, initial_credit);
861 
862       p_ccb = l2cu_find_ccb_by_remote_cid(p_lcb, rcid);
863       if (p_ccb) {
864         L2CAP_TRACE_WARNING("L2CAP - rcvd conn req for duplicated cid: 0x%04x",
865                             rcid);
866         l2cu_reject_ble_coc_connection(
867             p_lcb, id, L2CAP_LE_RESULT_SOURCE_CID_ALREADY_ALLOCATED);
868         break;
869       }
870 
871       p_rcb = l2cu_find_ble_rcb_by_psm(con_info.psm);
872       if (p_rcb == NULL) {
873         L2CAP_TRACE_WARNING("L2CAP - rcvd conn req for unknown PSM: 0x%04x",
874                             con_info.psm);
875         l2cu_reject_ble_coc_connection(p_lcb, id, L2CAP_LE_RESULT_NO_PSM);
876         break;
877       } else {
878         if (!p_rcb->api.pL2CA_ConnectInd_Cb) {
879           L2CAP_TRACE_WARNING(
880               "L2CAP - rcvd conn req for outgoing-only connection PSM: %d",
881               con_info.psm);
882           l2cu_reject_ble_coc_connection(p_lcb, id, L2CAP_CONN_NO_PSM);
883           break;
884         }
885       }
886 
887       /* Allocate a ccb for this.*/
888       p_ccb = l2cu_allocate_ccb(p_lcb, 0);
889       if (p_ccb == NULL) {
890         L2CAP_TRACE_ERROR("L2CAP - unable to allocate CCB");
891         l2cu_reject_ble_connection(p_ccb, id, L2CAP_CONN_NO_RESOURCES);
892         break;
893       }
894 
895       /* validate the parameters */
896       if (mtu < L2CAP_LE_MIN_MTU || mps < L2CAP_LE_MIN_MPS ||
897           mps > L2CAP_LE_MAX_MPS) {
898         L2CAP_TRACE_ERROR("L2CAP do not like the params");
899         l2cu_reject_ble_connection(p_ccb, id, L2CAP_CONN_NO_RESOURCES);
900         break;
901       }
902 
903       p_ccb->remote_id = id;
904       p_ccb->p_rcb = p_rcb;
905       p_ccb->remote_cid = rcid;
906 
907       p_ccb->local_conn_cfg.mtu = L2CAP_SDU_LENGTH_LE_MAX;
908       p_ccb->local_conn_cfg.mps =
909           controller_get_interface()->get_acl_data_size_ble();
910       p_ccb->local_conn_cfg.credits = L2CAP_LE_CREDIT_DEFAULT,
911 
912       p_ccb->peer_conn_cfg.mtu = mtu;
913       p_ccb->peer_conn_cfg.mps = mps;
914       p_ccb->peer_conn_cfg.credits = initial_credit;
915 
916       p_ccb->tx_mps = mps;
917       p_ccb->ble_sdu = NULL;
918       p_ccb->ble_sdu_length = 0;
919       p_ccb->is_first_seg = true;
920       p_ccb->peer_cfg.fcr.mode = L2CAP_FCR_LE_COC_MODE;
921 
922       p_ccb->connection_initiator = L2CAP_INITIATOR_REMOTE;
923 
924       l2c_csm_execute(p_ccb, L2CEVT_L2CAP_CONNECT_REQ, &con_info);
925       break;
926 
927     case L2CAP_CMD_BLE_CREDIT_BASED_CONN_RES:
928       L2CAP_TRACE_DEBUG("Recv L2CAP_CMD_BLE_CREDIT_BASED_CONN_RES");
929       /* For all channels, see whose identifier matches this id */
930       for (temp_p_ccb = p_lcb->ccb_queue.p_first_ccb; temp_p_ccb;
931            temp_p_ccb = temp_p_ccb->p_next_ccb) {
932         if (temp_p_ccb->local_id == id) {
933           p_ccb = temp_p_ccb;
934           break;
935         }
936       }
937       if (p_ccb) {
938         L2CAP_TRACE_DEBUG("I remember the connection req");
939         if (p + 10 > p_pkt_end) {
940           android_errorWriteLog(0x534e4554, "80261585");
941           LOG(ERROR) << "invalid read";
942           return;
943         }
944 
945         STREAM_TO_UINT16(p_ccb->remote_cid, p);
946         STREAM_TO_UINT16(p_ccb->peer_conn_cfg.mtu, p);
947         STREAM_TO_UINT16(p_ccb->peer_conn_cfg.mps, p);
948         STREAM_TO_UINT16(p_ccb->peer_conn_cfg.credits, p);
949         STREAM_TO_UINT16(con_info.l2cap_result, p);
950         con_info.remote_cid = p_ccb->remote_cid;
951 
952         L2CAP_TRACE_DEBUG(
953             "remote_cid = %d, "
954             "mtu = %d, "
955             "mps = %d, "
956             "initial_credit = %d, "
957             "con_info.l2cap_result = %d",
958             p_ccb->remote_cid, p_ccb->peer_conn_cfg.mtu,
959             p_ccb->peer_conn_cfg.mps, p_ccb->peer_conn_cfg.credits,
960             con_info.l2cap_result);
961 
962         /* validate the parameters */
963         if (p_ccb->peer_conn_cfg.mtu < L2CAP_LE_MIN_MTU ||
964             p_ccb->peer_conn_cfg.mps < L2CAP_LE_MIN_MPS ||
965             p_ccb->peer_conn_cfg.mps > L2CAP_LE_MAX_MPS) {
966           L2CAP_TRACE_ERROR("L2CAP do not like the params");
967           con_info.l2cap_result = L2CAP_LE_RESULT_NO_RESOURCES;
968           l2c_csm_execute(p_ccb, L2CEVT_L2CAP_CONNECT_RSP_NEG, &con_info);
969           break;
970         }
971 
972         p_ccb->tx_mps = p_ccb->peer_conn_cfg.mps;
973         p_ccb->ble_sdu = NULL;
974         p_ccb->ble_sdu_length = 0;
975         p_ccb->is_first_seg = true;
976         p_ccb->peer_cfg.fcr.mode = L2CAP_FCR_LE_COC_MODE;
977 
978         if (con_info.l2cap_result == L2CAP_LE_RESULT_CONN_OK)
979           l2c_csm_execute(p_ccb, L2CEVT_L2CAP_CONNECT_RSP, &con_info);
980         else
981           l2c_csm_execute(p_ccb, L2CEVT_L2CAP_CONNECT_RSP_NEG, &con_info);
982       } else {
983         L2CAP_TRACE_DEBUG("I DO NOT remember the connection req");
984         con_info.l2cap_result = L2CAP_LE_RESULT_INVALID_SOURCE_CID;
985         l2c_csm_execute(p_ccb, L2CEVT_L2CAP_CONNECT_RSP_NEG, &con_info);
986       }
987       break;
988 
989     case L2CAP_CMD_BLE_FLOW_CTRL_CREDIT:
990       if (p + 4 > p_pkt_end) {
991         android_errorWriteLog(0x534e4554, "80261585");
992         LOG(ERROR) << "invalid read";
993         return;
994       }
995 
996       STREAM_TO_UINT16(lcid, p);
997       p_ccb = l2cu_find_ccb_by_remote_cid(p_lcb, lcid);
998       if (p_ccb == NULL) {
999         L2CAP_TRACE_DEBUG("%s Credit received for unknown channel id %d",
1000                           __func__, lcid);
1001         break;
1002       }
1003 
1004       STREAM_TO_UINT16(credit, p);
1005       l2c_csm_execute(p_ccb, L2CEVT_L2CAP_RECV_FLOW_CONTROL_CREDIT, &credit);
1006       L2CAP_TRACE_DEBUG("%s Credit received", __func__);
1007       break;
1008 
1009     case L2CAP_CMD_DISC_REQ:
1010       if (p + 4 > p_pkt_end) {
1011         android_errorWriteLog(0x534e4554, "74121659");
1012         return;
1013       }
1014       STREAM_TO_UINT16(lcid, p);
1015       STREAM_TO_UINT16(rcid, p);
1016 
1017       p_ccb = l2cu_find_ccb_by_cid(p_lcb, lcid);
1018       if (p_ccb != NULL) {
1019         if (p_ccb->remote_cid == rcid) {
1020           p_ccb->remote_id = id;
1021           l2c_csm_execute(p_ccb, L2CEVT_L2CAP_DISCONNECT_REQ, NULL);
1022         }
1023       } else
1024         l2cu_send_peer_disc_rsp(p_lcb, id, lcid, rcid);
1025 
1026       break;
1027 
1028     case L2CAP_CMD_DISC_RSP:
1029       if (p + 4 > p_pkt_end) {
1030         android_errorWriteLog(0x534e4554, "80261585");
1031         LOG(ERROR) << "invalid read";
1032         return;
1033       }
1034       STREAM_TO_UINT16(rcid, p);
1035       STREAM_TO_UINT16(lcid, p);
1036 
1037       p_ccb = l2cu_find_ccb_by_cid(p_lcb, lcid);
1038       if (p_ccb != NULL) {
1039         if ((p_ccb->remote_cid == rcid) && (p_ccb->local_id == id))
1040           l2c_csm_execute(p_ccb, L2CEVT_L2CAP_DISCONNECT_RSP, NULL);
1041       }
1042       break;
1043 
1044     default:
1045       L2CAP_TRACE_WARNING("L2CAP - LE - unknown cmd code: %d", cmd_code);
1046       l2cu_send_peer_cmd_reject(p_lcb, L2CAP_CMD_REJ_NOT_UNDERSTOOD, id, 0, 0);
1047       break;
1048   }
1049 }
1050 
1051 /** This function is to initate a direct connection. Returns true if connection
1052  * initiated, false otherwise. */
l2cble_create_conn(tL2C_LCB * p_lcb)1053 bool l2cble_create_conn(tL2C_LCB* p_lcb) {
1054   if (!acl_create_le_connection(p_lcb->remote_bd_addr)) {
1055     return false;
1056   }
1057 
1058   p_lcb->link_state = LST_CONNECTING;
1059 
1060   // TODO: we should not need this timer at all, the connection failure should
1061   // be reported from lower layer
1062   alarm_set_on_mloop(p_lcb->l2c_lcb_timer, L2CAP_BLE_LINK_CONNECT_TIMEOUT_MS,
1063                      l2c_lcb_timer_timeout, p_lcb);
1064   return true;
1065 }
1066 
1067 /*******************************************************************************
1068  *
1069  * Function         l2c_link_processs_ble_num_bufs
1070  *
1071  * Description      This function is called when a "controller buffer size"
1072  *                  event is first received from the controller. It updates
1073  *                  the L2CAP values.
1074  *
1075  * Returns          void
1076  *
1077  ******************************************************************************/
l2c_link_processs_ble_num_bufs(uint16_t num_lm_ble_bufs)1078 void l2c_link_processs_ble_num_bufs(uint16_t num_lm_ble_bufs) {
1079   if (bluetooth::shim::is_gd_l2cap_enabled()) {
1080     return;
1081   }
1082 
1083   if (num_lm_ble_bufs == 0) {
1084     num_lm_ble_bufs = L2C_DEF_NUM_BLE_BUF_SHARED;
1085     l2cb.num_lm_acl_bufs -= L2C_DEF_NUM_BLE_BUF_SHARED;
1086   }
1087 
1088   l2cb.num_lm_ble_bufs = num_lm_ble_bufs;
1089   l2cb.controller_le_xmit_window = num_lm_ble_bufs;
1090 }
1091 
1092 /*******************************************************************************
1093  *
1094  * Function         l2c_ble_link_adjust_allocation
1095  *
1096  * Description      This function is called when a link is created or removed
1097  *                  to calculate the amount of packets each link may send to
1098  *                  the HCI without an ack coming back.
1099  *
1100  *                  Currently, this is a simple allocation, dividing the
1101  *                  number of Controller Packets by the number of links. In
1102  *                  the future, QOS configuration should be examined.
1103  *
1104  * Returns          void
1105  *
1106  ******************************************************************************/
l2c_ble_link_adjust_allocation(void)1107 void l2c_ble_link_adjust_allocation(void) {
1108   uint16_t qq, yy, qq_remainder;
1109   tL2C_LCB* p_lcb;
1110   uint16_t hi_quota, low_quota;
1111   uint16_t num_lowpri_links = 0;
1112   uint16_t num_hipri_links = 0;
1113   uint16_t controller_xmit_quota = l2cb.num_lm_ble_bufs;
1114   uint16_t high_pri_link_quota = L2CAP_HIGH_PRI_MIN_XMIT_QUOTA_A;
1115 
1116   /* If no links active, reset buffer quotas and controller buffers */
1117   if (l2cb.num_ble_links_active == 0) {
1118     l2cb.controller_le_xmit_window = l2cb.num_lm_ble_bufs;
1119     l2cb.ble_round_robin_quota = l2cb.ble_round_robin_unacked = 0;
1120     return;
1121   }
1122 
1123   /* First, count the links */
1124   for (yy = 0, p_lcb = &l2cb.lcb_pool[0]; yy < MAX_L2CAP_LINKS; yy++, p_lcb++) {
1125     if (p_lcb->in_use && p_lcb->transport == BT_TRANSPORT_LE) {
1126       if (p_lcb->acl_priority == L2CAP_PRIORITY_HIGH)
1127         num_hipri_links++;
1128       else
1129         num_lowpri_links++;
1130     }
1131   }
1132 
1133   /* now adjust high priority link quota */
1134   low_quota = num_lowpri_links ? 1 : 0;
1135   while ((num_hipri_links * high_pri_link_quota + low_quota) >
1136          controller_xmit_quota)
1137     high_pri_link_quota--;
1138 
1139   /* Work out the xmit quota and buffer quota high and low priorities */
1140   hi_quota = num_hipri_links * high_pri_link_quota;
1141   low_quota =
1142       (hi_quota < controller_xmit_quota) ? controller_xmit_quota - hi_quota : 1;
1143 
1144   /* Work out and save the HCI xmit quota for each low priority link */
1145 
1146   /* If each low priority link cannot have at least one buffer */
1147   if (num_lowpri_links > low_quota) {
1148     l2cb.ble_round_robin_quota = low_quota;
1149     qq = qq_remainder = 0;
1150   }
1151   /* If each low priority link can have at least one buffer */
1152   else if (num_lowpri_links > 0) {
1153     l2cb.ble_round_robin_quota = 0;
1154     l2cb.ble_round_robin_unacked = 0;
1155     qq = low_quota / num_lowpri_links;
1156     qq_remainder = low_quota % num_lowpri_links;
1157   }
1158   /* If no low priority link */
1159   else {
1160     l2cb.ble_round_robin_quota = 0;
1161     l2cb.ble_round_robin_unacked = 0;
1162     qq = qq_remainder = 0;
1163   }
1164   L2CAP_TRACE_EVENT(
1165       "l2c_ble_link_adjust_allocation  num_hipri: %u  num_lowpri: %u  "
1166       "low_quota: %u  round_robin_quota: %u  qq: %u",
1167       num_hipri_links, num_lowpri_links, low_quota, l2cb.ble_round_robin_quota,
1168       qq);
1169 
1170   /* Now, assign the quotas to each link */
1171   for (yy = 0, p_lcb = &l2cb.lcb_pool[0]; yy < MAX_L2CAP_LINKS; yy++, p_lcb++) {
1172     if (p_lcb->in_use && p_lcb->transport == BT_TRANSPORT_LE) {
1173       if (p_lcb->acl_priority == L2CAP_PRIORITY_HIGH) {
1174         p_lcb->link_xmit_quota = high_pri_link_quota;
1175       } else {
1176         /* Safety check in case we switched to round-robin with something
1177          * outstanding */
1178         /* if sent_not_acked is added into round_robin_unacked then do not add
1179          * it again */
1180         /* l2cap keeps updating sent_not_acked for exiting from round robin */
1181         if ((p_lcb->link_xmit_quota > 0) && (qq == 0))
1182           l2cb.ble_round_robin_unacked += p_lcb->sent_not_acked;
1183 
1184         p_lcb->link_xmit_quota = qq;
1185         if (qq_remainder > 0) {
1186           p_lcb->link_xmit_quota++;
1187           qq_remainder--;
1188         }
1189       }
1190 
1191       L2CAP_TRACE_EVENT(
1192           "l2c_ble_link_adjust_allocation LCB %d   Priority: %d  XmitQuota: %d",
1193           yy, p_lcb->acl_priority, p_lcb->link_xmit_quota);
1194 
1195       L2CAP_TRACE_EVENT("        SentNotAcked: %d  RRUnacked: %d",
1196                         p_lcb->sent_not_acked, l2cb.round_robin_unacked);
1197 
1198       /* There is a special case where we have readjusted the link quotas and */
1199       /* this link may have sent anything but some other link sent packets so */
1200       /* so we may need a timer to kick off this link's transmissions. */
1201       if ((p_lcb->link_state == LST_CONNECTED) &&
1202           (!list_is_empty(p_lcb->link_xmit_data_q)) &&
1203           (p_lcb->sent_not_acked < p_lcb->link_xmit_quota)) {
1204         alarm_set_on_mloop(p_lcb->l2c_lcb_timer,
1205                            L2CAP_LINK_FLOW_CONTROL_TIMEOUT_MS,
1206                            l2c_lcb_timer_timeout, p_lcb);
1207       }
1208     }
1209   }
1210 }
1211 
1212 /*******************************************************************************
1213  *
1214  * Function         l2cble_process_rc_param_request_evt
1215  *
1216  * Description      process LE Remote Connection Parameter Request Event.
1217  *
1218  * Returns          void
1219  *
1220  ******************************************************************************/
l2cble_process_rc_param_request_evt(uint16_t handle,uint16_t int_min,uint16_t int_max,uint16_t latency,uint16_t timeout)1221 void l2cble_process_rc_param_request_evt(uint16_t handle, uint16_t int_min,
1222                                          uint16_t int_max, uint16_t latency,
1223                                          uint16_t timeout) {
1224   tL2C_LCB* p_lcb = l2cu_find_lcb_by_handle(handle);
1225 
1226   if (p_lcb != NULL) {
1227     p_lcb->min_interval = int_min;
1228     p_lcb->max_interval = int_max;
1229     p_lcb->latency = latency;
1230     p_lcb->timeout = timeout;
1231 
1232     /* if update is enabled, always accept connection parameter update */
1233     if ((p_lcb->conn_update_mask & L2C_BLE_CONN_UPDATE_DISABLE) == 0) {
1234       btsnd_hcic_ble_rc_param_req_reply(handle, int_min, int_max, latency,
1235                                         timeout, 0, 0);
1236     } else {
1237       L2CAP_TRACE_EVENT("L2CAP - LE - update currently disabled");
1238       p_lcb->conn_update_mask |= L2C_BLE_NEW_CONN_PARAM;
1239       btsnd_hcic_ble_rc_param_req_neg_reply(handle,
1240                                             HCI_ERR_UNACCEPT_CONN_INTERVAL);
1241     }
1242 
1243   } else {
1244     L2CAP_TRACE_WARNING("No link to update connection parameter")
1245   }
1246 }
1247 
1248 /*******************************************************************************
1249  *
1250  * Function         l2cble_update_data_length
1251  *
1252  * Description      This function update link tx data length if applicable
1253  *
1254  * Returns          void
1255  *
1256  ******************************************************************************/
l2cble_update_data_length(tL2C_LCB * p_lcb)1257 void l2cble_update_data_length(tL2C_LCB* p_lcb) {
1258   uint16_t tx_mtu = 0;
1259   uint16_t i = 0;
1260 
1261   L2CAP_TRACE_DEBUG("%s", __func__);
1262 
1263   /* See if we have a link control block for the connection */
1264   if (p_lcb == NULL) return;
1265 
1266   for (i = 0; i < L2CAP_NUM_FIXED_CHNLS; i++) {
1267     if (i + L2CAP_FIRST_FIXED_CHNL != L2CAP_BLE_SIGNALLING_CID) {
1268       if ((p_lcb->p_fixed_ccbs[i] != NULL) &&
1269           (tx_mtu < (p_lcb->p_fixed_ccbs[i]->tx_data_len + L2CAP_PKT_OVERHEAD)))
1270         tx_mtu = p_lcb->p_fixed_ccbs[i]->tx_data_len + L2CAP_PKT_OVERHEAD;
1271     }
1272   }
1273 
1274   if (tx_mtu > BTM_BLE_DATA_SIZE_MAX) tx_mtu = BTM_BLE_DATA_SIZE_MAX;
1275 
1276   /* update TX data length if changed */
1277   if (p_lcb->tx_data_len != tx_mtu)
1278     BTM_SetBleDataLength(p_lcb->remote_bd_addr, tx_mtu);
1279 }
1280 
1281 /*******************************************************************************
1282  *
1283  * Function         l2cble_process_data_length_change_evt
1284  *
1285  * Description      This function process the data length change event
1286  *
1287  * Returns          void
1288  *
1289  ******************************************************************************/
l2cble_process_data_length_change_event(uint16_t handle,uint16_t tx_data_len,uint16_t rx_data_len)1290 void l2cble_process_data_length_change_event(uint16_t handle,
1291                                              uint16_t tx_data_len,
1292                                              uint16_t rx_data_len) {
1293   tL2C_LCB* p_lcb = l2cu_find_lcb_by_handle(handle);
1294 
1295   L2CAP_TRACE_DEBUG("%s TX data len = %d", __func__, tx_data_len);
1296   if (p_lcb == NULL) return;
1297 
1298   if (tx_data_len > 0) p_lcb->tx_data_len = tx_data_len;
1299 
1300   /* ignore rx_data len for now */
1301 }
1302 
1303 /*******************************************************************************
1304  *
1305  * Function         l2cble_credit_based_conn_req
1306  *
1307  * Description      This function sends LE Credit Based Connection Request for
1308  *                  LE connection oriented channels.
1309  *
1310  * Returns          void
1311  *
1312  ******************************************************************************/
l2cble_credit_based_conn_req(tL2C_CCB * p_ccb)1313 void l2cble_credit_based_conn_req(tL2C_CCB* p_ccb) {
1314   if (!p_ccb) return;
1315 
1316   if (p_ccb->p_lcb && p_ccb->p_lcb->transport != BT_TRANSPORT_LE) {
1317     L2CAP_TRACE_WARNING("LE link doesn't exist");
1318     return;
1319   }
1320 
1321   if (p_ccb->ecoc) {
1322     l2cu_send_peer_credit_based_conn_req(p_ccb);
1323   } else {
1324     l2cu_send_peer_ble_credit_based_conn_req(p_ccb);
1325   }
1326   return;
1327 }
1328 
1329 /*******************************************************************************
1330  *
1331  * Function         l2cble_credit_based_conn_res
1332  *
1333  * Description      This function sends LE Credit Based Connection Response for
1334  *                  LE connection oriented channels.
1335  *
1336  * Returns          void
1337  *
1338  ******************************************************************************/
l2cble_credit_based_conn_res(tL2C_CCB * p_ccb,uint16_t result)1339 void l2cble_credit_based_conn_res(tL2C_CCB* p_ccb, uint16_t result) {
1340   if (!p_ccb) return;
1341 
1342   if (p_ccb->p_lcb && p_ccb->p_lcb->transport != BT_TRANSPORT_LE) {
1343     L2CAP_TRACE_WARNING("LE link doesn't exist");
1344     return;
1345   }
1346 
1347   l2cu_send_peer_ble_credit_based_conn_res(p_ccb, result);
1348   return;
1349 }
1350 
1351 /*******************************************************************************
1352  *
1353  * Function         l2cble_send_flow_control_credit
1354  *
1355  * Description      This function sends flow control credits for
1356  *                  LE connection oriented channels.
1357  *
1358  * Returns          void
1359  *
1360  ******************************************************************************/
l2cble_send_flow_control_credit(tL2C_CCB * p_ccb,uint16_t credit_value)1361 void l2cble_send_flow_control_credit(tL2C_CCB* p_ccb, uint16_t credit_value) {
1362   if (!p_ccb) return;
1363 
1364   if (p_ccb->p_lcb && p_ccb->p_lcb->transport != BT_TRANSPORT_LE) {
1365     L2CAP_TRACE_WARNING("LE link doesn't exist");
1366     return;
1367   }
1368 
1369   l2cu_send_peer_ble_flow_control_credit(p_ccb, credit_value);
1370   return;
1371 }
1372 
1373 /*******************************************************************************
1374  *
1375  * Function         l2cble_send_peer_disc_req
1376  *
1377  * Description      This function sends disconnect request
1378  *                  to the peer LE device
1379  *
1380  * Returns          void
1381  *
1382  ******************************************************************************/
l2cble_send_peer_disc_req(tL2C_CCB * p_ccb)1383 void l2cble_send_peer_disc_req(tL2C_CCB* p_ccb) {
1384   L2CAP_TRACE_DEBUG("%s", __func__);
1385   if (!p_ccb) return;
1386 
1387   if (p_ccb->p_lcb && p_ccb->p_lcb->transport != BT_TRANSPORT_LE) {
1388     L2CAP_TRACE_WARNING("LE link doesn't exist");
1389     return;
1390   }
1391 
1392   l2cu_send_peer_ble_credit_based_disconn_req(p_ccb);
1393   return;
1394 }
1395 
1396 /*******************************************************************************
1397  *
1398  * Function         l2cble_sec_comp
1399  *
1400  * Description      This function is called when security procedure for an LE
1401  *                  COC link is done
1402  *
1403  * Returns          void
1404  *
1405  ******************************************************************************/
l2cble_sec_comp(const RawAddress * bda,tBT_TRANSPORT transport,void * p_ref_data,tBTM_STATUS status)1406 void l2cble_sec_comp(const RawAddress* bda, tBT_TRANSPORT transport,
1407                      void* p_ref_data, tBTM_STATUS status) {
1408   const RawAddress& p_bda = *bda;
1409   tL2C_LCB* p_lcb = l2cu_find_lcb_by_bd_addr(p_bda, BT_TRANSPORT_LE);
1410   tL2CAP_SEC_DATA* p_buf = NULL;
1411   uint8_t sec_act;
1412 
1413   if (!p_lcb) {
1414     L2CAP_TRACE_WARNING("%s: security complete for unknown device. bda=%s",
1415                         __func__, bda->ToString().c_str());
1416     return;
1417   }
1418 
1419   sec_act = p_lcb->sec_act;
1420   p_lcb->sec_act = 0;
1421 
1422   if (!fixed_queue_is_empty(p_lcb->le_sec_pending_q)) {
1423     p_buf = (tL2CAP_SEC_DATA*)fixed_queue_dequeue(p_lcb->le_sec_pending_q);
1424     if (!p_buf) {
1425       L2CAP_TRACE_WARNING(
1426           "%s Security complete for request not initiated from L2CAP",
1427           __func__);
1428       return;
1429     }
1430 
1431     if (status != BTM_SUCCESS) {
1432       (*(p_buf->p_callback))(p_bda, BT_TRANSPORT_LE, p_buf->p_ref_data, status);
1433     } else {
1434       if (sec_act == BTM_SEC_ENCRYPT_MITM) {
1435         if (BTM_IsLinkKeyAuthed(p_bda, transport))
1436           (*(p_buf->p_callback))(p_bda, BT_TRANSPORT_LE, p_buf->p_ref_data,
1437                                  status);
1438         else {
1439           L2CAP_TRACE_DEBUG("%s MITM Protection Not present", __func__);
1440           (*(p_buf->p_callback))(p_bda, BT_TRANSPORT_LE, p_buf->p_ref_data,
1441                                  BTM_FAILED_ON_SECURITY);
1442         }
1443       } else {
1444         L2CAP_TRACE_DEBUG("%s MITM Protection not required sec_act = %d",
1445                           __func__, p_lcb->sec_act);
1446 
1447         (*(p_buf->p_callback))(p_bda, BT_TRANSPORT_LE, p_buf->p_ref_data,
1448                                status);
1449       }
1450     }
1451   } else {
1452     L2CAP_TRACE_WARNING(
1453         "%s Security complete for request not initiated from L2CAP", __func__);
1454     return;
1455   }
1456   osi_free(p_buf);
1457 
1458   while (!fixed_queue_is_empty(p_lcb->le_sec_pending_q)) {
1459     p_buf = (tL2CAP_SEC_DATA*)fixed_queue_dequeue(p_lcb->le_sec_pending_q);
1460 
1461     if (status != BTM_SUCCESS)
1462       (*(p_buf->p_callback))(p_bda, BT_TRANSPORT_LE, p_buf->p_ref_data, status);
1463     else
1464       l2ble_sec_access_req(p_bda, p_buf->psm, p_buf->is_originator,
1465                            p_buf->p_callback, p_buf->p_ref_data);
1466 
1467     osi_free(p_buf);
1468   }
1469 }
1470 
1471 /*******************************************************************************
1472  *
1473  * Function         l2ble_sec_access_req
1474  *
1475  * Description      This function is called by LE COC link to meet the
1476  *                  security requirement for the link
1477  *
1478  * Returns          Returns  - L2CAP LE Connection Response Result Code.
1479  *
1480  ******************************************************************************/
l2ble_sec_access_req(const RawAddress & bd_addr,uint16_t psm,bool is_originator,tL2CAP_SEC_CBACK * p_callback,void * p_ref_data)1481 tL2CAP_LE_RESULT_CODE l2ble_sec_access_req(const RawAddress& bd_addr,
1482                                            uint16_t psm, bool is_originator,
1483                                            tL2CAP_SEC_CBACK* p_callback,
1484                                            void* p_ref_data) {
1485   tL2CAP_LE_RESULT_CODE result;
1486   tL2C_LCB* p_lcb = NULL;
1487 
1488   if (!p_callback) {
1489     LOG_ERROR("No callback function");
1490     return L2CAP_LE_RESULT_NO_RESOURCES;
1491   }
1492 
1493   p_lcb = l2cu_find_lcb_by_bd_addr(bd_addr, BT_TRANSPORT_LE);
1494 
1495   if (!p_lcb) {
1496     LOG_ERROR("Security check for unknown device");
1497     p_callback(bd_addr, BT_TRANSPORT_LE, p_ref_data, BTM_UNKNOWN_ADDR);
1498     return L2CAP_LE_RESULT_NO_RESOURCES;
1499   }
1500 
1501   tL2CAP_SEC_DATA* p_buf =
1502       (tL2CAP_SEC_DATA*)osi_malloc((uint16_t)sizeof(tL2CAP_SEC_DATA));
1503   if (!p_buf) {
1504     LOG_ERROR("No resources for connection");
1505     p_callback(bd_addr, BT_TRANSPORT_LE, p_ref_data, BTM_NO_RESOURCES);
1506     return L2CAP_LE_RESULT_NO_RESOURCES;
1507   }
1508 
1509   p_buf->psm = psm;
1510   p_buf->is_originator = is_originator;
1511   p_buf->p_callback = p_callback;
1512   p_buf->p_ref_data = p_ref_data;
1513   fixed_queue_enqueue(p_lcb->le_sec_pending_q, p_buf);
1514   result = btm_ble_start_sec_check(bd_addr, psm, is_originator,
1515                                    &l2cble_sec_comp, p_ref_data);
1516 
1517   return result;
1518 }
1519 
1520 /* This function is called to adjust the connection intervals based on various
1521  * constraints. For example, when there is at least one Hearing Aid device
1522  * bonded, the minimum interval is raised. On return, min_interval and
1523  * max_interval are updated. */
L2CA_AdjustConnectionIntervals(uint16_t * min_interval,uint16_t * max_interval,uint16_t floor_interval)1524 void L2CA_AdjustConnectionIntervals(uint16_t* min_interval,
1525                                     uint16_t* max_interval,
1526                                     uint16_t floor_interval) {
1527   uint16_t phone_min_interval = floor_interval;
1528 
1529   if (HearingAid::GetDeviceCount() > 0) {
1530     // When there are bonded Hearing Aid devices, we will constrained this
1531     // minimum interval.
1532     phone_min_interval = BTM_BLE_CONN_INT_MIN_HEARINGAID;
1533     L2CAP_TRACE_DEBUG("%s: Have Hearing Aids. Min. interval is set to %d",
1534                       __func__, phone_min_interval);
1535   }
1536 
1537   if (*min_interval < phone_min_interval) {
1538     L2CAP_TRACE_DEBUG("%s: requested min_interval=%d too small. Set to %d",
1539                       __func__, *min_interval, phone_min_interval);
1540     *min_interval = phone_min_interval;
1541   }
1542 
1543   // While this could result in connection parameters that fall
1544   // outside fo the range requested, this will allow the connection
1545   // to remain established.
1546   // In other words, this is a workaround for certain peripherals.
1547   if (*max_interval < phone_min_interval) {
1548     L2CAP_TRACE_DEBUG("%s: requested max_interval=%d too small. Set to %d",
1549                       __func__, *max_interval, phone_min_interval);
1550     *max_interval = phone_min_interval;
1551   }
1552 }
1553 
l2cble_use_preferred_conn_params(const RawAddress & bda)1554 void l2cble_use_preferred_conn_params(const RawAddress& bda) {
1555   tL2C_LCB* p_lcb = l2cu_find_lcb_by_bd_addr(bda, BT_TRANSPORT_LE);
1556   tBTM_SEC_DEV_REC* p_dev_rec = btm_find_or_alloc_dev(bda);
1557 
1558   /* If there are any preferred connection parameters, set them now */
1559   if ((p_lcb != NULL) && (p_dev_rec != NULL) &&
1560       (p_dev_rec->conn_params.min_conn_int >= BTM_BLE_CONN_INT_MIN) &&
1561       (p_dev_rec->conn_params.min_conn_int <= BTM_BLE_CONN_INT_MAX) &&
1562       (p_dev_rec->conn_params.max_conn_int >= BTM_BLE_CONN_INT_MIN) &&
1563       (p_dev_rec->conn_params.max_conn_int <= BTM_BLE_CONN_INT_MAX) &&
1564       (p_dev_rec->conn_params.peripheral_latency <= BTM_BLE_CONN_LATENCY_MAX) &&
1565       (p_dev_rec->conn_params.supervision_tout >= BTM_BLE_CONN_SUP_TOUT_MIN) &&
1566       (p_dev_rec->conn_params.supervision_tout <= BTM_BLE_CONN_SUP_TOUT_MAX) &&
1567       ((p_lcb->min_interval < p_dev_rec->conn_params.min_conn_int &&
1568         p_dev_rec->conn_params.min_conn_int != BTM_BLE_CONN_PARAM_UNDEF) ||
1569        (p_lcb->min_interval > p_dev_rec->conn_params.max_conn_int) ||
1570        (p_lcb->latency > p_dev_rec->conn_params.peripheral_latency) ||
1571        (p_lcb->timeout > p_dev_rec->conn_params.supervision_tout))) {
1572     BTM_TRACE_DEBUG(
1573         "%s: HANDLE=%d min_conn_int=%d max_conn_int=%d peripheral_latency=%d "
1574         "supervision_tout=%d",
1575         __func__, p_lcb->Handle(), p_dev_rec->conn_params.min_conn_int,
1576         p_dev_rec->conn_params.max_conn_int,
1577         p_dev_rec->conn_params.peripheral_latency,
1578         p_dev_rec->conn_params.supervision_tout);
1579 
1580     p_lcb->min_interval = p_dev_rec->conn_params.min_conn_int;
1581     p_lcb->max_interval = p_dev_rec->conn_params.max_conn_int;
1582     p_lcb->timeout = p_dev_rec->conn_params.supervision_tout;
1583     p_lcb->latency = p_dev_rec->conn_params.peripheral_latency;
1584 
1585     btsnd_hcic_ble_upd_ll_conn_params(
1586         p_lcb->Handle(), p_dev_rec->conn_params.min_conn_int,
1587         p_dev_rec->conn_params.max_conn_int,
1588         p_dev_rec->conn_params.peripheral_latency,
1589         p_dev_rec->conn_params.supervision_tout, 0, 0);
1590   }
1591 }
1592