1/******************************************************************************
2 *
3 *  Copyright (C) 2002-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 functions for parsing and building AVDTP signaling
22 *  messages.  It also contains functions called by the SCB or CCB state
23 *  machines for sending command, response, and reject messages.  It also
24 *  contains a function that processes incoming messages and dispatches them
25 *  to the appropriate SCB or CCB.
26 *
27 ******************************************************************************/
28
29#include <string.h>
30#include "data_types.h"
31#include "bt_target.h"
32#include "bt_utils.h"
33#include "avdt_api.h"
34#include "avdtc_api.h"
35#include "avdt_int.h"
36#include "gki.h"
37#include "btu.h"
38
39/*****************************************************************************
40** constants
41*****************************************************************************/
42
43/* mask of all psc values */
44#define AVDT_MSG_PSC_MASK   (AVDT_PSC_TRANS | AVDT_PSC_REPORT | AVDT_PSC_DELAY_RPT | \
45                             AVDT_PSC_RECOV | AVDT_PSC_HDRCMP | AVDT_PSC_MUX)
46#define AVDT_PSC_PROTECT    (1<<4)  /* Content Protection */
47#define AVDT_PSC_CODEC      (1<<7)  /* codec */
48
49
50/*****************************************************************************
51** type definitions
52*****************************************************************************/
53
54/* type for message building functions */
55typedef void (*tAVDT_MSG_BLD)(UINT8 **p, tAVDT_MSG *p_msg);
56
57/* type for message parsing functions */
58typedef UINT8 (*tAVDT_MSG_PRS)(tAVDT_MSG *p_msg, UINT8 *p, UINT16 len);
59
60
61/*****************************************************************************
62** local function declarations
63*****************************************************************************/
64
65static void avdt_msg_bld_none(UINT8 **p, tAVDT_MSG *p_msg);
66static void avdt_msg_bld_single(UINT8 **p, tAVDT_MSG *p_msg);
67static void avdt_msg_bld_setconfig_cmd(UINT8 **p, tAVDT_MSG *p_msg);
68static void avdt_msg_bld_reconfig_cmd(UINT8 **p, tAVDT_MSG *p_msg);
69static void avdt_msg_bld_multi(UINT8 **p, tAVDT_MSG *p_msg);
70static void avdt_msg_bld_security_cmd(UINT8 **p, tAVDT_MSG *p_msg);
71static void avdt_msg_bld_discover_rsp(UINT8 **p, tAVDT_MSG *p_msg);
72static void avdt_msg_bld_svccap(UINT8 **p, tAVDT_MSG *p_msg);
73static void avdt_msg_bld_security_rsp(UINT8 **p, tAVDT_MSG *p_msg);
74static void avdt_msg_bld_all_svccap(UINT8 **p, tAVDT_MSG *p_msg);
75static void avdt_msg_bld_delay_rpt(UINT8 **p, tAVDT_MSG *p_msg);
76
77static UINT8 avdt_msg_prs_none(tAVDT_MSG *p_msg, UINT8 *p, UINT16 len);
78static UINT8 avdt_msg_prs_single(tAVDT_MSG *p_msg, UINT8 *p, UINT16 len);
79static UINT8 avdt_msg_prs_setconfig_cmd(tAVDT_MSG *p_msg, UINT8 *p, UINT16 len);
80static UINT8 avdt_msg_prs_reconfig_cmd(tAVDT_MSG *p_msg, UINT8 *p, UINT16 len);
81static UINT8 avdt_msg_prs_multi(tAVDT_MSG *p_msg, UINT8 *p, UINT16 len);
82static UINT8 avdt_msg_prs_security_cmd(tAVDT_MSG *p_msg, UINT8 *p, UINT16 len);
83static UINT8 avdt_msg_prs_discover_rsp(tAVDT_MSG *p_msg, UINT8 *p, UINT16 len);
84static UINT8 avdt_msg_prs_svccap(tAVDT_MSG *p_msg, UINT8 *p, UINT16 len);
85static UINT8 avdt_msg_prs_all_svccap(tAVDT_MSG *p_msg, UINT8 *p, UINT16 len);
86static UINT8 avdt_msg_prs_security_rsp(tAVDT_MSG *p_msg, UINT8 *p, UINT16 len);
87static UINT8 avdt_msg_prs_delay_rpt (tAVDT_MSG *p_msg, UINT8 *p, UINT16 len);
88
89/*****************************************************************************
90** constants
91*****************************************************************************/
92
93/* table of information element minimum lengths used for parsing */
94const UINT8 avdt_msg_ie_len_min[] = {
95    0,                              /* unused */
96    AVDT_LEN_TRANS_MIN,             /* media transport */
97    AVDT_LEN_REPORT_MIN,            /* reporting */
98    AVDT_LEN_RECOV_MIN,             /* recovery */
99    AVDT_LEN_PROTECT_MIN,           /* content protection */
100    AVDT_LEN_HDRCMP_MIN,            /* header compression */
101    AVDT_LEN_MUX_MIN,               /* multiplexing */
102    AVDT_LEN_CODEC_MIN,             /* codec */
103    AVDT_LEN_DELAY_RPT_MIN          /* delay report */
104};
105
106/* table of information element minimum lengths used for parsing */
107const UINT8 avdt_msg_ie_len_max[] = {
108    0,                              /* unused */
109    AVDT_LEN_TRANS_MAX,             /* media transport */
110    AVDT_LEN_REPORT_MAX,            /* reporting */
111    AVDT_LEN_RECOV_MAX,             /* recovery */
112    AVDT_LEN_PROTECT_MAX,           /* content protection */
113    AVDT_LEN_HDRCMP_MAX,            /* header compression */
114    AVDT_LEN_MUX_MAX,               /* multiplexing */
115    AVDT_LEN_CODEC_MAX,             /* codec */
116    AVDT_LEN_DELAY_RPT_MAX          /* delay report */
117};
118
119/* table of error codes used when decoding information elements */
120const UINT8 avdt_msg_ie_err[] = {
121    0,                              /* unused */
122    AVDT_ERR_MEDIA_TRANS,           /* media transport */
123    AVDT_ERR_LENGTH,                /* reporting */
124    AVDT_ERR_RECOV_FMT,             /* recovery */
125    AVDT_ERR_CP_FMT,                /* content protection */
126    AVDT_ERR_ROHC_FMT,              /* header compression */
127    AVDT_ERR_MUX_FMT,               /* multiplexing */
128    AVDT_ERR_SERVICE,               /* codec */
129    AVDT_ERR_SERVICE                /* delay report ?? */
130};
131
132/* table of packet type minimum lengths */
133static const UINT8 avdt_msg_pkt_type_len[] = {
134    AVDT_LEN_TYPE_SINGLE,
135    AVDT_LEN_TYPE_START,
136    AVDT_LEN_TYPE_CONT,
137    AVDT_LEN_TYPE_END
138};
139
140/* function table for building command messages */
141const tAVDT_MSG_BLD avdt_msg_bld_cmd[] = {
142    avdt_msg_bld_none,            /* discover */
143    avdt_msg_bld_single,          /* get capabilities */
144    avdt_msg_bld_setconfig_cmd,   /* set configuration */
145    avdt_msg_bld_single,          /* get configuration */
146    avdt_msg_bld_reconfig_cmd,    /* reconfigure */
147    avdt_msg_bld_single,          /* open */
148    avdt_msg_bld_multi,           /* start */
149    avdt_msg_bld_single,          /* close */
150    avdt_msg_bld_multi,           /* suspend */
151    avdt_msg_bld_single,          /* abort */
152    avdt_msg_bld_security_cmd,    /* security control */
153    avdt_msg_bld_single,          /* get all capabilities */
154    avdt_msg_bld_delay_rpt        /* delay report */
155};
156
157/* function table for building response messages */
158const tAVDT_MSG_BLD avdt_msg_bld_rsp[] = {
159    avdt_msg_bld_discover_rsp,    /* discover */
160    avdt_msg_bld_svccap,          /* get capabilities */
161    avdt_msg_bld_none,            /* set configuration */
162    avdt_msg_bld_all_svccap,      /* get configuration */
163    avdt_msg_bld_none,            /* reconfigure */
164    avdt_msg_bld_none,            /* open */
165    avdt_msg_bld_none,            /* start */
166    avdt_msg_bld_none,            /* close */
167    avdt_msg_bld_none,            /* suspend */
168    avdt_msg_bld_none,            /* abort */
169    avdt_msg_bld_security_rsp,    /* security control */
170    avdt_msg_bld_all_svccap,      /* get all capabilities */
171    avdt_msg_bld_none             /* delay report */
172};
173
174/* function table for parsing command messages */
175const tAVDT_MSG_PRS avdt_msg_prs_cmd[] = {
176    avdt_msg_prs_none,            /* discover */
177    avdt_msg_prs_single,          /* get capabilities */
178    avdt_msg_prs_setconfig_cmd,   /* set configuration */
179    avdt_msg_prs_single,          /* get configuration */
180    avdt_msg_prs_reconfig_cmd,    /* reconfigure */
181    avdt_msg_prs_single,          /* open */
182    avdt_msg_prs_multi,           /* start */
183    avdt_msg_prs_single,          /* close */
184    avdt_msg_prs_multi,           /* suspend */
185    avdt_msg_prs_single,          /* abort */
186    avdt_msg_prs_security_cmd,    /* security control */
187    avdt_msg_prs_single,          /* get all capabilities */
188    avdt_msg_prs_delay_rpt        /* delay report */
189};
190
191/* function table for parsing response messages */
192const tAVDT_MSG_PRS avdt_msg_prs_rsp[] = {
193    avdt_msg_prs_discover_rsp,    /* discover */
194    avdt_msg_prs_svccap,          /* get capabilities */
195    avdt_msg_prs_none,            /* set configuration */
196    avdt_msg_prs_all_svccap,      /* get configuration */
197    avdt_msg_prs_none,            /* reconfigure */
198    avdt_msg_prs_none,            /* open */
199    avdt_msg_prs_none,            /* start */
200    avdt_msg_prs_none,            /* close */
201    avdt_msg_prs_none,            /* suspend */
202    avdt_msg_prs_none,            /* abort */
203    avdt_msg_prs_security_rsp,    /* security control */
204    avdt_msg_prs_all_svccap,      /* get all capabilities */
205    avdt_msg_prs_none             /* delay report */
206};
207
208/* command message-to-event lookup table */
209const UINT8 avdt_msg_cmd_2_evt[] = {
210    AVDT_CCB_MSG_DISCOVER_CMD_EVT + AVDT_CCB_MKR,   /* discover */
211    AVDT_CCB_MSG_GETCAP_CMD_EVT + AVDT_CCB_MKR,     /* get capabilities */
212    AVDT_SCB_MSG_SETCONFIG_CMD_EVT,                 /* set configuration */
213    AVDT_SCB_MSG_GETCONFIG_CMD_EVT,                 /* get configuration */
214    AVDT_SCB_MSG_RECONFIG_CMD_EVT,                  /* reconfigure */
215    AVDT_SCB_MSG_OPEN_CMD_EVT,                      /* open */
216    AVDT_CCB_MSG_START_CMD_EVT + AVDT_CCB_MKR,      /* start */
217    AVDT_SCB_MSG_CLOSE_CMD_EVT,                     /* close */
218    AVDT_CCB_MSG_SUSPEND_CMD_EVT + AVDT_CCB_MKR,    /* suspend */
219    AVDT_SCB_MSG_ABORT_CMD_EVT,                     /* abort */
220    AVDT_SCB_MSG_SECURITY_CMD_EVT,                  /* security control */
221    AVDT_CCB_MSG_GETCAP_CMD_EVT + AVDT_CCB_MKR,     /* get all capabilities */
222    AVDT_SCB_MSG_DELAY_RPT_CMD_EVT                  /* delay report */
223};
224
225/* response message-to-event lookup table */
226const UINT8 avdt_msg_rsp_2_evt[] = {
227    AVDT_CCB_MSG_DISCOVER_RSP_EVT + AVDT_CCB_MKR,   /* discover */
228    AVDT_CCB_MSG_GETCAP_RSP_EVT + AVDT_CCB_MKR,     /* get capabilities */
229    AVDT_SCB_MSG_SETCONFIG_RSP_EVT,                 /* set configuration */
230    AVDT_SCB_MSG_GETCONFIG_RSP_EVT,                 /* get configuration */
231    AVDT_SCB_MSG_RECONFIG_RSP_EVT,                  /* reconfigure */
232    AVDT_SCB_MSG_OPEN_RSP_EVT,                      /* open */
233    AVDT_CCB_MSG_START_RSP_EVT + AVDT_CCB_MKR,      /* start */
234    AVDT_SCB_MSG_CLOSE_RSP_EVT,                     /* close */
235    AVDT_CCB_MSG_SUSPEND_RSP_EVT + AVDT_CCB_MKR,    /* suspend */
236    AVDT_SCB_MSG_ABORT_RSP_EVT,                     /* abort */
237    AVDT_SCB_MSG_SECURITY_RSP_EVT,                  /* security control */
238    AVDT_CCB_MSG_GETCAP_RSP_EVT + AVDT_CCB_MKR,     /* get all capabilities */
239    AVDT_SCB_MSG_DELAY_RPT_RSP_EVT                  /* delay report */
240};
241
242/* reject message-to-event lookup table */
243const UINT8 avdt_msg_rej_2_evt[] = {
244    AVDT_CCB_MSG_DISCOVER_RSP_EVT + AVDT_CCB_MKR,   /* discover */
245    AVDT_CCB_MSG_GETCAP_RSP_EVT + AVDT_CCB_MKR,     /* get capabilities */
246    AVDT_SCB_MSG_SETCONFIG_REJ_EVT,                 /* set configuration */
247    AVDT_SCB_MSG_GETCONFIG_RSP_EVT,                 /* get configuration */
248    AVDT_SCB_MSG_RECONFIG_RSP_EVT,                  /* reconfigure */
249    AVDT_SCB_MSG_OPEN_REJ_EVT,                      /* open */
250    AVDT_CCB_MSG_START_RSP_EVT + AVDT_CCB_MKR,      /* start */
251    AVDT_SCB_MSG_CLOSE_RSP_EVT,                     /* close */
252    AVDT_CCB_MSG_SUSPEND_RSP_EVT + AVDT_CCB_MKR,    /* suspend */
253    AVDT_SCB_MSG_ABORT_RSP_EVT,                     /* abort */
254    AVDT_SCB_MSG_SECURITY_RSP_EVT,                  /* security control */
255    AVDT_CCB_MSG_GETCAP_RSP_EVT + AVDT_CCB_MKR,     /* get all capabilities */
256    0                                               /* delay report */
257};
258
259/*******************************************************************************
260**
261** Function         avdt_msg_bld_cfg
262**
263** Description      This function builds the configuration parameters contained
264**                  in a command or response message.
265**
266**
267** Returns          void.
268**
269*******************************************************************************/
270static void avdt_msg_bld_cfg(UINT8 **p, tAVDT_CFG *p_cfg)
271{
272    UINT8 len;
273
274    /* for now, just build media transport, codec, and content protection, and multiplexing */
275
276    /* media transport */
277    if (p_cfg->psc_mask & AVDT_PSC_TRANS)
278    {
279        *(*p)++ = AVDT_CAT_TRANS;
280        *(*p)++ = 0; /* length */
281    }
282
283#if AVDT_REPORTING == TRUE
284    /* reporting transport */
285    if (p_cfg->psc_mask & AVDT_PSC_REPORT)
286    {
287        *(*p)++ = AVDT_CAT_REPORT;
288        *(*p)++ = 0; /* length */
289    }
290#endif
291
292    /* codec */
293    if (p_cfg->num_codec != 0)
294    {
295        *(*p)++ = AVDT_CAT_CODEC;
296        len = p_cfg->codec_info[0] + 1;
297        if( len > AVDT_CODEC_SIZE )
298            len = AVDT_CODEC_SIZE;
299
300        memcpy(*p, p_cfg->codec_info, len);
301        *p += len;
302    }
303
304    /* content protection */
305    if (p_cfg->num_protect != 0)
306    {
307        *(*p)++ = AVDT_CAT_PROTECT;
308        len = p_cfg->protect_info[0] + 1;
309        if( len > AVDT_PROTECT_SIZE )
310            len = AVDT_PROTECT_SIZE;
311
312        memcpy(*p, p_cfg->protect_info, len);
313        *p += len;
314    }
315
316#if AVDT_MULTIPLEXING == TRUE
317    /* multiplexing */
318    if (p_cfg->psc_mask & AVDT_PSC_MUX)
319    {
320        *(*p)++ = AVDT_CAT_MUX;
321        /* length */
322        if (p_cfg->psc_mask & AVDT_PSC_RECOV)
323            *(*p)++ = 7; /* frag (1) + media + report + recovery */
324        else if (p_cfg->psc_mask & AVDT_PSC_REPORT)
325            *(*p)++ = 5; /* frag (1) + media + report */
326        else
327            *(*p)++ = 3; /* frag (1) + media */
328
329        /* allow fragmentation */
330        if(p_cfg->mux_mask & AVDT_MUX_FRAG)
331            *(*p)++ = 0x80;
332        else
333            *(*p)++ = 0;
334
335        /* media transport session */
336        *(*p)++ = p_cfg->mux_tsid_media<<3; /* TSID */
337        *(*p)++ = p_cfg->mux_tcid_media<<3; /* TCID */
338
339        if (p_cfg->psc_mask & AVDT_PSC_RECOV)
340        {
341            /* reporting transport session */
342            *(*p)++ = p_cfg->mux_tsid_report<<3; /* TSID */
343            *(*p)++ = p_cfg->mux_tcid_report<<3; /* TCID */
344            /* recovery transport session */
345            *(*p)++ = p_cfg->mux_tsid_recov<<3; /* TSID */
346            *(*p)++ = p_cfg->mux_tcid_recov<<3; /* TCID */
347        }
348        else if (p_cfg->psc_mask & AVDT_PSC_REPORT)
349        {
350            /* reporting transport session */
351            *(*p)++ = p_cfg->mux_tsid_report<<3; /* TSID */
352            *(*p)++ = p_cfg->mux_tcid_report<<3; /* TCID */
353        }
354    }
355#endif
356
357    /* delay report */
358    if (p_cfg->psc_mask & AVDT_PSC_DELAY_RPT)
359    {
360        *(*p)++ = AVDT_CAT_DELAY_RPT;
361        *(*p)++ = 0; /* length */
362    }
363}
364
365/*******************************************************************************
366**
367** Function         avdt_msg_bld_none
368**
369** Description      This message building function builds an empty message.
370**
371**
372** Returns          void.
373**
374*******************************************************************************/
375static void avdt_msg_bld_none(UINT8 **p, tAVDT_MSG *p_msg)
376{
377    UNUSED(p);
378    UNUSED(p_msg);
379    return;
380}
381
382/*******************************************************************************
383**
384** Function         avdt_msg_bld_single
385**
386** Description      This message building function builds a message containing
387**                  a single SEID.
388**
389**
390** Returns          void.
391**
392*******************************************************************************/
393static void avdt_msg_bld_single(UINT8 **p, tAVDT_MSG *p_msg)
394{
395    AVDT_MSG_BLD_SEID(*p, p_msg->single.seid);
396}
397
398/*******************************************************************************
399**
400** Function         avdt_msg_bld_setconfig_cmd
401**
402** Description      This message building function builds a set configuration
403**                  command message.
404**
405**
406** Returns          void.
407**
408*******************************************************************************/
409static void avdt_msg_bld_setconfig_cmd(UINT8 **p, tAVDT_MSG *p_msg)
410{
411    AVDT_MSG_BLD_SEID(*p, p_msg->config_cmd.hdr.seid);
412    AVDT_MSG_BLD_SEID(*p, p_msg->config_cmd.int_seid);
413    avdt_msg_bld_cfg(p, p_msg->config_cmd.p_cfg);
414}
415
416/*******************************************************************************
417**
418** Function         avdt_msg_bld_reconfig_cmd
419**
420** Description      This message building function builds a reconfiguration
421**                  command message.
422**
423**
424** Returns          void.
425**
426*******************************************************************************/
427static void avdt_msg_bld_reconfig_cmd(UINT8 **p, tAVDT_MSG *p_msg)
428{
429    AVDT_MSG_BLD_SEID(*p, p_msg->reconfig_cmd.hdr.seid);
430
431    /* force psc mask zero to build only codec and security */
432    p_msg->reconfig_cmd.p_cfg->psc_mask = 0;
433    avdt_msg_bld_cfg(p, p_msg->reconfig_cmd.p_cfg);
434}
435
436/*******************************************************************************
437**
438** Function         avdt_msg_bld_multi
439**
440** Description      This message building function builds a message containing
441**                  multiple SEID's.
442**
443**
444** Returns          void.
445**
446*******************************************************************************/
447static void avdt_msg_bld_multi(UINT8 **p, tAVDT_MSG *p_msg)
448{
449    int i;
450
451    for (i = 0; i < p_msg->multi.num_seps; i++)
452    {
453        AVDT_MSG_BLD_SEID(*p, p_msg->multi.seid_list[i]);
454    }
455}
456
457/*******************************************************************************
458**
459** Function         avdt_msg_bld_security_cmd
460**
461** Description      This message building function builds a security
462**                  command message.
463**
464** Returns          void.
465**
466*******************************************************************************/
467static void avdt_msg_bld_security_cmd(UINT8 **p, tAVDT_MSG *p_msg)
468{
469    AVDT_MSG_BLD_SEID(*p, p_msg->security_cmd.hdr.seid);
470    memcpy(*p, p_msg->security_cmd.p_data, p_msg->security_cmd.len);
471    *p += p_msg->security_cmd.len;
472}
473
474/*******************************************************************************
475**
476** Function         avdt_msg_bld_delay_rpt
477**
478** Description      This message building function builds a delay report
479**                  command message.
480**
481** Returns          void.
482**
483*******************************************************************************/
484static void avdt_msg_bld_delay_rpt(UINT8 **p, tAVDT_MSG *p_msg)
485{
486    AVDT_MSG_BLD_SEID(*p, p_msg->delay_rpt_cmd.hdr.seid);
487    UINT16_TO_BE_STREAM(*p, p_msg->delay_rpt_cmd.delay);
488}
489
490/*******************************************************************************
491**
492** Function         avdt_msg_bld_discover_rsp
493**
494** Description      This message building function builds a discover
495**                  response message.
496**
497**
498** Returns          void.
499**
500*******************************************************************************/
501static void avdt_msg_bld_discover_rsp(UINT8 **p, tAVDT_MSG *p_msg)
502{
503    int     i;
504
505    for (i = 0; i < p_msg->discover_rsp.num_seps; i++)
506    {
507        /* build discover rsp info */
508        AVDT_MSG_BLD_DISC(*p, p_msg->discover_rsp.p_sep_info[i].seid,
509                              p_msg->discover_rsp.p_sep_info[i].in_use,
510                              p_msg->discover_rsp.p_sep_info[i].media_type,
511                              p_msg->discover_rsp.p_sep_info[i].tsep);
512    }
513}
514
515/*******************************************************************************
516**
517** Function         avdt_msg_bld_svccap
518**
519** Description      This message building function builds a message containing
520**                  service capabilities parameters.
521**
522**
523** Returns          void.
524**
525*******************************************************************************/
526static void avdt_msg_bld_svccap(UINT8 **p, tAVDT_MSG *p_msg)
527{
528    tAVDT_CFG cfg;
529
530    /* make sure the delay report category is not reported */
531    memcpy (&cfg, p_msg->svccap.p_cfg, sizeof(tAVDT_CFG));
532    cfg.psc_mask &= ~AVDT_PSC_DELAY_RPT;
533    avdt_msg_bld_cfg(p, &cfg);
534}
535
536/*******************************************************************************
537**
538** Function         avdt_msg_bld_all_svccap
539**
540** Description      This message building function builds a message containing
541**                  service capabilities parameters.
542**
543**
544** Returns          void.
545**
546*******************************************************************************/
547static void avdt_msg_bld_all_svccap(UINT8 **p, tAVDT_MSG *p_msg)
548{
549    avdt_msg_bld_cfg(p, p_msg->svccap.p_cfg);
550}
551
552/*******************************************************************************
553**
554** Function         avdt_msg_bld_security_rsp
555**
556** Description      This message building function builds a security
557**                  response message.
558**
559**
560** Returns          void.
561**
562*******************************************************************************/
563static void avdt_msg_bld_security_rsp(UINT8 **p, tAVDT_MSG *p_msg)
564{
565    memcpy(*p, p_msg->security_rsp.p_data, p_msg->security_rsp.len);
566    *p += p_msg->security_rsp.len;
567}
568
569/*******************************************************************************
570**
571** Function         avdt_msg_prs_cfg
572**
573** Description      This message parsing function parses the configuration
574**                  parameters field of a message.
575**
576**
577** Returns          Error code or zero if no error, and element that failed
578**                  in p_elem.
579**
580*******************************************************************************/
581static UINT8 avdt_msg_prs_cfg(tAVDT_CFG *p_cfg, UINT8 *p, UINT16 len, UINT8* p_elem, UINT8 sig_id)
582{
583    UINT8   *p_end;
584    UINT8   elem = 0;
585    UINT8   elem_len;
586    UINT8   tmp;
587    UINT8   err = 0;
588    UINT8   protect_offset = 0;
589
590    if (!p_cfg)
591    {
592        AVDT_TRACE_ERROR ("not expecting this cfg");
593        return AVDT_ERR_BAD_STATE;
594    }
595
596    p_cfg->psc_mask = 0;
597    p_cfg->num_codec = 0;
598    p_cfg->num_protect = 0;
599#if AVDT_MULTIPLEXING == TRUE
600    p_cfg->mux_mask = 0;
601#endif
602
603    /* while there is still data to parse */
604    p_end = p + len;
605    while ((p < p_end) && (err == 0))
606    {
607        /* verify overall length */
608        if ((p_end - p) < AVDT_LEN_CFG_MIN)
609        {
610            err = AVDT_ERR_PAYLOAD;
611            break;
612        }
613
614        /* get and verify info elem id, length */
615        elem = *p++;
616        elem_len = *p++;
617
618        if ((elem == 0) || (elem > AVDT_CAT_MAX_CUR))
619        {
620            /* this may not be really bad.
621             * It may be a service category that is too new for us.
622             * allow these to be parsed without reporting an error.
623             * If this is a "capability" (as in GetCapRsp & GetConfigRsp), this is filtered out.
624             * If this is a Configuration (as in SetConfigCmd & ReconfigCmd),
625             *    this will be marked as an error in the caller of this function */
626            if ((sig_id == AVDT_SIG_SETCONFIG) || (sig_id == AVDT_SIG_RECONFIG))
627            {
628                /* Cannot accept unknown category. */
629                err = AVDT_ERR_CATEGORY;
630                break;
631            }
632            else    /* GETCAP or GET_ALLCAP */
633            {
634                /* Skip unknown categories. */
635                p += elem_len;
636                AVDT_TRACE_DEBUG("skipping unknown service category=%d len: %d", elem, elem_len);
637                continue;
638            }
639        }
640
641        if ((elem_len > avdt_msg_ie_len_max[elem]) ||
642            (elem_len < avdt_msg_ie_len_min[elem]))
643        {
644            err = avdt_msg_ie_err[elem];
645            break;
646        }
647
648        /* add element to psc mask, but mask out codec or protect */
649        p_cfg->psc_mask |= (1 << elem);
650        AVDT_TRACE_DEBUG("elem=%d elem_len: %d psc_mask=0x%x", elem, elem_len, p_cfg->psc_mask);
651
652        /* parse individual information elements with additional parameters */
653        switch (elem)
654        {
655            case AVDT_CAT_RECOV:
656                p_cfg->recov_type = *p++;
657                p_cfg->recov_mrws = *p++;
658                p_cfg->recov_mnmp = *p++;
659                if (p_cfg->recov_type != AVDT_RECOV_RFC2733)
660                {
661                    err = AVDT_ERR_RECOV_TYPE;
662                }
663                else if ((p_cfg->recov_mrws < AVDT_RECOV_MRWS_MIN) ||
664                         (p_cfg->recov_mrws > AVDT_RECOV_MRWS_MAX) ||
665                         (p_cfg->recov_mnmp < AVDT_RECOV_MNMP_MIN) ||
666                         (p_cfg->recov_mnmp > AVDT_RECOV_MNMP_MAX))
667                {
668                    err = AVDT_ERR_RECOV_FMT;
669                }
670                break;
671
672            case AVDT_CAT_PROTECT:
673                p_cfg->psc_mask &= ~AVDT_PSC_PROTECT;
674                if ((elem_len + protect_offset) < AVDT_PROTECT_SIZE)
675                {
676                    p_cfg->num_protect++;
677                    p_cfg->protect_info[protect_offset] = elem_len;
678                    protect_offset++;
679                    memcpy(&p_cfg->protect_info[protect_offset], p, elem_len);
680                    protect_offset += elem_len;
681                }
682                p += elem_len;
683                break;
684
685            case AVDT_CAT_HDRCMP:
686                p_cfg->hdrcmp_mask = *p++;
687                break;
688
689#if AVDT_MULTIPLEXING == TRUE
690            case AVDT_CAT_MUX:
691                /* verify length */
692                AVDT_TRACE_WARNING("psc_mask=0x%x elem_len=%d", p_cfg->psc_mask, elem_len);
693                if( ((0 == (p_cfg->psc_mask & (AVDT_PSC_RECOV|AVDT_PSC_REPORT))) && (elem_len != 3))
694                    || (((p_cfg->psc_mask & AVDT_PSC_REPORT) && !(p_cfg->psc_mask & AVDT_PSC_RECOV))
695                    && (elem_len != 5))
696                    || ((!(p_cfg->psc_mask & AVDT_PSC_REPORT) && (p_cfg->psc_mask & AVDT_PSC_RECOV))
697                    && (elem_len != 5))
698                    || (((p_cfg->psc_mask & AVDT_PSC_REPORT) && (p_cfg->psc_mask & AVDT_PSC_RECOV))
699                    && (elem_len != 7)) )
700                {
701                    err = AVDT_ERR_MUX_FMT;
702                    break;
703                }
704
705                /* parse fragmentation */
706                p_cfg->mux_mask = *p++ & (UINT8)AVDT_MUX_FRAG;
707
708                /* parse TSIDs and TCIDs */
709                if(--elem_len)
710                    p_cfg->mux_tsid_media = (*p++)>>3;
711                else
712                    break;
713
714                if(--elem_len)
715                    p_cfg->mux_tcid_media = (*p++)>>3;
716                else
717                    break;
718
719                if(--elem_len)
720                    p_cfg->mux_tsid_report = (*p++)>>3;
721                else
722                    break;
723
724                if(--elem_len)
725                    p_cfg->mux_tcid_report = (*p++)>>3;
726                else
727                    break;
728
729                if(--elem_len)
730                    p_cfg->mux_tsid_recov = (*p++)>>3;
731                else
732                    break;
733
734                if(--elem_len)
735                    p_cfg->mux_tcid_recov = (*p++)>>3;
736                else
737                    break;
738                break;
739#endif
740
741            case AVDT_CAT_CODEC:
742                p_cfg->psc_mask &= ~AVDT_PSC_CODEC;
743                tmp = elem_len;
744                if (elem_len >= AVDT_CODEC_SIZE)
745                {
746                    tmp = AVDT_CODEC_SIZE - 1;
747                }
748                p_cfg->num_codec++;
749                p_cfg->codec_info[0] = elem_len;
750                memcpy(&p_cfg->codec_info[1], p, tmp);
751                p += elem_len;
752                break;
753
754            case AVDT_CAT_DELAY_RPT:
755                break;
756
757            default:
758                p += elem_len;
759                break;
760        } /* switch */
761    } /* while ! err, !end*/
762    *p_elem = elem;
763    AVDT_TRACE_DEBUG("err=0x%x, elem:0x%x psc_mask=0x%x", err, elem, p_cfg->psc_mask);
764
765    return err;
766}
767
768/*******************************************************************************
769**
770** Function         avdt_msg_prs_none
771**
772** Description      This message parsing function parses a message with no parameters.
773
774**
775**
776** Returns          Error code or zero if no error.
777**
778*******************************************************************************/
779static UINT8 avdt_msg_prs_none(tAVDT_MSG *p_msg, UINT8 *p, UINT16 len)
780{
781    UNUSED(p_msg);
782    UNUSED(p);
783    UNUSED(len);
784    return 0;
785}
786
787/*******************************************************************************
788**
789** Function         avdt_msg_prs_single
790**
791** Description      This message parsing function parses a message with a
792**                  single SEID.
793**
794**
795** Returns          Error code or zero if no error.
796**
797*******************************************************************************/
798static UINT8 avdt_msg_prs_single(tAVDT_MSG *p_msg, UINT8 *p, UINT16 len)
799{
800    UINT8       err = 0;
801
802    /* verify len */
803    if (len != AVDT_LEN_SINGLE)
804    {
805        err = AVDT_ERR_LENGTH;
806    }
807    else
808    {
809        AVDT_MSG_PRS_SEID(p, p_msg->single.seid);
810
811        if (avdt_scb_by_hdl(p_msg->single.seid) == NULL)
812        {
813            err = AVDT_ERR_SEID;
814        }
815    }
816    return err;
817}
818
819/*******************************************************************************
820**
821** Function         avdt_msg_prs_setconfig_cmd
822**
823** Description      This message parsing function parses a set configuration
824**                  command message.
825**
826**
827** Returns          Error code or zero if no error.
828**
829*******************************************************************************/
830static UINT8 avdt_msg_prs_setconfig_cmd(tAVDT_MSG *p_msg, UINT8 *p, UINT16 len)
831{
832    UINT8       err = 0;
833
834    p_msg->hdr.err_param = 0;
835
836    /* verify len */
837    if (len < AVDT_LEN_SETCONFIG_MIN)
838    {
839        err = AVDT_ERR_LENGTH;
840    }
841    else
842    {
843        /* get seids */
844        AVDT_MSG_PRS_SEID(p, p_msg->config_cmd.hdr.seid);
845        if (avdt_scb_by_hdl(p_msg->config_cmd.hdr.seid) == NULL)
846        {
847            err = AVDT_ERR_SEID;
848        }
849
850        AVDT_MSG_PRS_SEID(p, p_msg->config_cmd.int_seid);
851        if ((p_msg->config_cmd.int_seid < AVDT_SEID_MIN) ||
852            (p_msg->config_cmd.int_seid > AVDT_SEID_MAX))
853        {
854            err = AVDT_ERR_SEID;
855        }
856    }
857
858    if (!err)
859    {
860        /* parse configuration parameters */
861        len -= 2;
862        err = avdt_msg_prs_cfg(p_msg->config_cmd.p_cfg, p, len, &p_msg->hdr.err_param, AVDT_SIG_SETCONFIG);
863
864        if (!err)
865        {
866            /* verify protocol service capabilities are supported */
867            if (((p_msg->config_cmd.p_cfg->psc_mask & (~AVDT_PSC)) != 0) ||
868                (p_msg->config_cmd.p_cfg->num_codec == 0))
869            {
870                err = AVDT_ERR_INVALID_CAP;
871            }
872        }
873    }
874
875    return err;
876}
877
878/*******************************************************************************
879**
880** Function         avdt_msg_prs_reconfig_cmd
881**
882** Description      This message parsing function parses a reconfiguration
883**                  command message.
884**
885**
886** Returns          Error code or zero if no error.
887**
888*******************************************************************************/
889static UINT8 avdt_msg_prs_reconfig_cmd(tAVDT_MSG *p_msg, UINT8 *p, UINT16 len)
890{
891    UINT8       err = 0;
892
893    p_msg->hdr.err_param = 0;
894
895    /* verify len */
896    if (len < AVDT_LEN_RECONFIG_MIN)
897    {
898        err = AVDT_ERR_LENGTH;
899    }
900    else
901    {
902        /* get seid */
903        AVDT_MSG_PRS_SEID(p, p_msg->reconfig_cmd.hdr.seid);
904        if (avdt_scb_by_hdl(p_msg->reconfig_cmd.hdr.seid) == NULL)
905        {
906            err = AVDT_ERR_SEID;
907        }
908        else
909        {
910            /* parse config parameters */
911            len--;
912            err = avdt_msg_prs_cfg(p_msg->config_cmd.p_cfg, p, len, &p_msg->hdr.err_param, AVDT_SIG_RECONFIG);
913
914            /* verify no protocol service capabilities in parameters */
915            if (!err)
916            {
917                AVDT_TRACE_DEBUG("avdt_msg_prs_reconfig_cmd psc_mask=0x%x/0x%x", p_msg->config_cmd.p_cfg->psc_mask, AVDT_MSG_PSC_MASK);
918                if ((p_msg->config_cmd.p_cfg->psc_mask != 0) ||
919                    (p_msg->config_cmd.p_cfg->num_codec == 0 && p_msg->config_cmd.p_cfg->num_protect == 0))
920                {
921                    err = AVDT_ERR_INVALID_CAP;
922                }
923            }
924        }
925    }
926    return err;
927}
928
929/*******************************************************************************
930**
931** Function         avdt_msg_prs_multi
932**
933** Description      This message parsing function parses a message containing
934**                  multiple SEID's.
935**
936**
937** Returns          Error code or zero if no error.
938**
939*******************************************************************************/
940static UINT8 avdt_msg_prs_multi(tAVDT_MSG *p_msg, UINT8 *p, UINT16 len)
941{
942    int     i;
943    UINT8   err = 0;
944
945    p_msg->hdr.err_param = 0;
946
947    /* verify len */
948    if (len < AVDT_LEN_MULTI_MIN || (len > AVDT_NUM_SEPS))
949    {
950        err = AVDT_ERR_LENGTH;
951    }
952    else
953    {
954        /* get and verify all seps */
955        for (i = 0; i < len; i++)
956        {
957            AVDT_MSG_PRS_SEID(p, p_msg->multi.seid_list[i]);
958            if (avdt_scb_by_hdl(p_msg->multi.seid_list[i]) == NULL)
959            {
960                err = AVDT_ERR_SEID;
961                p_msg->hdr.err_param = p_msg->multi.seid_list[i];
962                break;
963            }
964        }
965        p_msg->multi.num_seps = (UINT8)i;
966    }
967
968    return err;
969}
970
971/*******************************************************************************
972**
973** Function         avdt_msg_prs_security_cmd
974**
975** Description      This message parsing function parses a security
976**                  command message.
977**
978**
979** Returns          Error code or zero if no error.
980**
981*******************************************************************************/
982static UINT8 avdt_msg_prs_security_cmd(tAVDT_MSG *p_msg, UINT8 *p, UINT16 len)
983{
984    UINT8       err = 0;
985
986    /* verify len */
987    if (len < AVDT_LEN_SECURITY_MIN)
988    {
989        err = AVDT_ERR_LENGTH;
990    }
991    else
992    {
993        /* get seid */
994        AVDT_MSG_PRS_SEID(p, p_msg->security_cmd.hdr.seid);
995        if (avdt_scb_by_hdl(p_msg->security_cmd.hdr.seid) == NULL)
996        {
997            err = AVDT_ERR_SEID;
998        }
999        else
1000        {
1001            p_msg->security_cmd.p_data = p;
1002            p_msg->security_cmd.len = len - 1;
1003        }
1004    }
1005    return err;
1006}
1007
1008/*******************************************************************************
1009**
1010** Function         avdt_msg_prs_discover_rsp
1011**
1012** Description      This message parsing function parses a discover
1013**                  response message.
1014**
1015**
1016** Returns          Error code or zero if no error.
1017**
1018*******************************************************************************/
1019static UINT8 avdt_msg_prs_discover_rsp(tAVDT_MSG *p_msg, UINT8 *p, UINT16 len)
1020{
1021    int     i;
1022    UINT8   err = 0;
1023
1024    /* determine number of seps; seps in msg is len/2, but set to minimum
1025    ** of seps app has supplied memory for and seps in msg
1026    */
1027    if (p_msg->discover_rsp.num_seps > (len / 2))
1028    {
1029        p_msg->discover_rsp.num_seps = (len / 2);
1030    }
1031
1032    /* parse out sep info */
1033    for (i = 0; i < p_msg->discover_rsp.num_seps; i++)
1034    {
1035        /* parse discover rsp info */
1036        AVDT_MSG_PRS_DISC(p, p_msg->discover_rsp.p_sep_info[i].seid,
1037                          p_msg->discover_rsp.p_sep_info[i].in_use,
1038                          p_msg->discover_rsp.p_sep_info[i].media_type,
1039                          p_msg->discover_rsp.p_sep_info[i].tsep);
1040
1041        /* verify that seid is valid */
1042        if ((p_msg->discover_rsp.p_sep_info[i].seid < AVDT_SEID_MIN) ||
1043            (p_msg->discover_rsp.p_sep_info[i].seid > AVDT_SEID_MAX))
1044        {
1045            err = AVDT_ERR_SEID;
1046            break;
1047        }
1048    }
1049
1050    return err;
1051}
1052
1053/*******************************************************************************
1054**
1055** Function         avdt_msg_prs_svccap
1056**
1057** Description      This message parsing function parses a message containing
1058**                  service capabilities parameters.
1059**
1060**
1061** Returns          Error code or zero if no error.
1062**
1063*******************************************************************************/
1064static UINT8 avdt_msg_prs_svccap(tAVDT_MSG *p_msg, UINT8 *p, UINT16 len)
1065{
1066    /* parse parameters */
1067    UINT8   err = avdt_msg_prs_cfg(p_msg->svccap.p_cfg, p, len, &p_msg->hdr.err_param, AVDT_SIG_GETCAP);
1068    if (p_msg->svccap.p_cfg)
1069    {
1070        p_msg->svccap.p_cfg->psc_mask &= AVDT_LEG_PSC;
1071    }
1072
1073    return (err);
1074}
1075
1076/*******************************************************************************
1077**
1078** Function         avdt_msg_prs_all_svccap
1079**
1080** Description      This message parsing function parses a message containing
1081**                  service capabilities parameters.
1082**
1083**
1084** Returns          Error code or zero if no error.
1085**
1086*******************************************************************************/
1087static UINT8 avdt_msg_prs_all_svccap(tAVDT_MSG *p_msg, UINT8 *p, UINT16 len)
1088{
1089    UINT8   err = avdt_msg_prs_cfg(p_msg->svccap.p_cfg, p, len, &p_msg->hdr.err_param, AVDT_SIG_GET_ALLCAP);
1090    if (p_msg->svccap.p_cfg)
1091    {
1092        p_msg->svccap.p_cfg->psc_mask &= AVDT_MSG_PSC_MASK;
1093    }
1094    return (err);
1095}
1096
1097/*******************************************************************************
1098**
1099** Function         avdt_msg_prs_security_rsp
1100**
1101** Description      This message parsing function parsing a security
1102**                  response message.
1103**
1104**
1105** Returns          Error code or zero if no error.
1106**
1107*******************************************************************************/
1108static UINT8 avdt_msg_prs_security_rsp(tAVDT_MSG *p_msg, UINT8 *p, UINT16 len)
1109{
1110    p_msg->security_rsp.p_data = p;
1111    p_msg->security_rsp.len = len;
1112
1113    return 0;
1114}
1115
1116/*******************************************************************************
1117**
1118** Function         avdt_msg_prs_rej
1119**
1120** Description
1121**
1122**
1123** Returns          Error code or zero if no error.
1124**
1125*******************************************************************************/
1126static UINT8 avdt_msg_prs_rej(tAVDT_MSG *p_msg, UINT8 *p, UINT8 sig)
1127{
1128    if ((sig == AVDT_SIG_SETCONFIG) || (sig == AVDT_SIG_RECONFIG))
1129    {
1130        p_msg->hdr.err_param = *p++;
1131        p_msg->hdr.err_code = *p;
1132    }
1133    else if ((sig == AVDT_SIG_START) || (sig == AVDT_SIG_SUSPEND))
1134    {
1135        AVDT_MSG_PRS_SEID(p, p_msg->hdr.err_param);
1136        p_msg->hdr.err_code = *p;
1137    }
1138    else
1139    {
1140        p_msg->hdr.err_code = *p;
1141    }
1142
1143    return 0;
1144}
1145
1146/*******************************************************************************
1147**
1148** Function         avdt_msg_prs_delay_rpt
1149**
1150** Description      This message parsing function parses a security
1151**                  command message.
1152**
1153**
1154** Returns          Error code or zero if no error.
1155**
1156*******************************************************************************/
1157static UINT8 avdt_msg_prs_delay_rpt (tAVDT_MSG *p_msg, UINT8 *p, UINT16 len)
1158{
1159    UINT8       err = 0;
1160
1161    /* verify len */
1162    if (len != AVDT_LEN_DELAY_RPT)
1163    {
1164        AVDT_TRACE_WARNING("avdt_msg_prs_delay_rpt expected len: %u  got: %u", AVDT_LEN_DELAY_RPT, len);
1165        err = AVDT_ERR_LENGTH;
1166    }
1167    else
1168    {
1169        /* get seid */
1170        AVDT_MSG_PRS_SEID (p, p_msg->delay_rpt_cmd.hdr.seid);
1171
1172        if (avdt_scb_by_hdl(p_msg->delay_rpt_cmd.hdr.seid) == NULL)
1173        {
1174            err = AVDT_ERR_SEID;
1175        }
1176        else
1177        {
1178            BE_STREAM_TO_UINT16 (p_msg->delay_rpt_cmd.delay, p);
1179            AVDT_TRACE_DEBUG("avdt_msg_prs_delay_rpt delay: %u", p_msg->delay_rpt_cmd.delay);
1180        }
1181    }
1182    return err;
1183}
1184
1185
1186/*******************************************************************************
1187**
1188** Function         avdt_msg_send
1189**
1190** Description      Send, and if necessary fragment the next message.
1191**
1192**
1193** Returns          Congested state; TRUE if CCB congested, FALSE if not.
1194**
1195*******************************************************************************/
1196BOOLEAN avdt_msg_send(tAVDT_CCB *p_ccb, BT_HDR *p_msg)
1197{
1198    UINT16          curr_msg_len;
1199    UINT8           pkt_type;
1200    UINT8           hdr_len;
1201    tAVDT_TC_TBL    *p_tbl;
1202    BT_HDR          *p_buf;
1203    UINT8           *p;
1204    UINT8           label;
1205    UINT8           msg;
1206    UINT8           sig;
1207    UINT8           nosp = 0;       /* number of subsequent packets */
1208
1209    /* look up transport channel table entry to get peer mtu */
1210    p_tbl = avdt_ad_tc_tbl_by_type(AVDT_CHAN_SIG, p_ccb, NULL);
1211
1212    /* set the current message if there is a message passed in */
1213    if (p_msg != NULL)
1214    {
1215        p_ccb->p_curr_msg = p_msg;
1216    }
1217
1218    /* store copy of curr_msg->len */
1219    curr_msg_len = p_ccb->p_curr_msg->len;
1220
1221    /* while not congested and we haven't sent it all */
1222    while ((!p_ccb->cong) && (p_ccb->p_curr_msg != NULL))
1223    {
1224        /* check what kind of message we've got here; we are using the offset
1225        ** to indicate that a message is being fragmented
1226        */
1227
1228        /* if message isn't being fragmented and it fits in mtu */
1229        if ((p_ccb->p_curr_msg->offset == AVDT_MSG_OFFSET) &&
1230            (p_ccb->p_curr_msg->len <= p_tbl->peer_mtu - AVDT_LEN_TYPE_SINGLE))
1231        {
1232            pkt_type = AVDT_PKT_TYPE_SINGLE;
1233            hdr_len = AVDT_LEN_TYPE_SINGLE;
1234            p_buf = p_ccb->p_curr_msg;
1235        }
1236        /* if message isn't being fragmented and it doesn't fit in mtu */
1237        else if ((p_ccb->p_curr_msg->offset == AVDT_MSG_OFFSET) &&
1238                 (p_ccb->p_curr_msg->len > p_tbl->peer_mtu - AVDT_LEN_TYPE_SINGLE))
1239        {
1240            pkt_type = AVDT_PKT_TYPE_START;
1241            hdr_len = AVDT_LEN_TYPE_START;
1242            nosp = (p_ccb->p_curr_msg->len + AVDT_LEN_TYPE_START - p_tbl->peer_mtu) /
1243                   (p_tbl->peer_mtu - 1) + 2;
1244
1245            /* get a new buffer for fragment we are sending */
1246            if ((p_buf = (BT_HDR *) GKI_getpoolbuf(AVDT_CMD_POOL_ID)) == NULL)
1247            {
1248                /* do we even want to try and recover from this? could do so
1249                by setting retransmission timer */
1250                return TRUE;
1251            }
1252
1253            /* copy portion of data from current message to new buffer */
1254            p_buf->offset = L2CAP_MIN_OFFSET + hdr_len;
1255            p_buf->len = p_tbl->peer_mtu - hdr_len;
1256            memcpy((UINT8 *)(p_buf + 1) + p_buf->offset,
1257                   (UINT8 *)(p_ccb->p_curr_msg + 1) + p_ccb->p_curr_msg->offset, p_buf->len);
1258        }
1259        /* if message is being fragmented and remaining bytes don't fit in mtu */
1260        else if ((p_ccb->p_curr_msg->offset > AVDT_MSG_OFFSET) &&
1261                 (p_ccb->p_curr_msg->len > (p_tbl->peer_mtu - AVDT_LEN_TYPE_CONT)))
1262        {
1263            pkt_type = AVDT_PKT_TYPE_CONT;
1264            hdr_len = AVDT_LEN_TYPE_CONT;
1265
1266            /* get a new buffer for fragment we are sending */
1267            if ((p_buf = (BT_HDR *) GKI_getpoolbuf(AVDT_CMD_POOL_ID)) == NULL)
1268            {
1269                /* do we even want to try and recover from this? could do so
1270                by setting retransmission timer */
1271                return TRUE;
1272            }
1273
1274            /* copy portion of data from current message to new buffer */
1275            p_buf->offset = L2CAP_MIN_OFFSET + hdr_len;
1276            p_buf->len = p_tbl->peer_mtu - hdr_len;
1277            memcpy((UINT8 *)(p_buf + 1) + p_buf->offset,
1278                   (UINT8 *)(p_ccb->p_curr_msg + 1) + p_ccb->p_curr_msg->offset, p_buf->len);
1279        }
1280        /* if message is being fragmented and remaining bytes do fit in mtu */
1281        else
1282        {
1283            pkt_type = AVDT_PKT_TYPE_END;
1284            hdr_len = AVDT_LEN_TYPE_END;
1285            p_buf = p_ccb->p_curr_msg;
1286        }
1287
1288        /* label, sig id, msg type are in hdr of p_curr_msg */
1289        label = AVDT_LAYERSPEC_LABEL(p_ccb->p_curr_msg->layer_specific);
1290        msg = AVDT_LAYERSPEC_MSG(p_ccb->p_curr_msg->layer_specific);
1291        sig = (UINT8) p_ccb->p_curr_msg->event;
1292        AVDT_TRACE_DEBUG("avdt_msg_send label:%d, msg:%d, sig:%d", label, msg, sig);
1293
1294        /* keep track of how much of msg we've sent */
1295        curr_msg_len -= p_buf->len;
1296        if (curr_msg_len == 0)
1297        {
1298            /* entire message sent; mark as finished */
1299            p_ccb->p_curr_msg = NULL;
1300
1301            /* start timer here for commands */
1302            if (msg == AVDT_MSG_TYPE_CMD)
1303            {
1304                /* if retransmit timeout set to zero, sig doesn't use retransmit */
1305                if ((sig == AVDT_SIG_DISCOVER) || (sig == AVDT_SIG_GETCAP) ||
1306                    (sig == AVDT_SIG_SECURITY) || (avdt_cb.rcb.ret_tout == 0))
1307                {
1308                    btu_start_timer(&p_ccb->timer_entry, BTU_TTYPE_AVDT_CCB_RSP, avdt_cb.rcb.sig_tout);
1309                }
1310                else if (sig != AVDT_SIG_DELAY_RPT)
1311                {
1312                    btu_start_timer(&p_ccb->timer_entry, BTU_TTYPE_AVDT_CCB_RET, avdt_cb.rcb.ret_tout);
1313                }
1314            }
1315        }
1316        else
1317        {
1318            /* message being fragmented and not completely sent */
1319            p_ccb->p_curr_msg->len -= p_buf->len;
1320            p_ccb->p_curr_msg->offset += p_buf->len;
1321        }
1322
1323        /* set up to build header */
1324        p_buf->len += hdr_len;
1325        p_buf->offset -= hdr_len;
1326        p = (UINT8 *)(p_buf + 1) + p_buf->offset;
1327
1328        /* build header */
1329        AVDT_MSG_BLD_HDR(p, label, pkt_type, msg);
1330        if (pkt_type == AVDT_PKT_TYPE_START)
1331        {
1332            AVDT_MSG_BLD_NOSP(p, nosp);
1333        }
1334        if ((pkt_type == AVDT_PKT_TYPE_START) || (pkt_type == AVDT_PKT_TYPE_SINGLE))
1335        {
1336            AVDT_MSG_BLD_SIG(p, sig);
1337        }
1338
1339        /* send msg buffer down */
1340        avdt_ad_write_req(AVDT_CHAN_SIG, p_ccb, NULL, p_buf);
1341    }
1342    return (p_ccb->cong);
1343}
1344
1345/*******************************************************************************
1346**
1347** Function         avdt_msg_asmbl
1348**
1349** Description      Reassemble incoming message.
1350**
1351**
1352** Returns          Pointer to reassembled message;  NULL if no message
1353**                  available.
1354**
1355*******************************************************************************/
1356BT_HDR *avdt_msg_asmbl(tAVDT_CCB *p_ccb, BT_HDR *p_buf)
1357{
1358    UINT8   *p;
1359    UINT8   pkt_type;
1360    BT_HDR  *p_ret;
1361    UINT16  buf_len;
1362
1363    /* parse the message header */
1364    p = (UINT8 *)(p_buf + 1) + p_buf->offset;
1365    AVDT_MSG_PRS_PKT_TYPE(p, pkt_type);
1366
1367    /* quick sanity check on length */
1368    if (p_buf->len < avdt_msg_pkt_type_len[pkt_type])
1369    {
1370        GKI_freebuf(p_buf);
1371        AVDT_TRACE_WARNING("Bad length during reassembly");
1372        p_ret = NULL;
1373    }
1374    /* single packet */
1375    else if (pkt_type == AVDT_PKT_TYPE_SINGLE)
1376    {
1377        /* if reassembly in progress drop message and process new single */
1378        if (p_ccb->p_rx_msg != NULL)
1379        {
1380            GKI_freebuf(p_ccb->p_rx_msg);
1381            p_ccb->p_rx_msg = NULL;
1382            AVDT_TRACE_WARNING("Got single during reassembly");
1383        }
1384        p_ret = p_buf;
1385    }
1386    /* start packet */
1387    else if (pkt_type == AVDT_PKT_TYPE_START)
1388    {
1389        /* if reassembly in progress drop message and process new single */
1390        if (p_ccb->p_rx_msg != NULL)
1391        {
1392            GKI_freebuf(p_ccb->p_rx_msg);
1393            AVDT_TRACE_WARNING("Got start during reassembly");
1394        }
1395        p_ccb->p_rx_msg = p_buf;
1396
1397        /* copy first header byte over nosp */
1398        *(p + 1) = *p;
1399
1400        /* set offset to point to where to copy next */
1401        p_ccb->p_rx_msg->offset += p_ccb->p_rx_msg->len;
1402
1403        /* adjust length for packet header */
1404        p_ccb->p_rx_msg->len -= 1;
1405
1406        p_ret = NULL;
1407    }
1408    /* continue or end */
1409    else
1410    {
1411        /* if no reassembly in progress drop message */
1412        if (p_ccb->p_rx_msg == NULL)
1413        {
1414            GKI_freebuf(p_buf);
1415            AVDT_TRACE_WARNING("Pkt type=%d out of order", pkt_type);
1416            p_ret = NULL;
1417        }
1418        else
1419        {
1420            /* get size of buffer holding assembled message */
1421            buf_len = GKI_get_buf_size(p_ccb->p_rx_msg) - sizeof(BT_HDR);
1422
1423            /* adjust offset and len of fragment for header byte */
1424            p_buf->offset += AVDT_LEN_TYPE_CONT;
1425            p_buf->len -= AVDT_LEN_TYPE_CONT;
1426
1427            /* verify length */
1428            if ((p_ccb->p_rx_msg->offset + p_buf->len) > buf_len)
1429            {
1430                /* won't fit; free everything */
1431                GKI_freebuf(p_ccb->p_rx_msg);
1432                p_ccb->p_rx_msg = NULL;
1433                GKI_freebuf(p_buf);
1434                p_ret = NULL;
1435            }
1436            else
1437            {
1438                /* copy contents of p_buf to p_rx_msg */
1439                memcpy((UINT8 *)(p_ccb->p_rx_msg + 1) + p_ccb->p_rx_msg->offset,
1440                       (UINT8 *)(p_buf + 1) + p_buf->offset, p_buf->len);
1441
1442                if (pkt_type == AVDT_PKT_TYPE_END)
1443                {
1444                    p_ccb->p_rx_msg->offset -= p_ccb->p_rx_msg->len;
1445                    p_ccb->p_rx_msg->len += p_buf->len;
1446                    p_ret = p_ccb->p_rx_msg;
1447                    p_ccb->p_rx_msg = NULL;
1448                }
1449                else
1450                {
1451                    p_ccb->p_rx_msg->offset += p_buf->len;
1452                    p_ccb->p_rx_msg->len += p_buf->len;
1453                    p_ret = NULL;
1454                }
1455                GKI_freebuf(p_buf);
1456            }
1457        }
1458    }
1459    return p_ret;
1460}
1461
1462/*******************************************************************************
1463**
1464** Function         avdt_msg_send_cmd
1465**
1466** Description      This function is called to send a command message.  The
1467**                  sig_id parameter indicates the message type, p_params
1468**                  points to the message parameters, if any.  It gets a buffer
1469**                  from the AVDTP command pool, executes the message building
1470**                  function for this message type.  It then queues the message
1471**                  in the command queue for this CCB.
1472**
1473**
1474** Returns          Nothing.
1475**
1476*******************************************************************************/
1477void avdt_msg_send_cmd(tAVDT_CCB *p_ccb, void *p_scb, UINT8 sig_id, tAVDT_MSG *p_params)
1478{
1479    BT_HDR      *p_buf;
1480    UINT8       *p;
1481    UINT8       *p_start;
1482
1483    /* get a buffer */
1484    p_buf = (BT_HDR *) GKI_getpoolbuf(AVDT_CMD_POOL_ID);
1485    if (p_buf == NULL)
1486    {
1487        AVDT_TRACE_ERROR("avdt_msg_send_cmd out of buffer!!");
1488        return;
1489    }
1490
1491    /* set up gki buf pointer and offset */
1492    p_buf->offset = AVDT_MSG_OFFSET;
1493    p_start = p = (UINT8 *)(p_buf + 1) + p_buf->offset;
1494
1495    /* execute parameter building function to build message */
1496    (*avdt_msg_bld_cmd[sig_id - 1])(&p, p_params);
1497
1498    /* set len */
1499    p_buf->len = (UINT16) (p - p_start);
1500
1501    /* now store scb hdls, if any, in buf */
1502    if (p_scb != NULL)
1503    {
1504        p = (UINT8 *)(p_buf + 1);
1505
1506        /* for start and suspend, p_scb points to array of handles */
1507        if ((sig_id == AVDT_SIG_START) || (sig_id == AVDT_SIG_SUSPEND))
1508        {
1509            memcpy(p, (UINT8 *) p_scb, p_buf->len);
1510        }
1511        /* for all others, p_scb points to scb as usual */
1512        else
1513        {
1514            *p = avdt_scb_to_hdl((tAVDT_SCB *) p_scb);
1515        }
1516    }
1517
1518    /* stash sig, label, and message type in buf */
1519    p_buf->event = sig_id;
1520    AVDT_BLD_LAYERSPEC(p_buf->layer_specific, AVDT_MSG_TYPE_CMD, p_ccb->label);
1521
1522    /* increment label */
1523    p_ccb->label = (p_ccb->label + 1) % 16;
1524
1525    /* queue message and trigger ccb to send it */
1526    GKI_enqueue(&p_ccb->cmd_q, p_buf);
1527    avdt_ccb_event(p_ccb, AVDT_CCB_SENDMSG_EVT, NULL);
1528}
1529
1530
1531/*******************************************************************************
1532**
1533** Function         avdt_msg_send_rsp
1534**
1535** Description      This function is called to send a response message.  The
1536**                  sig_id parameter indicates the message type, p_params
1537**                  points to the message parameters, if any.  It gets a buffer
1538**                  from the AVDTP command pool, executes the message building
1539**                  function for this message type.  It then queues the message
1540**                  in the response queue for this CCB.
1541**
1542**
1543** Returns          Nothing.
1544**
1545*******************************************************************************/
1546void avdt_msg_send_rsp(tAVDT_CCB *p_ccb, UINT8 sig_id, tAVDT_MSG *p_params)
1547{
1548    BT_HDR      *p_buf;
1549    UINT8       *p;
1550    UINT8       *p_start;
1551
1552    /* get a buffer */
1553    p_buf = (BT_HDR *) GKI_getpoolbuf(AVDT_CMD_POOL_ID);
1554    if (p_buf == NULL) return;
1555
1556    /* set up gki buf pointer and offset */
1557    p_buf->offset = AVDT_MSG_OFFSET;
1558    p_start = p = (UINT8 *)(p_buf + 1) + p_buf->offset;
1559
1560    /* execute parameter building function to build message */
1561    (*avdt_msg_bld_rsp[sig_id - 1])(&p, p_params);
1562
1563    /* set length */
1564    p_buf->len = (UINT16) (p - p_start);
1565
1566    /* stash sig, label, and message type in buf */
1567    p_buf->event = sig_id;
1568    AVDT_BLD_LAYERSPEC(p_buf->layer_specific, AVDT_MSG_TYPE_RSP, p_params->hdr.label);
1569
1570    /* queue message and trigger ccb to send it */
1571    GKI_enqueue(&p_ccb->rsp_q, p_buf);
1572    avdt_ccb_event(p_ccb, AVDT_CCB_SENDMSG_EVT, NULL);
1573}
1574
1575
1576/*******************************************************************************
1577**
1578** Function         avdt_msg_send_rej
1579**
1580** Description      This function is called to send a reject message.  The
1581**                  sig_id parameter indicates the message type.  It gets
1582**                  a buffer from the AVDTP command pool and builds the
1583**                  message based on the message type and the error code.
1584**                  It then queues the message in the response queue for
1585**                  this CCB.
1586**
1587**
1588** Returns          Nothing.
1589**
1590*******************************************************************************/
1591void avdt_msg_send_rej(tAVDT_CCB *p_ccb, UINT8 sig_id, tAVDT_MSG *p_params)
1592{
1593    BT_HDR      *p_buf;
1594    UINT8       *p;
1595    UINT8       *p_start;
1596
1597    /* get a buffer */
1598    p_buf = (BT_HDR *) GKI_getpoolbuf(AVDT_CMD_POOL_ID);
1599    if (p_buf == NULL) return;
1600
1601    /* set up gki buf pointer and offset */
1602    p_buf->offset = AVDT_MSG_OFFSET;
1603    p_start = p = (UINT8 *)(p_buf + 1) + p_buf->offset;
1604
1605    /* if sig id included, build into message */
1606    if (sig_id != AVDT_SIG_NONE)
1607    {
1608        /* if this sig has a parameter, add the parameter */
1609        if ((sig_id == AVDT_SIG_SETCONFIG) ||
1610            (sig_id == AVDT_SIG_RECONFIG))
1611        {
1612            AVDT_MSG_BLD_PARAM(p, p_params->hdr.err_param);
1613        }
1614        else if ((sig_id == AVDT_SIG_START) ||
1615                 (sig_id == AVDT_SIG_SUSPEND))
1616        {
1617            AVDT_MSG_BLD_SEID(p, p_params->hdr.err_param);
1618        }
1619
1620        /* add the error code */
1621        AVDT_MSG_BLD_ERR(p, p_params->hdr.err_code);
1622    }
1623    AVDT_TRACE_DEBUG("avdt_msg_send_rej");
1624
1625    /* calculate length */
1626    p_buf->len = (UINT16) (p - p_start);
1627
1628    /* stash sig, label, and message type in buf */
1629    p_buf->event = sig_id;
1630    AVDT_BLD_LAYERSPEC(p_buf->layer_specific, AVDT_MSG_TYPE_REJ, p_params->hdr.label);
1631
1632    /* queue message and trigger ccb to send it */
1633    GKI_enqueue(&p_ccb->rsp_q, p_buf);
1634    avdt_ccb_event(p_ccb, AVDT_CCB_SENDMSG_EVT, NULL);
1635}
1636
1637/*******************************************************************************
1638**
1639** Function         avdt_msg_send_grej
1640**
1641** Description      This function is called to send a general reject message.  The
1642**                  sig_id parameter indicates the message type.  It gets
1643**                  a buffer from the AVDTP command pool and builds the
1644**                  message based on the message type and the error code.
1645**                  It then queues the message in the response queue for
1646**                  this CCB.
1647**
1648**
1649** Returns          Nothing.
1650**
1651*******************************************************************************/
1652void avdt_msg_send_grej(tAVDT_CCB *p_ccb, UINT8 sig_id, tAVDT_MSG *p_params)
1653{
1654    BT_HDR      *p_buf;
1655    UINT8       *p;
1656    UINT8       *p_start;
1657
1658    /* get a buffer */
1659    p_buf = (BT_HDR *) GKI_getpoolbuf(AVDT_CMD_POOL_ID);
1660    if (p_buf == NULL) return;
1661
1662    /* set up gki buf pointer and offset */
1663    p_buf->offset = AVDT_MSG_OFFSET;
1664    p_start = p = (UINT8 *)(p_buf + 1) + p_buf->offset;
1665
1666    /* calculate length */
1667    p_buf->len = (UINT16) (p - p_start);
1668
1669    /* stash sig, label, and message type in buf */
1670    p_buf->event = sig_id;
1671    AVDT_BLD_LAYERSPEC(p_buf->layer_specific, AVDT_MSG_TYPE_GRJ, p_params->hdr.label);
1672    //p_buf->event = 0;
1673    //AVDT_BLD_LAYERSPEC(p_buf->layer_specific, 0, p_params->hdr.label);
1674    AVDT_TRACE_DEBUG("avdt_msg_send_grej");
1675
1676    /* queue message and trigger ccb to send it */
1677    GKI_enqueue(&p_ccb->rsp_q, p_buf);
1678    avdt_ccb_event(p_ccb, AVDT_CCB_SENDMSG_EVT, NULL);
1679}
1680
1681/*******************************************************************************
1682**
1683** Function         avdt_msg_ind
1684**
1685** Description      This function is called by the adaption layer when an
1686**                  incoming message is received on the signaling channel.
1687**                  It parses the message and sends an event to the appropriate
1688**                  SCB or CCB for the message.
1689**
1690**
1691** Returns          Nothing.
1692**
1693*******************************************************************************/
1694void avdt_msg_ind(tAVDT_CCB *p_ccb, BT_HDR *p_buf)
1695{
1696    tAVDT_SCB   *p_scb;
1697    UINT8       *p;
1698    BOOLEAN     ok = TRUE;
1699    BOOLEAN     handle_rsp = FALSE;
1700    BOOLEAN     gen_rej = FALSE;
1701    UINT8       label;
1702    UINT8       pkt_type;
1703    UINT8       msg_type;
1704    UINT8       sig = 0;
1705    tAVDT_MSG   msg;
1706    tAVDT_CFG   cfg;
1707    UINT8       err;
1708    UINT8       evt = 0;
1709    UINT8       scb_hdl;
1710
1711    /* reassemble message; if no message available (we received a fragment) return */
1712    if ((p_buf = avdt_msg_asmbl(p_ccb, p_buf)) == NULL)
1713    {
1714        return;
1715    }
1716
1717    p = (UINT8 *)(p_buf + 1) + p_buf->offset;
1718
1719    /* parse the message header */
1720    AVDT_MSG_PRS_HDR(p, label, pkt_type, msg_type);
1721
1722    /* AVDT_TRACE_DEBUG("msg_type=%d", msg_type); */
1723    /* set up label and ccb_idx in message hdr */
1724    msg.hdr.label = label;
1725    msg.hdr.ccb_idx = avdt_ccb_to_idx(p_ccb);
1726
1727    /* verify msg type */
1728    if (msg_type == AVDT_MSG_TYPE_GRJ)
1729    {
1730        AVDT_TRACE_WARNING("Dropping msg msg_type=%d", msg_type);
1731        ok = FALSE;
1732    }
1733    /* check for general reject */
1734    else if ((msg_type == AVDT_MSG_TYPE_REJ) && (p_buf->len == AVDT_LEN_GEN_REJ))
1735    {
1736        gen_rej = TRUE;
1737        if (p_ccb->p_curr_cmd != NULL)
1738        {
1739            msg.hdr.sig_id = sig = (UINT8) p_ccb->p_curr_cmd->event;
1740            evt = avdt_msg_rej_2_evt[sig - 1];
1741            msg.hdr.err_code = AVDT_ERR_NSC;
1742            msg.hdr.err_param = 0;
1743        }
1744    }
1745    else /* not a general reject */
1746    {
1747        /* get and verify signal */
1748        AVDT_MSG_PRS_SIG(p, sig);
1749        msg.hdr.sig_id = sig;
1750        if ((sig == 0) || (sig > AVDT_SIG_MAX))
1751        {
1752            AVDT_TRACE_WARNING("Dropping msg sig=%d msg_type:%d", sig, msg_type);
1753            ok = FALSE;
1754
1755            /* send a general reject */
1756            if (msg_type == AVDT_MSG_TYPE_CMD)
1757            {
1758                avdt_msg_send_grej(p_ccb, sig, &msg);
1759            }
1760        }
1761    }
1762
1763    if (ok && !gen_rej)
1764    {
1765        /* skip over header (msg length already verified during reassembly) */
1766        p_buf->len -= AVDT_LEN_TYPE_SINGLE;
1767
1768        /* set up to parse message */
1769        if ((msg_type == AVDT_MSG_TYPE_RSP) && (sig == AVDT_SIG_DISCOVER))
1770        {
1771            /* parse discover rsp message to struct supplied by app */
1772            msg.discover_rsp.p_sep_info = (tAVDT_SEP_INFO *) p_ccb->p_proc_data;
1773            msg.discover_rsp.num_seps = p_ccb->proc_param;
1774        }
1775        else if ((msg_type == AVDT_MSG_TYPE_RSP) &&
1776            ((sig == AVDT_SIG_GETCAP) || (sig == AVDT_SIG_GET_ALLCAP)))
1777        {
1778            /* parse discover rsp message to struct supplied by app */
1779            msg.svccap.p_cfg = (tAVDT_CFG *) p_ccb->p_proc_data;
1780        }
1781        else if ((msg_type == AVDT_MSG_TYPE_RSP) && (sig == AVDT_SIG_GETCONFIG))
1782        {
1783            /* parse get config rsp message to struct allocated locally */
1784            msg.svccap.p_cfg = &cfg;
1785        }
1786        else if ((msg_type == AVDT_MSG_TYPE_CMD) && (sig == AVDT_SIG_SETCONFIG))
1787        {
1788            /* parse config cmd message to struct allocated locally */
1789            msg.config_cmd.p_cfg = &cfg;
1790        }
1791        else if ((msg_type == AVDT_MSG_TYPE_CMD) && (sig == AVDT_SIG_RECONFIG))
1792        {
1793            /* parse reconfig cmd message to struct allocated locally */
1794            msg.reconfig_cmd.p_cfg = &cfg;
1795        }
1796
1797        /* parse message; while we're at it map message sig to event */
1798        if (msg_type == AVDT_MSG_TYPE_CMD)
1799        {
1800            msg.hdr.err_code = err = (*avdt_msg_prs_cmd[sig - 1])(&msg, p, p_buf->len);
1801            evt = avdt_msg_cmd_2_evt[sig - 1];
1802        }
1803        else if (msg_type == AVDT_MSG_TYPE_RSP)
1804        {
1805            msg.hdr.err_code = err = (*avdt_msg_prs_rsp[sig - 1])(&msg, p, p_buf->len);
1806            evt = avdt_msg_rsp_2_evt[sig - 1];
1807        }
1808        else /* msg_type == AVDT_MSG_TYPE_REJ */
1809        {
1810            err = avdt_msg_prs_rej(&msg, p, sig);
1811            evt = avdt_msg_rej_2_evt[sig - 1];
1812        }
1813
1814        /* if parsing failed */
1815        if (err != 0)
1816        {
1817            AVDT_TRACE_WARNING("Parsing failed sig=%d err=0x%x", sig, err);
1818
1819            /* if its a rsp or rej, drop it; if its a cmd, send a rej;
1820            ** note special case for abort; never send abort reject
1821            */
1822            ok = FALSE;
1823            if ((msg_type == AVDT_MSG_TYPE_CMD) && (sig != AVDT_SIG_ABORT))
1824            {
1825                avdt_msg_send_rej(p_ccb, sig, &msg);
1826            }
1827        }
1828    }
1829
1830    /* if its a rsp or rej, check sent cmd to see if we're waiting for
1831    ** the rsp or rej.  If we didn't send a cmd for it, drop it.  If
1832    ** it does match a cmd, stop timer for the cmd.
1833    */
1834    if (ok)
1835    {
1836        if ((msg_type == AVDT_MSG_TYPE_RSP) || (msg_type == AVDT_MSG_TYPE_REJ))
1837        {
1838            if ((p_ccb->p_curr_cmd != NULL) &&
1839                (p_ccb->p_curr_cmd->event == sig) &&
1840                (AVDT_LAYERSPEC_LABEL(p_ccb->p_curr_cmd->layer_specific) == label))
1841            {
1842                /* stop timer */
1843                btu_stop_timer(&p_ccb->timer_entry);
1844
1845                /* clear retransmission count */
1846                p_ccb->ret_count = 0;
1847
1848                /* later in this function handle ccb event */
1849                handle_rsp = TRUE;
1850            }
1851            else
1852            {
1853                ok = FALSE;
1854                AVDT_TRACE_WARNING("Cmd not found for rsp sig=%d label=%d", sig, label);
1855            }
1856        }
1857    }
1858
1859    if (ok)
1860    {
1861        /* if it's a ccb event send to ccb */
1862        if (evt & AVDT_CCB_MKR)
1863        {
1864            avdt_ccb_event(p_ccb, (UINT8)(evt & ~AVDT_CCB_MKR), (tAVDT_CCB_EVT *) &msg);
1865        }
1866        /* if it's a scb event */
1867        else
1868        {
1869            /* Scb events always have a single seid.  For cmd, get seid from
1870            ** message.  For rej and rsp, get seid from p_curr_cmd.
1871            */
1872            if (msg_type == AVDT_MSG_TYPE_CMD)
1873            {
1874                scb_hdl = msg.single.seid;
1875            }
1876            else
1877            {
1878                scb_hdl = *((UINT8 *)(p_ccb->p_curr_cmd + 1));
1879            }
1880
1881            /* Map seid to the scb and send it the event.  For cmd, seid has
1882            ** already been verified by parsing function.
1883            */
1884            if (evt && (p_scb = avdt_scb_by_hdl(scb_hdl)) != NULL)
1885            {
1886                avdt_scb_event(p_scb, evt, (tAVDT_SCB_EVT *) &msg);
1887            }
1888        }
1889    }
1890
1891    /* free message buffer */
1892    GKI_freebuf(p_buf);
1893
1894    /* if its a rsp or rej, send event to ccb to free associated
1895    ** cmd msg buffer and handle cmd queue
1896    */
1897    if (handle_rsp)
1898    {
1899        avdt_ccb_event(p_ccb, AVDT_CCB_RCVRSP_EVT, NULL);
1900    }
1901}
1902