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