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