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