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