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