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