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