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