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