• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  *
3  *  Copyright 1999-2012 Broadcom Corporation
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at:
8  *
9  *  http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  ******************************************************************************/
18 
19 /******************************************************************************
20  *
21  *  This file contains the main L2CAP entry points
22  *
23  ******************************************************************************/
24 
25 #define LOG_TAG "bt_l2c_main"
26 
27 #include <string.h>
28 
29 #include "bt_target.h"
30 #include "gd/hal/snoop_logger.h"
31 #include "hcimsgs.h"  // HCID_GET_
32 #include "main/shim/shim.h"
33 #include "osi/include/allocator.h"
34 #include "osi/include/log.h"
35 #include "osi/include/osi.h"
36 #include "stack/include/bt_hdr.h"
37 #include "stack/include/l2c_api.h"
38 #include "stack/include/l2cdefs.h"
39 #include "stack/l2cap/l2c_int.h"
40 
41 /******************************************************************************/
42 /*            L O C A L    F U N C T I O N     P R O T O T Y P E S            */
43 /******************************************************************************/
44 static void process_l2cap_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len);
45 
46 /******************************************************************************/
47 /*               G L O B A L      L 2 C A P       D A T A                     */
48 /******************************************************************************/
49 tL2C_CB l2cb;
50 
51 /*******************************************************************************
52  *
53  * Function         l2c_rcv_acl_data
54  *
55  * Description      This function is called from the HCI Interface when an ACL
56  *                  data packet is received.
57  *
58  * Returns          void
59  *
60  ******************************************************************************/
l2c_rcv_acl_data(BT_HDR * p_msg)61 void l2c_rcv_acl_data(BT_HDR* p_msg) {
62   uint8_t* p = (uint8_t*)(p_msg + 1) + p_msg->offset;
63 
64   /* Extract the handle */
65   uint16_t handle;
66   STREAM_TO_UINT16(handle, p);
67   uint8_t pkt_type = HCID_GET_EVENT(handle);
68   handle = HCID_GET_HANDLE(handle);
69 
70   /* Since the HCI Transport is putting segmented packets back together, we */
71   /* should never get a valid packet with the type set to "continuation"    */
72   if (pkt_type == L2CAP_PKT_CONTINUE) {
73     L2CAP_TRACE_WARNING("L2CAP - received packet continuation");
74     osi_free(p_msg);
75     return;
76   }
77 
78   uint16_t hci_len;
79   STREAM_TO_UINT16(hci_len, p);
80   if (hci_len < L2CAP_PKT_OVERHEAD || hci_len != p_msg->len - 4) {
81     /* Remote-declared packet size must match HCI_ACL size - ACL header (4) */
82     L2CAP_TRACE_WARNING("L2CAP - got incorrect hci header");
83     osi_free(p_msg);
84     return;
85   }
86 
87   uint16_t l2cap_len, rcv_cid;
88   STREAM_TO_UINT16(l2cap_len, p);
89   STREAM_TO_UINT16(rcv_cid, p);
90 
91   /* Find the LCB based on the handle */
92   tL2C_LCB* p_lcb = l2cu_find_lcb_by_handle(handle);
93   if (!p_lcb) {
94     LOG_ERROR("L2CAP - rcvd ACL for unknown handle:%d ls:%d cid:%d", handle,
95               p_msg->layer_specific, rcv_cid);
96     osi_free(p_msg);
97     return;
98   }
99 
100   /* Update the buffer header */
101   p_msg->offset += 4;
102 
103   /* for BLE channel, always notify connection when ACL data received on the
104    * link */
105   if (p_lcb && p_lcb->transport == BT_TRANSPORT_LE &&
106       p_lcb->link_state != LST_DISCONNECTING) {
107     /* only process fixed channel data as channel open indication when link is
108      * not in disconnecting mode */
109     l2cble_notify_le_connection(p_lcb->remote_bd_addr);
110   }
111 
112   /* Find the CCB for this CID */
113   tL2C_CCB* p_ccb = NULL;
114   if (rcv_cid >= L2CAP_BASE_APPL_CID) {
115     p_ccb = l2cu_find_ccb_by_cid(p_lcb, rcv_cid);
116     if (!p_ccb) {
117       L2CAP_TRACE_WARNING("L2CAP - unknown CID: 0x%04x", rcv_cid);
118       osi_free(p_msg);
119       return;
120     }
121   }
122 
123   p_msg->len = hci_len - L2CAP_PKT_OVERHEAD;
124   p_msg->offset += L2CAP_PKT_OVERHEAD;
125 
126   if (l2cap_len != p_msg->len) {
127     L2CAP_TRACE_WARNING("L2CAP - bad length in pkt. Exp: %d  Act: %d",
128                         l2cap_len, p_msg->len);
129     osi_free(p_msg);
130     return;
131   }
132 
133   /* Send the data through the channel state machine */
134   if (rcv_cid == L2CAP_SIGNALLING_CID) {
135     process_l2cap_cmd(p_lcb, p, l2cap_len);
136     osi_free(p_msg);
137     return;
138   }
139 
140   if (rcv_cid == L2CAP_CONNECTIONLESS_CID) {
141     /* process_connectionless_data (p_lcb); */
142     osi_free(p_msg);
143     return;
144   }
145 
146   if (rcv_cid == L2CAP_BLE_SIGNALLING_CID) {
147     l2cble_process_sig_cmd(p_lcb, p, l2cap_len);
148     osi_free(p_msg);
149     return;
150   }
151 
152   if ((rcv_cid >= L2CAP_FIRST_FIXED_CHNL) &&
153       (rcv_cid <= L2CAP_LAST_FIXED_CHNL) &&
154       (l2cb.fixed_reg[rcv_cid - L2CAP_FIRST_FIXED_CHNL].pL2CA_FixedData_Cb !=
155        NULL)) {
156     /* only process fixed channel data when link is open or wait for data
157      * indication */
158     if (!p_lcb || p_lcb->link_state == LST_DISCONNECTING ||
159         !l2cu_initialize_fixed_ccb(p_lcb, rcv_cid)) {
160       osi_free(p_msg);
161       return;
162     }
163 
164     /* If no CCB for this channel, allocate one */
165     p_ccb = p_lcb->p_fixed_ccbs[rcv_cid - L2CAP_FIRST_FIXED_CHNL];
166     p_ccb->metrics.rx(p_msg->len);
167 
168     if (p_ccb->peer_cfg.fcr.mode != L2CAP_FCR_BASIC_MODE)
169       l2c_fcr_proc_pdu(p_ccb, p_msg);
170     else
171       (*l2cb.fixed_reg[rcv_cid - L2CAP_FIRST_FIXED_CHNL].pL2CA_FixedData_Cb)(
172           rcv_cid, p_lcb->remote_bd_addr, p_msg);
173     return;
174   }
175 
176   if (!p_ccb) {
177     osi_free(p_msg);
178     return;
179   }
180 
181   if (p_lcb->transport == BT_TRANSPORT_LE) {
182     l2c_lcc_proc_pdu(p_ccb, p_msg);
183 
184     /* The remote device has one less credit left */
185     --p_ccb->remote_credit_count;
186 
187     /* If the credits left on the remote device are getting low, send some */
188     if (p_ccb->remote_credit_count <= L2CA_LeCreditThreshold()) {
189       uint16_t credits = L2CA_LeCreditDefault() - p_ccb->remote_credit_count;
190       p_ccb->remote_credit_count = L2CA_LeCreditDefault();
191 
192       /* Return back credits */
193       l2c_csm_execute(p_ccb, L2CEVT_L2CA_SEND_FLOW_CONTROL_CREDIT, &credits);
194     }
195   } else {
196     /* Basic mode packets go straight to the state machine */
197     if (p_ccb->peer_cfg.fcr.mode == L2CAP_FCR_BASIC_MODE)
198       l2c_csm_execute(p_ccb, L2CEVT_L2CAP_DATA, p_msg);
199     else {
200       /* eRTM or streaming mode, so we need to validate states first */
201       if ((p_ccb->chnl_state == CST_OPEN) || (p_ccb->chnl_state == CST_CONFIG))
202         l2c_fcr_proc_pdu(p_ccb, p_msg);
203       else
204         osi_free(p_msg);
205     }
206   }
207 }
208 
209 /*******************************************************************************
210  *
211  * Function         process_l2cap_cmd
212  *
213  * Description      This function is called when a packet is received on the
214  *                  L2CAP signalling CID
215  *
216  * Returns          void
217  *
218  ******************************************************************************/
process_l2cap_cmd(tL2C_LCB * p_lcb,uint8_t * p,uint16_t pkt_len)219 static void process_l2cap_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) {
220   tL2C_CONN_INFO con_info;
221   tL2C_RCB* p_rcb;
222 
223   /* if l2cap command received in CID 1 on top of an LE link, ignore this
224    * command */
225   if (p_lcb->transport == BT_TRANSPORT_LE) {
226     LOG_INFO("Dropping data on CID 1 for LE link");
227     return;
228   }
229 
230   /* Reject the packet if it exceeds the default Signalling Channel MTU */
231   bool pkt_size_rej = false;
232   if (pkt_len > L2CAP_DEFAULT_MTU) {
233     /* Core Spec requires a single response to the first command found in a
234      * multi-command L2cap packet.  If only responses in the packet, then it
235      * will be ignored. Here we simply mark the bad packet and decide which cmd
236      * ID to reject later */
237     pkt_size_rej = true;
238     LOG_WARN("Signaling pkt_len=%d exceeds MTU size %d", pkt_len,
239              L2CAP_DEFAULT_MTU);
240   }
241 
242   uint8_t* p_next_cmd = p;
243   uint8_t* p_pkt_end = p + pkt_len;
244   uint8_t last_id = 0;
245   bool first_cmd = true;
246 
247   tL2CAP_CFG_INFO cfg_info;
248   memset(&cfg_info, 0, sizeof(cfg_info));
249 
250   /* An L2CAP packet may contain multiple commands */
251   while (true) {
252     /* Smallest command is 4 bytes */
253     p = p_next_cmd;
254     if (p > (p_pkt_end - 4)) {
255       /* Reject to the previous endpoint if reliable channel is being used.
256        * This is required in L2CAP/COS/CED/BI-02-C */
257       if (!first_cmd &&
258           (cfg_info.fcr.mode == L2CAP_FCR_BASIC_MODE ||
259            cfg_info.fcr.mode == L2CAP_FCR_ERTM_MODE) &&
260           p != p_pkt_end)
261         l2cu_send_peer_cmd_reject(p_lcb, L2CAP_CMD_REJ_NOT_UNDERSTOOD, last_id,
262                                   0, 0);
263       break;
264     }
265 
266     uint8_t cmd_code, id;
267     uint16_t cmd_len;
268     STREAM_TO_UINT8(cmd_code, p);
269     STREAM_TO_UINT8(id, p);
270     STREAM_TO_UINT16(cmd_len, p);
271 
272     last_id = id;
273     first_cmd = false;
274 
275     if (cmd_len > BT_SMALL_BUFFER_SIZE) {
276       LOG_WARN("Command size %u exceeds limit %d", cmd_len,
277                BT_SMALL_BUFFER_SIZE);
278       l2cu_send_peer_cmd_reject(p_lcb, L2CAP_CMD_REJ_MTU_EXCEEDED, id, 0, 0);
279       return;
280     }
281 
282     /* Check command length does not exceed packet length */
283     p_next_cmd = p + cmd_len;
284     if (p_next_cmd > p_pkt_end) {
285       LOG_WARN("cmd_len > pkt_len, pkt_len=%d, cmd_len=%d, code=%d", pkt_len,
286                cmd_len, cmd_code);
287       break;
288     }
289 
290     LOG_DEBUG("cmd_code: %d, id:%d, cmd_len:%d", cmd_code, id, cmd_len);
291 
292     /* Bad L2CAP packet length, look for cmd to reject */
293     if (pkt_size_rej) {
294       /* If command found rejected it and we're done, otherwise keep looking */
295       if (l2c_is_cmd_rejected(cmd_code, id, p_lcb)) {
296         LOG_WARN("Rejected command %d due to bad packet length", cmd_code);
297         return;
298       } else {
299         LOG_WARN("No need to reject command %d for bad packet len", cmd_code);
300         continue; /* Look for next cmd/response in current packet */
301       }
302     }
303 
304     switch (cmd_code) {
305       case L2CAP_CMD_REJECT:
306         uint16_t rej_reason;
307         if (p + 2 > p_next_cmd) {
308           LOG_WARN("Not enough data for L2CAP_CMD_REJECT");
309           return;
310         }
311         STREAM_TO_UINT16(rej_reason, p);
312         if (rej_reason == L2CAP_CMD_REJ_MTU_EXCEEDED) {
313           uint16_t rej_mtu;
314           if (p + 2 > p_next_cmd) {
315             LOG_WARN("Not enough data for L2CAP_CMD_REJ_MTU_EXCEEDED");
316             return;
317           }
318           STREAM_TO_UINT16(rej_mtu, p);
319           /* What to do with the MTU reject ? We have negotiated an MTU. For now
320            * we will ignore it and let a higher protocol timeout take care of it
321            */
322           LOG_WARN("MTU rej Handle: %d MTU: %d", p_lcb->Handle(), rej_mtu);
323         }
324         if (rej_reason == L2CAP_CMD_REJ_INVALID_CID) {
325           uint16_t lcid, rcid;
326           if (p + 4 > p_next_cmd) {
327             LOG_WARN("Not enough data for L2CAP_CMD_REJ_INVALID_CID");
328             return;
329           }
330           STREAM_TO_UINT16(rcid, p);
331           STREAM_TO_UINT16(lcid, p);
332 
333           LOG_WARN("Rejected due to invalid CID, LCID: 0x%04x RCID: 0x%04x",
334                    lcid, rcid);
335 
336           /* Remote CID invalid. Treat as a disconnect */
337           tL2C_CCB* p_ccb = l2cu_find_ccb_by_cid(p_lcb, lcid);
338           if ((p_ccb != NULL) && (p_ccb->remote_cid == rcid)) {
339             /* Fake link disconnect - no reply is generated */
340             LOG_WARN("Remote CID is invalid, treat as disconnected");
341             l2c_csm_execute(p_ccb, L2CEVT_LP_DISCONNECT_IND, NULL);
342           }
343         }
344 
345         /* SonyEricsson Info request Bug workaround (Continue connection) */
346         else if (rej_reason == L2CAP_CMD_REJ_NOT_UNDERSTOOD &&
347                  p_lcb->w4_info_rsp) {
348           alarm_cancel(p_lcb->info_resp_timer);
349 
350           p_lcb->w4_info_rsp = false;
351           tL2C_CONN_INFO ci;
352           ci.status = HCI_SUCCESS;
353           ci.bd_addr = p_lcb->remote_bd_addr;
354 
355           /* For all channels, send the event through their FSMs */
356           for (tL2C_CCB* p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb;
357                p_ccb = p_ccb->p_next_ccb) {
358             l2c_csm_execute(p_ccb, L2CEVT_L2CAP_INFO_RSP, &ci);
359           }
360         }
361         break;
362 
363       case L2CAP_CMD_CONN_REQ: {
364         uint16_t rcid;
365         if (p + 4 > p_next_cmd) {
366           LOG_WARN("Not enough data for L2CAP_CMD_CONN_REQ");
367           return;
368         }
369         STREAM_TO_UINT16(con_info.psm, p);
370         STREAM_TO_UINT16(rcid, p);
371         p_rcb = l2cu_find_rcb_by_psm(con_info.psm);
372         if (!p_rcb) {
373           LOG_WARN("Rcvd conn req for unknown PSM: %d", con_info.psm);
374           l2cu_reject_connection(p_lcb, rcid, id, L2CAP_CONN_NO_PSM);
375           break;
376         } else {
377           if (!p_rcb->api.pL2CA_ConnectInd_Cb) {
378             LOG_WARN("Rcvd conn req for outgoing-only connection PSM: %d",
379                      con_info.psm);
380             l2cu_reject_connection(p_lcb, rcid, id, L2CAP_CONN_NO_PSM);
381             break;
382           }
383         }
384         tL2C_CCB* p_ccb = l2cu_allocate_ccb(p_lcb, 0);
385         if (p_ccb == nullptr) {
386           LOG_ERROR("Unable to allocate CCB");
387           l2cu_reject_connection(p_lcb, rcid, id, L2CAP_CONN_NO_RESOURCES);
388           break;
389         }
390         p_ccb->remote_id = id;
391         p_ccb->p_rcb = p_rcb;
392         p_ccb->remote_cid = rcid;
393         p_ccb->connection_initiator = L2CAP_INITIATOR_REMOTE;
394 
395         if (p_rcb->psm == BT_PSM_RFCOMM) {
396           bluetooth::shim::GetSnoopLogger()->AddRfcommL2capChannel(
397               p_lcb->Handle(), p_ccb->local_cid, p_ccb->remote_cid);
398         } else if (p_rcb->log_packets) {
399           bluetooth::shim::GetSnoopLogger()->AcceptlistL2capChannel(
400               p_lcb->Handle(), p_ccb->local_cid, p_ccb->remote_cid);
401         }
402 
403         l2c_csm_execute(p_ccb, L2CEVT_L2CAP_CONNECT_REQ, &con_info);
404         break;
405       }
406 
407       case L2CAP_CMD_CONN_RSP: {
408         uint16_t lcid;
409         if (p + 8 > p_next_cmd) {
410           LOG_WARN("Not enough data for L2CAP_CMD_CONN_REQ");
411           return;
412         }
413         STREAM_TO_UINT16(con_info.remote_cid, p);
414         STREAM_TO_UINT16(lcid, p);
415         STREAM_TO_UINT16(con_info.l2cap_result, p);
416         STREAM_TO_UINT16(con_info.l2cap_status, p);
417 
418         tL2C_CCB* p_ccb = l2cu_find_ccb_by_cid(p_lcb, lcid);
419         if (!p_ccb) {
420           LOG_WARN("no CCB for conn rsp, LCID: %d RCID: %d", lcid,
421                    con_info.remote_cid);
422           break;
423         }
424         if (p_ccb->local_id != id) {
425           LOG_WARN("con rsp - bad ID. Exp: %d Got: %d", p_ccb->local_id, id);
426           break;
427         }
428 
429         if (con_info.l2cap_result == L2CAP_CONN_OK) {
430           l2c_csm_execute(p_ccb, L2CEVT_L2CAP_CONNECT_RSP, &con_info);
431         } else if (con_info.l2cap_result == L2CAP_CONN_PENDING) {
432           l2c_csm_execute(p_ccb, L2CEVT_L2CAP_CONNECT_RSP_PND, &con_info);
433         } else {
434           l2c_csm_execute(p_ccb, L2CEVT_L2CAP_CONNECT_RSP_NEG, &con_info);
435 
436           p_rcb = p_ccb->p_rcb;
437           if (p_rcb->psm == BT_PSM_RFCOMM) {
438             bluetooth::shim::GetSnoopLogger()->AddRfcommL2capChannel(
439                 p_lcb->Handle(), p_ccb->local_cid, p_ccb->remote_cid);
440           } else if (p_rcb->log_packets) {
441             bluetooth::shim::GetSnoopLogger()->AcceptlistL2capChannel(
442                 p_lcb->Handle(), p_ccb->local_cid, p_ccb->remote_cid);
443           }
444         }
445 
446         break;
447       }
448 
449       case L2CAP_CMD_CONFIG_REQ: {
450         uint8_t* p_cfg_end = p + cmd_len;
451         bool cfg_rej = false;
452         uint16_t cfg_rej_len = 0;
453 
454         uint16_t lcid;
455         if (p + 4 > p_next_cmd) {
456           LOG_WARN("Not enough data for L2CAP_CMD_CONFIG_REQ");
457           return;
458         }
459         STREAM_TO_UINT16(lcid, p);
460         STREAM_TO_UINT16(cfg_info.flags, p);
461 
462         uint8_t* p_cfg_start = p;
463 
464         cfg_info.flush_to_present = cfg_info.mtu_present =
465             cfg_info.qos_present = cfg_info.fcr_present = cfg_info.fcs_present =
466                 false;
467 
468         while (p < p_cfg_end) {
469           uint8_t cfg_code, cfg_len;
470           if (p + 2 > p_next_cmd) {
471             LOG_WARN("Not enough data for L2CAP_CMD_CONFIG_REQ sub_event");
472             return;
473           }
474           STREAM_TO_UINT8(cfg_code, p);
475           STREAM_TO_UINT8(cfg_len, p);
476 
477           switch (cfg_code & 0x7F) {
478             case L2CAP_CFG_TYPE_MTU:
479               cfg_info.mtu_present = true;
480               if (cfg_len != 2) {
481                 return;
482               }
483               if (p + cfg_len > p_next_cmd) {
484                 return;
485               }
486               STREAM_TO_UINT16(cfg_info.mtu, p);
487               break;
488 
489             case L2CAP_CFG_TYPE_FLUSH_TOUT:
490               cfg_info.flush_to_present = true;
491               if (cfg_len != 2) {
492                 return;
493               }
494               if (p + cfg_len > p_next_cmd) {
495                 return;
496               }
497               STREAM_TO_UINT16(cfg_info.flush_to, p);
498               break;
499 
500             case L2CAP_CFG_TYPE_QOS:
501               cfg_info.qos_present = true;
502               if (cfg_len != 2 + 5 * 4) {
503                 return;
504               }
505               if (p + cfg_len > p_next_cmd) {
506                 return;
507               }
508               STREAM_TO_UINT8(cfg_info.qos.qos_flags, p);
509               STREAM_TO_UINT8(cfg_info.qos.service_type, p);
510               STREAM_TO_UINT32(cfg_info.qos.token_rate, p);
511               STREAM_TO_UINT32(cfg_info.qos.token_bucket_size, p);
512               STREAM_TO_UINT32(cfg_info.qos.peak_bandwidth, p);
513               STREAM_TO_UINT32(cfg_info.qos.latency, p);
514               STREAM_TO_UINT32(cfg_info.qos.delay_variation, p);
515               break;
516 
517             case L2CAP_CFG_TYPE_FCR:
518               cfg_info.fcr_present = true;
519               if (cfg_len != 3 + 3 * 2) {
520                 return;
521               }
522               if (p + cfg_len > p_next_cmd) {
523                 return;
524               }
525               STREAM_TO_UINT8(cfg_info.fcr.mode, p);
526               STREAM_TO_UINT8(cfg_info.fcr.tx_win_sz, p);
527               STREAM_TO_UINT8(cfg_info.fcr.max_transmit, p);
528               STREAM_TO_UINT16(cfg_info.fcr.rtrans_tout, p);
529               STREAM_TO_UINT16(cfg_info.fcr.mon_tout, p);
530               STREAM_TO_UINT16(cfg_info.fcr.mps, p);
531               break;
532 
533             case L2CAP_CFG_TYPE_FCS:
534               cfg_info.fcs_present = true;
535               if (cfg_len != 1) {
536                 return;
537               }
538               if (p + cfg_len > p_next_cmd) {
539                 return;
540               }
541               STREAM_TO_UINT8(cfg_info.fcs, p);
542               break;
543 
544             case L2CAP_CFG_TYPE_EXT_FLOW:
545               cfg_info.ext_flow_spec_present = true;
546               if (cfg_len != 2 + 2 + 3 * 4) {
547                 return;
548               }
549               if (p + cfg_len > p_next_cmd) {
550                 return;
551               }
552               STREAM_TO_UINT8(cfg_info.ext_flow_spec.id, p);
553               STREAM_TO_UINT8(cfg_info.ext_flow_spec.stype, p);
554               STREAM_TO_UINT16(cfg_info.ext_flow_spec.max_sdu_size, p);
555               STREAM_TO_UINT32(cfg_info.ext_flow_spec.sdu_inter_time, p);
556               STREAM_TO_UINT32(cfg_info.ext_flow_spec.access_latency, p);
557               STREAM_TO_UINT32(cfg_info.ext_flow_spec.flush_timeout, p);
558               break;
559 
560             default:
561               /* sanity check option length */
562               if ((cfg_len + L2CAP_CFG_OPTION_OVERHEAD) <= cmd_len) {
563                 if (p + cfg_len > p_next_cmd) return;
564                 p += cfg_len;
565                 if ((cfg_code & 0x80) == 0) {
566                   cfg_rej_len += cfg_len + L2CAP_CFG_OPTION_OVERHEAD;
567                   cfg_rej = true;
568                 }
569               }
570               /* bad length; force loop exit */
571               else {
572                 p = p_cfg_end;
573                 cfg_rej = true;
574               }
575               break;
576           }
577         }
578 
579         tL2C_CCB* p_ccb = l2cu_find_ccb_by_cid(p_lcb, lcid);
580         if (p_ccb) {
581           p_ccb->remote_id = id;
582           if (cfg_rej) {
583             l2cu_send_peer_config_rej(
584                 p_ccb, p_cfg_start, (uint16_t)(cmd_len - L2CAP_CONFIG_REQ_LEN),
585                 cfg_rej_len);
586           } else {
587             l2c_csm_execute(p_ccb, L2CEVT_L2CAP_CONFIG_REQ, &cfg_info);
588           }
589         } else {
590           /* updated spec says send command reject on invalid cid */
591           l2cu_send_peer_cmd_reject(p_lcb, L2CAP_CMD_REJ_INVALID_CID, id, 0, 0);
592         }
593         break;
594       }
595 
596       case L2CAP_CMD_CONFIG_RSP: {
597         uint8_t* p_cfg_end = p + cmd_len;
598         uint16_t lcid;
599         if (p + 6 > p_next_cmd) {
600           LOG_WARN("Not enough data for L2CAP_CMD_CONFIG_RSP");
601           return;
602         }
603         STREAM_TO_UINT16(lcid, p);
604         STREAM_TO_UINT16(cfg_info.flags, p);
605         STREAM_TO_UINT16(cfg_info.result, p);
606 
607         cfg_info.flush_to_present = cfg_info.mtu_present =
608             cfg_info.qos_present = cfg_info.fcr_present = cfg_info.fcs_present =
609                 false;
610 
611         while (p < p_cfg_end) {
612           uint8_t cfg_code, cfg_len;
613           if (p + 2 > p_next_cmd) {
614             LOG_WARN("Not enough data for L2CAP_CMD_CONFIG_RSP sub_event");
615             return;
616           }
617           STREAM_TO_UINT8(cfg_code, p);
618           STREAM_TO_UINT8(cfg_len, p);
619 
620           switch (cfg_code & 0x7F) {
621             case L2CAP_CFG_TYPE_MTU:
622               cfg_info.mtu_present = true;
623               if (p + 2 > p_next_cmd) {
624                 LOG_WARN("Not enough data for L2CAP_CFG_TYPE_MTU");
625                 return;
626               }
627               STREAM_TO_UINT16(cfg_info.mtu, p);
628               break;
629 
630             case L2CAP_CFG_TYPE_FLUSH_TOUT:
631               cfg_info.flush_to_present = true;
632               if (p + 2 > p_next_cmd) {
633                 LOG_WARN("Not enough data for L2CAP_CFG_TYPE_FLUSH_TOUT");
634                 return;
635               }
636               STREAM_TO_UINT16(cfg_info.flush_to, p);
637               break;
638 
639             case L2CAP_CFG_TYPE_QOS:
640               cfg_info.qos_present = true;
641               if (p + 2 + 5 * 4 > p_next_cmd) {
642                 LOG_WARN("Not enough data for L2CAP_CFG_TYPE_QOS");
643                 return;
644               }
645               STREAM_TO_UINT8(cfg_info.qos.qos_flags, p);
646               STREAM_TO_UINT8(cfg_info.qos.service_type, p);
647               STREAM_TO_UINT32(cfg_info.qos.token_rate, p);
648               STREAM_TO_UINT32(cfg_info.qos.token_bucket_size, p);
649               STREAM_TO_UINT32(cfg_info.qos.peak_bandwidth, p);
650               STREAM_TO_UINT32(cfg_info.qos.latency, p);
651               STREAM_TO_UINT32(cfg_info.qos.delay_variation, p);
652               break;
653 
654             case L2CAP_CFG_TYPE_FCR:
655               cfg_info.fcr_present = true;
656               if (p + 3 + 3 * 2 > p_next_cmd) {
657                 LOG_WARN("Not enough data for L2CAP_CFG_TYPE_FCR");
658                 return;
659               }
660               STREAM_TO_UINT8(cfg_info.fcr.mode, p);
661               STREAM_TO_UINT8(cfg_info.fcr.tx_win_sz, p);
662               STREAM_TO_UINT8(cfg_info.fcr.max_transmit, p);
663               STREAM_TO_UINT16(cfg_info.fcr.rtrans_tout, p);
664               STREAM_TO_UINT16(cfg_info.fcr.mon_tout, p);
665               STREAM_TO_UINT16(cfg_info.fcr.mps, p);
666               break;
667 
668             case L2CAP_CFG_TYPE_FCS:
669               cfg_info.fcs_present = true;
670               if (p + 1 > p_next_cmd) {
671                 LOG_WARN("Not enough data for L2CAP_CFG_TYPE_FCS");
672                 return;
673               }
674               STREAM_TO_UINT8(cfg_info.fcs, p);
675               break;
676 
677             case L2CAP_CFG_TYPE_EXT_FLOW:
678               cfg_info.ext_flow_spec_present = true;
679               if (p + 2 + 2 + 3 * 4 > p_next_cmd) {
680                 LOG_WARN("Not enough data for L2CAP_CFG_TYPE_EXT_FLOW");
681                 return;
682               }
683               STREAM_TO_UINT8(cfg_info.ext_flow_spec.id, p);
684               STREAM_TO_UINT8(cfg_info.ext_flow_spec.stype, p);
685               STREAM_TO_UINT16(cfg_info.ext_flow_spec.max_sdu_size, p);
686               STREAM_TO_UINT32(cfg_info.ext_flow_spec.sdu_inter_time, p);
687               STREAM_TO_UINT32(cfg_info.ext_flow_spec.access_latency, p);
688               STREAM_TO_UINT32(cfg_info.ext_flow_spec.flush_timeout, p);
689               break;
690           }
691         }
692 
693         tL2C_CCB* p_ccb = l2cu_find_ccb_by_cid(p_lcb, lcid);
694         if (p_ccb) {
695           if (p_ccb->local_id != id) {
696             LOG_WARN("cfg rsp - bad ID. Exp: %d Got: %d", p_ccb->local_id, id);
697             break;
698           }
699           if (cfg_info.result == L2CAP_CFG_OK) {
700             l2c_csm_execute(p_ccb, L2CEVT_L2CAP_CONFIG_RSP, &cfg_info);
701           } else {
702             l2c_csm_execute(p_ccb, L2CEVT_L2CAP_CONFIG_RSP_NEG, &cfg_info);
703           }
704         } else {
705           LOG_WARN("Rcvd cfg rsp for unknown CID: 0x%04x", lcid);
706         }
707         break;
708       }
709 
710       case L2CAP_CMD_DISC_REQ: {
711         uint16_t lcid, rcid;
712         if (p + 4 > p_next_cmd) {
713           LOG_WARN("Not enough data for L2CAP_CMD_DISC_REQ");
714           return;
715         }
716         STREAM_TO_UINT16(lcid, p);
717         STREAM_TO_UINT16(rcid, p);
718 
719         tL2C_CCB* p_ccb = l2cu_find_ccb_by_cid(p_lcb, lcid);
720         if (p_ccb) {
721           if (p_ccb->remote_cid == rcid) {
722             p_ccb->remote_id = id;
723             l2c_csm_execute(p_ccb, L2CEVT_L2CAP_DISCONNECT_REQ, &con_info);
724           }
725         } else
726           l2cu_send_peer_disc_rsp(p_lcb, id, lcid, rcid);
727 
728         break;
729       }
730 
731       case L2CAP_CMD_DISC_RSP: {
732         uint16_t lcid, rcid;
733         if (p + 4 > p_next_cmd) {
734           LOG_WARN("Not enough data for L2CAP_CMD_DISC_RSP");
735           return;
736         }
737         STREAM_TO_UINT16(rcid, p);
738         STREAM_TO_UINT16(lcid, p);
739 
740         tL2C_CCB* p_ccb = l2cu_find_ccb_by_cid(p_lcb, lcid);
741         if (p_ccb) {
742           if ((p_ccb->remote_cid == rcid) && (p_ccb->local_id == id)) {
743             l2c_csm_execute(p_ccb, L2CEVT_L2CAP_DISCONNECT_RSP, &con_info);
744           }
745         }
746         break;
747       }
748 
749       case L2CAP_CMD_ECHO_REQ:
750         l2cu_send_peer_echo_rsp(p_lcb, id, p, cmd_len);
751         break;
752 
753       case L2CAP_CMD_INFO_REQ: {
754         uint16_t info_type;
755         if (p + 2 > p_next_cmd) {
756           LOG_WARN("Not enough data for L2CAP_CMD_INFO_REQ");
757           return;
758         }
759         STREAM_TO_UINT16(info_type, p);
760         l2cu_send_peer_info_rsp(p_lcb, id, info_type);
761         break;
762       }
763 
764       case L2CAP_CMD_INFO_RSP:
765         /* Stop the link connect timer if sent before L2CAP connection is up */
766         if (p_lcb->w4_info_rsp) {
767           alarm_cancel(p_lcb->info_resp_timer);
768           p_lcb->w4_info_rsp = false;
769         }
770 
771         uint16_t info_type, result;
772         if (p + 4 > p_next_cmd) {
773           LOG_WARN("Not enough data for L2CAP_CMD_INFO_RSP");
774           return;
775         }
776         STREAM_TO_UINT16(info_type, p);
777         STREAM_TO_UINT16(result, p);
778 
779         if ((info_type == L2CAP_EXTENDED_FEATURES_INFO_TYPE) &&
780             (result == L2CAP_INFO_RESP_RESULT_SUCCESS)) {
781           if (p + 4 > p_next_cmd) {
782             LOG_WARN("Not enough data for L2CAP_CMD_INFO_RSP sub_event");
783             return;
784           }
785           STREAM_TO_UINT32(p_lcb->peer_ext_fea, p);
786 
787           if (p_lcb->peer_ext_fea & L2CAP_EXTFEA_FIXED_CHNLS) {
788             l2cu_send_peer_info_req(p_lcb, L2CAP_FIXED_CHANNELS_INFO_TYPE);
789             break;
790           } else {
791             l2cu_process_fixed_chnl_resp(p_lcb);
792           }
793         }
794 
795         if (info_type == L2CAP_FIXED_CHANNELS_INFO_TYPE) {
796           if (result == L2CAP_INFO_RESP_RESULT_SUCCESS) {
797             if (p + L2CAP_FIXED_CHNL_ARRAY_SIZE > p_next_cmd) {
798               return;
799             }
800             memcpy(p_lcb->peer_chnl_mask, p, L2CAP_FIXED_CHNL_ARRAY_SIZE);
801           }
802 
803           l2cu_process_fixed_chnl_resp(p_lcb);
804         }
805         {
806           tL2C_CONN_INFO ci;
807           ci.status = HCI_SUCCESS;
808           ci.bd_addr = p_lcb->remote_bd_addr;
809           for (tL2C_CCB* p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb;
810                p_ccb = p_ccb->p_next_ccb) {
811             l2c_csm_execute(p_ccb, L2CEVT_L2CAP_INFO_RSP, &ci);
812           }
813         }
814         break;
815 
816       default:
817         LOG_WARN("Bad cmd code: %d", cmd_code);
818         l2cu_send_peer_cmd_reject(p_lcb, L2CAP_CMD_REJ_NOT_UNDERSTOOD, id, 0,
819                                   0);
820         return;
821     }
822   }
823 }
824 
825 /*******************************************************************************
826  *
827  * Function         l2c_init
828  *
829  * Description      This function is called once at startup to initialize
830  *                  all the L2CAP structures
831  *
832  * Returns          void
833  *
834  ******************************************************************************/
l2c_init(void)835 void l2c_init(void) {
836   if (bluetooth::shim::is_gd_l2cap_enabled()) {
837     // L2CAP init should be handled by GD stack manager
838     return;
839   }
840 
841   int16_t xx;
842 
843   memset(&l2cb, 0, sizeof(tL2C_CB));
844 
845   /* the LE PSM is increased by 1 before being used */
846   l2cb.le_dyn_psm = LE_DYNAMIC_PSM_START - 1;
847 
848   /* Put all the channel control blocks on the free queue */
849   for (xx = 0; xx < MAX_L2CAP_CHANNELS - 1; xx++) {
850     l2cb.ccb_pool[xx].p_next_ccb = &l2cb.ccb_pool[xx + 1];
851   }
852 
853   /* it will be set to L2CAP_PKT_START_NON_FLUSHABLE if controller supports */
854   l2cb.non_flushable_pbf = L2CAP_PKT_START << L2CAP_PKT_TYPE_SHIFT;
855 
856   l2cb.p_free_ccb_first = &l2cb.ccb_pool[0];
857   l2cb.p_free_ccb_last = &l2cb.ccb_pool[MAX_L2CAP_CHANNELS - 1];
858 
859   /* Set the default idle timeout */
860   l2cb.idle_timeout = L2CAP_LINK_INACTIVITY_TOUT;
861 
862 #if defined(L2CAP_INITIAL_TRACE_LEVEL)
863   l2cb.l2cap_trace_level = L2CAP_INITIAL_TRACE_LEVEL;
864 #else
865   l2cb.l2cap_trace_level = BT_TRACE_LEVEL_NONE; /* No traces */
866 #endif
867 
868 #if (L2CAP_CONFORMANCE_TESTING == TRUE)
869   /* Conformance testing needs a dynamic response */
870   l2cb.test_info_resp = L2CAP_EXTFEA_SUPPORTED_MASK;
871 #endif
872 
873   /* Number of ACL buffers to use for high priority channel */
874 
875   l2cb.l2c_ble_fixed_chnls_mask = L2CAP_FIXED_CHNL_ATT_BIT |
876                                   L2CAP_FIXED_CHNL_BLE_SIG_BIT |
877                                   L2CAP_FIXED_CHNL_SMP_BIT;
878 }
879 
l2c_free(void)880 void l2c_free(void) {
881   if (bluetooth::shim::is_gd_l2cap_enabled()) {
882     // L2CAP cleanup should be handled by GD stack manager
883     return;
884   }
885 }
886 
l2c_ccb_timer_timeout(void * data)887 void l2c_ccb_timer_timeout(void* data) {
888   tL2C_CCB* p_ccb = (tL2C_CCB*)data;
889 
890   l2c_csm_execute(p_ccb, L2CEVT_TIMEOUT, NULL);
891 }
892 
l2c_fcrb_ack_timer_timeout(void * data)893 void l2c_fcrb_ack_timer_timeout(void* data) {
894   tL2C_CCB* p_ccb = (tL2C_CCB*)data;
895 
896   l2c_csm_execute(p_ccb, L2CEVT_ACK_TIMEOUT, NULL);
897 }
898 
l2c_lcb_timer_timeout(void * data)899 void l2c_lcb_timer_timeout(void* data) {
900   tL2C_LCB* p_lcb = (tL2C_LCB*)data;
901 
902   l2c_link_timeout(p_lcb);
903 }
904 
905 /*******************************************************************************
906  *
907  * Function         l2c_data_write
908  *
909  * Description      API functions call this function to write data.
910  *
911  * Returns          L2CAP_DW_SUCCESS, if data accepted, else false
912  *                  L2CAP_DW_CONGESTED, if data accepted and the channel is
913  *                                      congested
914  *                  L2CAP_DW_FAILED, if error
915  *
916  ******************************************************************************/
l2c_data_write(uint16_t cid,BT_HDR * p_data,uint16_t flags)917 uint8_t l2c_data_write(uint16_t cid, BT_HDR* p_data, uint16_t flags) {
918   /* Find the channel control block. We don't know the link it is on. */
919   tL2C_CCB* p_ccb = l2cu_find_ccb_by_cid(NULL, cid);
920   if (!p_ccb) {
921     L2CAP_TRACE_WARNING("L2CAP - no CCB for L2CA_DataWrite, CID: %d", cid);
922     osi_free(p_data);
923     return (L2CAP_DW_FAILED);
924   }
925 
926   /* Sending message bigger than mtu size of peer is a violation of protocol */
927   uint16_t mtu;
928 
929   if (p_ccb->p_lcb->transport == BT_TRANSPORT_LE)
930     mtu = p_ccb->peer_conn_cfg.mtu;
931   else
932     mtu = p_ccb->peer_cfg.mtu;
933 
934   if (p_data->len > mtu) {
935     L2CAP_TRACE_WARNING(
936         "L2CAP - CID: 0x%04x  cannot send message bigger than peer's mtu size: "
937         "len=%u mtu=%u",
938         cid, p_data->len, mtu);
939     osi_free(p_data);
940     return (L2CAP_DW_FAILED);
941   }
942 
943   /* channel based, packet based flushable or non-flushable */
944   p_data->layer_specific = flags;
945 
946   /* If already congested, do not accept any more packets */
947   if (p_ccb->cong_sent) {
948     L2CAP_TRACE_ERROR(
949         "L2CAP - CID: 0x%04x cannot send, already congested  "
950         "xmit_hold_q.count: %u  buff_quota: %u",
951         p_ccb->local_cid, fixed_queue_length(p_ccb->xmit_hold_q),
952         p_ccb->buff_quota);
953 
954     osi_free(p_data);
955     return (L2CAP_DW_FAILED);
956   }
957 
958   l2c_csm_execute(p_ccb, L2CEVT_L2CA_DATA_WRITE, p_data);
959 
960   if (p_ccb->cong_sent) return (L2CAP_DW_CONGESTED);
961 
962   return (L2CAP_DW_SUCCESS);
963 }
964