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