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