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