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