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