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