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