• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  *
3  *  Copyright 2003-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 module contains action functions of the link control state machine.
22  *
23  ******************************************************************************/
24 
25 #include <string.h>
26 
27 #include "avct_api.h"
28 #include "avct_int.h"
29 #include "bt_target.h"
30 #include "bt_utils.h"
31 #include "bta/include/bta_api.h"
32 #include "btm_api.h"
33 #include "osi/include/allocator.h"
34 #include "osi/include/log.h"
35 #include "osi/include/osi.h"
36 #include "stack/btm/btm_sec.h"
37 #include "stack/include/bt_hdr.h"
38 
39 /* packet header length lookup table */
40 const uint8_t avct_lcb_pkt_type_len[] = {AVCT_HDR_LEN_SINGLE,
41                                          AVCT_HDR_LEN_START, AVCT_HDR_LEN_CONT,
42                                          AVCT_HDR_LEN_END};
43 
44 /*******************************************************************************
45  *
46  * Function         avct_lcb_msg_asmbl
47  *
48  * Description      Reassemble incoming message.
49  *
50  *
51  * Returns          Pointer to reassembled message;  NULL if no message
52  *                  available.
53  *
54  ******************************************************************************/
avct_lcb_msg_asmbl(tAVCT_LCB * p_lcb,BT_HDR * p_buf)55 static BT_HDR* avct_lcb_msg_asmbl(tAVCT_LCB* p_lcb, BT_HDR* p_buf) {
56   uint8_t* p;
57   uint8_t pkt_type;
58   BT_HDR* p_ret;
59 
60   if (p_buf->len < 1) {
61     osi_free(p_buf);
62     p_ret = NULL;
63     return p_ret;
64   }
65 
66   /* parse the message header */
67   p = (uint8_t*)(p_buf + 1) + p_buf->offset;
68   pkt_type = AVCT_PKT_TYPE(p);
69 
70   /* quick sanity check on length */
71   if (p_buf->len < avct_lcb_pkt_type_len[pkt_type] ||
72       (sizeof(BT_HDR) + p_buf->offset + p_buf->len) > BT_DEFAULT_BUFFER_SIZE) {
73     osi_free(p_buf);
74     AVCT_TRACE_WARNING("Bad length during reassembly");
75     p_ret = NULL;
76   }
77   /* single packet */
78   else if (pkt_type == AVCT_PKT_TYPE_SINGLE) {
79     /* if reassembly in progress drop message and process new single */
80     if (p_lcb->p_rx_msg != NULL)
81       AVCT_TRACE_WARNING("Got single during reassembly");
82 
83     osi_free_and_reset((void**)&p_lcb->p_rx_msg);
84 
85     p_ret = p_buf;
86   }
87   /* start packet */
88   else if (pkt_type == AVCT_PKT_TYPE_START) {
89     /* if reassembly in progress drop message and process new start */
90     if (p_lcb->p_rx_msg != NULL)
91       AVCT_TRACE_WARNING("Got start during reassembly");
92 
93     osi_free_and_reset((void**)&p_lcb->p_rx_msg);
94 
95     /*
96      * Allocate bigger buffer for reassembly. As lower layers are
97      * not aware of possible packet size after reassembly, they
98      * would have allocated smaller buffer.
99      */
100     if (sizeof(BT_HDR) + p_buf->offset + p_buf->len > BT_DEFAULT_BUFFER_SIZE) {
101       osi_free(p_buf);
102       p_ret = NULL;
103       return p_ret;
104     }
105     p_lcb->p_rx_msg = (BT_HDR*)osi_malloc(BT_DEFAULT_BUFFER_SIZE);
106     memcpy(p_lcb->p_rx_msg, p_buf, sizeof(BT_HDR) + p_buf->offset + p_buf->len);
107 
108     /* Free original buffer */
109     osi_free(p_buf);
110 
111     /* update p to point to new buffer */
112     p = (uint8_t*)(p_lcb->p_rx_msg + 1) + p_lcb->p_rx_msg->offset;
113 
114     /* copy first header byte over nosp */
115     *(p + 1) = *p;
116 
117     /* set offset to point to where to copy next */
118     p_lcb->p_rx_msg->offset += p_lcb->p_rx_msg->len;
119 
120     /* adjust length for packet header */
121     p_lcb->p_rx_msg->len -= 1;
122 
123     p_ret = NULL;
124   }
125   /* continue or end */
126   else {
127     /* if no reassembly in progress drop message */
128     if (p_lcb->p_rx_msg == NULL) {
129       osi_free(p_buf);
130       AVCT_TRACE_WARNING("Pkt type=%d out of order", pkt_type);
131       p_ret = NULL;
132     } else {
133       /* get size of buffer holding assembled message */
134       /*
135        * NOTE: The buffer is allocated above at the beginning of the
136        * reassembly, and is always of size BT_DEFAULT_BUFFER_SIZE.
137        */
138       uint16_t buf_len = BT_DEFAULT_BUFFER_SIZE - sizeof(BT_HDR);
139 
140       /* adjust offset and len of fragment for header byte */
141       p_buf->offset += AVCT_HDR_LEN_CONT;
142       p_buf->len -= AVCT_HDR_LEN_CONT;
143 
144       /* verify length */
145       if ((p_lcb->p_rx_msg->offset + p_buf->len) > buf_len) {
146         /* won't fit; free everything */
147         AVCT_TRACE_WARNING("%s: Fragmented message too big!", __func__);
148         osi_free_and_reset((void**)&p_lcb->p_rx_msg);
149         osi_free(p_buf);
150         p_ret = NULL;
151       } else {
152         /* copy contents of p_buf to p_rx_msg */
153         memcpy((uint8_t*)(p_lcb->p_rx_msg + 1) + p_lcb->p_rx_msg->offset,
154                (uint8_t*)(p_buf + 1) + p_buf->offset, p_buf->len);
155 
156         if (pkt_type == AVCT_PKT_TYPE_END) {
157           p_lcb->p_rx_msg->offset -= p_lcb->p_rx_msg->len;
158           p_lcb->p_rx_msg->len += p_buf->len;
159           p_ret = p_lcb->p_rx_msg;
160           p_lcb->p_rx_msg = NULL;
161         } else {
162           p_lcb->p_rx_msg->offset += p_buf->len;
163           p_lcb->p_rx_msg->len += p_buf->len;
164           p_ret = NULL;
165         }
166         osi_free(p_buf);
167       }
168     }
169   }
170   return p_ret;
171 }
172 
173 /*******************************************************************************
174  *
175  * Function         avct_lcb_chnl_open
176  *
177  * Description      Open L2CAP channel to peer
178  *
179  *
180  * Returns          Nothing.
181  *
182  ******************************************************************************/
avct_lcb_chnl_open(tAVCT_LCB * p_lcb,UNUSED_ATTR tAVCT_LCB_EVT * p_data)183 void avct_lcb_chnl_open(tAVCT_LCB* p_lcb, UNUSED_ATTR tAVCT_LCB_EVT* p_data) {
184   uint16_t result = AVCT_RESULT_FAIL;
185 
186   p_lcb->ch_state = AVCT_CH_CONN;
187   p_lcb->ch_lcid =
188       L2CA_ConnectReq2(AVCT_PSM, p_lcb->peer_addr, BTA_SEC_AUTHENTICATE);
189   if (p_lcb->ch_lcid == 0) {
190     /* if connect req failed, send ourselves close event */
191     tAVCT_LCB_EVT avct_lcb_evt;
192     avct_lcb_evt.result = result;
193     avct_lcb_event(p_lcb, AVCT_LCB_LL_CLOSE_EVT, &avct_lcb_evt);
194   }
195 }
196 
197 /*******************************************************************************
198  *
199  * Function         avct_lcb_unbind_disc
200  *
201  * Description      Deallocate ccb and call callback with disconnect event.
202  *
203  *
204  * Returns          Nothing.
205  *
206  ******************************************************************************/
avct_lcb_unbind_disc(UNUSED_ATTR tAVCT_LCB * p_lcb,tAVCT_LCB_EVT * p_data)207 void avct_lcb_unbind_disc(UNUSED_ATTR tAVCT_LCB* p_lcb, tAVCT_LCB_EVT* p_data) {
208   avct_ccb_dealloc(p_data->p_ccb, AVCT_DISCONNECT_CFM_EVT, 0, NULL);
209 }
210 
211 /*******************************************************************************
212  *
213  * Function         avct_lcb_open_ind
214  *
215  * Description      Handle an LL_OPEN event.  For each allocated ccb already
216  *                  bound to this lcb, send a connect event.  For each
217  *                  unbound ccb with a new PID, bind that ccb to this lcb and
218  *                  send a connect event.
219  *
220  *
221  * Returns          Nothing.
222  *
223  ******************************************************************************/
avct_lcb_open_ind(tAVCT_LCB * p_lcb,tAVCT_LCB_EVT * p_data)224 void avct_lcb_open_ind(tAVCT_LCB* p_lcb, tAVCT_LCB_EVT* p_data) {
225   tAVCT_CCB* p_ccb = &avct_cb.ccb[0];
226   int i;
227   bool bind = false;
228 
229   for (i = 0; i < AVCT_NUM_CONN; i++, p_ccb++) {
230     /* if ccb allocated and */
231     if (p_ccb->allocated) {
232       /* if bound to this lcb send connect confirm event */
233       if (p_ccb->p_lcb == p_lcb) {
234         bind = true;
235         L2CA_SetTxPriority(p_lcb->ch_lcid, L2CAP_CHNL_PRIORITY_HIGH);
236         p_ccb->cc.p_ctrl_cback(avct_ccb_to_idx(p_ccb), AVCT_CONNECT_CFM_EVT, 0,
237                                &p_lcb->peer_addr);
238       }
239       /* if unbound acceptor and lcb doesn't already have a ccb for this PID */
240       else if ((p_ccb->p_lcb == NULL) && (p_ccb->cc.role == AVCT_ACP) &&
241                (avct_lcb_has_pid(p_lcb, p_ccb->cc.pid) == NULL)) {
242         /* bind ccb to lcb and send connect ind event */
243         bind = true;
244         p_ccb->p_lcb = p_lcb;
245         L2CA_SetTxPriority(p_lcb->ch_lcid, L2CAP_CHNL_PRIORITY_HIGH);
246         p_ccb->cc.p_ctrl_cback(avct_ccb_to_idx(p_ccb), AVCT_CONNECT_IND_EVT, 0,
247                                &p_lcb->peer_addr);
248       }
249     }
250   }
251 
252   /* if no ccbs bound to this lcb, disconnect */
253   if (!bind) {
254     avct_lcb_event(p_lcb, AVCT_LCB_INT_CLOSE_EVT, p_data);
255   }
256 }
257 
258 /*******************************************************************************
259  *
260  * Function         avct_lcb_open_fail
261  *
262  * Description      L2CAP channel open attempt failed.  Deallocate any ccbs
263  *                  on this lcb and send connect confirm event with failure.
264  *
265  *
266  * Returns          Nothing.
267  *
268  ******************************************************************************/
avct_lcb_open_fail(tAVCT_LCB * p_lcb,tAVCT_LCB_EVT * p_data)269 void avct_lcb_open_fail(tAVCT_LCB* p_lcb, tAVCT_LCB_EVT* p_data) {
270   tAVCT_CCB* p_ccb = &avct_cb.ccb[0];
271   int i;
272 
273   for (i = 0; i < AVCT_NUM_CONN; i++, p_ccb++) {
274     if (p_ccb->allocated && (p_ccb->p_lcb == p_lcb)) {
275       avct_ccb_dealloc(p_ccb, AVCT_CONNECT_CFM_EVT, p_data->result,
276                        &p_lcb->peer_addr);
277     }
278   }
279 }
280 
281 /*******************************************************************************
282  *
283  * Function         avct_lcb_close_ind
284  *
285  * Description      L2CAP channel closed by peer.  Deallocate any initiator
286  *                  ccbs on this lcb and send disconnect ind event.
287  *
288  *
289  * Returns          Nothing.
290  *
291  ******************************************************************************/
avct_lcb_close_ind(tAVCT_LCB * p_lcb,UNUSED_ATTR tAVCT_LCB_EVT * p_data)292 void avct_lcb_close_ind(tAVCT_LCB* p_lcb, UNUSED_ATTR tAVCT_LCB_EVT* p_data) {
293   tAVCT_CCB* p_ccb = &avct_cb.ccb[0];
294   int i;
295 
296   for (i = 0; i < AVCT_NUM_CONN; i++, p_ccb++) {
297     if (p_ccb->allocated && (p_ccb->p_lcb == p_lcb)) {
298       if (p_ccb->cc.role == AVCT_INT) {
299         avct_ccb_dealloc(p_ccb, AVCT_DISCONNECT_IND_EVT, 0, &p_lcb->peer_addr);
300       } else {
301         p_ccb->p_lcb = NULL;
302         (*p_ccb->cc.p_ctrl_cback)(avct_ccb_to_idx(p_ccb),
303                                   AVCT_DISCONNECT_IND_EVT, 0,
304                                   &p_lcb->peer_addr);
305       }
306     }
307   }
308 }
309 
310 /*******************************************************************************
311  *
312  * Function         avct_lcb_close_cfm
313  *
314  * Description      L2CAP channel closed by us.  Deallocate any initiator
315  *                  ccbs on this lcb and send disconnect ind or cfm event.
316  *
317  *
318  * Returns          Nothing.
319  *
320  ******************************************************************************/
avct_lcb_close_cfm(tAVCT_LCB * p_lcb,tAVCT_LCB_EVT * p_data)321 void avct_lcb_close_cfm(tAVCT_LCB* p_lcb, tAVCT_LCB_EVT* p_data) {
322   tAVCT_CCB* p_ccb = &avct_cb.ccb[0];
323   int i;
324   uint8_t event;
325 
326   for (i = 0; i < AVCT_NUM_CONN; i++, p_ccb++) {
327     if (p_ccb->allocated && (p_ccb->p_lcb == p_lcb)) {
328       /* if this ccb initiated close send disconnect cfm otherwise ind */
329       if (p_ccb->ch_close) {
330         p_ccb->ch_close = false;
331         event = AVCT_DISCONNECT_CFM_EVT;
332       } else {
333         event = AVCT_DISCONNECT_IND_EVT;
334       }
335 
336       if (p_ccb->cc.role == AVCT_INT) {
337         avct_ccb_dealloc(p_ccb, event, p_data->result, &p_lcb->peer_addr);
338       } else {
339         p_ccb->p_lcb = NULL;
340         (*p_ccb->cc.p_ctrl_cback)(avct_ccb_to_idx(p_ccb), event, p_data->result,
341                                   &p_lcb->peer_addr);
342       }
343     }
344   }
345 }
346 
347 /*******************************************************************************
348  *
349  * Function         avct_lcb_bind_conn
350  *
351  * Description      Bind ccb to lcb and send connect cfm event.
352  *
353  *
354  * Returns          Nothing.
355  *
356  ******************************************************************************/
avct_lcb_bind_conn(tAVCT_LCB * p_lcb,tAVCT_LCB_EVT * p_data)357 void avct_lcb_bind_conn(tAVCT_LCB* p_lcb, tAVCT_LCB_EVT* p_data) {
358   p_data->p_ccb->p_lcb = p_lcb;
359   (*p_data->p_ccb->cc.p_ctrl_cback)(avct_ccb_to_idx(p_data->p_ccb),
360                                     AVCT_CONNECT_CFM_EVT, 0, &p_lcb->peer_addr);
361 }
362 
363 /*******************************************************************************
364  *
365  * Function         avct_lcb_chk_disc
366  *
367  * Description      A ccb wants to close; if it is the last ccb on this lcb,
368  *                  close channel.  Otherwise just deallocate and call
369  *                  callback.
370  *
371  * Returns          Nothing.
372  *
373  ******************************************************************************/
avct_lcb_chk_disc(tAVCT_LCB * p_lcb,tAVCT_LCB_EVT * p_data)374 void avct_lcb_chk_disc(tAVCT_LCB* p_lcb, tAVCT_LCB_EVT* p_data) {
375   avct_close_bcb(p_lcb, p_data);
376   if (avct_lcb_last_ccb(p_lcb, p_data->p_ccb)) {
377     LOG_INFO("Closing last avct channel to device");
378     p_data->p_ccb->ch_close = true;
379     avct_lcb_event(p_lcb, AVCT_LCB_INT_CLOSE_EVT, p_data);
380   } else {
381     LOG_INFO("Closing avct channel with active remaining channels");
382     avct_lcb_unbind_disc(p_lcb, p_data);
383   }
384 }
385 
386 /*******************************************************************************
387  *
388  * Function         avct_lcb_chnl_disc
389  *
390  * Description      Disconnect L2CAP channel.
391  *
392  *
393  * Returns          Nothing.
394  *
395  ******************************************************************************/
avct_lcb_chnl_disc(tAVCT_LCB * p_lcb,UNUSED_ATTR tAVCT_LCB_EVT * p_data)396 void avct_lcb_chnl_disc(tAVCT_LCB* p_lcb, UNUSED_ATTR tAVCT_LCB_EVT* p_data) {
397   avct_l2c_disconnect(p_lcb->ch_lcid, 0);
398 }
399 
400 /*******************************************************************************
401  *
402  * Function         avct_lcb_bind_fail
403  *
404  * Description      Deallocate ccb and call callback with connect event
405  *                  with failure result.
406  *
407  *
408  * Returns          Nothing.
409  *
410  ******************************************************************************/
avct_lcb_bind_fail(UNUSED_ATTR tAVCT_LCB * p_lcb,tAVCT_LCB_EVT * p_data)411 void avct_lcb_bind_fail(UNUSED_ATTR tAVCT_LCB* p_lcb, tAVCT_LCB_EVT* p_data) {
412   avct_ccb_dealloc(p_data->p_ccb, AVCT_CONNECT_CFM_EVT, AVCT_RESULT_FAIL, NULL);
413 }
414 
415 /*******************************************************************************
416  *
417  * Function         avct_lcb_cong_ind
418  *
419  * Description      Handle congestion indication from L2CAP.
420  *
421  *
422  * Returns          Nothing.
423  *
424  ******************************************************************************/
avct_lcb_cong_ind(tAVCT_LCB * p_lcb,tAVCT_LCB_EVT * p_data)425 void avct_lcb_cong_ind(tAVCT_LCB* p_lcb, tAVCT_LCB_EVT* p_data) {
426   tAVCT_CCB* p_ccb = &avct_cb.ccb[0];
427   int i;
428   uint8_t event;
429   BT_HDR* p_buf;
430 
431   /* set event */
432   event = (p_data->cong) ? AVCT_CONG_IND_EVT : AVCT_UNCONG_IND_EVT;
433   p_lcb->cong = p_data->cong;
434   if (!p_lcb->cong && !fixed_queue_is_empty(p_lcb->tx_q)) {
435     while (!p_lcb->cong &&
436            (p_buf = (BT_HDR*)fixed_queue_try_dequeue(p_lcb->tx_q)) != NULL) {
437       if (L2CA_DataWrite(p_lcb->ch_lcid, p_buf) == L2CAP_DW_CONGESTED) {
438         p_lcb->cong = true;
439       }
440     }
441   }
442 
443   /* send event to all ccbs on this lcb */
444   for (i = 0; i < AVCT_NUM_CONN; i++, p_ccb++) {
445     if (p_ccb->allocated && (p_ccb->p_lcb == p_lcb)) {
446       (*p_ccb->cc.p_ctrl_cback)(avct_ccb_to_idx(p_ccb), event, 0,
447                                 &p_lcb->peer_addr);
448     }
449   }
450 }
451 
452 /*******************************************************************************
453  *
454  * Function         avct_lcb_discard_msg
455  *
456  * Description      Discard a message sent in from the API.
457  *
458  *
459  * Returns          Nothing.
460  *
461  ******************************************************************************/
avct_lcb_discard_msg(UNUSED_ATTR tAVCT_LCB * p_lcb,tAVCT_LCB_EVT * p_data)462 void avct_lcb_discard_msg(UNUSED_ATTR tAVCT_LCB* p_lcb, tAVCT_LCB_EVT* p_data) {
463   AVCT_TRACE_WARNING("%s Dropping message", __func__);
464   osi_free_and_reset((void**)&p_data->ul_msg.p_buf);
465 }
466 
467 /*******************************************************************************
468  *
469  * Function         avct_lcb_send_msg
470  *
471  * Description      Build and send an AVCTP message.
472  *
473  *
474  * Returns          Nothing.
475  *
476  ******************************************************************************/
avct_lcb_send_msg(tAVCT_LCB * p_lcb,tAVCT_LCB_EVT * p_data)477 void avct_lcb_send_msg(tAVCT_LCB* p_lcb, tAVCT_LCB_EVT* p_data) {
478   uint16_t curr_msg_len;
479   uint8_t pkt_type;
480   uint8_t hdr_len;
481   uint8_t* p;
482   uint8_t nosp = 0; /* number of subsequent packets */
483   uint16_t temp;
484   uint16_t buf_size = p_lcb->peer_mtu + L2CAP_MIN_OFFSET + BT_HDR_SIZE;
485 
486   /* store msg len */
487   curr_msg_len = p_data->ul_msg.p_buf->len;
488 
489   /* initialize packet type and other stuff */
490   if (curr_msg_len <= (p_lcb->peer_mtu - AVCT_HDR_LEN_SINGLE)) {
491     pkt_type = AVCT_PKT_TYPE_SINGLE;
492   } else {
493     pkt_type = AVCT_PKT_TYPE_START;
494     temp = (curr_msg_len + AVCT_HDR_LEN_START - p_lcb->peer_mtu);
495     nosp = temp / (p_lcb->peer_mtu - 1) + 1;
496     if ((temp % (p_lcb->peer_mtu - 1)) != 0) nosp++;
497   }
498 
499   /* while we haven't sent all packets */
500   while (curr_msg_len != 0) {
501     BT_HDR* p_buf;
502 
503     /* set header len */
504     hdr_len = avct_lcb_pkt_type_len[pkt_type];
505 
506     /* if remaining msg must be fragmented */
507     if (p_data->ul_msg.p_buf->len > (p_lcb->peer_mtu - hdr_len)) {
508       /* get a new buffer for fragment we are sending */
509       p_buf = (BT_HDR*)osi_malloc(buf_size);
510 
511       /* copy portion of data from current message to new buffer */
512       p_buf->offset = L2CAP_MIN_OFFSET + hdr_len;
513       p_buf->len = p_lcb->peer_mtu - hdr_len;
514 
515       memcpy(
516           (uint8_t*)(p_buf + 1) + p_buf->offset,
517           (uint8_t*)(p_data->ul_msg.p_buf + 1) + p_data->ul_msg.p_buf->offset,
518           p_buf->len);
519 
520       p_data->ul_msg.p_buf->offset += p_buf->len;
521       p_data->ul_msg.p_buf->len -= p_buf->len;
522     } else {
523       p_buf = p_data->ul_msg.p_buf;
524     }
525 
526     curr_msg_len -= p_buf->len;
527 
528     /* set up to build header */
529     p_buf->len += hdr_len;
530     p_buf->offset -= hdr_len;
531     p = (uint8_t*)(p_buf + 1) + p_buf->offset;
532 
533     /* build header */
534     AVCT_BUILD_HDR(p, p_data->ul_msg.label, pkt_type, p_data->ul_msg.cr);
535     if (pkt_type == AVCT_PKT_TYPE_START) {
536       UINT8_TO_STREAM(p, nosp);
537     }
538     if ((pkt_type == AVCT_PKT_TYPE_START) ||
539         (pkt_type == AVCT_PKT_TYPE_SINGLE)) {
540       UINT16_TO_BE_STREAM(p, p_data->ul_msg.p_ccb->cc.pid);
541     }
542 
543     if (p_lcb->cong) {
544       fixed_queue_enqueue(p_lcb->tx_q, p_buf);
545     }
546 
547     /* send message to L2CAP */
548     else {
549       if (L2CA_DataWrite(p_lcb->ch_lcid, p_buf) == L2CAP_DW_CONGESTED) {
550         p_lcb->cong = true;
551       }
552     }
553 
554     /* update pkt type for next packet */
555     if (curr_msg_len > (p_lcb->peer_mtu - AVCT_HDR_LEN_END)) {
556       pkt_type = AVCT_PKT_TYPE_CONT;
557     } else {
558       pkt_type = AVCT_PKT_TYPE_END;
559     }
560   }
561   AVCT_TRACE_DEBUG("%s tx_q_count:%d", __func__,
562                    fixed_queue_length(p_lcb->tx_q));
563   return;
564 }
565 
566 /*******************************************************************************
567  *
568  * Function         avct_lcb_free_msg_ind
569  *
570  * Description      Discard an incoming AVCTP message.
571  *
572  *
573  * Returns          Nothing.
574  *
575  ******************************************************************************/
avct_lcb_free_msg_ind(UNUSED_ATTR tAVCT_LCB * p_lcb,tAVCT_LCB_EVT * p_data)576 void avct_lcb_free_msg_ind(UNUSED_ATTR tAVCT_LCB* p_lcb,
577                            tAVCT_LCB_EVT* p_data) {
578   if (p_data == NULL) return;
579 
580   osi_free_and_reset((void**)&p_data->p_buf);
581 }
582 
583 /*******************************************************************************
584  *
585  * Function         avct_lcb_msg_ind
586  *
587  * Description      Handle an incoming AVCTP message.
588  *
589  *
590  * Returns          Nothing.
591  *
592  ******************************************************************************/
avct_lcb_msg_ind(tAVCT_LCB * p_lcb,tAVCT_LCB_EVT * p_data)593 void avct_lcb_msg_ind(tAVCT_LCB* p_lcb, tAVCT_LCB_EVT* p_data) {
594   uint8_t* p;
595   uint8_t label, type, cr_ipid;
596   uint16_t pid;
597   tAVCT_CCB* p_ccb;
598 
599   /* this p_buf is to be reported through p_msg_cback. The layer_specific
600    * needs to be set properly to indicate that it is received through
601    * control channel */
602   p_data->p_buf->layer_specific = AVCT_DATA_CTRL;
603 
604   /* reassemble message; if no message available (we received a fragment) return
605    */
606   p_data->p_buf = avct_lcb_msg_asmbl(p_lcb, p_data->p_buf);
607   if (p_data->p_buf == NULL) {
608     return;
609   }
610 
611   p = (uint8_t*)(p_data->p_buf + 1) + p_data->p_buf->offset;
612 
613   /* parse header byte */
614   AVCT_PARSE_HDR(p, label, type, cr_ipid);
615 
616   /* check for invalid cr_ipid */
617   if (cr_ipid == AVCT_CR_IPID_INVALID) {
618     AVCT_TRACE_WARNING("Invalid cr_ipid", cr_ipid);
619     osi_free_and_reset((void**)&p_data->p_buf);
620     return;
621   }
622 
623   /* parse and lookup PID */
624   BE_STREAM_TO_UINT16(pid, p);
625   p_ccb = avct_lcb_has_pid(p_lcb, pid);
626   if (p_ccb) {
627     /* PID found; send msg up, adjust bt hdr and call msg callback */
628     p_data->p_buf->offset += AVCT_HDR_LEN_SINGLE;
629     p_data->p_buf->len -= AVCT_HDR_LEN_SINGLE;
630     (*p_ccb->cc.p_msg_cback)(avct_ccb_to_idx(p_ccb), label, cr_ipid,
631                              p_data->p_buf);
632     return;
633   }
634 
635   /* PID not found; drop message */
636   AVCT_TRACE_WARNING("No ccb for PID=%x", pid);
637   osi_free_and_reset((void**)&p_data->p_buf);
638 
639   /* if command send reject */
640   if (cr_ipid == AVCT_CMD) {
641     BT_HDR* p_buf = (BT_HDR*)osi_malloc(AVCT_CMD_BUF_SIZE);
642     p_buf->len = AVCT_HDR_LEN_SINGLE;
643     p_buf->offset = AVCT_MSG_OFFSET - AVCT_HDR_LEN_SINGLE;
644     p = (uint8_t*)(p_buf + 1) + p_buf->offset;
645     AVCT_BUILD_HDR(p, label, AVCT_PKT_TYPE_SINGLE, AVCT_REJ);
646     UINT16_TO_BE_STREAM(p, pid);
647     L2CA_DataWrite(p_lcb->ch_lcid, p_buf);
648   }
649 }
650