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