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