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