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