• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 */
55 typedef void (*tAVDT_MSG_BLD)(UINT8 **p, tAVDT_MSG *p_msg);
56 
57 /* type for message parsing functions */
58 typedef UINT8 (*tAVDT_MSG_PRS)(tAVDT_MSG *p_msg, UINT8 *p, UINT16 len);
59 
60 
61 /*****************************************************************************
62 ** local function declarations
63 *****************************************************************************/
64 
65 static void avdt_msg_bld_none(UINT8 **p, tAVDT_MSG *p_msg);
66 static void avdt_msg_bld_single(UINT8 **p, tAVDT_MSG *p_msg);
67 static void avdt_msg_bld_setconfig_cmd(UINT8 **p, tAVDT_MSG *p_msg);
68 static void avdt_msg_bld_reconfig_cmd(UINT8 **p, tAVDT_MSG *p_msg);
69 static void avdt_msg_bld_multi(UINT8 **p, tAVDT_MSG *p_msg);
70 static void avdt_msg_bld_security_cmd(UINT8 **p, tAVDT_MSG *p_msg);
71 static void avdt_msg_bld_discover_rsp(UINT8 **p, tAVDT_MSG *p_msg);
72 static void avdt_msg_bld_svccap(UINT8 **p, tAVDT_MSG *p_msg);
73 static void avdt_msg_bld_security_rsp(UINT8 **p, tAVDT_MSG *p_msg);
74 static void avdt_msg_bld_all_svccap(UINT8 **p, tAVDT_MSG *p_msg);
75 static void avdt_msg_bld_delay_rpt(UINT8 **p, tAVDT_MSG *p_msg);
76 
77 static UINT8 avdt_msg_prs_none(tAVDT_MSG *p_msg, UINT8 *p, UINT16 len);
78 static UINT8 avdt_msg_prs_single(tAVDT_MSG *p_msg, UINT8 *p, UINT16 len);
79 static UINT8 avdt_msg_prs_setconfig_cmd(tAVDT_MSG *p_msg, UINT8 *p, UINT16 len);
80 static UINT8 avdt_msg_prs_reconfig_cmd(tAVDT_MSG *p_msg, UINT8 *p, UINT16 len);
81 static UINT8 avdt_msg_prs_multi(tAVDT_MSG *p_msg, UINT8 *p, UINT16 len);
82 static UINT8 avdt_msg_prs_security_cmd(tAVDT_MSG *p_msg, UINT8 *p, UINT16 len);
83 static UINT8 avdt_msg_prs_discover_rsp(tAVDT_MSG *p_msg, UINT8 *p, UINT16 len);
84 static UINT8 avdt_msg_prs_svccap(tAVDT_MSG *p_msg, UINT8 *p, UINT16 len);
85 static UINT8 avdt_msg_prs_all_svccap(tAVDT_MSG *p_msg, UINT8 *p, UINT16 len);
86 static UINT8 avdt_msg_prs_security_rsp(tAVDT_MSG *p_msg, UINT8 *p, UINT16 len);
87 static 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 */
94 const 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 */
107 const 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 */
120 const 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 */
133 static 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 */
141 const 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 */
158 const 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 */
175 const 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 */
192 const 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 */
209 const 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 */
226 const 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 */
243 const 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 *******************************************************************************/
avdt_msg_bld_cfg(UINT8 ** p,tAVDT_CFG * p_cfg)270 static 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 *******************************************************************************/
avdt_msg_bld_none(UINT8 ** p,tAVDT_MSG * p_msg)375 static 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 *******************************************************************************/
avdt_msg_bld_single(UINT8 ** p,tAVDT_MSG * p_msg)393 static 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 *******************************************************************************/
avdt_msg_bld_setconfig_cmd(UINT8 ** p,tAVDT_MSG * p_msg)409 static 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 *******************************************************************************/
avdt_msg_bld_reconfig_cmd(UINT8 ** p,tAVDT_MSG * p_msg)427 static 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 *******************************************************************************/
avdt_msg_bld_multi(UINT8 ** p,tAVDT_MSG * p_msg)447 static 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 *******************************************************************************/
avdt_msg_bld_security_cmd(UINT8 ** p,tAVDT_MSG * p_msg)467 static 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 *******************************************************************************/
avdt_msg_bld_delay_rpt(UINT8 ** p,tAVDT_MSG * p_msg)484 static 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 *******************************************************************************/
avdt_msg_bld_discover_rsp(UINT8 ** p,tAVDT_MSG * p_msg)501 static 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 *******************************************************************************/
avdt_msg_bld_svccap(UINT8 ** p,tAVDT_MSG * p_msg)526 static 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 *******************************************************************************/
avdt_msg_bld_all_svccap(UINT8 ** p,tAVDT_MSG * p_msg)547 static 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 *******************************************************************************/
avdt_msg_bld_security_rsp(UINT8 ** p,tAVDT_MSG * p_msg)563 static 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 *******************************************************************************/
avdt_msg_prs_cfg(tAVDT_CFG * p_cfg,UINT8 * p,UINT16 len,UINT8 * p_elem,UINT8 sig_id)581 static 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 *******************************************************************************/
avdt_msg_prs_none(tAVDT_MSG * p_msg,UINT8 * p,UINT16 len)779 static 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 *******************************************************************************/
avdt_msg_prs_single(tAVDT_MSG * p_msg,UINT8 * p,UINT16 len)798 static 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 *******************************************************************************/
avdt_msg_prs_setconfig_cmd(tAVDT_MSG * p_msg,UINT8 * p,UINT16 len)830 static 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 *******************************************************************************/
avdt_msg_prs_reconfig_cmd(tAVDT_MSG * p_msg,UINT8 * p,UINT16 len)889 static 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 *******************************************************************************/
avdt_msg_prs_multi(tAVDT_MSG * p_msg,UINT8 * p,UINT16 len)940 static 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 *******************************************************************************/
avdt_msg_prs_security_cmd(tAVDT_MSG * p_msg,UINT8 * p,UINT16 len)982 static 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 *******************************************************************************/
avdt_msg_prs_discover_rsp(tAVDT_MSG * p_msg,UINT8 * p,UINT16 len)1019 static 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 *******************************************************************************/
avdt_msg_prs_svccap(tAVDT_MSG * p_msg,UINT8 * p,UINT16 len)1064 static 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 *******************************************************************************/
avdt_msg_prs_all_svccap(tAVDT_MSG * p_msg,UINT8 * p,UINT16 len)1087 static 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 *******************************************************************************/
avdt_msg_prs_security_rsp(tAVDT_MSG * p_msg,UINT8 * p,UINT16 len)1108 static 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 *******************************************************************************/
avdt_msg_prs_rej(tAVDT_MSG * p_msg,UINT8 * p,UINT8 sig)1126 static 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 *******************************************************************************/
avdt_msg_prs_delay_rpt(tAVDT_MSG * p_msg,UINT8 * p,UINT16 len)1157 static 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 *******************************************************************************/
avdt_msg_send(tAVDT_CCB * p_ccb,BT_HDR * p_msg)1196 BOOLEAN 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 *******************************************************************************/
avdt_msg_asmbl(tAVDT_CCB * p_ccb,BT_HDR * p_buf)1356 BT_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 *******************************************************************************/
avdt_msg_send_cmd(tAVDT_CCB * p_ccb,void * p_scb,UINT8 sig_id,tAVDT_MSG * p_params)1477 void 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 *******************************************************************************/
avdt_msg_send_rsp(tAVDT_CCB * p_ccb,UINT8 sig_id,tAVDT_MSG * p_params)1546 void 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 *******************************************************************************/
avdt_msg_send_rej(tAVDT_CCB * p_ccb,UINT8 sig_id,tAVDT_MSG * p_params)1591 void 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 *******************************************************************************/
avdt_msg_send_grej(tAVDT_CCB * p_ccb,UINT8 sig_id,tAVDT_MSG * p_params)1652 void 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 *******************************************************************************/
avdt_msg_ind(tAVDT_CCB * p_ccb,BT_HDR * p_buf)1694 void 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