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