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"
30
31 #include <string.h>
32 #include "avdt_api.h"
33 #include "avdt_int.h"
34 #include "avdtc_api.h"
35 #include "bt_common.h"
36 #include "bt_target.h"
37 #include "bt_types.h"
38 #include "bt_utils.h"
39 #include "btu.h"
40 #include "osi/include/log.h"
41 #include "osi/include/osi.h"
42
43 /*****************************************************************************
44 * constants
45 ****************************************************************************/
46
47 /* mask of all psc values */
48 #define AVDT_MSG_PSC_MASK \
49 (AVDT_PSC_TRANS | AVDT_PSC_REPORT | AVDT_PSC_DELAY_RPT | AVDT_PSC_RECOV | \
50 AVDT_PSC_HDRCMP | AVDT_PSC_MUX)
51 #define AVDT_PSC_PROTECT (1 << 4) /* Content Protection */
52 #define AVDT_PSC_CODEC (1 << 7) /* codec */
53
54 /*****************************************************************************
55 * type definitions
56 ****************************************************************************/
57
58 /* type for message building functions */
59 typedef void (*tAVDT_MSG_BLD)(uint8_t** p, tAVDT_MSG* p_msg);
60
61 /* type for message parsing functions */
62 typedef uint8_t (*tAVDT_MSG_PRS)(tAVDT_MSG* p_msg, uint8_t* p, uint16_t len);
63
64 /*****************************************************************************
65 * local function declarations
66 ****************************************************************************/
67
68 static void avdt_msg_bld_none(uint8_t** p, tAVDT_MSG* p_msg);
69 static void avdt_msg_bld_single(uint8_t** p, tAVDT_MSG* p_msg);
70 static void avdt_msg_bld_setconfig_cmd(uint8_t** p, tAVDT_MSG* p_msg);
71 static void avdt_msg_bld_reconfig_cmd(uint8_t** p, tAVDT_MSG* p_msg);
72 static void avdt_msg_bld_multi(uint8_t** p, tAVDT_MSG* p_msg);
73 static void avdt_msg_bld_security_cmd(uint8_t** p, tAVDT_MSG* p_msg);
74 static void avdt_msg_bld_discover_rsp(uint8_t** p, tAVDT_MSG* p_msg);
75 static void avdt_msg_bld_svccap(uint8_t** p, tAVDT_MSG* p_msg);
76 static void avdt_msg_bld_security_rsp(uint8_t** p, tAVDT_MSG* p_msg);
77 static void avdt_msg_bld_all_svccap(uint8_t** p, tAVDT_MSG* p_msg);
78 static void avdt_msg_bld_delay_rpt(uint8_t** p, tAVDT_MSG* p_msg);
79
80 static uint8_t avdt_msg_prs_none(tAVDT_MSG* p_msg, uint8_t* p, uint16_t len);
81 static uint8_t avdt_msg_prs_single(tAVDT_MSG* p_msg, uint8_t* p, uint16_t len);
82 static uint8_t avdt_msg_prs_setconfig_cmd(tAVDT_MSG* p_msg, uint8_t* p,
83 uint16_t len);
84 static uint8_t avdt_msg_prs_reconfig_cmd(tAVDT_MSG* p_msg, uint8_t* p,
85 uint16_t len);
86 static uint8_t avdt_msg_prs_multi(tAVDT_MSG* p_msg, uint8_t* p, uint16_t len);
87 static uint8_t avdt_msg_prs_security_cmd(tAVDT_MSG* p_msg, uint8_t* p,
88 uint16_t len);
89 static uint8_t avdt_msg_prs_discover_rsp(tAVDT_MSG* p_msg, uint8_t* p,
90 uint16_t len);
91 static uint8_t avdt_msg_prs_svccap(tAVDT_MSG* p_msg, uint8_t* p, uint16_t len);
92 static uint8_t avdt_msg_prs_all_svccap(tAVDT_MSG* p_msg, uint8_t* p,
93 uint16_t len);
94 static uint8_t avdt_msg_prs_security_rsp(tAVDT_MSG* p_msg, uint8_t* p,
95 uint16_t len);
96 static uint8_t avdt_msg_prs_delay_rpt(tAVDT_MSG* p_msg, uint8_t* p,
97 uint16_t len);
98
99 /*****************************************************************************
100 * constants
101 ****************************************************************************/
102
103 /* table of information element minimum lengths used for parsing */
104 const uint8_t avdt_msg_ie_len_min[] = {
105 0, /* unused */
106 AVDT_LEN_TRANS_MIN, /* media transport */
107 AVDT_LEN_REPORT_MIN, /* reporting */
108 AVDT_LEN_RECOV_MIN, /* recovery */
109 AVDT_LEN_PROTECT_MIN, /* content protection */
110 AVDT_LEN_HDRCMP_MIN, /* header compression */
111 AVDT_LEN_MUX_MIN, /* multiplexing */
112 AVDT_LEN_CODEC_MIN, /* codec */
113 AVDT_LEN_DELAY_RPT_MIN /* delay report */
114 };
115
116 /* table of information element minimum lengths used for parsing */
117 const uint8_t avdt_msg_ie_len_max[] = {
118 0, /* unused */
119 AVDT_LEN_TRANS_MAX, /* media transport */
120 AVDT_LEN_REPORT_MAX, /* reporting */
121 AVDT_LEN_RECOV_MAX, /* recovery */
122 AVDT_LEN_PROTECT_MAX, /* content protection */
123 AVDT_LEN_HDRCMP_MAX, /* header compression */
124 AVDT_LEN_MUX_MAX, /* multiplexing */
125 AVDT_LEN_CODEC_MAX, /* codec */
126 AVDT_LEN_DELAY_RPT_MAX /* delay report */
127 };
128
129 /* table of error codes used when decoding information elements */
130 const uint8_t avdt_msg_ie_err[] = {
131 0, /* unused */
132 AVDT_ERR_MEDIA_TRANS, /* media transport */
133 AVDT_ERR_LENGTH, /* reporting */
134 AVDT_ERR_RECOV_FMT, /* recovery */
135 AVDT_ERR_CP_FMT, /* content protection */
136 AVDT_ERR_ROHC_FMT, /* header compression */
137 AVDT_ERR_MUX_FMT, /* multiplexing */
138 AVDT_ERR_SERVICE, /* codec */
139 AVDT_ERR_SERVICE /* delay report ?? */
140 };
141
142 /* table of packet type minimum lengths */
143 static const uint8_t avdt_msg_pkt_type_len[] = {
144 AVDT_LEN_TYPE_SINGLE, AVDT_LEN_TYPE_START, AVDT_LEN_TYPE_CONT,
145 AVDT_LEN_TYPE_END};
146
147 /* function table for building command messages */
148 const tAVDT_MSG_BLD avdt_msg_bld_cmd[] = {
149 avdt_msg_bld_none, /* discover */
150 avdt_msg_bld_single, /* get capabilities */
151 avdt_msg_bld_setconfig_cmd, /* set configuration */
152 avdt_msg_bld_single, /* get configuration */
153 avdt_msg_bld_reconfig_cmd, /* reconfigure */
154 avdt_msg_bld_single, /* open */
155 avdt_msg_bld_multi, /* start */
156 avdt_msg_bld_single, /* close */
157 avdt_msg_bld_multi, /* suspend */
158 avdt_msg_bld_single, /* abort */
159 avdt_msg_bld_security_cmd, /* security control */
160 avdt_msg_bld_single, /* get all capabilities */
161 avdt_msg_bld_delay_rpt /* delay report */
162 };
163
164 /* function table for building response messages */
165 const tAVDT_MSG_BLD avdt_msg_bld_rsp[] = {
166 avdt_msg_bld_discover_rsp, /* discover */
167 avdt_msg_bld_svccap, /* get capabilities */
168 avdt_msg_bld_none, /* set configuration */
169 avdt_msg_bld_all_svccap, /* get configuration */
170 avdt_msg_bld_none, /* reconfigure */
171 avdt_msg_bld_none, /* open */
172 avdt_msg_bld_none, /* start */
173 avdt_msg_bld_none, /* close */
174 avdt_msg_bld_none, /* suspend */
175 avdt_msg_bld_none, /* abort */
176 avdt_msg_bld_security_rsp, /* security control */
177 avdt_msg_bld_all_svccap, /* get all capabilities */
178 avdt_msg_bld_none /* delay report */
179 };
180
181 /* function table for parsing command messages */
182 const tAVDT_MSG_PRS avdt_msg_prs_cmd[] = {
183 avdt_msg_prs_none, /* discover */
184 avdt_msg_prs_single, /* get capabilities */
185 avdt_msg_prs_setconfig_cmd, /* set configuration */
186 avdt_msg_prs_single, /* get configuration */
187 avdt_msg_prs_reconfig_cmd, /* reconfigure */
188 avdt_msg_prs_single, /* open */
189 avdt_msg_prs_multi, /* start */
190 avdt_msg_prs_single, /* close */
191 avdt_msg_prs_multi, /* suspend */
192 avdt_msg_prs_single, /* abort */
193 avdt_msg_prs_security_cmd, /* security control */
194 avdt_msg_prs_single, /* get all capabilities */
195 avdt_msg_prs_delay_rpt /* delay report */
196 };
197
198 /* function table for parsing response messages */
199 const tAVDT_MSG_PRS avdt_msg_prs_rsp[] = {
200 avdt_msg_prs_discover_rsp, /* discover */
201 avdt_msg_prs_svccap, /* get capabilities */
202 avdt_msg_prs_none, /* set configuration */
203 avdt_msg_prs_all_svccap, /* get configuration */
204 avdt_msg_prs_none, /* reconfigure */
205 avdt_msg_prs_none, /* open */
206 avdt_msg_prs_none, /* start */
207 avdt_msg_prs_none, /* close */
208 avdt_msg_prs_none, /* suspend */
209 avdt_msg_prs_none, /* abort */
210 avdt_msg_prs_security_rsp, /* security control */
211 avdt_msg_prs_all_svccap, /* get all capabilities */
212 avdt_msg_prs_none /* delay report */
213 };
214
215 /* command message-to-event lookup table */
216 const uint8_t avdt_msg_cmd_2_evt[] = {
217 AVDT_CCB_MSG_DISCOVER_CMD_EVT + AVDT_CCB_MKR, /* discover */
218 AVDT_CCB_MSG_GETCAP_CMD_EVT + AVDT_CCB_MKR, /* get capabilities */
219 AVDT_SCB_MSG_SETCONFIG_CMD_EVT, /* set configuration */
220 AVDT_SCB_MSG_GETCONFIG_CMD_EVT, /* get configuration */
221 AVDT_SCB_MSG_RECONFIG_CMD_EVT, /* reconfigure */
222 AVDT_SCB_MSG_OPEN_CMD_EVT, /* open */
223 AVDT_CCB_MSG_START_CMD_EVT + AVDT_CCB_MKR, /* start */
224 AVDT_SCB_MSG_CLOSE_CMD_EVT, /* close */
225 AVDT_CCB_MSG_SUSPEND_CMD_EVT + AVDT_CCB_MKR, /* suspend */
226 AVDT_SCB_MSG_ABORT_CMD_EVT, /* abort */
227 AVDT_SCB_MSG_SECURITY_CMD_EVT, /* security control */
228 AVDT_CCB_MSG_GETCAP_CMD_EVT + AVDT_CCB_MKR, /* get all capabilities */
229 AVDT_SCB_MSG_DELAY_RPT_CMD_EVT /* delay report */
230 };
231
232 /* response message-to-event lookup table */
233 const uint8_t avdt_msg_rsp_2_evt[] = {
234 AVDT_CCB_MSG_DISCOVER_RSP_EVT + AVDT_CCB_MKR, /* discover */
235 AVDT_CCB_MSG_GETCAP_RSP_EVT + AVDT_CCB_MKR, /* get capabilities */
236 AVDT_SCB_MSG_SETCONFIG_RSP_EVT, /* set configuration */
237 AVDT_SCB_MSG_GETCONFIG_RSP_EVT, /* get configuration */
238 AVDT_SCB_MSG_RECONFIG_RSP_EVT, /* reconfigure */
239 AVDT_SCB_MSG_OPEN_RSP_EVT, /* open */
240 AVDT_CCB_MSG_START_RSP_EVT + AVDT_CCB_MKR, /* start */
241 AVDT_SCB_MSG_CLOSE_RSP_EVT, /* close */
242 AVDT_CCB_MSG_SUSPEND_RSP_EVT + AVDT_CCB_MKR, /* suspend */
243 AVDT_SCB_MSG_ABORT_RSP_EVT, /* abort */
244 AVDT_SCB_MSG_SECURITY_RSP_EVT, /* security control */
245 AVDT_CCB_MSG_GETCAP_RSP_EVT + AVDT_CCB_MKR, /* get all capabilities */
246 AVDT_SCB_MSG_DELAY_RPT_RSP_EVT /* delay report */
247 };
248
249 /* reject message-to-event lookup table */
250 const uint8_t avdt_msg_rej_2_evt[] = {
251 AVDT_CCB_MSG_DISCOVER_RSP_EVT + AVDT_CCB_MKR, /* discover */
252 AVDT_CCB_MSG_GETCAP_RSP_EVT + AVDT_CCB_MKR, /* get capabilities */
253 AVDT_SCB_MSG_SETCONFIG_REJ_EVT, /* set configuration */
254 AVDT_SCB_MSG_GETCONFIG_RSP_EVT, /* get configuration */
255 AVDT_SCB_MSG_RECONFIG_RSP_EVT, /* reconfigure */
256 AVDT_SCB_MSG_OPEN_REJ_EVT, /* open */
257 AVDT_CCB_MSG_START_RSP_EVT + AVDT_CCB_MKR, /* start */
258 AVDT_SCB_MSG_CLOSE_RSP_EVT, /* close */
259 AVDT_CCB_MSG_SUSPEND_RSP_EVT + AVDT_CCB_MKR, /* suspend */
260 AVDT_SCB_MSG_ABORT_RSP_EVT, /* abort */
261 AVDT_SCB_MSG_SECURITY_RSP_EVT, /* security control */
262 AVDT_CCB_MSG_GETCAP_RSP_EVT + AVDT_CCB_MKR, /* get all capabilities */
263 0 /* delay report */
264 };
265
266 /*******************************************************************************
267 *
268 * Function avdt_msg_bld_cfg
269 *
270 * Description This function builds the configuration parameters contained
271 * in a command or response message.
272 *
273 *
274 * Returns void.
275 *
276 ******************************************************************************/
avdt_msg_bld_cfg(uint8_t ** p,AvdtpSepConfig * p_cfg)277 static void avdt_msg_bld_cfg(uint8_t** p, AvdtpSepConfig* p_cfg) {
278 uint8_t len;
279
280 /* for now, just build media transport, codec, and content protection, and
281 * multiplexing */
282
283 /* media transport */
284 if (p_cfg->psc_mask & AVDT_PSC_TRANS) {
285 *(*p)++ = AVDT_CAT_TRANS;
286 *(*p)++ = 0; /* length */
287 }
288
289 /* reporting transport */
290 if (p_cfg->psc_mask & AVDT_PSC_REPORT) {
291 *(*p)++ = AVDT_CAT_REPORT;
292 *(*p)++ = 0; /* length */
293 }
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 AvdtpSepConfig cfg = *p_msg->svccap.p_cfg;
474
475 // Include only the Basic Capability
476 cfg.psc_mask &= AVDT_LEG_PSC;
477
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(AvdtpSepConfig * p_cfg,uint8_t * p,uint16_t len,uint8_t * p_elem,uint8_t sig_id)524 static uint8_t avdt_msg_prs_cfg(AvdtpSepConfig* 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 if ((p_end - p) < 3) {
592 err = AVDT_ERR_PAYLOAD;
593 break;
594 }
595 p_cfg->recov_type = *p++;
596 p_cfg->recov_mrws = *p++;
597 p_cfg->recov_mnmp = *p++;
598 if (p_cfg->recov_type != AVDT_RECOV_RFC2733) {
599 err = AVDT_ERR_RECOV_TYPE;
600 } else if ((p_cfg->recov_mrws < AVDT_RECOV_MRWS_MIN) ||
601 (p_cfg->recov_mrws > AVDT_RECOV_MRWS_MAX) ||
602 (p_cfg->recov_mnmp < AVDT_RECOV_MNMP_MIN) ||
603 (p_cfg->recov_mnmp > AVDT_RECOV_MNMP_MAX)) {
604 err = AVDT_ERR_RECOV_FMT;
605 }
606 break;
607
608 case AVDT_CAT_PROTECT:
609 p_cfg->psc_mask &= ~AVDT_PSC_PROTECT;
610 if (p + elem_len > p_end) {
611 err = AVDT_ERR_LENGTH;
612 android_errorWriteLog(0x534e4554, "78288378");
613 break;
614 }
615 if ((elem_len + protect_offset) < AVDT_PROTECT_SIZE) {
616 p_cfg->num_protect++;
617 p_cfg->protect_info[protect_offset] = elem_len;
618 protect_offset++;
619 memcpy(&p_cfg->protect_info[protect_offset], p, elem_len);
620 protect_offset += elem_len;
621 }
622 p += elem_len;
623 break;
624
625 case AVDT_CAT_HDRCMP:
626 if ((p_end - p) < 1) {
627 err = AVDT_ERR_PAYLOAD;
628 break;
629 }
630 p_cfg->hdrcmp_mask = *p++;
631 break;
632
633 case AVDT_CAT_CODEC:
634 p_cfg->psc_mask &= ~AVDT_PSC_CODEC;
635 tmp = elem_len;
636 if (elem_len >= AVDT_CODEC_SIZE) {
637 tmp = AVDT_CODEC_SIZE - 1;
638 }
639 if (p + tmp > p_end) {
640 err = AVDT_ERR_LENGTH;
641 android_errorWriteLog(0x534e4554, "78288378");
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 AVDT_TRACE_DEBUG("%s: Remote device supports delay reporting",
652 __func__);
653 break;
654
655 default:
656 p += elem_len;
657 break;
658 } /* switch */
659 } /* while ! err, !end*/
660 *p_elem = elem;
661 AVDT_TRACE_DEBUG("err=0x%x, elem:0x%x psc_mask=0x%x", err, elem,
662 p_cfg->psc_mask);
663
664 return err;
665 }
666
667 /*******************************************************************************
668 *
669 * Function avdt_msg_prs_none
670 *
671 * Description This message parsing function parses a message with no
672 * parameters.
673 *
674 *
675 * Returns Error code or zero if no error.
676 *
677 ******************************************************************************/
avdt_msg_prs_none(UNUSED_ATTR tAVDT_MSG * p_msg,UNUSED_ATTR uint8_t * p,UNUSED_ATTR uint16_t len)678 static uint8_t avdt_msg_prs_none(UNUSED_ATTR tAVDT_MSG* p_msg,
679 UNUSED_ATTR uint8_t* p,
680 UNUSED_ATTR uint16_t len) {
681 return 0;
682 }
683
684 /*******************************************************************************
685 *
686 * Function avdt_msg_prs_single
687 *
688 * Description This message parsing function parses a message with a
689 * single SEID.
690 *
691 *
692 * Returns Error code or zero if no error.
693 *
694 ******************************************************************************/
avdt_msg_prs_single(tAVDT_MSG * p_msg,uint8_t * p,uint16_t len)695 static uint8_t avdt_msg_prs_single(tAVDT_MSG* p_msg, uint8_t* p, uint16_t len) {
696 uint8_t err = 0;
697
698 /* verify len */
699 if (len != AVDT_LEN_SINGLE) {
700 err = AVDT_ERR_LENGTH;
701 } else {
702 AVDT_MSG_PRS_SEID(p, p_msg->single.seid);
703
704 if (avdt_scb_by_hdl(p_msg->single.seid) == NULL) {
705 err = AVDT_ERR_SEID;
706 }
707 }
708 return err;
709 }
710
711 /*******************************************************************************
712 *
713 * Function avdt_msg_prs_setconfig_cmd
714 *
715 * Description This message parsing function parses a set configuration
716 * command message.
717 *
718 *
719 * Returns Error code or zero if no error.
720 *
721 ******************************************************************************/
avdt_msg_prs_setconfig_cmd(tAVDT_MSG * p_msg,uint8_t * p,uint16_t len)722 static uint8_t avdt_msg_prs_setconfig_cmd(tAVDT_MSG* p_msg, uint8_t* p,
723 uint16_t len) {
724 uint8_t err = 0;
725
726 p_msg->hdr.err_param = 0;
727
728 /* verify len */
729 if (len < AVDT_LEN_SETCONFIG_MIN) {
730 err = AVDT_ERR_LENGTH;
731 } else {
732 /* get seids */
733 AVDT_MSG_PRS_SEID(p, p_msg->config_cmd.hdr.seid);
734 if (avdt_scb_by_hdl(p_msg->config_cmd.hdr.seid) == NULL) {
735 err = AVDT_ERR_SEID;
736 }
737
738 AVDT_MSG_PRS_SEID(p, p_msg->config_cmd.int_seid);
739 if ((p_msg->config_cmd.int_seid < AVDT_SEID_MIN) ||
740 (p_msg->config_cmd.int_seid > AVDT_SEID_MAX)) {
741 err = AVDT_ERR_SEID;
742 }
743 }
744
745 if (!err) {
746 /* parse configuration parameters */
747 len -= 2;
748 err = avdt_msg_prs_cfg(p_msg->config_cmd.p_cfg, p, len,
749 &p_msg->hdr.err_param, AVDT_SIG_SETCONFIG);
750
751 if (!err) {
752 /* verify protocol service capabilities are supported */
753 if (((p_msg->config_cmd.p_cfg->psc_mask & (~AVDT_PSC)) != 0) ||
754 (p_msg->config_cmd.p_cfg->num_codec == 0)) {
755 err = AVDT_ERR_INVALID_CAP;
756 }
757 }
758 }
759
760 return err;
761 }
762
763 /*******************************************************************************
764 *
765 * Function avdt_msg_prs_reconfig_cmd
766 *
767 * Description This message parsing function parses a reconfiguration
768 * command message.
769 *
770 *
771 * Returns Error code or zero if no error.
772 *
773 ******************************************************************************/
avdt_msg_prs_reconfig_cmd(tAVDT_MSG * p_msg,uint8_t * p,uint16_t len)774 static uint8_t avdt_msg_prs_reconfig_cmd(tAVDT_MSG* p_msg, uint8_t* p,
775 uint16_t len) {
776 uint8_t err = 0;
777
778 p_msg->hdr.err_param = 0;
779
780 /* verify len */
781 if (len < AVDT_LEN_RECONFIG_MIN) {
782 err = AVDT_ERR_LENGTH;
783 } else {
784 /* get seid */
785 AVDT_MSG_PRS_SEID(p, p_msg->reconfig_cmd.hdr.seid);
786 if (avdt_scb_by_hdl(p_msg->reconfig_cmd.hdr.seid) == NULL) {
787 err = AVDT_ERR_SEID;
788 } else {
789 /* parse config parameters */
790 len--;
791 err = avdt_msg_prs_cfg(p_msg->config_cmd.p_cfg, p, len,
792 &p_msg->hdr.err_param, AVDT_SIG_RECONFIG);
793
794 /* verify no protocol service capabilities in parameters */
795 if (!err) {
796 AVDT_TRACE_DEBUG("avdt_msg_prs_reconfig_cmd psc_mask=0x%x/0x%x",
797 p_msg->config_cmd.p_cfg->psc_mask, AVDT_MSG_PSC_MASK);
798 if ((p_msg->config_cmd.p_cfg->psc_mask != 0) ||
799 (p_msg->config_cmd.p_cfg->num_codec == 0 &&
800 p_msg->config_cmd.p_cfg->num_protect == 0)) {
801 err = AVDT_ERR_INVALID_CAP;
802 }
803 }
804 }
805 }
806 return err;
807 }
808
809 /*******************************************************************************
810 *
811 * Function avdt_msg_prs_multi
812 *
813 * Description This message parsing function parses a message containing
814 * multiple SEID's.
815 *
816 *
817 * Returns Error code or zero if no error.
818 *
819 ******************************************************************************/
avdt_msg_prs_multi(tAVDT_MSG * p_msg,uint8_t * p,uint16_t len)820 static uint8_t avdt_msg_prs_multi(tAVDT_MSG* p_msg, uint8_t* p, uint16_t len) {
821 int i;
822 uint8_t err = 0;
823
824 p_msg->hdr.err_param = 0;
825
826 /* verify len */
827 if (len < AVDT_LEN_MULTI_MIN || (len > AVDT_NUM_SEPS)) {
828 err = AVDT_ERR_LENGTH;
829 } else {
830 /* get and verify all seps */
831 for (i = 0; i < len; i++) {
832 AVDT_MSG_PRS_SEID(p, p_msg->multi.seid_list[i]);
833 if (avdt_scb_by_hdl(p_msg->multi.seid_list[i]) == NULL) {
834 err = AVDT_ERR_SEID;
835 p_msg->hdr.err_param = p_msg->multi.seid_list[i];
836 break;
837 }
838 }
839 p_msg->multi.num_seps = (uint8_t)i;
840 }
841
842 return err;
843 }
844
845 /*******************************************************************************
846 *
847 * Function avdt_msg_prs_security_cmd
848 *
849 * Description This message parsing function parses a security
850 * command message.
851 *
852 *
853 * Returns Error code or zero if no error.
854 *
855 ******************************************************************************/
avdt_msg_prs_security_cmd(tAVDT_MSG * p_msg,uint8_t * p,uint16_t len)856 static uint8_t avdt_msg_prs_security_cmd(tAVDT_MSG* p_msg, uint8_t* p,
857 uint16_t len) {
858 uint8_t err = 0;
859
860 /* verify len */
861 if (len < AVDT_LEN_SECURITY_MIN) {
862 err = AVDT_ERR_LENGTH;
863 } else {
864 /* get seid */
865 AVDT_MSG_PRS_SEID(p, p_msg->security_cmd.hdr.seid);
866 if (avdt_scb_by_hdl(p_msg->security_cmd.hdr.seid) == NULL) {
867 err = AVDT_ERR_SEID;
868 } else {
869 p_msg->security_cmd.p_data = p;
870 p_msg->security_cmd.len = len - 1;
871 }
872 }
873 return err;
874 }
875
876 /*******************************************************************************
877 *
878 * Function avdt_msg_prs_discover_rsp
879 *
880 * Description This message parsing function parses a discover
881 * response message.
882 *
883 *
884 * Returns Error code or zero if no error.
885 *
886 ******************************************************************************/
avdt_msg_prs_discover_rsp(tAVDT_MSG * p_msg,uint8_t * p,uint16_t len)887 static uint8_t avdt_msg_prs_discover_rsp(tAVDT_MSG* p_msg, uint8_t* p,
888 uint16_t len) {
889 int i;
890 uint8_t err = 0;
891
892 /* determine number of seps; seps in msg is len/2, but set to minimum
893 ** of seps app has supplied memory for and seps in msg
894 */
895 if (p_msg->discover_rsp.num_seps > (len / 2)) {
896 p_msg->discover_rsp.num_seps = (len / 2);
897 }
898
899 /* parse out sep info */
900 for (i = 0; i < p_msg->discover_rsp.num_seps; i++) {
901 /* parse discover rsp info */
902 AVDT_MSG_PRS_DISC(p, p_msg->discover_rsp.p_sep_info[i].seid,
903 p_msg->discover_rsp.p_sep_info[i].in_use,
904 p_msg->discover_rsp.p_sep_info[i].media_type,
905 p_msg->discover_rsp.p_sep_info[i].tsep);
906
907 /* verify that seid is valid */
908 if ((p_msg->discover_rsp.p_sep_info[i].seid < AVDT_SEID_MIN) ||
909 (p_msg->discover_rsp.p_sep_info[i].seid > AVDT_SEID_MAX)) {
910 err = AVDT_ERR_SEID;
911 break;
912 }
913 }
914
915 return err;
916 }
917
918 /*******************************************************************************
919 *
920 * Function avdt_msg_prs_svccap
921 *
922 * Description This message parsing function parses a message containing
923 * service capabilities parameters.
924 *
925 *
926 * Returns Error code or zero if no error.
927 *
928 ******************************************************************************/
avdt_msg_prs_svccap(tAVDT_MSG * p_msg,uint8_t * p,uint16_t len)929 static uint8_t avdt_msg_prs_svccap(tAVDT_MSG* p_msg, uint8_t* p, uint16_t len) {
930 /* parse parameters */
931 uint8_t err = avdt_msg_prs_cfg(p_msg->svccap.p_cfg, p, len,
932 &p_msg->hdr.err_param, AVDT_SIG_GETCAP);
933 if (p_msg->svccap.p_cfg) {
934 p_msg->svccap.p_cfg->psc_mask &= AVDT_LEG_PSC;
935 }
936
937 return (err);
938 }
939
940 /*******************************************************************************
941 *
942 * Function avdt_msg_prs_all_svccap
943 *
944 * Description This message parsing function parses a message containing
945 * service capabilities parameters.
946 *
947 *
948 * Returns Error code or zero if no error.
949 *
950 ******************************************************************************/
avdt_msg_prs_all_svccap(tAVDT_MSG * p_msg,uint8_t * p,uint16_t len)951 static uint8_t avdt_msg_prs_all_svccap(tAVDT_MSG* p_msg, uint8_t* p,
952 uint16_t len) {
953 uint8_t err = avdt_msg_prs_cfg(p_msg->svccap.p_cfg, p, len,
954 &p_msg->hdr.err_param, AVDT_SIG_GET_ALLCAP);
955 if (p_msg->svccap.p_cfg) {
956 p_msg->svccap.p_cfg->psc_mask &= AVDT_MSG_PSC_MASK;
957 }
958 return (err);
959 }
960
961 /*******************************************************************************
962 *
963 * Function avdt_msg_prs_security_rsp
964 *
965 * Description This message parsing function parsing a security
966 * response message.
967 *
968 *
969 * Returns Error code or zero if no error.
970 *
971 ******************************************************************************/
avdt_msg_prs_security_rsp(tAVDT_MSG * p_msg,uint8_t * p,uint16_t len)972 static uint8_t avdt_msg_prs_security_rsp(tAVDT_MSG* p_msg, uint8_t* p,
973 uint16_t len) {
974 p_msg->security_rsp.p_data = p;
975 p_msg->security_rsp.len = len;
976
977 return 0;
978 }
979
980 /*******************************************************************************
981 *
982 * Function avdt_msg_prs_rej
983 *
984 * Description
985 *
986 *
987 * Returns Error code or zero if no error.
988 *
989 ******************************************************************************/
avdt_msg_prs_rej(tAVDT_MSG * p_msg,uint8_t * p,uint16_t len,uint8_t sig)990 static uint8_t avdt_msg_prs_rej(tAVDT_MSG* p_msg, uint8_t* p, uint16_t len,
991 uint8_t sig) {
992 uint8_t error = 0;
993
994 if (len > 0) {
995 if ((sig == AVDT_SIG_SETCONFIG) || (sig == AVDT_SIG_RECONFIG)) {
996 p_msg->hdr.err_param = *p++;
997 len--;
998 } else if ((sig == AVDT_SIG_START) || (sig == AVDT_SIG_SUSPEND)) {
999 AVDT_MSG_PRS_SEID(p, p_msg->hdr.err_param);
1000 len--;
1001 }
1002 }
1003
1004 if (len < 1) {
1005 android_errorWriteLog(0x534e4554, "79702484");
1006 error = AVDT_ERR_LENGTH;
1007 } else {
1008 p_msg->hdr.err_code = *p;
1009 }
1010
1011 return error;
1012 }
1013
1014 /*******************************************************************************
1015 *
1016 * Function avdt_msg_prs_delay_rpt
1017 *
1018 * Description This message parsing function parses a security
1019 * command message.
1020 *
1021 *
1022 * Returns Error code or zero if no error.
1023 *
1024 ******************************************************************************/
avdt_msg_prs_delay_rpt(tAVDT_MSG * p_msg,uint8_t * p,uint16_t len)1025 static uint8_t avdt_msg_prs_delay_rpt(tAVDT_MSG* p_msg, uint8_t* p,
1026 uint16_t len) {
1027 uint8_t err = 0;
1028
1029 /* verify len */
1030 if (len != AVDT_LEN_DELAY_RPT) {
1031 AVDT_TRACE_WARNING("avdt_msg_prs_delay_rpt expected len: %u got: %u",
1032 AVDT_LEN_DELAY_RPT, len);
1033 err = AVDT_ERR_LENGTH;
1034 } else {
1035 /* get seid */
1036 AVDT_MSG_PRS_SEID(p, p_msg->delay_rpt_cmd.hdr.seid);
1037
1038 if (avdt_scb_by_hdl(p_msg->delay_rpt_cmd.hdr.seid) == NULL) {
1039 err = AVDT_ERR_SEID;
1040 } else {
1041 BE_STREAM_TO_UINT16(p_msg->delay_rpt_cmd.delay, p);
1042 AVDT_TRACE_DEBUG("avdt_msg_prs_delay_rpt delay: %u",
1043 p_msg->delay_rpt_cmd.delay);
1044 }
1045 }
1046 return err;
1047 }
1048
1049 /*******************************************************************************
1050 *
1051 * Function avdt_msg_send
1052 *
1053 * Description Send, and if necessary fragment the next message.
1054 *
1055 *
1056 * Returns Congested state; true if CCB congested, false if not.
1057 *
1058 ******************************************************************************/
avdt_msg_send(AvdtpCcb * p_ccb,BT_HDR * p_msg)1059 bool avdt_msg_send(AvdtpCcb* p_ccb, BT_HDR* p_msg) {
1060 uint16_t curr_msg_len;
1061 uint8_t pkt_type;
1062 uint8_t hdr_len;
1063 AvdtpTransportChannel* p_tbl;
1064 BT_HDR* p_buf;
1065 uint8_t* p;
1066 uint8_t label;
1067 uint8_t msg;
1068 uint8_t sig;
1069 uint8_t nosp = 0; /* number of subsequent packets */
1070
1071 /* look up transport channel table entry to get peer mtu */
1072 p_tbl = avdt_ad_tc_tbl_by_type(AVDT_CHAN_SIG, p_ccb, NULL);
1073
1074 /* set the current message if there is a message passed in */
1075 if (p_msg != NULL) {
1076 p_ccb->p_curr_msg = p_msg;
1077 }
1078
1079 /* store copy of curr_msg->len */
1080 curr_msg_len = p_ccb->p_curr_msg->len;
1081
1082 /* while not congested and we haven't sent it all */
1083 while ((!p_ccb->cong) && (p_ccb->p_curr_msg != NULL)) {
1084 /* check what kind of message we've got here; we are using the offset
1085 ** to indicate that a message is being fragmented
1086 */
1087
1088 /* if message isn't being fragmented and it fits in mtu */
1089 if ((p_ccb->p_curr_msg->offset == AVDT_MSG_OFFSET) &&
1090 (p_ccb->p_curr_msg->len <= p_tbl->peer_mtu - AVDT_LEN_TYPE_SINGLE)) {
1091 pkt_type = AVDT_PKT_TYPE_SINGLE;
1092 hdr_len = AVDT_LEN_TYPE_SINGLE;
1093 p_buf = p_ccb->p_curr_msg;
1094 }
1095 /* if message isn't being fragmented and it doesn'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_SINGLE)) {
1099 pkt_type = AVDT_PKT_TYPE_START;
1100 hdr_len = AVDT_LEN_TYPE_START;
1101 nosp = (p_ccb->p_curr_msg->len + AVDT_LEN_TYPE_START - p_tbl->peer_mtu) /
1102 (p_tbl->peer_mtu - 1) +
1103 2;
1104
1105 /* get a new buffer for fragment we are sending */
1106 p_buf = (BT_HDR*)osi_malloc(AVDT_CMD_BUF_SIZE);
1107
1108 /* copy portion of data from current message to new buffer */
1109 p_buf->offset = L2CAP_MIN_OFFSET + hdr_len;
1110 p_buf->len = p_tbl->peer_mtu - hdr_len;
1111 memcpy((uint8_t*)(p_buf + 1) + p_buf->offset,
1112 (uint8_t*)(p_ccb->p_curr_msg + 1) + p_ccb->p_curr_msg->offset,
1113 p_buf->len);
1114 }
1115 /* if message is being fragmented and remaining bytes don't fit in mtu */
1116 else if ((p_ccb->p_curr_msg->offset > AVDT_MSG_OFFSET) &&
1117 (p_ccb->p_curr_msg->len >
1118 (p_tbl->peer_mtu - AVDT_LEN_TYPE_CONT))) {
1119 pkt_type = AVDT_PKT_TYPE_CONT;
1120 hdr_len = AVDT_LEN_TYPE_CONT;
1121
1122 /* get a new buffer for fragment we are sending */
1123 p_buf = (BT_HDR*)osi_malloc(AVDT_CMD_BUF_SIZE);
1124
1125 /* copy portion of data from current message to new buffer */
1126 p_buf->offset = L2CAP_MIN_OFFSET + hdr_len;
1127 p_buf->len = p_tbl->peer_mtu - hdr_len;
1128 memcpy((uint8_t*)(p_buf + 1) + p_buf->offset,
1129 (uint8_t*)(p_ccb->p_curr_msg + 1) + p_ccb->p_curr_msg->offset,
1130 p_buf->len);
1131 }
1132 /* if message is being fragmented and remaining bytes do fit in mtu */
1133 else {
1134 pkt_type = AVDT_PKT_TYPE_END;
1135 hdr_len = AVDT_LEN_TYPE_END;
1136 p_buf = p_ccb->p_curr_msg;
1137 }
1138
1139 /* label, sig id, msg type are in hdr of p_curr_msg */
1140 label = AVDT_LAYERSPEC_LABEL(p_ccb->p_curr_msg->layer_specific);
1141 msg = AVDT_LAYERSPEC_MSG(p_ccb->p_curr_msg->layer_specific);
1142 sig = (uint8_t)p_ccb->p_curr_msg->event;
1143 AVDT_TRACE_DEBUG("avdt_msg_send label:%d, msg:%d, sig:%d", label, msg, sig);
1144
1145 /* keep track of how much of msg we've sent */
1146 curr_msg_len -= p_buf->len;
1147 if (curr_msg_len == 0) {
1148 /* entire message sent; mark as finished */
1149 p_ccb->p_curr_msg = NULL;
1150
1151 /* start timer here for commands */
1152 if (msg == AVDT_MSG_TYPE_CMD) {
1153 /* if retransmit timeout set to zero, sig doesn't use retransmit */
1154 if ((sig == AVDT_SIG_DISCOVER) || (sig == AVDT_SIG_GETCAP) ||
1155 (sig == AVDT_SIG_SECURITY) || (avdtp_cb.rcb.ret_tout == 0)) {
1156 alarm_cancel(p_ccb->idle_ccb_timer);
1157 alarm_cancel(p_ccb->ret_ccb_timer);
1158 uint64_t interval_ms = avdtp_cb.rcb.sig_tout * 1000;
1159 alarm_set_on_mloop(p_ccb->rsp_ccb_timer, interval_ms,
1160 avdt_ccb_rsp_ccb_timer_timeout, p_ccb);
1161 } else if (sig != AVDT_SIG_DELAY_RPT) {
1162 alarm_cancel(p_ccb->idle_ccb_timer);
1163 alarm_cancel(p_ccb->rsp_ccb_timer);
1164 uint64_t interval_ms = avdtp_cb.rcb.ret_tout * 1000;
1165 alarm_set_on_mloop(p_ccb->ret_ccb_timer, interval_ms,
1166 avdt_ccb_ret_ccb_timer_timeout, p_ccb);
1167 }
1168 }
1169 } else {
1170 /* message being fragmented and not completely sent */
1171 p_ccb->p_curr_msg->len -= p_buf->len;
1172 p_ccb->p_curr_msg->offset += p_buf->len;
1173 }
1174
1175 /* set up to build header */
1176 p_buf->len += hdr_len;
1177 p_buf->offset -= hdr_len;
1178 p = (uint8_t*)(p_buf + 1) + p_buf->offset;
1179
1180 /* build header */
1181 AVDT_MSG_BLD_HDR(p, label, pkt_type, msg);
1182 if (pkt_type == AVDT_PKT_TYPE_START) {
1183 AVDT_MSG_BLD_NOSP(p, nosp);
1184 }
1185 if ((pkt_type == AVDT_PKT_TYPE_START) ||
1186 (pkt_type == AVDT_PKT_TYPE_SINGLE)) {
1187 AVDT_MSG_BLD_SIG(p, sig);
1188 }
1189
1190 /* send msg buffer down */
1191 avdt_ad_write_req(AVDT_CHAN_SIG, p_ccb, NULL, p_buf);
1192 }
1193 return (p_ccb->cong);
1194 }
1195
1196 /*******************************************************************************
1197 *
1198 * Function avdt_msg_asmbl
1199 *
1200 * Description Reassemble incoming message.
1201 *
1202 *
1203 * Returns Pointer to reassembled message; NULL if no message
1204 * available.
1205 *
1206 ******************************************************************************/
avdt_msg_asmbl(AvdtpCcb * p_ccb,BT_HDR * p_buf)1207 BT_HDR* avdt_msg_asmbl(AvdtpCcb* p_ccb, BT_HDR* p_buf) {
1208 uint8_t* p;
1209 uint8_t pkt_type;
1210 BT_HDR* p_ret;
1211
1212 /* parse the message header */
1213 p = (uint8_t*)(p_buf + 1) + p_buf->offset;
1214
1215 /* Check if is valid length */
1216 if (p_buf->len < 1) {
1217 android_errorWriteLog(0x534e4554, "78287084");
1218 osi_free(p_buf);
1219 p_ret = NULL;
1220 return p_ret;
1221 }
1222 AVDT_MSG_PRS_PKT_TYPE(p, pkt_type);
1223
1224 /* quick sanity check on length */
1225 if (p_buf->len < avdt_msg_pkt_type_len[pkt_type]) {
1226 osi_free(p_buf);
1227 AVDT_TRACE_WARNING("Bad length during reassembly");
1228 p_ret = NULL;
1229 }
1230 /* single packet */
1231 else if (pkt_type == AVDT_PKT_TYPE_SINGLE) {
1232 /* if reassembly in progress drop message and process new single */
1233 if (p_ccb->p_rx_msg != NULL)
1234 AVDT_TRACE_WARNING("Got single during reassembly");
1235
1236 osi_free_and_reset((void**)&p_ccb->p_rx_msg);
1237
1238 p_ret = p_buf;
1239 }
1240 /* start packet */
1241 else if (pkt_type == AVDT_PKT_TYPE_START) {
1242 /* if reassembly in progress drop message and process new single */
1243 if (p_ccb->p_rx_msg != NULL)
1244 AVDT_TRACE_WARNING("Got start during reassembly");
1245
1246 osi_free_and_reset((void**)&p_ccb->p_rx_msg);
1247
1248 /*
1249 * Allocate bigger buffer for reassembly. As lower layers are
1250 * not aware of possible packet size after reassembly, they
1251 * would have allocated smaller buffer.
1252 */
1253 p_ccb->p_rx_msg = (BT_HDR*)osi_malloc(BT_DEFAULT_BUFFER_SIZE);
1254 memcpy(p_ccb->p_rx_msg, p_buf, sizeof(BT_HDR) + p_buf->offset + p_buf->len);
1255
1256 /* Free original buffer */
1257 osi_free(p_buf);
1258
1259 /* update p to point to new buffer */
1260 p = (uint8_t*)(p_ccb->p_rx_msg + 1) + p_ccb->p_rx_msg->offset;
1261
1262 /* copy first header byte over nosp */
1263 *(p + 1) = *p;
1264
1265 /* set offset to point to where to copy next */
1266 p_ccb->p_rx_msg->offset += p_ccb->p_rx_msg->len;
1267
1268 /* adjust length for packet header */
1269 p_ccb->p_rx_msg->len -= 1;
1270
1271 p_ret = NULL;
1272 }
1273 /* continue or end */
1274 else {
1275 /* if no reassembly in progress drop message */
1276 if (p_ccb->p_rx_msg == NULL) {
1277 osi_free(p_buf);
1278 AVDT_TRACE_WARNING("Pkt type=%d out of order", pkt_type);
1279 p_ret = NULL;
1280 } else {
1281 /* get size of buffer holding assembled message */
1282 /*
1283 * NOTE: The buffer is allocated above at the beginning of the
1284 * reassembly, and is always of size BT_DEFAULT_BUFFER_SIZE.
1285 */
1286 uint16_t buf_len = BT_DEFAULT_BUFFER_SIZE - sizeof(BT_HDR);
1287
1288 /* adjust offset and len of fragment for header byte */
1289 p_buf->offset += AVDT_LEN_TYPE_CONT;
1290 p_buf->len -= AVDT_LEN_TYPE_CONT;
1291
1292 /* verify length */
1293 if ((p_ccb->p_rx_msg->offset + p_buf->len) > buf_len) {
1294 /* won't fit; free everything */
1295 AVDT_TRACE_WARNING("%s: Fragmented message too big!", __func__);
1296 osi_free_and_reset((void**)&p_ccb->p_rx_msg);
1297 osi_free(p_buf);
1298 p_ret = NULL;
1299 } else {
1300 /* copy contents of p_buf to p_rx_msg */
1301 memcpy((uint8_t*)(p_ccb->p_rx_msg + 1) + p_ccb->p_rx_msg->offset,
1302 (uint8_t*)(p_buf + 1) + p_buf->offset, p_buf->len);
1303
1304 if (pkt_type == AVDT_PKT_TYPE_END) {
1305 p_ccb->p_rx_msg->offset -= p_ccb->p_rx_msg->len;
1306 p_ccb->p_rx_msg->len += p_buf->len;
1307 p_ret = p_ccb->p_rx_msg;
1308 p_ccb->p_rx_msg = NULL;
1309 } else {
1310 p_ccb->p_rx_msg->offset += p_buf->len;
1311 p_ccb->p_rx_msg->len += p_buf->len;
1312 p_ret = NULL;
1313 }
1314 osi_free(p_buf);
1315 }
1316 }
1317 }
1318 return p_ret;
1319 }
1320
1321 /*******************************************************************************
1322 *
1323 * Function avdt_msg_send_cmd
1324 *
1325 * Description This function is called to send a command message. The
1326 * sig_id parameter indicates the message type, p_params
1327 * points to the message parameters, if any. It gets a buffer
1328 * from the AVDTP command pool, executes the message building
1329 * function for this message type. It then queues the message
1330 * in the command queue for this CCB.
1331 *
1332 *
1333 * Returns Nothing.
1334 *
1335 ******************************************************************************/
avdt_msg_send_cmd(AvdtpCcb * p_ccb,void * p_scb,uint8_t sig_id,tAVDT_MSG * p_params)1336 void avdt_msg_send_cmd(AvdtpCcb* p_ccb, void* p_scb, uint8_t sig_id,
1337 tAVDT_MSG* p_params) {
1338 uint8_t* p;
1339 uint8_t* p_start;
1340 BT_HDR* p_buf = (BT_HDR*)osi_malloc(AVDT_CMD_BUF_SIZE);
1341
1342 /* set up buf pointer and offset */
1343 p_buf->offset = AVDT_MSG_OFFSET;
1344 p_start = p = (uint8_t*)(p_buf + 1) + p_buf->offset;
1345
1346 /* execute parameter building function to build message */
1347 (*avdt_msg_bld_cmd[sig_id - 1])(&p, p_params);
1348
1349 /* set len */
1350 p_buf->len = (uint16_t)(p - p_start);
1351
1352 /* now store scb hdls, if any, in buf */
1353 if (p_scb != NULL) {
1354 p = (uint8_t*)(p_buf + 1);
1355
1356 /* for start and suspend, p_scb points to array of handles */
1357 if ((sig_id == AVDT_SIG_START) || (sig_id == AVDT_SIG_SUSPEND)) {
1358 memcpy(p, (uint8_t*)p_scb, p_buf->len);
1359 }
1360 /* for all others, p_scb points to scb as usual */
1361 else {
1362 *p = avdt_scb_to_hdl((AvdtpScb*)p_scb);
1363 }
1364 }
1365
1366 /* stash sig, label, and message type in buf */
1367 p_buf->event = sig_id;
1368 AVDT_BLD_LAYERSPEC(p_buf->layer_specific, AVDT_MSG_TYPE_CMD, p_ccb->label);
1369
1370 /* increment label */
1371 p_ccb->label = (p_ccb->label + 1) % 16;
1372
1373 /* queue message and trigger ccb to send it */
1374 fixed_queue_enqueue(p_ccb->cmd_q, p_buf);
1375 avdt_ccb_event(p_ccb, AVDT_CCB_SENDMSG_EVT, NULL);
1376 }
1377
1378 /*******************************************************************************
1379 *
1380 * Function avdt_msg_send_rsp
1381 *
1382 * Description This function is called to send a response message. The
1383 * sig_id parameter indicates the message type, p_params
1384 * points to the message parameters, if any. It gets a buffer
1385 * from the AVDTP command pool, executes the message building
1386 * function for this message type. It then queues the message
1387 * in the response queue for this CCB.
1388 *
1389 *
1390 * Returns Nothing.
1391 *
1392 ******************************************************************************/
avdt_msg_send_rsp(AvdtpCcb * p_ccb,uint8_t sig_id,tAVDT_MSG * p_params)1393 void avdt_msg_send_rsp(AvdtpCcb* p_ccb, uint8_t sig_id, tAVDT_MSG* p_params) {
1394 uint8_t* p;
1395 uint8_t* p_start;
1396 BT_HDR* p_buf = (BT_HDR*)osi_malloc(AVDT_CMD_BUF_SIZE);
1397
1398 /* set up buf pointer and offset */
1399 p_buf->offset = AVDT_MSG_OFFSET;
1400 p_start = p = (uint8_t*)(p_buf + 1) + p_buf->offset;
1401
1402 /* execute parameter building function to build message */
1403 (*avdt_msg_bld_rsp[sig_id - 1])(&p, p_params);
1404
1405 /* set length */
1406 p_buf->len = (uint16_t)(p - p_start);
1407
1408 /* stash sig, label, and message type in buf */
1409 p_buf->event = sig_id;
1410 AVDT_BLD_LAYERSPEC(p_buf->layer_specific, AVDT_MSG_TYPE_RSP,
1411 p_params->hdr.label);
1412
1413 /* queue message and trigger ccb to send it */
1414 fixed_queue_enqueue(p_ccb->rsp_q, p_buf);
1415 avdt_ccb_event(p_ccb, AVDT_CCB_SENDMSG_EVT, NULL);
1416 }
1417
1418 /*******************************************************************************
1419 *
1420 * Function avdt_msg_send_rej
1421 *
1422 * Description This function is called to send a reject message. The
1423 * sig_id parameter indicates the message type. It gets
1424 * a buffer from the AVDTP command pool and builds the
1425 * message based on the message type and the error code.
1426 * It then queues the message in the response queue for
1427 * this CCB.
1428 *
1429 *
1430 * Returns Nothing.
1431 *
1432 ******************************************************************************/
avdt_msg_send_rej(AvdtpCcb * p_ccb,uint8_t sig_id,tAVDT_MSG * p_params)1433 void avdt_msg_send_rej(AvdtpCcb* p_ccb, uint8_t sig_id, tAVDT_MSG* p_params) {
1434 uint8_t* p;
1435 uint8_t* p_start;
1436 BT_HDR* p_buf = (BT_HDR*)osi_malloc(AVDT_CMD_BUF_SIZE);
1437
1438 /* set up buf pointer and offset */
1439 p_buf->offset = AVDT_MSG_OFFSET;
1440 p_start = p = (uint8_t*)(p_buf + 1) + p_buf->offset;
1441
1442 /* if sig id included, build into message */
1443 if (sig_id != AVDT_SIG_NONE) {
1444 /* if this sig has a parameter, add the parameter */
1445 if ((sig_id == AVDT_SIG_SETCONFIG) || (sig_id == AVDT_SIG_RECONFIG)) {
1446 AVDT_MSG_BLD_PARAM(p, p_params->hdr.err_param);
1447 } else if ((sig_id == AVDT_SIG_START) || (sig_id == AVDT_SIG_SUSPEND)) {
1448 AVDT_MSG_BLD_SEID(p, p_params->hdr.err_param);
1449 }
1450
1451 /* add the error code */
1452 AVDT_MSG_BLD_ERR(p, p_params->hdr.err_code);
1453 }
1454 AVDT_TRACE_DEBUG("avdt_msg_send_rej");
1455
1456 /* calculate length */
1457 p_buf->len = (uint16_t)(p - p_start);
1458
1459 /* stash sig, label, and message type in buf */
1460 p_buf->event = sig_id;
1461 AVDT_BLD_LAYERSPEC(p_buf->layer_specific, AVDT_MSG_TYPE_REJ,
1462 p_params->hdr.label);
1463
1464 /* queue message and trigger ccb to send it */
1465 fixed_queue_enqueue(p_ccb->rsp_q, p_buf);
1466 avdt_ccb_event(p_ccb, AVDT_CCB_SENDMSG_EVT, NULL);
1467 }
1468
1469 /*******************************************************************************
1470 *
1471 * Function avdt_msg_send_grej
1472 *
1473 * Description This function is called to send a general reject message.
1474 * The sig_id parameter indicates the message type. It gets
1475 * a buffer from the AVDTP command pool and builds the
1476 * message based on the message type and the error code.
1477 * It then queues the message in the response queue for
1478 * this CCB.
1479 *
1480 *
1481 * Returns Nothing.
1482 *
1483 ******************************************************************************/
avdt_msg_send_grej(AvdtpCcb * p_ccb,uint8_t sig_id,tAVDT_MSG * p_params)1484 void avdt_msg_send_grej(AvdtpCcb* p_ccb, uint8_t sig_id, tAVDT_MSG* p_params) {
1485 uint8_t* p;
1486 uint8_t* p_start;
1487 BT_HDR* p_buf = (BT_HDR*)osi_malloc(AVDT_CMD_BUF_SIZE);
1488
1489 /* set up buf pointer and offset */
1490 p_buf->offset = AVDT_MSG_OFFSET;
1491 p_start = p = (uint8_t*)(p_buf + 1) + p_buf->offset;
1492
1493 /* calculate length */
1494 p_buf->len = (uint16_t)(p - p_start);
1495
1496 /* stash sig, label, and message type in buf */
1497 p_buf->event = sig_id;
1498 AVDT_BLD_LAYERSPEC(p_buf->layer_specific, AVDT_MSG_TYPE_GRJ,
1499 p_params->hdr.label);
1500 AVDT_TRACE_DEBUG(__func__);
1501
1502 /* queue message and trigger ccb to send it */
1503 fixed_queue_enqueue(p_ccb->rsp_q, p_buf);
1504 avdt_ccb_event(p_ccb, AVDT_CCB_SENDMSG_EVT, NULL);
1505 }
1506
1507 /*******************************************************************************
1508 *
1509 * Function avdt_msg_ind
1510 *
1511 * Description This function is called by the adaption layer when an
1512 * incoming message is received on the signaling channel.
1513 * It parses the message and sends an event to the appropriate
1514 * SCB or CCB for the message.
1515 *
1516 *
1517 * Returns Nothing.
1518 *
1519 ******************************************************************************/
avdt_msg_ind(AvdtpCcb * p_ccb,BT_HDR * p_buf)1520 void avdt_msg_ind(AvdtpCcb* p_ccb, BT_HDR* p_buf) {
1521 AvdtpScb* p_scb;
1522 uint8_t* p;
1523 bool ok = true;
1524 bool handle_rsp = false;
1525 bool gen_rej = false;
1526 uint8_t label;
1527 uint8_t pkt_type;
1528 uint8_t msg_type;
1529 uint8_t sig = 0;
1530 tAVDT_MSG msg{};
1531 AvdtpSepConfig cfg{};
1532 uint8_t err;
1533 uint8_t evt = 0;
1534 uint8_t scb_hdl;
1535
1536 /* reassemble message; if no message available (we received a fragment) return
1537 */
1538 p_buf = avdt_msg_asmbl(p_ccb, p_buf);
1539 if (p_buf == NULL) {
1540 return;
1541 }
1542
1543 p = (uint8_t*)(p_buf + 1) + p_buf->offset;
1544
1545 /* parse the message header */
1546 AVDT_MSG_PRS_HDR(p, label, pkt_type, msg_type);
1547
1548 AVDT_TRACE_DEBUG("msg_type=%d, sig=%d", msg_type, sig);
1549 /* set up label and ccb_idx in message hdr */
1550 msg.hdr.label = label;
1551 msg.hdr.ccb_idx = avdt_ccb_to_idx(p_ccb);
1552
1553 /* verify msg type */
1554 if (msg_type == AVDT_MSG_TYPE_GRJ) {
1555 AVDT_TRACE_WARNING("Dropping msg msg_type=%d", msg_type);
1556 ok = false;
1557 }
1558 /* check for general reject */
1559 else if ((msg_type == AVDT_MSG_TYPE_REJ) &&
1560 (p_buf->len == AVDT_LEN_GEN_REJ)) {
1561 gen_rej = true;
1562 if (p_ccb->p_curr_cmd != NULL) {
1563 msg.hdr.sig_id = sig = (uint8_t)p_ccb->p_curr_cmd->event;
1564 evt = avdt_msg_rej_2_evt[sig - 1];
1565 msg.hdr.err_code = AVDT_ERR_NSC;
1566 msg.hdr.err_param = 0;
1567 }
1568 } else /* not a general reject */
1569 {
1570 /* get and verify signal */
1571 AVDT_MSG_PRS_SIG(p, sig);
1572 msg.hdr.sig_id = sig;
1573 if ((sig == 0) || (sig > AVDT_SIG_MAX)) {
1574 AVDT_TRACE_WARNING("Dropping msg sig=%d msg_type:%d", sig, msg_type);
1575 ok = false;
1576
1577 /* send a general reject */
1578 if (msg_type == AVDT_MSG_TYPE_CMD) {
1579 avdt_msg_send_grej(p_ccb, sig, &msg);
1580 }
1581 }
1582 }
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 AVDT_TRACE_WARNING("Parsing failed sig=%d 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 AVDT_TRACE_WARNING("Cmd not found for rsp sig=%d label=%d", 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