• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  *
3  *  Copyright 1999-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 the L2CAP channel state machine
22  *
23  ******************************************************************************/
24 #define LOG_TAG "l2c_csm"
25 
26 #include <base/functional/callback.h>
27 #include <base/logging.h>
28 #include <frameworks/proto_logging/stats/enums/bluetooth/enums.pb.h>
29 
30 #include <string>
31 
32 #include "bt_target.h"
33 #include "common/time_util.h"
34 #include "gd/hal/snoop_logger.h"
35 #include "main/shim/metrics_api.h"
36 #include "main/shim/shim.h"
37 #include "osi/include/allocator.h"
38 #include "osi/include/log.h"
39 #include "stack/btm/btm_sec.h"
40 #include "stack/include/acl_api.h"
41 #include "stack/include/bt_hdr.h"
42 #include "stack/include/l2cdefs.h"
43 #include "stack/l2cap/l2c_int.h"
44 
45 /******************************************************************************/
46 /*            L O C A L    F U N C T I O N     P R O T O T Y P E S            */
47 /******************************************************************************/
48 static void l2c_csm_closed(tL2C_CCB* p_ccb, tL2CEVT event, void* p_data);
49 static void l2c_csm_orig_w4_sec_comp(tL2C_CCB* p_ccb, tL2CEVT event,
50                                      void* p_data);
51 static void l2c_csm_term_w4_sec_comp(tL2C_CCB* p_ccb, tL2CEVT event,
52                                      void* p_data);
53 static void l2c_csm_w4_l2cap_connect_rsp(tL2C_CCB* p_ccb, tL2CEVT event,
54                                          void* p_data);
55 static void l2c_csm_w4_l2ca_connect_rsp(tL2C_CCB* p_ccb, tL2CEVT event,
56                                         void* p_data);
57 static void l2c_csm_config(tL2C_CCB* p_ccb, tL2CEVT event, void* p_data);
58 static void l2c_csm_open(tL2C_CCB* p_ccb, tL2CEVT event, void* p_data);
59 static void l2c_csm_w4_l2cap_disconnect_rsp(tL2C_CCB* p_ccb, tL2CEVT event,
60                                             void* p_data);
61 static void l2c_csm_w4_l2ca_disconnect_rsp(tL2C_CCB* p_ccb, tL2CEVT event,
62                                            void* p_data);
63 
64 static const char* l2c_csm_get_event_name(tL2CEVT event);
65 
66 // Send a connect response with result OK and adjust the state machine
l2c_csm_send_connect_rsp(tL2C_CCB * p_ccb)67 static void l2c_csm_send_connect_rsp(tL2C_CCB* p_ccb) {
68   l2c_csm_execute(p_ccb, L2CEVT_L2CA_CONNECT_RSP, NULL);
69 }
70 
71 // Send a config request and adjust the state machine
l2c_csm_send_config_req(tL2C_CCB * p_ccb)72 static void l2c_csm_send_config_req(tL2C_CCB* p_ccb) {
73   tL2CAP_CFG_INFO config{};
74   config.mtu_present = true;
75   config.mtu = p_ccb->p_rcb->my_mtu;
76   p_ccb->max_rx_mtu = config.mtu;
77   if (p_ccb->p_rcb->ertm_info.preferred_mode != L2CAP_FCR_BASIC_MODE) {
78     config.fcr_present = true;
79     config.fcr = kDefaultErtmOptions;
80   }
81   p_ccb->our_cfg = config;
82   l2c_csm_execute(p_ccb, L2CEVT_L2CA_CONFIG_REQ, &config);
83 }
84 
85 // Send a config response with result OK and adjust the state machine
l2c_csm_send_config_rsp_ok(tL2C_CCB * p_ccb,bool cbit)86 static void l2c_csm_send_config_rsp_ok(tL2C_CCB* p_ccb, bool cbit) {
87   tL2CAP_CFG_INFO config{};
88   config.result = L2CAP_CFG_OK;
89   if (cbit) {
90     config.flags = L2CAP_CFG_FLAGS_MASK_CONT;
91   }
92   l2c_csm_execute(p_ccb, L2CEVT_L2CA_CONFIG_RSP, &config);
93 }
94 
l2c_csm_send_disconnect_rsp(tL2C_CCB * p_ccb)95 static void l2c_csm_send_disconnect_rsp(tL2C_CCB* p_ccb) {
96   l2c_csm_execute(p_ccb, L2CEVT_L2CA_DISCONNECT_RSP, NULL);
97 }
98 
l2c_csm_indicate_connection_open(tL2C_CCB * p_ccb)99 static void l2c_csm_indicate_connection_open(tL2C_CCB* p_ccb) {
100   if (p_ccb->connection_initiator == L2CAP_INITIATOR_LOCAL) {
101     (*p_ccb->p_rcb->api.pL2CA_ConnectCfm_Cb)(p_ccb->local_cid, L2CAP_CONN_OK);
102   } else {
103     (*p_ccb->p_rcb->api.pL2CA_ConnectInd_Cb)(
104         p_ccb->p_lcb->remote_bd_addr, p_ccb->local_cid, p_ccb->p_rcb->psm,
105         p_ccb->remote_id);
106   }
107   if (p_ccb->chnl_state == CST_OPEN && !p_ccb->p_lcb->is_transport_ble()) {
108     (*p_ccb->p_rcb->api.pL2CA_ConfigCfm_Cb)(
109         p_ccb->local_cid, p_ccb->connection_initiator, &p_ccb->peer_cfg);
110   }
111 }
112 
113 /*******************************************************************************
114  *
115  * Function         l2c_csm_execute
116  *
117  * Description      This function executes the state machine.
118  *
119  * Returns          void
120  *
121  ******************************************************************************/
l2c_csm_execute(tL2C_CCB * p_ccb,tL2CEVT event,void * p_data)122 void l2c_csm_execute(tL2C_CCB* p_ccb, tL2CEVT event, void* p_data) {
123   if (p_ccb == nullptr) {
124     LOG_WARN("CCB is null for event (%d)", event);
125     return;
126   }
127 
128   if (!l2cu_is_ccb_active(p_ccb)) {
129     LOG_WARN("CCB not in use, event (%d) cannot be processed", event);
130     return;
131   }
132 
133   LOG_VERBOSE("Entry chnl_state=%s [%d], event=%s [%d]",
134               channel_state_text(p_ccb->chnl_state).c_str(), p_ccb->chnl_state,
135               l2c_csm_get_event_name(event), event);
136 
137   switch (p_ccb->chnl_state) {
138     case CST_CLOSED:
139       l2c_csm_closed(p_ccb, event, p_data);
140       break;
141 
142     case CST_ORIG_W4_SEC_COMP:
143       l2c_csm_orig_w4_sec_comp(p_ccb, event, p_data);
144       break;
145 
146     case CST_TERM_W4_SEC_COMP:
147       l2c_csm_term_w4_sec_comp(p_ccb, event, p_data);
148       break;
149 
150     case CST_W4_L2CAP_CONNECT_RSP:
151       l2c_csm_w4_l2cap_connect_rsp(p_ccb, event, p_data);
152       break;
153 
154     case CST_W4_L2CA_CONNECT_RSP:
155       l2c_csm_w4_l2ca_connect_rsp(p_ccb, event, p_data);
156       break;
157 
158     case CST_CONFIG:
159       l2c_csm_config(p_ccb, event, p_data);
160       break;
161 
162     case CST_OPEN:
163       l2c_csm_open(p_ccb, event, p_data);
164       break;
165 
166     case CST_W4_L2CAP_DISCONNECT_RSP:
167       l2c_csm_w4_l2cap_disconnect_rsp(p_ccb, event, p_data);
168       break;
169 
170     case CST_W4_L2CA_DISCONNECT_RSP:
171       l2c_csm_w4_l2ca_disconnect_rsp(p_ccb, event, p_data);
172       break;
173 
174     default:
175       LOG_ERROR("Unhandled state %d, event %d", p_ccb->chnl_state, event);
176       break;
177   }
178 }
179 
180 /*******************************************************************************
181  *
182  * Function         l2c_csm_closed
183  *
184  * Description      This function handles events when the channel is in
185  *                  CLOSED state. This state exists only when the link is
186  *                  being initially established.
187  *
188  * Returns          void
189  *
190  ******************************************************************************/
l2c_csm_closed(tL2C_CCB * p_ccb,tL2CEVT event,void * p_data)191 static void l2c_csm_closed(tL2C_CCB* p_ccb, tL2CEVT event, void* p_data) {
192   tL2C_CONN_INFO* p_ci = (tL2C_CONN_INFO*)p_data;
193   uint16_t local_cid = p_ccb->local_cid;
194   tL2CA_DISCONNECT_IND_CB* disconnect_ind;
195 
196   if (p_ccb->p_rcb == NULL) {
197     LOG_ERROR("LCID: 0x%04x  st: CLOSED  evt: %s p_rcb == NULL",
198               p_ccb->local_cid, l2c_csm_get_event_name(event));
199     return;
200   }
201 
202   disconnect_ind = p_ccb->p_rcb->api.pL2CA_DisconnectInd_Cb;
203 
204   LOG_DEBUG("LCID: 0x%04x  st: CLOSED  evt: %s", p_ccb->local_cid,
205             l2c_csm_get_event_name(event));
206 
207   switch (event) {
208     case L2CEVT_LP_DISCONNECT_IND: /* Link was disconnected */
209       LOG_DEBUG("Calling Disconnect_Ind_Cb(), CID: 0x%04x  No Conf Needed",
210                 p_ccb->local_cid);
211       l2cu_release_ccb(p_ccb);
212       (*disconnect_ind)(local_cid, false);
213       break;
214 
215     case L2CEVT_LP_CONNECT_CFM: /* Link came up         */
216       if (p_ccb->p_lcb->transport == BT_TRANSPORT_LE) {
217         p_ccb->chnl_state = CST_ORIG_W4_SEC_COMP;
218         l2ble_sec_access_req(p_ccb->p_lcb->remote_bd_addr, p_ccb->p_rcb->psm,
219                              true, &l2c_link_sec_comp2, p_ccb);
220       } else {
221         p_ccb->chnl_state = CST_ORIG_W4_SEC_COMP;
222         btm_sec_l2cap_access_req(p_ccb->p_lcb->remote_bd_addr,
223                                  p_ccb->p_rcb->psm, true, &l2c_link_sec_comp,
224                                  p_ccb);
225       }
226       break;
227 
228     case L2CEVT_LP_CONNECT_CFM_NEG: /* Link failed          */
229       if (p_ci->status == HCI_ERR_CONNECTION_EXISTS) {
230         btm_acl_notif_conn_collision(p_ccb->p_lcb->remote_bd_addr);
231       } else {
232         l2cu_release_ccb(p_ccb);
233         (*p_ccb->p_rcb->api.pL2CA_Error_Cb)(local_cid,
234                                             L2CAP_CONN_ACL_CONNECTION_FAILED);
235         bluetooth::shim::CountCounterMetrics(
236             android::bluetooth::CodePathCounterKeyEnum::
237                 L2CAP_CONNECT_CONFIRM_NEG,
238             1);
239       }
240       break;
241 
242     case L2CEVT_L2CA_CREDIT_BASED_CONNECT_REQ: /* API connect request  */
243     case L2CEVT_L2CA_CONNECT_REQ:
244       if (p_ccb->p_lcb->transport == BT_TRANSPORT_LE) {
245         p_ccb->chnl_state = CST_ORIG_W4_SEC_COMP;
246         l2ble_sec_access_req(p_ccb->p_lcb->remote_bd_addr, p_ccb->p_rcb->psm,
247                              true, &l2c_link_sec_comp2, p_ccb);
248       } else {
249         if (!BTM_SetLinkPolicyActiveMode(p_ccb->p_lcb->remote_bd_addr)) {
250           LOG_WARN("Unable to set link policy active");
251         }
252         /* If sec access does not result in started SEC_COM or COMP_NEG are
253          * already processed */
254         if (btm_sec_l2cap_access_req(
255                 p_ccb->p_lcb->remote_bd_addr, p_ccb->p_rcb->psm, true,
256                 &l2c_link_sec_comp, p_ccb) == BTM_CMD_STARTED) {
257           p_ccb->chnl_state = CST_ORIG_W4_SEC_COMP;
258         }
259       }
260       break;
261 
262     case L2CEVT_SEC_COMP:
263       p_ccb->chnl_state = CST_W4_L2CAP_CONNECT_RSP;
264 
265       /* Wait for the info resp in this state before sending connect req (if
266        * needed) */
267       if (!p_ccb->p_lcb->w4_info_rsp) {
268         /* Need to have at least one compatible channel to continue */
269         if (!l2c_fcr_chk_chan_modes(p_ccb)) {
270           l2cu_release_ccb(p_ccb);
271           (*p_ccb->p_rcb->api.pL2CA_Error_Cb)(local_cid,
272                                               L2CAP_CONN_OTHER_ERROR);
273           bluetooth::shim::CountCounterMetrics(
274               android::bluetooth::CodePathCounterKeyEnum::
275                   L2CAP_NO_COMPATIBLE_CHANNEL_AT_CSM_CLOSED,
276               1);
277         } else {
278           l2cu_send_peer_connect_req(p_ccb);
279           alarm_set_on_mloop(p_ccb->l2c_ccb_timer,
280                              L2CAP_CHNL_CONNECT_TIMEOUT_MS,
281                              l2c_ccb_timer_timeout, p_ccb);
282         }
283       }
284       break;
285 
286     case L2CEVT_SEC_COMP_NEG: /* something is really bad with security */
287       l2cu_release_ccb(p_ccb);
288       (*p_ccb->p_rcb->api.pL2CA_Error_Cb)(
289           local_cid, L2CAP_CONN_CLIENT_SECURITY_CLEARANCE_FAILED);
290       bluetooth::shim::CountCounterMetrics(
291           android::bluetooth::CodePathCounterKeyEnum::
292               L2CAP_SECURITY_NEG_AT_CSM_CLOSED,
293           1);
294       break;
295 
296     case L2CEVT_L2CAP_CREDIT_BASED_CONNECT_REQ: /* Peer connect request */
297     case L2CEVT_L2CAP_CONNECT_REQ:
298       /* stop link timer to avoid race condition between A2MP, Security, and
299        * L2CAP */
300       alarm_cancel(p_ccb->p_lcb->l2c_lcb_timer);
301 
302       if (p_ccb->p_lcb->transport == BT_TRANSPORT_LE) {
303         p_ccb->chnl_state = CST_TERM_W4_SEC_COMP;
304         tL2CAP_LE_RESULT_CODE result = l2ble_sec_access_req(
305             p_ccb->p_lcb->remote_bd_addr, p_ccb->p_rcb->psm, false,
306             &l2c_link_sec_comp2, p_ccb);
307 
308         switch (result) {
309           case L2CAP_LE_RESULT_INSUFFICIENT_AUTHORIZATION:
310           case L2CAP_LE_RESULT_UNACCEPTABLE_PARAMETERS:
311           case L2CAP_LE_RESULT_INVALID_PARAMETERS:
312           case L2CAP_LE_RESULT_INSUFFICIENT_AUTHENTICATION:
313           case L2CAP_LE_RESULT_INSUFFICIENT_ENCRYP_KEY_SIZE:
314           case L2CAP_LE_RESULT_INSUFFICIENT_ENCRYP:
315             l2cu_reject_ble_connection(p_ccb, p_ccb->remote_id, result);
316             l2cu_release_ccb(p_ccb);
317             break;
318           case L2CAP_LE_RESULT_CONN_OK:
319           case L2CAP_LE_RESULT_NO_PSM:
320           case L2CAP_LE_RESULT_NO_RESOURCES:
321           case L2CAP_LE_RESULT_INVALID_SOURCE_CID:
322           case L2CAP_LE_RESULT_SOURCE_CID_ALREADY_ALLOCATED:
323             break;
324         }
325       } else {
326         if (!BTM_SetLinkPolicyActiveMode(p_ccb->p_lcb->remote_bd_addr)) {
327           LOG_WARN("Unable to set link policy active");
328         }
329         p_ccb->chnl_state = CST_TERM_W4_SEC_COMP;
330         auto status = btm_sec_l2cap_access_req(p_ccb->p_lcb->remote_bd_addr,
331                                                p_ccb->p_rcb->psm, false,
332                                                &l2c_link_sec_comp, p_ccb);
333         if (status == BTM_CMD_STARTED) {
334           // started the security process, tell the peer to set a longer timer
335           l2cu_send_peer_connect_rsp(p_ccb, L2CAP_CONN_PENDING, 0);
336         } else {
337           LOG_INFO("Check security for psm 0x%04x, status %d",
338                    p_ccb->p_rcb->psm, status);
339         }
340       }
341       break;
342 
343     case L2CEVT_TIMEOUT:
344       l2cu_release_ccb(p_ccb);
345       (*p_ccb->p_rcb->api.pL2CA_Error_Cb)(local_cid, L2CAP_CONN_OTHER_ERROR);
346       bluetooth::shim::CountCounterMetrics(
347           android::bluetooth::CodePathCounterKeyEnum::
348               L2CAP_TIMEOUT_AT_CSM_CLOSED,
349           1);
350       break;
351 
352     case L2CEVT_L2CAP_DATA:      /* Peer data packet rcvd    */
353     case L2CEVT_L2CA_DATA_WRITE: /* Upper layer data to send */
354       osi_free(p_data);
355       break;
356 
357     case L2CEVT_L2CA_DISCONNECT_REQ: /* Upper wants to disconnect */
358       l2cu_release_ccb(p_ccb);
359       break;
360 
361     default:
362       LOG_ERROR("Handling unexpected event:%s", l2c_csm_get_event_name(event));
363   }
364   LOG_VERBOSE("Exit chnl_state=%s [%d], event=%s [%d]",
365               channel_state_text(p_ccb->chnl_state).c_str(), p_ccb->chnl_state,
366               l2c_csm_get_event_name(event), event);
367 }
368 
369 /*******************************************************************************
370  *
371  * Function         l2c_csm_orig_w4_sec_comp
372  *
373  * Description      This function handles events when the channel is in
374  *                  CST_ORIG_W4_SEC_COMP state.
375  *
376  * Returns          void
377  *
378  ******************************************************************************/
l2c_csm_orig_w4_sec_comp(tL2C_CCB * p_ccb,tL2CEVT event,void * p_data)379 static void l2c_csm_orig_w4_sec_comp(tL2C_CCB* p_ccb, tL2CEVT event,
380                                      void* p_data) {
381   tL2CA_DISCONNECT_IND_CB* disconnect_ind =
382       p_ccb->p_rcb->api.pL2CA_DisconnectInd_Cb;
383   uint16_t local_cid = p_ccb->local_cid;
384 
385   LOG_DEBUG("%s - LCID: 0x%04x  st: ORIG_W4_SEC_COMP  evt: %s",
386             ((p_ccb->p_lcb) && (p_ccb->p_lcb->transport == BT_TRANSPORT_LE))
387                 ? "LE "
388                 : "",
389             p_ccb->local_cid, l2c_csm_get_event_name(event));
390 
391   switch (event) {
392     case L2CEVT_LP_DISCONNECT_IND: /* Link was disconnected */
393       LOG_DEBUG("Calling Disconnect_Ind_Cb(), CID: 0x%04x  No Conf Needed",
394                 p_ccb->local_cid);
395       l2cu_release_ccb(p_ccb);
396       (*disconnect_ind)(local_cid, false);
397       break;
398 
399     case L2CEVT_SEC_RE_SEND_CMD: /* BTM has enough info to proceed */
400     case L2CEVT_LP_CONNECT_CFM:  /* Link came up         */
401       if (p_ccb->p_lcb->transport == BT_TRANSPORT_LE) {
402         l2ble_sec_access_req(p_ccb->p_lcb->remote_bd_addr, p_ccb->p_rcb->psm,
403                              false, &l2c_link_sec_comp2, p_ccb);
404       } else {
405         btm_sec_l2cap_access_req(p_ccb->p_lcb->remote_bd_addr,
406                                  p_ccb->p_rcb->psm, true, &l2c_link_sec_comp,
407                                  p_ccb);
408       }
409       break;
410 
411     case L2CEVT_SEC_COMP: /* Security completed success */
412       /* Wait for the info resp in this state before sending connect req (if
413        * needed) */
414       p_ccb->chnl_state = CST_W4_L2CAP_CONNECT_RSP;
415       if (p_ccb->p_lcb->transport == BT_TRANSPORT_LE) {
416         alarm_set_on_mloop(p_ccb->l2c_ccb_timer, L2CAP_CHNL_CONNECT_TIMEOUT_MS,
417                            l2c_ccb_timer_timeout, p_ccb);
418         l2cble_credit_based_conn_req(p_ccb); /* Start Connection     */
419       } else {
420         if (!p_ccb->p_lcb->w4_info_rsp) {
421           /* Need to have at least one compatible channel to continue */
422           if (!l2c_fcr_chk_chan_modes(p_ccb)) {
423             l2cu_release_ccb(p_ccb);
424             (*p_ccb->p_rcb->api.pL2CA_Error_Cb)(local_cid,
425                                                 L2CAP_CONN_OTHER_ERROR);
426             bluetooth::shim::CountCounterMetrics(
427                 android::bluetooth::CodePathCounterKeyEnum::
428                     L2CAP_NO_COMPATIBLE_CHANNEL_AT_W4_SEC,
429                 1);
430           } else {
431             alarm_set_on_mloop(p_ccb->l2c_ccb_timer,
432                                L2CAP_CHNL_CONNECT_TIMEOUT_MS,
433                                l2c_ccb_timer_timeout, p_ccb);
434             l2cu_send_peer_connect_req(p_ccb); /* Start Connection     */
435           }
436         }
437       }
438       break;
439 
440     case L2CEVT_SEC_COMP_NEG:
441       /* If last channel immediately disconnect the ACL for better security.
442          Also prevents a race condition between BTM and L2CAP */
443       if ((p_ccb == p_ccb->p_lcb->ccb_queue.p_first_ccb) &&
444           (p_ccb == p_ccb->p_lcb->ccb_queue.p_last_ccb)) {
445         p_ccb->p_lcb->idle_timeout = 0;
446       }
447 
448       l2cu_release_ccb(p_ccb);
449       (*p_ccb->p_rcb->api.pL2CA_Error_Cb)(
450           local_cid, L2CAP_CONN_CLIENT_SECURITY_CLEARANCE_FAILED);
451       bluetooth::shim::CountCounterMetrics(
452           android::bluetooth::CodePathCounterKeyEnum::
453               L2CAP_SECURITY_NEG_AT_W4_SEC,
454           1);
455       break;
456 
457     case L2CEVT_L2CA_DATA_WRITE: /* Upper layer data to send */
458     case L2CEVT_L2CAP_DATA:      /* Peer data packet rcvd    */
459       osi_free(p_data);
460       break;
461 
462     case L2CEVT_L2CA_DISCONNECT_REQ: /* Upper wants to disconnect */
463       /* Tell security manager to abort */
464       btm_sec_abort_access_req(p_ccb->p_lcb->remote_bd_addr);
465 
466       l2cu_release_ccb(p_ccb);
467       break;
468 
469     default:
470       LOG_ERROR("Handling unexpected event:%s", l2c_csm_get_event_name(event));
471   }
472   LOG_VERBOSE("Exit chnl_state=%s [%d], event=%s [%d]",
473               channel_state_text(p_ccb->chnl_state).c_str(), p_ccb->chnl_state,
474               l2c_csm_get_event_name(event), event);
475 }
476 
477 /*******************************************************************************
478  *
479  * Function         l2c_csm_term_w4_sec_comp
480  *
481  * Description      This function handles events when the channel is in
482  *                  CST_TERM_W4_SEC_COMP state.
483  *
484  * Returns          void
485  *
486  ******************************************************************************/
l2c_csm_term_w4_sec_comp(tL2C_CCB * p_ccb,tL2CEVT event,void * p_data)487 static void l2c_csm_term_w4_sec_comp(tL2C_CCB* p_ccb, tL2CEVT event,
488                                      void* p_data) {
489   LOG_DEBUG("LCID: 0x%04x  st: TERM_W4_SEC_COMP  evt: %s", p_ccb->local_cid,
490             l2c_csm_get_event_name(event));
491 
492   switch (event) {
493     case L2CEVT_LP_DISCONNECT_IND: /* Link was disconnected */
494       /* Tell security manager to abort */
495       btm_sec_abort_access_req(p_ccb->p_lcb->remote_bd_addr);
496 
497       l2cu_release_ccb(p_ccb);
498       break;
499 
500     case L2CEVT_SEC_COMP:
501       p_ccb->chnl_state = CST_W4_L2CA_CONNECT_RSP;
502 
503       /* Wait for the info resp in next state before sending connect ind (if
504        * needed) */
505       if (!p_ccb->p_lcb->w4_info_rsp) {
506         LOG_DEBUG("Not waiting for info response, sending connect response");
507         /* Don't need to get info from peer or already retrieved so continue */
508         alarm_set_on_mloop(p_ccb->l2c_ccb_timer, L2CAP_CHNL_CONNECT_TIMEOUT_MS,
509                            l2c_ccb_timer_timeout, p_ccb);
510 
511         if (p_ccb->p_lcb->transport != BT_TRANSPORT_LE) {
512           LOG_DEBUG("Not LE connection, sending configure request");
513           l2c_csm_send_connect_rsp(p_ccb);
514           l2c_csm_send_config_req(p_ccb);
515         } else {
516           if (p_ccb->ecoc) {
517             /* Handle Credit Based Connection */
518             LOG_DEBUG("Calling CreditBasedConnect_Ind_Cb(), num of cids: %d",
519                       p_ccb->p_lcb->pending_ecoc_conn_cnt);
520 
521             std::vector<uint16_t> pending_cids;
522             for (int i = 0; i < p_ccb->p_lcb->pending_ecoc_conn_cnt; i++) {
523               uint16_t cid = p_ccb->p_lcb->pending_ecoc_connection_cids[i];
524               if (cid != 0) pending_cids.push_back(cid);
525             }
526 
527             (*p_ccb->p_rcb->api.pL2CA_CreditBasedConnectInd_Cb)(
528                 p_ccb->p_lcb->remote_bd_addr, pending_cids, p_ccb->p_rcb->psm,
529                 p_ccb->peer_conn_cfg.mtu, p_ccb->remote_id);
530           } else {
531             /* Handle BLE CoC */
532             LOG_DEBUG("Calling Connect_Ind_Cb(), CID: 0x%04x",
533                       p_ccb->local_cid);
534             l2c_csm_send_connect_rsp(p_ccb);
535             l2c_csm_indicate_connection_open(p_ccb);
536           }
537         }
538       } else {
539         /*
540         ** L2CAP Connect Response will be sent out by 3 sec timer expiration
541         ** because Bluesoleil doesn't respond to L2CAP Information Request.
542         ** Bluesoleil seems to disconnect ACL link as failure case, because
543         ** it takes too long (4~7secs) to get response.
544         ** product version : Bluesoleil 2.1.1.0 EDR Release 060123
545         ** stack version   : 05.04.11.20060119
546         */
547 
548         /* Cancel ccb timer as security complete. waiting for w4_info_rsp
549         ** once info rsp received, connection rsp timer will be started
550         ** while sending connection ind to profiles
551         */
552         alarm_cancel(p_ccb->l2c_ccb_timer);
553 
554         /* Waiting for the info resp, tell the peer to set a longer timer */
555         LOG_DEBUG("Waiting for info response, sending connect pending");
556         l2cu_send_peer_connect_rsp(p_ccb, L2CAP_CONN_PENDING, 0);
557       }
558       break;
559 
560     case L2CEVT_SEC_COMP_NEG:
561       if (((tL2C_CONN_INFO*)p_data)->status == BTM_DELAY_CHECK) {
562         /* start a timer - encryption change not received before L2CAP connect
563          * req */
564         alarm_set_on_mloop(p_ccb->l2c_ccb_timer,
565                            L2CAP_DELAY_CHECK_SM4_TIMEOUT_MS,
566                            l2c_ccb_timer_timeout, p_ccb);
567       } else {
568         if (p_ccb->p_lcb->transport == BT_TRANSPORT_LE)
569           l2cu_reject_ble_connection(
570               p_ccb, p_ccb->remote_id,
571               L2CAP_LE_RESULT_INSUFFICIENT_AUTHENTICATION);
572         else
573           l2cu_send_peer_connect_rsp(p_ccb, L2CAP_CONN_SECURITY_BLOCK, 0);
574         l2cu_release_ccb(p_ccb);
575       }
576       break;
577 
578     case L2CEVT_L2CA_DATA_WRITE: /* Upper layer data to send */
579     case L2CEVT_L2CAP_DATA:      /* Peer data packet rcvd    */
580       osi_free(p_data);
581       break;
582 
583     case L2CEVT_L2CA_DISCONNECT_REQ: /* Upper wants to disconnect */
584       l2cu_release_ccb(p_ccb);
585       break;
586 
587     case L2CEVT_L2CAP_DISCONNECT_REQ: /* Peer disconnected request */
588       l2cu_send_peer_disc_rsp(p_ccb->p_lcb, p_ccb->remote_id, p_ccb->local_cid,
589                               p_ccb->remote_cid);
590 
591       /* Tell security manager to abort */
592       btm_sec_abort_access_req(p_ccb->p_lcb->remote_bd_addr);
593 
594       l2cu_release_ccb(p_ccb);
595       break;
596 
597     case L2CEVT_TIMEOUT:
598       /* SM4 related. */
599       acl_disconnect_from_handle(
600           p_ccb->p_lcb->Handle(), HCI_ERR_AUTH_FAILURE,
601           "stack::l2cap::l2c_csm::l2c_csm_term_w4_sec_comp Event timeout");
602       break;
603 
604     case L2CEVT_SEC_RE_SEND_CMD: /* BTM has enough info to proceed */
605       btm_sec_l2cap_access_req(p_ccb->p_lcb->remote_bd_addr, p_ccb->p_rcb->psm,
606                                false, &l2c_link_sec_comp, p_ccb);
607       break;
608 
609     default:
610       LOG_ERROR("Handling unexpected event:%s", l2c_csm_get_event_name(event));
611   }
612   LOG_VERBOSE("Exit chnl_state=%s [%d], event=%s [%d]",
613               channel_state_text(p_ccb->chnl_state).c_str(), p_ccb->chnl_state,
614               l2c_csm_get_event_name(event), event);
615 }
616 
617 /*******************************************************************************
618  *
619  * Function         l2c_csm_w4_l2cap_connect_rsp
620  *
621  * Description      This function handles events when the channel is in
622  *                  CST_W4_L2CAP_CONNECT_RSP state.
623  *
624  * Returns          void
625  *
626  ******************************************************************************/
l2c_csm_w4_l2cap_connect_rsp(tL2C_CCB * p_ccb,tL2CEVT event,void * p_data)627 static void l2c_csm_w4_l2cap_connect_rsp(tL2C_CCB* p_ccb, tL2CEVT event,
628                                          void* p_data) {
629   tL2C_CONN_INFO* p_ci = (tL2C_CONN_INFO*)p_data;
630   tL2CA_DISCONNECT_IND_CB* disconnect_ind =
631       p_ccb->p_rcb->api.pL2CA_DisconnectInd_Cb;
632   tL2CA_CREDIT_BASED_CONNECT_CFM_CB* credit_based_connect_cfm =
633       p_ccb->p_rcb->api.pL2CA_CreditBasedConnectCfm_Cb;
634   uint16_t local_cid = p_ccb->local_cid;
635   tL2C_LCB* p_lcb = p_ccb->p_lcb;
636 
637   LOG_DEBUG("LCID: 0x%04x  st: W4_L2CAP_CON_RSP  evt: %s", p_ccb->local_cid,
638             l2c_csm_get_event_name(event));
639 
640   switch (event) {
641     case L2CEVT_LP_DISCONNECT_IND: /* Link was disconnected */
642       /* Send disc indication unless peer to peer race condition AND normal
643        * disconnect */
644       /* *((uint8_t *)p_data) != HCI_ERR_PEER_USER happens when peer device try
645        * to disconnect for normal reason */
646       p_ccb->chnl_state = CST_CLOSED;
647       if ((p_ccb->flags & CCB_FLAG_NO_RETRY) || !p_data ||
648           (*((uint8_t*)p_data) != HCI_ERR_PEER_USER)) {
649         LOG_DEBUG("Calling Disconnect_Ind_Cb(), CID: 0x%04x  No Conf Needed",
650                   p_ccb->local_cid);
651         l2cu_release_ccb(p_ccb);
652         (*disconnect_ind)(local_cid, false);
653       }
654       p_ccb->flags |= CCB_FLAG_NO_RETRY;
655       break;
656 
657     case L2CEVT_L2CAP_CONNECT_RSP: /* Got peer connect confirm */
658       p_ccb->remote_cid = p_ci->remote_cid;
659       if (p_ccb->p_lcb->transport == BT_TRANSPORT_LE) {
660         /* Connection is completed */
661         alarm_cancel(p_ccb->l2c_ccb_timer);
662         p_ccb->chnl_state = CST_OPEN;
663         l2c_csm_indicate_connection_open(p_ccb);
664         p_ccb->local_conn_cfg = p_ccb->p_rcb->coc_cfg;
665         p_ccb->remote_credit_count = p_ccb->p_rcb->coc_cfg.credits;
666         l2c_csm_execute(p_ccb, L2CEVT_L2CA_CONNECT_RSP, NULL);
667       } else {
668         p_ccb->chnl_state = CST_CONFIG;
669         alarm_set_on_mloop(p_ccb->l2c_ccb_timer, L2CAP_CHNL_CFG_TIMEOUT_MS,
670                            l2c_ccb_timer_timeout, p_ccb);
671       }
672       LOG_DEBUG("Calling Connect_Cfm_Cb(), CID: 0x%04x, Success",
673                 p_ccb->local_cid);
674 
675       l2c_csm_send_config_req(p_ccb);
676       break;
677 
678     case L2CEVT_L2CAP_CONNECT_RSP_PND: /* Got peer connect pending */
679       p_ccb->remote_cid = p_ci->remote_cid;
680       alarm_set_on_mloop(p_ccb->l2c_ccb_timer,
681                          L2CAP_CHNL_CONNECT_EXT_TIMEOUT_MS,
682                          l2c_ccb_timer_timeout, p_ccb);
683       break;
684 
685     case L2CEVT_L2CAP_CREDIT_BASED_CONNECT_RSP:
686       alarm_cancel(p_ccb->l2c_ccb_timer);
687       p_ccb->chnl_state = CST_OPEN;
688       LOG_DEBUG(
689           "Calling credit_based_connect_cfm(),"
690           "cid %d, result 0x%04x",
691           p_ccb->local_cid, L2CAP_CONN_OK);
692 
693       (*credit_based_connect_cfm)(p_lcb->remote_bd_addr, p_ccb->local_cid,
694                                   p_ci->peer_mtu, L2CAP_CONN_OK);
695       break;
696 
697     case L2CEVT_L2CAP_CREDIT_BASED_CONNECT_RSP_NEG:
698       LOG_DEBUG(
699           "Calling pL2CA_Error_Cb(),"
700           "cid %d, result 0x%04x",
701           local_cid, p_ci->l2cap_result);
702       (*p_ccb->p_rcb->api.pL2CA_Error_Cb)(local_cid, p_ci->l2cap_result);
703       bluetooth::shim::CountCounterMetrics(
704           android::bluetooth::CodePathCounterKeyEnum::
705               L2CAP_CREDIT_BASED_CONNECT_RSP_NEG,
706           1);
707 
708       l2cu_release_ccb(p_ccb);
709       break;
710 
711     case L2CEVT_L2CAP_CONNECT_RSP_NEG: /* Peer rejected connection */
712       LOG(WARNING) << __func__ << ": L2CAP connection rejected, lcid="
713                    << loghex(p_ccb->local_cid)
714                    << ", reason=" << loghex(p_ci->l2cap_result);
715       l2cu_release_ccb(p_ccb);
716       if (p_lcb->transport == BT_TRANSPORT_LE) {
717         (*p_ccb->p_rcb->api.pL2CA_Error_Cb)(
718             local_cid, le_result_to_l2c_conn(p_ci->l2cap_result));
719       } else {
720         (*p_ccb->p_rcb->api.pL2CA_Error_Cb)(local_cid, L2CAP_CONN_OTHER_ERROR);
721       }
722       bluetooth::shim::CountCounterMetrics(
723           android::bluetooth::CodePathCounterKeyEnum::L2CAP_CONNECT_RSP_NEG, 1);
724       break;
725 
726     case L2CEVT_TIMEOUT:
727       LOG(WARNING) << __func__ << ": L2CAP connection timeout";
728 
729       if (p_ccb->ecoc) {
730         for (int i = 0; i < p_lcb->pending_ecoc_conn_cnt; i++) {
731           uint16_t cid = p_lcb->pending_ecoc_connection_cids[i];
732           tL2C_CCB* temp_p_ccb = l2cu_find_ccb_by_cid(p_lcb, cid);
733           LOG(WARNING) << __func__ << ": lcid= " << loghex(cid);
734           (*p_ccb->p_rcb->api.pL2CA_Error_Cb)(p_ccb->local_cid,
735                                               L2CAP_CONN_TIMEOUT);
736           bluetooth::shim::CountCounterMetrics(
737               android::bluetooth::CodePathCounterKeyEnum::
738                   L2CAP_TIMEOUT_AT_CONNECT_RSP,
739               1);
740           l2cu_release_ccb(temp_p_ccb);
741         }
742         p_lcb->pending_ecoc_conn_cnt = 0;
743         memset(p_lcb->pending_ecoc_connection_cids, 0,
744                L2CAP_CREDIT_BASED_MAX_CIDS);
745 
746       } else {
747         LOG(WARNING) << __func__ << ": lcid= " << loghex(p_ccb->local_cid);
748         l2cu_release_ccb(p_ccb);
749         (*p_ccb->p_rcb->api.pL2CA_Error_Cb)(local_cid, L2CAP_CONN_OTHER_ERROR);
750         bluetooth::shim::CountCounterMetrics(
751             android::bluetooth::CodePathCounterKeyEnum::
752                 L2CAP_CONN_OTHER_ERROR_AT_CONNECT_RSP,
753             1);
754       }
755       break;
756 
757     case L2CEVT_L2CA_DISCONNECT_REQ: /* Upper wants to disconnect */
758       /* If we know peer CID from connect pending, we can send disconnect */
759       if (p_ccb->remote_cid != 0) {
760         l2cu_send_peer_disc_req(p_ccb);
761         p_ccb->chnl_state = CST_W4_L2CAP_DISCONNECT_RSP;
762         alarm_set_on_mloop(p_ccb->l2c_ccb_timer,
763                            L2CAP_CHNL_DISCONNECT_TIMEOUT_MS,
764                            l2c_ccb_timer_timeout, p_ccb);
765       } else {
766         tL2CA_DISCONNECT_CFM_CB* disconnect_cfm =
767             p_ccb->p_rcb->api.pL2CA_DisconnectCfm_Cb;
768         l2cu_release_ccb(p_ccb);
769         if (disconnect_cfm != nullptr) {
770           (*disconnect_cfm)(local_cid, L2CAP_CONN_NO_LINK);
771         }
772       }
773       break;
774 
775     case L2CEVT_L2CA_DATA_WRITE: /* Upper layer data to send */
776     case L2CEVT_L2CAP_DATA:      /* Peer data packet rcvd    */
777       osi_free(p_data);
778       break;
779 
780     case L2CEVT_L2CAP_INFO_RSP:
781       /* Need to have at least one compatible channel to continue */
782       if (!l2c_fcr_chk_chan_modes(p_ccb)) {
783         l2cu_release_ccb(p_ccb);
784         (*p_ccb->p_rcb->api.pL2CA_Error_Cb)(local_cid, L2CAP_CONN_OTHER_ERROR);
785         bluetooth::shim::CountCounterMetrics(
786             android::bluetooth::CodePathCounterKeyEnum::
787                 L2CAP_INFO_NO_COMPATIBLE_CHANNEL_AT_RSP,
788             1);
789       } else {
790         /* We have feature info, so now send peer connect request */
791         alarm_set_on_mloop(p_ccb->l2c_ccb_timer, L2CAP_CHNL_CONNECT_TIMEOUT_MS,
792                            l2c_ccb_timer_timeout, p_ccb);
793         l2cu_send_peer_connect_req(p_ccb); /* Start Connection     */
794       }
795       break;
796 
797     default:
798       LOG_ERROR("Handling unexpected event:%s", l2c_csm_get_event_name(event));
799   }
800   LOG_VERBOSE("Exit chnl_state=%s [%d], event=%s [%d]",
801               channel_state_text(p_ccb->chnl_state).c_str(), p_ccb->chnl_state,
802               l2c_csm_get_event_name(event), event);
803 }
804 
805 /*******************************************************************************
806  *
807  * Function         l2c_csm_w4_l2ca_connect_rsp
808  *
809  * Description      This function handles events when the channel is in
810  *                  CST_W4_L2CA_CONNECT_RSP state.
811  *
812  * Returns          void
813  *
814  ******************************************************************************/
l2c_csm_w4_l2ca_connect_rsp(tL2C_CCB * p_ccb,tL2CEVT event,void * p_data)815 static void l2c_csm_w4_l2ca_connect_rsp(tL2C_CCB* p_ccb, tL2CEVT event,
816                                         void* p_data) {
817   tL2C_CONN_INFO* p_ci;
818   tL2C_LCB* p_lcb = p_ccb->p_lcb;
819   tL2CA_DISCONNECT_IND_CB* disconnect_ind =
820       p_ccb->p_rcb->api.pL2CA_DisconnectInd_Cb;
821   uint16_t local_cid = p_ccb->local_cid;
822 
823   LOG_DEBUG("LCID: 0x%04x  st: W4_L2CA_CON_RSP  evt: %s", p_ccb->local_cid,
824             l2c_csm_get_event_name(event));
825 
826   switch (event) {
827     case L2CEVT_LP_DISCONNECT_IND: /* Link was disconnected */
828       LOG_DEBUG("Calling Disconnect_Ind_Cb(), CID: 0x%04x  No Conf Needed",
829                 p_ccb->local_cid);
830       l2cu_release_ccb(p_ccb);
831       (*disconnect_ind)(local_cid, false);
832       break;
833 
834     case L2CEVT_L2CA_CREDIT_BASED_CONNECT_RSP:
835       p_ci = (tL2C_CONN_INFO*)p_data;
836       if ((p_lcb == nullptr) || (p_lcb && p_lcb->transport != BT_TRANSPORT_LE)) {
837         LOG_WARN("LE link doesn't exist");
838         return;
839       }
840       l2cu_send_peer_credit_based_conn_res(p_ccb, p_ci->lcids,
841                                            p_ci->l2cap_result);
842       alarm_cancel(p_ccb->l2c_ccb_timer);
843 
844       for (int i = 0; i < p_lcb->pending_ecoc_conn_cnt; i++) {
845         uint16_t cid = p_lcb->pending_ecoc_connection_cids[i];
846         if (cid == 0) {
847             LOG_WARN("pending_ecoc_connection_cids[%d] is %d", i, cid);
848             continue;
849         }
850 
851         tL2C_CCB* temp_p_ccb = l2cu_find_ccb_by_cid(p_lcb, cid);
852         if (temp_p_ccb) {
853           auto it = std::find(p_ci->lcids.begin(), p_ci->lcids.end(), cid);
854           if (it != p_ci->lcids.end()) {
855             temp_p_ccb->chnl_state = CST_OPEN;
856           } else {
857             l2cu_release_ccb(temp_p_ccb);
858           }
859         }
860         else {
861             LOG_WARN("temp_p_ccb is NULL, pending_ecoc_connection_cids[%d] is %d", i, cid);
862         }
863       }
864       p_lcb->pending_ecoc_conn_cnt = 0;
865       memset(p_lcb->pending_ecoc_connection_cids, 0,
866              L2CAP_CREDIT_BASED_MAX_CIDS);
867 
868       break;
869     case L2CEVT_L2CA_CONNECT_RSP:
870       p_ci = (tL2C_CONN_INFO*)p_data;
871       if (p_ccb->p_lcb->transport == BT_TRANSPORT_LE) {
872         /* Result should be OK or Reject */
873         if ((!p_ci) || (p_ci->l2cap_result == L2CAP_CONN_OK)) {
874           l2cble_credit_based_conn_res(p_ccb, L2CAP_CONN_OK);
875           p_ccb->chnl_state = CST_OPEN;
876           alarm_cancel(p_ccb->l2c_ccb_timer);
877         } else {
878           l2cble_credit_based_conn_res(p_ccb, p_ci->l2cap_result);
879           l2cu_release_ccb(p_ccb);
880         }
881       } else {
882         /* Result should be OK or PENDING */
883         if ((!p_ci) || (p_ci->l2cap_result == L2CAP_CONN_OK)) {
884           LOG_DEBUG("Sending connection ok for BR_EDR");
885           l2cu_send_peer_connect_rsp(p_ccb, L2CAP_CONN_OK, 0);
886           p_ccb->chnl_state = CST_CONFIG;
887           alarm_set_on_mloop(p_ccb->l2c_ccb_timer, L2CAP_CHNL_CFG_TIMEOUT_MS,
888                              l2c_ccb_timer_timeout, p_ccb);
889         } else {
890           /* If pending, stay in same state and start extended timer */
891           LOG_DEBUG("Sending connection result %d and status %d",
892                     p_ci->l2cap_result, p_ci->l2cap_status);
893           l2cu_send_peer_connect_rsp(p_ccb, p_ci->l2cap_result,
894                                      p_ci->l2cap_status);
895           alarm_set_on_mloop(p_ccb->l2c_ccb_timer,
896                              L2CAP_CHNL_CONNECT_EXT_TIMEOUT_MS,
897                              l2c_ccb_timer_timeout, p_ccb);
898         }
899       }
900       break;
901 
902     case L2CEVT_L2CA_CREDIT_BASED_CONNECT_RSP_NEG:
903       p_ci = (tL2C_CONN_INFO*)p_data;
904       alarm_cancel(p_ccb->l2c_ccb_timer);
905       if (p_lcb != nullptr) {
906         if (p_lcb->transport == BT_TRANSPORT_LE) {
907           l2cu_send_peer_credit_based_conn_res(p_ccb, p_ci->lcids,
908                                                p_ci->l2cap_result);
909         }
910         for (int i = 0; i < p_lcb->pending_ecoc_conn_cnt; i++) {
911           uint16_t cid = p_lcb->pending_ecoc_connection_cids[i];
912           tL2C_CCB* temp_p_ccb = l2cu_find_ccb_by_cid(p_lcb, cid);
913           l2cu_release_ccb(temp_p_ccb);
914         }
915 
916         p_lcb->pending_ecoc_conn_cnt = 0;
917         memset(p_lcb->pending_ecoc_connection_cids, 0,
918                L2CAP_CREDIT_BASED_MAX_CIDS);
919       }
920       break;
921     case L2CEVT_L2CA_CONNECT_RSP_NEG:
922       p_ci = (tL2C_CONN_INFO*)p_data;
923       if (p_ccb->p_lcb->transport == BT_TRANSPORT_LE)
924         l2cble_credit_based_conn_res(p_ccb, p_ci->l2cap_result);
925       else
926         l2cu_send_peer_connect_rsp(p_ccb, p_ci->l2cap_result,
927                                    p_ci->l2cap_status);
928       l2cu_release_ccb(p_ccb);
929       break;
930 
931     case L2CEVT_TIMEOUT:
932       l2cu_send_peer_connect_rsp(p_ccb, L2CAP_CONN_NO_PSM, 0);
933       LOG_DEBUG("Calling Disconnect_Ind_Cb(), CID: 0x%04x  No Conf Needed",
934                 p_ccb->local_cid);
935       l2cu_release_ccb(p_ccb);
936       (*disconnect_ind)(local_cid, false);
937       break;
938 
939     case L2CEVT_L2CA_DATA_WRITE: /* Upper layer data to send */
940     case L2CEVT_L2CAP_DATA:      /* Peer data packet rcvd    */
941       osi_free(p_data);
942       break;
943 
944     case L2CEVT_L2CA_DISCONNECT_REQ: /* Upper wants to disconnect */
945       l2cu_send_peer_disc_req(p_ccb);
946       p_ccb->chnl_state = CST_W4_L2CAP_DISCONNECT_RSP;
947       alarm_set_on_mloop(p_ccb->l2c_ccb_timer, L2CAP_CHNL_DISCONNECT_TIMEOUT_MS,
948                          l2c_ccb_timer_timeout, p_ccb);
949       break;
950 
951     case L2CEVT_L2CAP_INFO_RSP:
952       /* We have feature info, so now give the upper layer connect IND */
953       alarm_set_on_mloop(p_ccb->l2c_ccb_timer, L2CAP_CHNL_CONNECT_TIMEOUT_MS,
954                          l2c_ccb_timer_timeout, p_ccb);
955       LOG_DEBUG("Calling Connect_Ind_Cb(), CID: 0x%04x", p_ccb->local_cid);
956 
957       l2c_csm_send_connect_rsp(p_ccb);
958       l2c_csm_send_config_req(p_ccb);
959       break;
960     default:
961       LOG_ERROR("Handling unexpected event:%s", l2c_csm_get_event_name(event));
962   }
963   LOG_VERBOSE("Exit chnl_state=%s [%d], event=%s [%d]",
964               channel_state_text(p_ccb->chnl_state).c_str(), p_ccb->chnl_state,
965               l2c_csm_get_event_name(event), event);
966 }
967 
968 /*******************************************************************************
969  *
970  * Function         l2c_csm_config
971  *
972  * Description      This function handles events when the channel is in
973  *                  CONFIG state.
974  *
975  * Returns          void
976  *
977  ******************************************************************************/
l2c_csm_config(tL2C_CCB * p_ccb,tL2CEVT event,void * p_data)978 static void l2c_csm_config(tL2C_CCB* p_ccb, tL2CEVT event, void* p_data) {
979   tL2CAP_CFG_INFO* p_cfg = (tL2CAP_CFG_INFO*)p_data;
980   tL2CA_DISCONNECT_IND_CB* disconnect_ind =
981       p_ccb->p_rcb->api.pL2CA_DisconnectInd_Cb;
982   uint16_t local_cid = p_ccb->local_cid;
983   uint8_t cfg_result;
984   tL2C_LCB* p_lcb = p_ccb->p_lcb;
985   tL2C_CCB* temp_p_ccb;
986   tL2CAP_LE_CFG_INFO* p_le_cfg = (tL2CAP_LE_CFG_INFO*)p_data;
987 
988   LOG_DEBUG("LCID: 0x%04x  st: CONFIG  evt: %s", p_ccb->local_cid,
989             l2c_csm_get_event_name(event));
990 
991   switch (event) {
992     case L2CEVT_LP_DISCONNECT_IND: /* Link was disconnected */
993       LOG_DEBUG("Calling Disconnect_Ind_Cb(), CID: 0x%04x  No Conf Needed",
994                 p_ccb->local_cid);
995       l2cu_release_ccb(p_ccb);
996       (*disconnect_ind)(local_cid, false);
997       break;
998 
999     case L2CEVT_L2CAP_CREDIT_BASED_RECONFIG_REQ:
1000       /* For ecoc reconfig is handled below in l2c_ble. In case of success
1001        * let us notify upper layer about the reconfig
1002        */
1003       LOG_DEBUG("Calling LeReconfigCompleted_Cb(), CID: 0x%04x",
1004                 p_ccb->local_cid);
1005 
1006       (*p_ccb->p_rcb->api.pL2CA_CreditBasedReconfigCompleted_Cb)(
1007           p_lcb->remote_bd_addr, p_ccb->local_cid, false, p_le_cfg);
1008       break;
1009     case L2CEVT_L2CAP_CONFIG_REQ: /* Peer config request   */
1010       cfg_result = l2cu_process_peer_cfg_req(p_ccb, p_cfg);
1011       if (cfg_result == L2CAP_PEER_CFG_OK) {
1012         LOG_DEBUG("Calling Config_Req_Cb(), CID: 0x%04x, C-bit %d",
1013                   p_ccb->local_cid, (p_cfg->flags & L2CAP_CFG_FLAGS_MASK_CONT));
1014         l2c_csm_send_config_rsp_ok(p_ccb,
1015                                    p_cfg->flags & L2CAP_CFG_FLAGS_MASK_CONT);
1016         if (p_ccb->config_done & OB_CFG_DONE) {
1017           if (p_ccb->remote_config_rsp_result == L2CAP_CFG_OK) {
1018             l2c_csm_indicate_connection_open(p_ccb);
1019           } else {
1020             if (p_ccb->connection_initiator == L2CAP_INITIATOR_LOCAL) {
1021               (*p_ccb->p_rcb->api.pL2CA_Error_Cb)(p_ccb->local_cid,
1022                                                   L2CAP_CFG_FAILED_NO_REASON);
1023               bluetooth::shim::CountCounterMetrics(
1024                   android::bluetooth::CodePathCounterKeyEnum::
1025                       L2CAP_CONFIG_REQ_FAILURE,
1026                   1);
1027             }
1028           }
1029         }
1030       } else if (cfg_result == L2CAP_PEER_CFG_DISCONNECT) {
1031         /* Disconnect if channels are incompatible */
1032         LOG_DEBUG("incompatible configurations disconnect");
1033         l2cu_disconnect_chnl(p_ccb);
1034       } else /* Return error to peer so it can renegotiate if possible */
1035       {
1036         LOG_DEBUG("incompatible configurations trying reconfig");
1037         l2cu_send_peer_config_rsp(p_ccb, p_cfg);
1038       }
1039       break;
1040 
1041     case L2CEVT_L2CAP_CREDIT_BASED_RECONFIG_RSP:
1042       p_ccb->config_done |= OB_CFG_DONE;
1043       p_ccb->config_done |= RECONFIG_FLAG;
1044       p_ccb->chnl_state = CST_OPEN;
1045       alarm_cancel(p_ccb->l2c_ccb_timer);
1046 
1047       LOG_DEBUG("Calling Config_Rsp_Cb(), CID: 0x%04x", p_ccb->local_cid);
1048 
1049       p_ccb->p_rcb->api.pL2CA_CreditBasedReconfigCompleted_Cb(
1050           p_lcb->remote_bd_addr, p_ccb->local_cid, true, p_le_cfg);
1051 
1052       break;
1053     case L2CEVT_L2CAP_CONFIG_RSP: /* Peer config response  */
1054       l2cu_process_peer_cfg_rsp(p_ccb, p_cfg);
1055 
1056       /* TBD: When config options grow beyong minimum MTU (48 bytes)
1057        *      logic needs to be added to handle responses with
1058        *      continuation bit set in flags field.
1059        *       1. Send additional config request out until C-bit is cleared in
1060        * response
1061        */
1062       p_ccb->config_done |= OB_CFG_DONE;
1063 
1064       if (p_ccb->config_done & IB_CFG_DONE) {
1065         /* Verify two sides are in compatible modes before continuing */
1066         if (p_ccb->our_cfg.fcr.mode != p_ccb->peer_cfg.fcr.mode) {
1067           l2cu_send_peer_disc_req(p_ccb);
1068           LOG_WARN(
1069               "Calling Disconnect_Ind_Cb(Incompatible CFG), CID: "
1070               "0x%04x  No Conf Needed",
1071               p_ccb->local_cid);
1072           l2cu_release_ccb(p_ccb);
1073           (*disconnect_ind)(local_cid, false);
1074           break;
1075         }
1076 
1077         p_ccb->config_done |= RECONFIG_FLAG;
1078         p_ccb->chnl_state = CST_OPEN;
1079         l2c_link_adjust_chnl_allocation();
1080         alarm_cancel(p_ccb->l2c_ccb_timer);
1081 
1082         /* If using eRTM and waiting for an ACK, restart the ACK timer */
1083         if (p_ccb->fcrb.wait_ack) l2c_fcr_start_timer(p_ccb);
1084 
1085         /*
1086          ** check p_ccb->our_cfg.fcr.mon_tout and
1087          *p_ccb->our_cfg.fcr.rtrans_tout
1088          ** we may set them to zero when sending config request during
1089          *renegotiation
1090          */
1091         if ((p_ccb->our_cfg.fcr.mode == L2CAP_FCR_ERTM_MODE) &&
1092             ((p_ccb->our_cfg.fcr.mon_tout == 0) ||
1093              (p_ccb->our_cfg.fcr.rtrans_tout))) {
1094           l2c_fcr_adj_monitor_retran_timeout(p_ccb);
1095         }
1096 
1097         /* See if we can forward anything on the hold queue */
1098         if (!fixed_queue_is_empty(p_ccb->xmit_hold_q)) {
1099           l2c_link_check_send_pkts(p_ccb->p_lcb, 0, NULL);
1100         }
1101       }
1102 
1103       if (p_ccb->config_done & RECONFIG_FLAG) {
1104         // Notify only once
1105         bluetooth::shim::GetSnoopLogger()->SetL2capChannelOpen(
1106             p_ccb->p_lcb->Handle(), p_ccb->local_cid, p_ccb->remote_cid,
1107             p_ccb->p_rcb->psm,
1108             p_ccb->peer_cfg.fcr.mode != L2CAP_FCR_BASIC_MODE);
1109       }
1110 
1111       LOG_DEBUG("Calling Config_Rsp_Cb(), CID: 0x%04x", p_ccb->local_cid);
1112       p_ccb->remote_config_rsp_result = p_cfg->result;
1113       if (p_ccb->config_done & IB_CFG_DONE) {
1114         l2c_csm_indicate_connection_open(p_ccb);
1115       }
1116       break;
1117 
1118     case L2CEVT_L2CAP_CONFIG_RSP_NEG: /* Peer config error rsp */
1119                                       /* Disable the Timer */
1120       alarm_cancel(p_ccb->l2c_ccb_timer);
1121 
1122       /* If failure was channel mode try to renegotiate */
1123       if (!l2c_fcr_renegotiate_chan(p_ccb, p_cfg)) {
1124         LOG_DEBUG("Calling Config_Rsp_Cb(), CID: 0x%04x, Failure: %d",
1125                   p_ccb->local_cid, p_cfg->result);
1126         if (p_ccb->connection_initiator == L2CAP_INITIATOR_LOCAL) {
1127           (*p_ccb->p_rcb->api.pL2CA_Error_Cb)(p_ccb->local_cid,
1128                                               L2CAP_CFG_FAILED_NO_REASON);
1129           bluetooth::shim::CountCounterMetrics(
1130               android::bluetooth::CodePathCounterKeyEnum::L2CAP_CONFIG_RSP_NEG,
1131               1);
1132         }
1133       }
1134       break;
1135 
1136     case L2CEVT_L2CAP_DISCONNECT_REQ: /* Peer disconnected request */
1137       alarm_set_on_mloop(p_ccb->l2c_ccb_timer, L2CAP_CHNL_DISCONNECT_TIMEOUT_MS,
1138                          l2c_ccb_timer_timeout, p_ccb);
1139       p_ccb->chnl_state = CST_W4_L2CA_DISCONNECT_RSP;
1140       LOG_DEBUG("Calling Disconnect_Ind_Cb(), CID: 0x%04x  Conf Needed",
1141                 p_ccb->local_cid);
1142       (*p_ccb->p_rcb->api.pL2CA_DisconnectInd_Cb)(p_ccb->local_cid, true);
1143       l2c_csm_send_disconnect_rsp(p_ccb);
1144       break;
1145 
1146     case L2CEVT_L2CA_CREDIT_BASED_RECONFIG_REQ:
1147       l2cu_send_credit_based_reconfig_req(p_ccb, (tL2CAP_LE_CFG_INFO*)p_data);
1148       alarm_set_on_mloop(p_ccb->l2c_ccb_timer, L2CAP_CHNL_CFG_TIMEOUT_MS,
1149                          l2c_ccb_timer_timeout, p_ccb);
1150       break;
1151     case L2CEVT_L2CA_CONFIG_REQ: /* Upper layer config req   */
1152       l2cu_process_our_cfg_req(p_ccb, p_cfg);
1153       l2cu_send_peer_config_req(p_ccb, p_cfg);
1154       alarm_set_on_mloop(p_ccb->l2c_ccb_timer, L2CAP_CHNL_CFG_TIMEOUT_MS,
1155                          l2c_ccb_timer_timeout, p_ccb);
1156       break;
1157 
1158     case L2CEVT_L2CA_CONFIG_RSP: /* Upper layer config rsp   */
1159       l2cu_process_our_cfg_rsp(p_ccb, p_cfg);
1160 
1161       p_ccb->config_done |= IB_CFG_DONE;
1162 
1163       if (p_ccb->config_done & OB_CFG_DONE) {
1164         /* Verify two sides are in compatible modes before continuing */
1165         if (p_ccb->our_cfg.fcr.mode != p_ccb->peer_cfg.fcr.mode) {
1166           l2cu_send_peer_disc_req(p_ccb);
1167           LOG_WARN(
1168               "Calling Disconnect_Ind_Cb(Incompatible CFG), CID: "
1169               "0x%04x  No Conf Needed",
1170               p_ccb->local_cid);
1171           l2cu_release_ccb(p_ccb);
1172           (*disconnect_ind)(local_cid, false);
1173           break;
1174         }
1175 
1176         p_ccb->config_done |= RECONFIG_FLAG;
1177         p_ccb->chnl_state = CST_OPEN;
1178         l2c_link_adjust_chnl_allocation();
1179         alarm_cancel(p_ccb->l2c_ccb_timer);
1180       }
1181 
1182       l2cu_send_peer_config_rsp(p_ccb, p_cfg);
1183 
1184       /* If using eRTM and waiting for an ACK, restart the ACK timer */
1185       if (p_ccb->fcrb.wait_ack) l2c_fcr_start_timer(p_ccb);
1186 
1187       if (p_ccb->config_done & RECONFIG_FLAG) {
1188         // Notify only once
1189         bluetooth::shim::GetSnoopLogger()->SetL2capChannelOpen(
1190             p_ccb->p_lcb->Handle(), p_ccb->local_cid, p_ccb->remote_cid,
1191             p_ccb->p_rcb->psm,
1192             p_ccb->peer_cfg.fcr.mode != L2CAP_FCR_BASIC_MODE);
1193       }
1194 
1195       /* See if we can forward anything on the hold queue */
1196       if ((p_ccb->chnl_state == CST_OPEN) &&
1197           (!fixed_queue_is_empty(p_ccb->xmit_hold_q))) {
1198         l2c_link_check_send_pkts(p_ccb->p_lcb, 0, NULL);
1199       }
1200       break;
1201 
1202     case L2CEVT_L2CA_DISCONNECT_REQ: /* Upper wants to disconnect */
1203       l2cu_send_peer_disc_req(p_ccb);
1204       p_ccb->chnl_state = CST_W4_L2CAP_DISCONNECT_RSP;
1205       alarm_set_on_mloop(p_ccb->l2c_ccb_timer, L2CAP_CHNL_DISCONNECT_TIMEOUT_MS,
1206                          l2c_ccb_timer_timeout, p_ccb);
1207       break;
1208 
1209     case L2CEVT_L2CAP_DATA: /* Peer data packet rcvd    */
1210       LOG_DEBUG("Calling DataInd_Cb(), CID: 0x%04x", p_ccb->local_cid);
1211       if (p_ccb->local_cid >= L2CAP_FIRST_FIXED_CHNL &&
1212           p_ccb->local_cid <= L2CAP_LAST_FIXED_CHNL) {
1213         if (p_ccb->local_cid < L2CAP_BASE_APPL_CID) {
1214           if (l2cb.fixed_reg[p_ccb->local_cid - L2CAP_FIRST_FIXED_CHNL]
1215                   .pL2CA_FixedData_Cb != nullptr) {
1216             p_ccb->metrics.rx(static_cast<BT_HDR*>(p_data)->len);
1217             (*l2cb.fixed_reg[p_ccb->local_cid - L2CAP_FIRST_FIXED_CHNL]
1218                   .pL2CA_FixedData_Cb)(p_ccb->local_cid,
1219                                        p_ccb->p_lcb->remote_bd_addr,
1220                                        (BT_HDR*)p_data);
1221           } else {
1222             if (p_data != nullptr) osi_free_and_reset(&p_data);
1223           }
1224           break;
1225         }
1226       }
1227       if (p_data) p_ccb->metrics.rx(static_cast<BT_HDR*>(p_data)->len);
1228       (*p_ccb->p_rcb->api.pL2CA_DataInd_Cb)(p_ccb->local_cid, (BT_HDR*)p_data);
1229       break;
1230 
1231     case L2CEVT_L2CA_DATA_WRITE: /* Upper layer data to send */
1232       if (p_ccb->config_done & OB_CFG_DONE)
1233         l2c_enqueue_peer_data(p_ccb, (BT_HDR*)p_data);
1234       else
1235         osi_free(p_data);
1236       break;
1237 
1238     case L2CEVT_TIMEOUT:
1239       if (p_ccb->ecoc) {
1240         for (temp_p_ccb = p_lcb->ccb_queue.p_first_ccb; temp_p_ccb;
1241              temp_p_ccb = temp_p_ccb->p_next_ccb) {
1242           if ((temp_p_ccb->in_use) && (temp_p_ccb->reconfig_started)) {
1243             (*temp_p_ccb->p_rcb->api.pL2CA_DisconnectInd_Cb)(
1244                 temp_p_ccb->local_cid, false);
1245             l2cu_release_ccb(temp_p_ccb);
1246           }
1247         }
1248 
1249         acl_disconnect_from_handle(
1250             p_ccb->p_lcb->Handle(), HCI_ERR_CONN_CAUSE_LOCAL_HOST,
1251             "stack::l2cap::l2c_csm::l2c_csm_config timeout");
1252         return;
1253       }
1254 
1255       l2cu_send_peer_disc_req(p_ccb);
1256       LOG_DEBUG("Calling Disconnect_Ind_Cb(), CID: 0x%04x  No Conf Needed",
1257                 p_ccb->local_cid);
1258       l2cu_release_ccb(p_ccb);
1259       (*disconnect_ind)(local_cid, false);
1260       break;
1261     default:
1262       LOG_ERROR("Handling unexpected event:%s", l2c_csm_get_event_name(event));
1263   }
1264   LOG_VERBOSE("Exit chnl_state=%s [%d], event=%s [%d]",
1265               channel_state_text(p_ccb->chnl_state).c_str(), p_ccb->chnl_state,
1266               l2c_csm_get_event_name(event), event);
1267 }
1268 
1269 /*******************************************************************************
1270  *
1271  * Function         l2c_csm_open
1272  *
1273  * Description      This function handles events when the channel is in
1274  *                  OPEN state.
1275  *
1276  * Returns          void
1277  *
1278  ******************************************************************************/
l2c_csm_open(tL2C_CCB * p_ccb,tL2CEVT event,void * p_data)1279 static void l2c_csm_open(tL2C_CCB* p_ccb, tL2CEVT event, void* p_data) {
1280   uint16_t local_cid = p_ccb->local_cid;
1281   tL2CAP_CFG_INFO* p_cfg;
1282   tL2C_CHNL_STATE tempstate;
1283   uint8_t tempcfgdone;
1284   uint8_t cfg_result = L2CAP_PEER_CFG_DISCONNECT;
1285   uint16_t credit = 0;
1286   tL2CAP_LE_CFG_INFO* p_le_cfg = (tL2CAP_LE_CFG_INFO*)p_data;
1287 
1288   LOG_VERBOSE("LCID: 0x%04x  st: OPEN  evt: %s", p_ccb->local_cid,
1289               l2c_csm_get_event_name(event));
1290 
1291   switch (event) {
1292     case L2CEVT_LP_DISCONNECT_IND: /* Link was disconnected */
1293       LOG_DEBUG("Calling Disconnect_Ind_Cb(), CID: 0x%04x  No Conf Needed",
1294                 p_ccb->local_cid);
1295       l2cu_release_ccb(p_ccb);
1296       if (p_ccb->p_rcb)
1297         (*p_ccb->p_rcb->api.pL2CA_DisconnectInd_Cb)(local_cid, false);
1298       break;
1299 
1300     case L2CEVT_L2CAP_CREDIT_BASED_RECONFIG_REQ:
1301       /* For ecoc reconfig is handled below in l2c_ble. In case of success
1302        * let us notify upper layer about the reconfig
1303        */
1304       if (p_le_cfg) {
1305         LOG_DEBUG("Calling LeReconfigCompleted_Cb(), CID: 0x%04x",
1306                   p_ccb->local_cid);
1307         (*p_ccb->p_rcb->api.pL2CA_CreditBasedReconfigCompleted_Cb)(
1308             p_ccb->p_lcb->remote_bd_addr, p_ccb->local_cid, false, p_le_cfg);
1309       }
1310       break;
1311 
1312     case L2CEVT_L2CAP_CONFIG_REQ: /* Peer config request   */
1313       p_cfg = (tL2CAP_CFG_INFO*)p_data;
1314 
1315       tempstate = p_ccb->chnl_state;
1316       tempcfgdone = p_ccb->config_done;
1317       p_ccb->chnl_state = CST_CONFIG;
1318       // clear cached configuration in case reconfig takes place later
1319       p_ccb->peer_cfg.mtu_present = false;
1320       p_ccb->peer_cfg.flush_to_present = false;
1321       p_ccb->peer_cfg.qos_present = false;
1322       p_ccb->config_done &= ~IB_CFG_DONE;
1323 
1324       alarm_set_on_mloop(p_ccb->l2c_ccb_timer, L2CAP_CHNL_CFG_TIMEOUT_MS,
1325                          l2c_ccb_timer_timeout, p_ccb);
1326       if (p_cfg) {
1327         cfg_result = l2cu_process_peer_cfg_req(p_ccb, p_cfg);
1328       }
1329       if (cfg_result == L2CAP_PEER_CFG_OK) {
1330         (*p_ccb->p_rcb->api.pL2CA_ConfigInd_Cb)(p_ccb->local_cid, p_cfg);
1331         l2c_csm_send_config_rsp_ok(p_ccb,
1332                                    p_cfg->flags & L2CAP_CFG_FLAGS_MASK_CONT);
1333       }
1334 
1335       /* Error in config parameters: reset state and config flag */
1336       else if (cfg_result == L2CAP_PEER_CFG_UNACCEPTABLE) {
1337         alarm_cancel(p_ccb->l2c_ccb_timer);
1338         p_ccb->chnl_state = tempstate;
1339         p_ccb->config_done = tempcfgdone;
1340         l2cu_send_peer_config_rsp(p_ccb, p_cfg);
1341       } else /* L2CAP_PEER_CFG_DISCONNECT */
1342       {
1343         /* Disconnect if channels are incompatible
1344          * Note this should not occur if reconfigure
1345          * since this should have never passed original config.
1346          */
1347         l2cu_disconnect_chnl(p_ccb);
1348       }
1349       break;
1350 
1351     case L2CEVT_L2CAP_DISCONNECT_REQ: /* Peer disconnected request */
1352       if (p_ccb->p_lcb->transport != BT_TRANSPORT_LE) {
1353         if (!BTM_SetLinkPolicyActiveMode(p_ccb->p_lcb->remote_bd_addr)) {
1354           LOG_WARN("Unable to set link policy active");
1355         }
1356       }
1357 
1358       p_ccb->chnl_state = CST_W4_L2CA_DISCONNECT_RSP;
1359       alarm_set_on_mloop(p_ccb->l2c_ccb_timer, L2CAP_CHNL_DISCONNECT_TIMEOUT_MS,
1360                          l2c_ccb_timer_timeout, p_ccb);
1361       LOG_DEBUG("Calling Disconnect_Ind_Cb(), CID: 0x%04x  Conf Needed",
1362                 p_ccb->local_cid);
1363       (*p_ccb->p_rcb->api.pL2CA_DisconnectInd_Cb)(p_ccb->local_cid, true);
1364       l2c_csm_send_disconnect_rsp(p_ccb);
1365       break;
1366 
1367     case L2CEVT_L2CAP_DATA: /* Peer data packet rcvd    */
1368       if (p_data && (p_ccb->p_rcb) && (p_ccb->p_rcb->api.pL2CA_DataInd_Cb)) {
1369         p_ccb->metrics.rx(static_cast<BT_HDR*>(p_data)->len);
1370         (*p_ccb->p_rcb->api.pL2CA_DataInd_Cb)(p_ccb->local_cid,
1371                                               (BT_HDR*)p_data);
1372       }
1373       break;
1374 
1375     case L2CEVT_L2CA_DISCONNECT_REQ: /* Upper wants to disconnect */
1376       if (p_ccb->p_lcb->transport != BT_TRANSPORT_LE) {
1377         /* Make sure we are not in sniff mode */
1378         if (!BTM_SetLinkPolicyActiveMode(p_ccb->p_lcb->remote_bd_addr)) {
1379           LOG_WARN("Unable to set link policy active");
1380         }
1381       }
1382 
1383       if (p_ccb->p_lcb->transport == BT_TRANSPORT_LE)
1384         l2cble_send_peer_disc_req(p_ccb);
1385       else
1386         l2cu_send_peer_disc_req(p_ccb);
1387 
1388       p_ccb->chnl_state = CST_W4_L2CAP_DISCONNECT_RSP;
1389       alarm_set_on_mloop(p_ccb->l2c_ccb_timer, L2CAP_CHNL_DISCONNECT_TIMEOUT_MS,
1390                          l2c_ccb_timer_timeout, p_ccb);
1391       break;
1392 
1393     case L2CEVT_L2CA_DATA_WRITE: /* Upper layer data to send */
1394       if (p_data) {
1395         l2c_enqueue_peer_data(p_ccb, (BT_HDR*)p_data);
1396         l2c_link_check_send_pkts(p_ccb->p_lcb, 0, NULL);
1397       }
1398       break;
1399 
1400     case L2CEVT_L2CA_CREDIT_BASED_RECONFIG_REQ:
1401       p_ccb->chnl_state = CST_CONFIG;
1402       p_ccb->config_done &= ~OB_CFG_DONE;
1403 
1404       if (p_data) {
1405         l2cu_send_credit_based_reconfig_req(p_ccb, (tL2CAP_LE_CFG_INFO*)p_data);
1406 
1407         alarm_set_on_mloop(p_ccb->l2c_ccb_timer, L2CAP_CHNL_CFG_TIMEOUT_MS,
1408                            l2c_ccb_timer_timeout, p_ccb);
1409       }
1410       break;
1411 
1412     case L2CEVT_L2CA_CONFIG_REQ: /* Upper layer config req   */
1413       LOG_ERROR(
1414           "Dropping L2CAP re-config request because there is no usage and "
1415           "should not be invoked");
1416       break;
1417 
1418     case L2CEVT_TIMEOUT:
1419       /* Process the monitor/retransmission time-outs in flow control/retrans
1420        * mode */
1421       if (p_ccb->peer_cfg.fcr.mode == L2CAP_FCR_ERTM_MODE)
1422         l2c_fcr_proc_tout(p_ccb);
1423       break;
1424 
1425     case L2CEVT_ACK_TIMEOUT:
1426       l2c_fcr_proc_ack_tout(p_ccb);
1427       break;
1428 
1429     case L2CEVT_L2CA_SEND_FLOW_CONTROL_CREDIT:
1430       if (p_data) {
1431         LOG_DEBUG("Sending credit");
1432         credit = *(uint16_t*)p_data;
1433         l2cble_send_flow_control_credit(p_ccb, credit);
1434       }
1435       break;
1436 
1437     case L2CEVT_L2CAP_RECV_FLOW_CONTROL_CREDIT:
1438       if (p_data) {
1439         credit = *(uint16_t*)p_data;
1440         LOG_DEBUG("Credits received %d", credit);
1441         if ((p_ccb->peer_conn_cfg.credits + credit) > L2CAP_LE_CREDIT_MAX) {
1442           /* we have received credits more than max coc credits,
1443            * so disconnecting the Le Coc Channel
1444            */
1445           l2cble_send_peer_disc_req(p_ccb);
1446         } else {
1447           p_ccb->peer_conn_cfg.credits += credit;
1448           l2c_link_check_send_pkts(p_ccb->p_lcb, 0, NULL);
1449         }
1450       }
1451       break;
1452     default:
1453       LOG_ERROR("Handling unexpected event:%s", l2c_csm_get_event_name(event));
1454   }
1455   LOG_VERBOSE("Exit chnl_state=%s [%d], event=%s [%d]",
1456               channel_state_text(p_ccb->chnl_state).c_str(), p_ccb->chnl_state,
1457               l2c_csm_get_event_name(event), event);
1458 }
1459 
1460 /*******************************************************************************
1461  *
1462  * Function         l2c_csm_w4_l2cap_disconnect_rsp
1463  *
1464  * Description      This function handles events when the channel is in
1465  *                  CST_W4_L2CAP_DISCONNECT_RSP state.
1466  *
1467  * Returns          void
1468  *
1469  ******************************************************************************/
l2c_csm_w4_l2cap_disconnect_rsp(tL2C_CCB * p_ccb,tL2CEVT event,void * p_data)1470 static void l2c_csm_w4_l2cap_disconnect_rsp(tL2C_CCB* p_ccb, tL2CEVT event,
1471                                             void* p_data) {
1472   tL2CA_DISCONNECT_CFM_CB* disconnect_cfm =
1473       p_ccb->p_rcb->api.pL2CA_DisconnectCfm_Cb;
1474   uint16_t local_cid = p_ccb->local_cid;
1475 
1476   LOG_DEBUG("LCID: 0x%04x  st: W4_L2CAP_DISC_RSP  evt: %s", p_ccb->local_cid,
1477             l2c_csm_get_event_name(event));
1478 
1479   switch (event) {
1480     case L2CEVT_L2CAP_DISCONNECT_RSP: /* Peer disconnect response */
1481       l2cu_release_ccb(p_ccb);
1482       if (disconnect_cfm != nullptr) {
1483         (*disconnect_cfm)(local_cid, L2CAP_DISC_OK);
1484       }
1485       break;
1486 
1487     case L2CEVT_L2CAP_DISCONNECT_REQ: /* Peer disconnect request  */
1488       l2cu_send_peer_disc_rsp(p_ccb->p_lcb, p_ccb->remote_id, p_ccb->local_cid,
1489                               p_ccb->remote_cid);
1490       l2cu_release_ccb(p_ccb);
1491       if (disconnect_cfm != nullptr) {
1492         (*disconnect_cfm)(local_cid, L2CAP_DISC_OK);
1493       }
1494       break;
1495 
1496     case L2CEVT_LP_DISCONNECT_IND: /* Link was disconnected */
1497     case L2CEVT_TIMEOUT:           /* Timeout */
1498       l2cu_release_ccb(p_ccb);
1499       if (disconnect_cfm != nullptr) {
1500         (*disconnect_cfm)(local_cid, L2CAP_DISC_TIMEOUT);
1501       }
1502 
1503       break;
1504 
1505     case L2CEVT_L2CAP_DATA:      /* Peer data packet rcvd    */
1506     case L2CEVT_L2CA_DATA_WRITE: /* Upper layer data to send */
1507       osi_free(p_data);
1508       break;
1509     default:
1510       LOG_ERROR("Handling unexpected event:%s", l2c_csm_get_event_name(event));
1511   }
1512   LOG_VERBOSE("Exit chnl_state=%s [%d], event=%s [%d]",
1513               channel_state_text(p_ccb->chnl_state).c_str(), p_ccb->chnl_state,
1514               l2c_csm_get_event_name(event), event);
1515 }
1516 
1517 /*******************************************************************************
1518  *
1519  * Function         l2c_csm_w4_l2ca_disconnect_rsp
1520  *
1521  * Description      This function handles events when the channel is in
1522  *                  CST_W4_L2CA_DISCONNECT_RSP state.
1523  *
1524  * Returns          void
1525  *
1526  ******************************************************************************/
l2c_csm_w4_l2ca_disconnect_rsp(tL2C_CCB * p_ccb,tL2CEVT event,void * p_data)1527 static void l2c_csm_w4_l2ca_disconnect_rsp(tL2C_CCB* p_ccb, tL2CEVT event,
1528                                            void* p_data) {
1529   tL2CA_DISCONNECT_IND_CB* disconnect_ind =
1530       p_ccb->p_rcb->api.pL2CA_DisconnectInd_Cb;
1531   uint16_t local_cid = p_ccb->local_cid;
1532 
1533   LOG_DEBUG("LCID: 0x%04x  st: W4_L2CA_DISC_RSP  evt: %s", p_ccb->local_cid,
1534             l2c_csm_get_event_name(event));
1535 
1536   switch (event) {
1537     case L2CEVT_LP_DISCONNECT_IND: /* Link was disconnected */
1538       LOG_DEBUG("Calling Disconnect_Ind_Cb(), CID: 0x%04x  No Conf Needed",
1539                 p_ccb->local_cid);
1540       l2cu_release_ccb(p_ccb);
1541       (*disconnect_ind)(local_cid, false);
1542       break;
1543 
1544     case L2CEVT_TIMEOUT:
1545       l2cu_send_peer_disc_rsp(p_ccb->p_lcb, p_ccb->remote_id, p_ccb->local_cid,
1546                               p_ccb->remote_cid);
1547       LOG_DEBUG("Calling Disconnect_Ind_Cb(), CID: 0x%04x  No Conf Needed",
1548                 p_ccb->local_cid);
1549       l2cu_release_ccb(p_ccb);
1550       (*disconnect_ind)(local_cid, false);
1551       break;
1552 
1553     case L2CEVT_L2CA_DISCONNECT_REQ: /* Upper disconnect request */
1554     case L2CEVT_L2CA_DISCONNECT_RSP: /* Upper disconnect response */
1555       l2cu_send_peer_disc_rsp(p_ccb->p_lcb, p_ccb->remote_id, p_ccb->local_cid,
1556                               p_ccb->remote_cid);
1557       l2cu_release_ccb(p_ccb);
1558       break;
1559 
1560     case L2CEVT_L2CAP_DATA:      /* Peer data packet rcvd    */
1561     case L2CEVT_L2CA_DATA_WRITE: /* Upper layer data to send */
1562       osi_free(p_data);
1563       break;
1564     default:
1565       LOG_ERROR("Handling unexpected event:%s", l2c_csm_get_event_name(event));
1566   }
1567   LOG_VERBOSE("Exit chnl_state=%s [%d], event=%s [%d]",
1568               channel_state_text(p_ccb->chnl_state).c_str(), p_ccb->chnl_state,
1569               l2c_csm_get_event_name(event), event);
1570 }
1571 
1572 /*******************************************************************************
1573  *
1574  * Function         l2c_csm_get_event_name
1575  *
1576  * Description      This function returns the event name.
1577  *
1578  * NOTE             conditionally compiled to save memory.
1579  *
1580  * Returns          pointer to the name
1581  *
1582  ******************************************************************************/
l2c_csm_get_event_name(tL2CEVT event)1583 static const char* l2c_csm_get_event_name(tL2CEVT event) {
1584   switch (event) {
1585     case L2CEVT_LP_CONNECT_CFM: /* Lower layer connect confirm          */
1586       return ("LOWER_LAYER_CONNECT_CFM");
1587     case L2CEVT_LP_CONNECT_CFM_NEG: /* Lower layer connect confirm (failed) */
1588       return ("LOWER_LAYER_CONNECT_CFM_NEG");
1589     case L2CEVT_LP_CONNECT_IND: /* Lower layer connect indication       */
1590       return ("LOWER_LAYER_CONNECT_IND");
1591     case L2CEVT_LP_DISCONNECT_IND: /* Lower layer disconnect indication    */
1592       return ("LOWER_LAYER_DISCONNECT_IND");
1593 
1594     case L2CEVT_SEC_COMP: /* Security cleared successfully        */
1595       return ("SECURITY_COMPLETE");
1596     case L2CEVT_SEC_COMP_NEG: /* Security procedure failed            */
1597       return ("SECURITY_COMPLETE_NEG");
1598 
1599     case L2CEVT_L2CAP_CONNECT_REQ: /* Peer connection request              */
1600       return ("PEER_CONNECT_REQ");
1601     case L2CEVT_L2CAP_CONNECT_RSP: /* Peer connection response             */
1602       return ("PEER_CONNECT_RSP");
1603     case L2CEVT_L2CAP_CONNECT_RSP_PND: /* Peer connection response pending */
1604       return ("PEER_CONNECT_RSP_PND");
1605     case L2CEVT_L2CAP_CONNECT_RSP_NEG: /* Peer connection response (failed) */
1606       return ("PEER_CONNECT_RSP_NEG");
1607     case L2CEVT_L2CAP_CONFIG_REQ: /* Peer configuration request           */
1608       return ("PEER_CONFIG_REQ");
1609     case L2CEVT_L2CAP_CONFIG_RSP: /* Peer configuration response          */
1610       return ("PEER_CONFIG_RSP");
1611     case L2CEVT_L2CAP_CONFIG_RSP_NEG: /* Peer configuration response (failed) */
1612       return ("PEER_CONFIG_RSP_NEG");
1613     case L2CEVT_L2CAP_DISCONNECT_REQ: /* Peer disconnect request              */
1614       return ("PEER_DISCONNECT_REQ");
1615     case L2CEVT_L2CAP_DISCONNECT_RSP: /* Peer disconnect response             */
1616       return ("PEER_DISCONNECT_RSP");
1617     case L2CEVT_L2CAP_DATA: /* Peer data                            */
1618       return ("PEER_DATA");
1619 
1620     case L2CEVT_L2CA_CONNECT_REQ: /* Upper layer connect request          */
1621       return ("UPPER_LAYER_CONNECT_REQ");
1622     case L2CEVT_L2CA_CONNECT_RSP: /* Upper layer connect response         */
1623       return ("UPPER_LAYER_CONNECT_RSP");
1624     case L2CEVT_L2CA_CONNECT_RSP_NEG: /* Upper layer connect response (failed)*/
1625       return ("UPPER_LAYER_CONNECT_RSP_NEG");
1626     case L2CEVT_L2CA_CONFIG_REQ: /* Upper layer config request           */
1627       return ("UPPER_LAYER_CONFIG_REQ");
1628     case L2CEVT_L2CA_CONFIG_RSP: /* Upper layer config response          */
1629       return ("UPPER_LAYER_CONFIG_RSP");
1630     case L2CEVT_L2CA_DISCONNECT_REQ: /* Upper layer disconnect request       */
1631       return ("UPPER_LAYER_DISCONNECT_REQ");
1632     case L2CEVT_L2CA_DISCONNECT_RSP: /* Upper layer disconnect response      */
1633       return ("UPPER_LAYER_DISCONNECT_RSP");
1634     case L2CEVT_L2CA_DATA_READ: /* Upper layer data read                */
1635       return ("UPPER_LAYER_DATA_READ");
1636     case L2CEVT_L2CA_DATA_WRITE: /* Upper layer data write               */
1637       return ("UPPER_LAYER_DATA_WRITE");
1638     case L2CEVT_TIMEOUT: /* Timeout                              */
1639       return ("TIMEOUT");
1640     case L2CEVT_SEC_RE_SEND_CMD:
1641       return ("SEC_RE_SEND_CMD");
1642     case L2CEVT_L2CAP_INFO_RSP: /* Peer information response            */
1643       return ("L2CEVT_L2CAP_INFO_RSP");
1644     case L2CEVT_ACK_TIMEOUT:
1645       return ("L2CEVT_ACK_TIMEOUT");
1646     case L2CEVT_L2CA_SEND_FLOW_CONTROL_CREDIT: /* Upper layer send credit packet
1647                                                 */
1648       return ("SEND_FLOW_CONTROL_CREDIT");
1649     case L2CEVT_L2CA_CREDIT_BASED_CONNECT_REQ: /* Upper layer credit based
1650                                                   connect request */
1651       return ("SEND_CREDIT_BASED_CONNECT_REQ");
1652     case L2CEVT_L2CA_CREDIT_BASED_CONNECT_RSP: /* Upper layer credit based
1653                                                   connect response */
1654       return ("SEND_CREDIT_BASED_CONNECT_RSP");
1655     case L2CEVT_L2CA_CREDIT_BASED_CONNECT_RSP_NEG: /* Upper layer credit based
1656                                                       connect response
1657                                                       (failed)*/
1658       return ("SEND_CREDIT_BASED_CONNECT_RSP_NEG");
1659     case L2CEVT_L2CA_CREDIT_BASED_RECONFIG_REQ: /* Upper layer credit based
1660                                                    reconfig request */
1661       return ("SEND_CREDIT_BASED_RECONFIG_REQ");
1662     case L2CEVT_L2CAP_RECV_FLOW_CONTROL_CREDIT: /* Peer send credit packet */
1663       return ("RECV_FLOW_CONTROL_CREDIT");
1664     case L2CEVT_L2CAP_CREDIT_BASED_CONNECT_REQ: /* Peer send credit based
1665                                                    connect request */
1666       return ("RECV_CREDIT_BASED_CONNECT_REQ");
1667     case L2CEVT_L2CAP_CREDIT_BASED_CONNECT_RSP: /* Peer send credit based
1668                                                    connect response */
1669       return ("RECV_CREDIT_BASED_CONNECT_RSP");
1670     case L2CEVT_L2CAP_CREDIT_BASED_CONNECT_RSP_NEG: /* Peer send reject credit
1671                                                        based connect response */
1672       return ("RECV_CREDIT_BASED_CONNECT_RSP_NEG");
1673     case L2CEVT_L2CAP_CREDIT_BASED_RECONFIG_REQ: /* Peer send credit based
1674                                                     reconfig request */
1675       return ("RECV_CREDIT_BASED_RECONFIG_REQ");
1676     case L2CEVT_L2CAP_CREDIT_BASED_RECONFIG_RSP: /* Peer send credit based
1677                                                     reconfig response */
1678       return ("RECV_CREDIT_BASED_RECONFIG_RSP");
1679     default:
1680       return ("???? UNKNOWN EVENT");
1681   }
1682 }
1683 
1684 /*******************************************************************************
1685  *
1686  * Function         l2c_enqueue_peer_data
1687  *
1688  * Description      Enqueues data destined for the peer in the ccb. Handles
1689  *                  FCR segmentation and checks for congestion.
1690  *
1691  * Returns          void
1692  *
1693  ******************************************************************************/
l2c_enqueue_peer_data(tL2C_CCB * p_ccb,BT_HDR * p_buf)1694 void l2c_enqueue_peer_data(tL2C_CCB* p_ccb, BT_HDR* p_buf) {
1695   CHECK(p_ccb != nullptr);
1696 
1697   p_ccb->metrics.tx(p_buf->len);
1698 
1699   uint8_t* p;
1700 
1701   if (p_ccb->peer_cfg.fcr.mode != L2CAP_FCR_BASIC_MODE) {
1702     p_buf->event = 0;
1703   } else {
1704     /* Save the channel ID for faster counting */
1705     p_buf->event = p_ccb->local_cid;
1706 
1707     /* Step back to add the L2CAP header */
1708     p_buf->offset -= L2CAP_PKT_OVERHEAD;
1709     p_buf->len += L2CAP_PKT_OVERHEAD;
1710 
1711     /* Set the pointer to the beginning of the data */
1712     p = (uint8_t*)(p_buf + 1) + p_buf->offset;
1713 
1714     /* Now the L2CAP header */
1715     UINT16_TO_STREAM(p, p_buf->len - L2CAP_PKT_OVERHEAD);
1716     UINT16_TO_STREAM(p, p_ccb->remote_cid);
1717   }
1718 
1719   if (p_ccb->xmit_hold_q == NULL) {
1720     LOG_ERROR(
1721         "empty queue: p_ccb = %p p_ccb->in_use = %d p_ccb->chnl_state = %d "
1722         "p_ccb->local_cid = %u p_ccb->remote_cid = %u",
1723         p_ccb, p_ccb->in_use, p_ccb->chnl_state, p_ccb->local_cid,
1724         p_ccb->remote_cid);
1725   } else {
1726     fixed_queue_enqueue(p_ccb->xmit_hold_q, p_buf);
1727   }
1728 
1729   l2cu_check_channel_congestion(p_ccb);
1730 
1731   /* if new packet is higher priority than serving ccb and it is not overrun */
1732   if ((p_ccb->p_lcb->rr_pri > p_ccb->ccb_priority) &&
1733       (p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].quota > 0)) {
1734     /* send out higher priority packet */
1735     p_ccb->p_lcb->rr_pri = p_ccb->ccb_priority;
1736   }
1737 
1738   /* if we are doing a round robin scheduling, set the flag */
1739   if (p_ccb->p_lcb->link_xmit_quota == 0) l2cb.check_round_robin = true;
1740 }
1741