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