1 /****************************************************************************** 2 * 3 * Copyright 2003-2016 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 * Interface to AVRCP mandatory commands 22 * 23 ******************************************************************************/ 24 #include <base/logging.h> 25 #include <string.h> 26 27 #include "avrc_api.h" 28 #include "avrc_int.h" 29 #include "bt_common.h" 30 #include "btu.h" 31 #include "osi/include/fixed_queue.h" 32 #include "osi/include/osi.h" 33 34 /***************************************************************************** 35 * Global data 36 ****************************************************************************/ 37 38 #define AVRC_MAX_RCV_CTRL_EVT AVCT_BROWSE_UNCONG_IND_EVT 39 40 #ifndef MAX 41 #define MAX(a, b) ((a) > (b) ? (a) : (b)) 42 #endif 43 44 static const uint8_t avrc_ctrl_event_map[] = { 45 AVRC_OPEN_IND_EVT, /* AVCT_CONNECT_CFM_EVT */ 46 AVRC_OPEN_IND_EVT, /* AVCT_CONNECT_IND_EVT */ 47 AVRC_CLOSE_IND_EVT, /* AVCT_DISCONNECT_CFM_EVT */ 48 AVRC_CLOSE_IND_EVT, /* AVCT_DISCONNECT_IND_EVT */ 49 AVRC_CONG_IND_EVT, /* AVCT_CONG_IND_EVT */ 50 AVRC_UNCONG_IND_EVT, /* AVCT_UNCONG_IND_EVT */ 51 AVRC_BROWSE_OPEN_IND_EVT, /* AVCT_BROWSE_CONN_CFM_EVT */ 52 AVRC_BROWSE_OPEN_IND_EVT, /* AVCT_BROWSE_CONN_IND_EVT */ 53 AVRC_BROWSE_CLOSE_IND_EVT, /* AVCT_BROWSE_DISCONN_CFM_EVT */ 54 AVRC_BROWSE_CLOSE_IND_EVT, /* AVCT_BROWSE_DISCONN_IND_EVT */ 55 AVRC_BROWSE_CONG_IND_EVT, /* AVCT_BROWSE_CONG_IND_EVT */ 56 AVRC_BROWSE_UNCONG_IND_EVT /* AVCT_BROWSE_UNCONG_IND_EVT */ 57 }; 58 59 /* use this unused opcode to indication no need to call the callback function */ 60 #define AVRC_OP_DROP 0xFE 61 /* use this unused opcode to indication no need to call the callback function & 62 * free buffer */ 63 #define AVRC_OP_DROP_N_FREE 0xFD 64 65 #define AVRC_OP_UNIT_INFO_RSP_LEN 8 66 #define AVRC_OP_SUB_UNIT_INFO_RSP_LEN 8 67 #define AVRC_OP_REJ_MSG_LEN 11 68 69 /* Flags definitions for AVRC_MsgReq */ 70 #define AVRC_MSG_MASK_IS_VENDOR_CMD 0x01 71 #define AVRC_MSG_MASK_IS_CONTINUATION_RSP 0x02 72 73 /****************************************************************************** 74 * 75 * Function avrc_ctrl_cback 76 * 77 * Description This is the callback function used by AVCTP to report 78 * received link events. 79 * 80 * Returns Nothing. 81 * 82 *****************************************************************************/ 83 static void avrc_ctrl_cback(uint8_t handle, uint8_t event, uint16_t result, 84 const RawAddress* peer_addr) { 85 uint8_t avrc_event; 86 87 if (event <= AVRC_MAX_RCV_CTRL_EVT && avrc_cb.ccb[handle].ctrl_cback) { 88 avrc_event = avrc_ctrl_event_map[event]; 89 if (event == AVCT_CONNECT_CFM_EVT) { 90 if (result != 0) /* failed */ 91 avrc_event = AVRC_CLOSE_IND_EVT; 92 } 93 avrc_cb.ccb[handle].ctrl_cback.Run(handle, avrc_event, result, peer_addr); 94 } 95 96 if ((event == AVCT_DISCONNECT_CFM_EVT) || 97 (event == AVCT_DISCONNECT_IND_EVT)) { 98 avrc_flush_cmd_q(handle); 99 alarm_free(avrc_cb.ccb_int[handle].tle); 100 avrc_cb.ccb_int[handle].tle = NULL; 101 } 102 } 103 104 /****************************************************************************** 105 * 106 * Function avrc_flush_cmd_q 107 * 108 * Description Flush command queue for the specified avrc handle 109 * 110 * Returns Nothing. 111 * 112 *****************************************************************************/ 113 void avrc_flush_cmd_q(uint8_t handle) { 114 AVRC_TRACE_DEBUG("AVRC: Flushing command queue for handle=0x%02x", handle); 115 avrc_cb.ccb_int[handle].flags &= ~AVRC_CB_FLAGS_RSP_PENDING; 116 117 alarm_cancel(avrc_cb.ccb_int[handle].tle); 118 fixed_queue_free(avrc_cb.ccb_int[handle].cmd_q, osi_free); 119 avrc_cb.ccb_int[handle].cmd_q = NULL; 120 } 121 122 /****************************************************************************** 123 * 124 * Function avrc_process_timeout 125 * 126 * Description Handle avrc command timeout 127 * 128 * Returns Nothing. 129 * 130 *****************************************************************************/ 131 void avrc_process_timeout(void* data) { 132 tAVRC_PARAM* param = (tAVRC_PARAM*)data; 133 134 AVRC_TRACE_DEBUG("AVRC: command timeout (handle=0x%02x, label=0x%02x)", 135 param->handle, param->label); 136 137 /* Notify app */ 138 if (avrc_cb.ccb[param->handle].ctrl_cback) { 139 avrc_cb.ccb[param->handle].ctrl_cback.Run( 140 param->handle, AVRC_CMD_TIMEOUT_EVT, param->label, NULL); 141 } 142 143 /* If vendor command timed-out, then send next command in the queue */ 144 if (param->msg_mask & AVRC_MSG_MASK_IS_VENDOR_CMD) { 145 avrc_send_next_vendor_cmd(param->handle); 146 } 147 osi_free(param); 148 } 149 150 /****************************************************************************** 151 * 152 * Function avrc_send_next_vendor_cmd 153 * 154 * Description Dequeue and send next vendor command for given handle 155 * 156 * Returns Nothing. 157 * 158 *****************************************************************************/ 159 void avrc_send_next_vendor_cmd(uint8_t handle) { 160 BT_HDR* p_next_cmd; 161 uint8_t next_label; 162 163 while ((p_next_cmd = (BT_HDR*)fixed_queue_try_dequeue( 164 avrc_cb.ccb_int[handle].cmd_q)) != NULL) { 165 p_next_cmd->event &= 0xFF; /* opcode */ 166 next_label = (p_next_cmd->layer_specific) >> 8; /* extract label */ 167 p_next_cmd->layer_specific &= 0xFF; /* AVCT_DATA_CTRL or AVCT_DATA_BROWSE */ 168 169 AVRC_TRACE_DEBUG( 170 "AVRC: Dequeuing command 0x%08x (handle=0x%02x, label=0x%02x)", 171 p_next_cmd, handle, next_label); 172 173 /* Send the message */ 174 if ((AVCT_MsgReq(handle, next_label, AVCT_CMD, p_next_cmd)) == 175 AVCT_SUCCESS) { 176 /* Start command timer to wait for response */ 177 avrc_start_cmd_timer(handle, next_label, AVRC_MSG_MASK_IS_VENDOR_CMD); 178 return; 179 } 180 } 181 182 if (p_next_cmd == NULL) { 183 /* cmd queue empty */ 184 avrc_cb.ccb_int[handle].flags &= ~AVRC_CB_FLAGS_RSP_PENDING; 185 } 186 } 187 188 /****************************************************************************** 189 * 190 * Function avrc_start_cmd_timer 191 * 192 * Description Start timer for waiting for responses 193 * 194 * Returns Nothing. 195 * 196 *****************************************************************************/ 197 void avrc_start_cmd_timer(uint8_t handle, uint8_t label, uint8_t msg_mask) { 198 tAVRC_PARAM* param = 199 static_cast<tAVRC_PARAM*>(osi_malloc(sizeof(tAVRC_PARAM))); 200 param->handle = handle; 201 param->label = label; 202 param->msg_mask = msg_mask; 203 204 AVRC_TRACE_DEBUG("AVRC: starting timer (handle=0x%02x, label=0x%02x)", handle, 205 label); 206 207 alarm_set_on_mloop(avrc_cb.ccb_int[handle].tle, AVRC_CMD_TOUT_MS, 208 avrc_process_timeout, param); 209 } 210 211 /****************************************************************************** 212 * 213 * Function avrc_get_data_ptr 214 * 215 * Description Gets a pointer to the data payload in the packet. 216 * 217 * Returns A pointer to the data payload. 218 * 219 *****************************************************************************/ 220 static uint8_t* avrc_get_data_ptr(BT_HDR* p_pkt) { 221 return (uint8_t*)(p_pkt + 1) + p_pkt->offset; 222 } 223 224 /****************************************************************************** 225 * 226 * Function avrc_copy_packet 227 * 228 * Description Copies an AVRC packet to a new buffer. In the new buffer, 229 * the payload offset is at least AVCT_MSG_OFFSET octets. 230 * 231 * Returns The buffer with the copied data. 232 * 233 *****************************************************************************/ 234 static BT_HDR* avrc_copy_packet(BT_HDR* p_pkt, int rsp_pkt_len) { 235 const int offset = MAX(AVCT_MSG_OFFSET, p_pkt->offset); 236 const int pkt_len = MAX(rsp_pkt_len, p_pkt->len); 237 BT_HDR* p_pkt_copy = (BT_HDR*)osi_malloc(BT_HDR_SIZE + offset + pkt_len); 238 239 /* Copy the packet header, set the new offset, and copy the payload */ 240 memcpy(p_pkt_copy, p_pkt, BT_HDR_SIZE); 241 p_pkt_copy->offset = offset; 242 uint8_t* p_data = avrc_get_data_ptr(p_pkt); 243 uint8_t* p_data_copy = avrc_get_data_ptr(p_pkt_copy); 244 memcpy(p_data_copy, p_data, p_pkt->len); 245 246 return p_pkt_copy; 247 } 248 249 /****************************************************************************** 250 * 251 * Function avrc_prep_end_frag 252 * 253 * Description This function prepares an end response fragment 254 * 255 * Returns Nothing. 256 * 257 *****************************************************************************/ 258 static void avrc_prep_end_frag(uint8_t handle) { 259 tAVRC_FRAG_CB* p_fcb; 260 BT_HDR* p_pkt_new; 261 uint8_t *p_data, *p_orig_data; 262 uint8_t rsp_type; 263 264 AVRC_TRACE_DEBUG("%s", __func__); 265 p_fcb = &avrc_cb.fcb[handle]; 266 267 /* The response type of the end fragment should be the same as the the PDU of 268 * "End Fragment Response" Errata: 269 * https://www.bluetooth.org/errata/errata_view.cfm?errata_id=4383 270 */ 271 p_orig_data = ((uint8_t*)(p_fcb->p_fmsg + 1) + p_fcb->p_fmsg->offset); 272 rsp_type = ((*p_orig_data) & AVRC_CTYPE_MASK); 273 274 p_pkt_new = p_fcb->p_fmsg; 275 p_pkt_new->len -= 276 (AVRC_MAX_CTRL_DATA_LEN - AVRC_VENDOR_HDR_SIZE - AVRC_MIN_META_HDR_SIZE); 277 p_pkt_new->offset += 278 (AVRC_MAX_CTRL_DATA_LEN - AVRC_VENDOR_HDR_SIZE - AVRC_MIN_META_HDR_SIZE); 279 p_data = (uint8_t*)(p_pkt_new + 1) + p_pkt_new->offset; 280 *p_data++ = rsp_type; 281 *p_data++ = (AVRC_SUB_PANEL << AVRC_SUBTYPE_SHIFT); 282 *p_data++ = AVRC_OP_VENDOR; 283 AVRC_CO_ID_TO_BE_STREAM(p_data, AVRC_CO_METADATA); 284 *p_data++ = p_fcb->frag_pdu; 285 *p_data++ = AVRC_PKT_END; 286 287 /* 4=pdu, pkt_type & len */ 288 UINT16_TO_BE_STREAM( 289 p_data, (p_pkt_new->len - AVRC_VENDOR_HDR_SIZE - AVRC_MIN_META_HDR_SIZE)); 290 } 291 292 /****************************************************************************** 293 * 294 * Function avrc_send_continue_frag 295 * 296 * Description This function sends a continue response fragment 297 * 298 * Returns AVRC_SUCCESS if successful. 299 * AVRC_BAD_HANDLE if handle is invalid. 300 * 301 *****************************************************************************/ 302 static uint16_t avrc_send_continue_frag(uint8_t handle, uint8_t label) { 303 tAVRC_FRAG_CB* p_fcb; 304 BT_HDR *p_pkt_old, *p_pkt; 305 uint8_t *p_old, *p_data; 306 uint8_t cr = AVCT_RSP; 307 308 p_fcb = &avrc_cb.fcb[handle]; 309 p_pkt = p_fcb->p_fmsg; 310 311 AVRC_TRACE_DEBUG("%s handle = %u label = %u len = %d", __func__, handle, 312 label, p_pkt->len); 313 if (p_pkt->len > AVRC_MAX_CTRL_DATA_LEN) { 314 int offset_len = MAX(AVCT_MSG_OFFSET, p_pkt->offset); 315 p_pkt_old = p_fcb->p_fmsg; 316 p_pkt = (BT_HDR*)osi_malloc(AVRC_PACKET_LEN + offset_len + BT_HDR_SIZE); 317 p_pkt->len = AVRC_MAX_CTRL_DATA_LEN; 318 p_pkt->offset = AVCT_MSG_OFFSET; 319 p_pkt->layer_specific = p_pkt_old->layer_specific; 320 p_pkt->event = p_pkt_old->event; 321 p_old = (uint8_t*)(p_pkt_old + 1) + p_pkt_old->offset; 322 p_data = (uint8_t*)(p_pkt + 1) + p_pkt->offset; 323 memcpy(p_data, p_old, AVRC_MAX_CTRL_DATA_LEN); 324 /* use AVRC continue packet type */ 325 p_data += AVRC_VENDOR_HDR_SIZE; 326 p_data++; /* pdu */ 327 *p_data++ = AVRC_PKT_CONTINUE; 328 /* 4=pdu, pkt_type & len */ 329 UINT16_TO_BE_STREAM(p_data, 330 (AVRC_MAX_CTRL_DATA_LEN - AVRC_VENDOR_HDR_SIZE - 4)); 331 332 /* prepare the left over for as an end fragment */ 333 avrc_prep_end_frag(handle); 334 } else { 335 /* end fragment. clean the control block */ 336 p_fcb->frag_enabled = false; 337 p_fcb->p_fmsg = NULL; 338 } 339 return AVCT_MsgReq(handle, label, cr, p_pkt); 340 } 341 342 /****************************************************************************** 343 * 344 * Function avrc_proc_vendor_command 345 * 346 * Description This function processes received vendor command. 347 * 348 * Returns if not NULL, the response to send right away. 349 * 350 *****************************************************************************/ 351 static BT_HDR* avrc_proc_vendor_command(uint8_t handle, uint8_t label, 352 BT_HDR* p_pkt, 353 tAVRC_MSG_VENDOR* p_msg) { 354 BT_HDR* p_rsp = NULL; 355 uint8_t* p_data; 356 uint8_t* p_begin; 357 uint8_t pkt_type; 358 bool abort_frag = false; 359 tAVRC_STS status = AVRC_STS_NO_ERROR; 360 tAVRC_FRAG_CB* p_fcb; 361 362 p_begin = (uint8_t*)(p_pkt + 1) + p_pkt->offset; 363 p_data = p_begin + AVRC_VENDOR_HDR_SIZE; 364 pkt_type = *(p_data + 1) & AVRC_PKT_TYPE_MASK; 365 366 if (pkt_type != AVRC_PKT_SINGLE) { 367 /* reject - commands can only be in single packets at AVRCP level */ 368 AVRC_TRACE_ERROR("commands must be in single packet pdu:0x%x", *p_data); 369 /* use the current GKI buffer to send the reject */ 370 status = AVRC_STS_BAD_CMD; 371 } 372 /* check if there are fragments waiting to be sent */ 373 else if (avrc_cb.fcb[handle].frag_enabled) { 374 p_fcb = &avrc_cb.fcb[handle]; 375 if (p_msg->company_id == AVRC_CO_METADATA) { 376 switch (*p_data) { 377 case AVRC_PDU_ABORT_CONTINUATION_RSP: 378 /* aborted by CT - send accept response */ 379 abort_frag = true; 380 p_begin = (uint8_t*)(p_pkt + 1) + p_pkt->offset; 381 *p_begin = (AVRC_RSP_ACCEPT & AVRC_CTYPE_MASK); 382 if (*(p_data + 4) != p_fcb->frag_pdu) { 383 *p_begin = (AVRC_RSP_REJ & AVRC_CTYPE_MASK); 384 *(p_data + 4) = AVRC_STS_BAD_PARAM; 385 } else { 386 p_data = (p_begin + AVRC_VENDOR_HDR_SIZE + 2); 387 UINT16_TO_BE_STREAM(p_data, 0); 388 p_pkt->len = (p_data - p_begin); 389 } 390 AVCT_MsgReq(handle, label, AVCT_RSP, p_pkt); 391 p_msg->hdr.opcode = 392 AVRC_OP_DROP; /* used the p_pkt to send response */ 393 break; 394 395 case AVRC_PDU_REQUEST_CONTINUATION_RSP: 396 if (*(p_data + 4) == p_fcb->frag_pdu) { 397 avrc_send_continue_frag(handle, label); 398 p_msg->hdr.opcode = AVRC_OP_DROP_N_FREE; 399 } else { 400 /* the pdu id does not match - reject the command using the current 401 * GKI buffer */ 402 AVRC_TRACE_ERROR( 403 "%s continue pdu: 0x%x does not match the current pdu: 0x%x", 404 __func__, *(p_data + 4), p_fcb->frag_pdu); 405 status = AVRC_STS_BAD_PARAM; 406 abort_frag = true; 407 } 408 break; 409 410 default: 411 /* implicit abort */ 412 abort_frag = true; 413 } 414 } else { 415 abort_frag = true; 416 /* implicit abort */ 417 } 418 419 if (abort_frag) { 420 osi_free_and_reset((void**)&p_fcb->p_fmsg); 421 p_fcb->frag_enabled = false; 422 } 423 } 424 425 if (status != AVRC_STS_NO_ERROR) { 426 p_rsp = (BT_HDR*)osi_malloc(BT_DEFAULT_BUFFER_SIZE); 427 p_rsp->offset = p_pkt->offset; 428 p_data = (uint8_t*)(p_rsp + 1) + p_pkt->offset; 429 *p_data++ = AVRC_RSP_REJ; 430 p_data += AVRC_VENDOR_HDR_SIZE; /* pdu */ 431 *p_data++ = 0; /* pkt_type */ 432 UINT16_TO_BE_STREAM(p_data, 1); /* len */ 433 *p_data++ = status; /* error code */ 434 p_rsp->len = AVRC_VENDOR_HDR_SIZE + 5; 435 } 436 437 return p_rsp; 438 } 439 440 /****************************************************************************** 441 * 442 * Function avrc_proc_far_msg 443 * 444 * Description This function processes metadata fragmenation 445 * and reassembly 446 * 447 * Returns 0, to report the message with msg_cback . 448 * 449 *****************************************************************************/ 450 static uint8_t avrc_proc_far_msg(uint8_t handle, uint8_t label, uint8_t cr, 451 BT_HDR** pp_pkt, tAVRC_MSG_VENDOR* p_msg) { 452 BT_HDR* p_pkt = *pp_pkt; 453 uint8_t* p_data; 454 uint8_t drop_code = 0; 455 bool buf_overflow = false; 456 BT_HDR* p_rsp = NULL; 457 BT_HDR* p_cmd = NULL; 458 bool req_continue = false; 459 BT_HDR* p_pkt_new = NULL; 460 uint8_t pkt_type; 461 tAVRC_RASM_CB* p_rcb; 462 tAVRC_NEXT_CMD avrc_cmd; 463 tAVRC_STS status; 464 465 p_data = (uint8_t*)(p_pkt + 1) + p_pkt->offset; 466 467 /* Skip over vendor header (ctype, subunit*, opcode, CO_ID) */ 468 p_data += AVRC_VENDOR_HDR_SIZE; 469 470 pkt_type = *(p_data + 1) & AVRC_PKT_TYPE_MASK; 471 AVRC_TRACE_DEBUG("pkt_type %d", pkt_type); 472 p_rcb = &avrc_cb.rcb[handle]; 473 474 /* check if the message needs to be re-assembled */ 475 if (pkt_type == AVRC_PKT_SINGLE || pkt_type == AVRC_PKT_START) { 476 /* previous fragments need to be dropped, when received another new message 477 */ 478 p_rcb->rasm_offset = 0; 479 osi_free_and_reset((void**)&p_rcb->p_rmsg); 480 } 481 482 if (pkt_type != AVRC_PKT_SINGLE && cr == AVCT_RSP) { 483 /* not a single response packet - need to re-assemble metadata messages */ 484 if (pkt_type == AVRC_PKT_START) { 485 /* Allocate buffer for re-assembly */ 486 p_rcb->rasm_pdu = *p_data; 487 p_rcb->p_rmsg = (BT_HDR*)osi_malloc(BT_DEFAULT_BUFFER_SIZE); 488 /* Copy START packet to buffer for re-assembling fragments */ 489 memcpy(p_rcb->p_rmsg, p_pkt, sizeof(BT_HDR)); /* Copy bt hdr */ 490 491 /* Copy metadata message */ 492 memcpy((uint8_t*)(p_rcb->p_rmsg + 1), 493 (uint8_t*)(p_pkt + 1) + p_pkt->offset, p_pkt->len); 494 495 /* offset of start of metadata response in reassembly buffer */ 496 p_rcb->p_rmsg->offset = p_rcb->rasm_offset = 0; 497 498 /* 499 * Free original START packet, replace with pointer to 500 * reassembly buffer. 501 */ 502 osi_free(p_pkt); 503 *pp_pkt = p_rcb->p_rmsg; 504 505 /* 506 * Set offset to point to where to copy next - use the same 507 * reassembly logic as AVCT. 508 */ 509 p_rcb->p_rmsg->offset += p_rcb->p_rmsg->len; 510 req_continue = true; 511 } else if (p_rcb->p_rmsg == NULL) { 512 /* Received a CONTINUE/END, but no corresponding START 513 (or previous fragmented response was dropped) */ 514 AVRC_TRACE_DEBUG( 515 "Received a CONTINUE/END without no corresponding START \ 516 (or previous fragmented response was dropped)"); 517 drop_code = 5; 518 osi_free(p_pkt); 519 *pp_pkt = NULL; 520 } else { 521 /* get size of buffer holding assembled message */ 522 /* 523 * NOTE: The buffer is allocated above at the beginning of the 524 * reassembly, and is always of size BT_DEFAULT_BUFFER_SIZE. 525 */ 526 uint16_t buf_len = BT_DEFAULT_BUFFER_SIZE - sizeof(BT_HDR); 527 /* adjust offset and len of fragment for header byte */ 528 p_pkt->offset += (AVRC_VENDOR_HDR_SIZE + AVRC_MIN_META_HDR_SIZE); 529 p_pkt->len -= (AVRC_VENDOR_HDR_SIZE + AVRC_MIN_META_HDR_SIZE); 530 /* verify length */ 531 if ((p_rcb->p_rmsg->offset + p_pkt->len) > buf_len) { 532 AVRC_TRACE_WARNING( 533 "Fragmented message too big! - report the partial message"); 534 p_pkt->len = buf_len - p_rcb->p_rmsg->offset; 535 pkt_type = AVRC_PKT_END; 536 buf_overflow = true; 537 } 538 539 /* copy contents of p_pkt to p_rx_msg */ 540 memcpy((uint8_t*)(p_rcb->p_rmsg + 1) + p_rcb->p_rmsg->offset, 541 (uint8_t*)(p_pkt + 1) + p_pkt->offset, p_pkt->len); 542 543 if (pkt_type == AVRC_PKT_END) { 544 p_rcb->p_rmsg->offset = p_rcb->rasm_offset; 545 p_rcb->p_rmsg->len += p_pkt->len; 546 p_pkt_new = p_rcb->p_rmsg; 547 p_rcb->rasm_offset = 0; 548 p_rcb->p_rmsg = NULL; 549 p_msg->p_vendor_data = (uint8_t*)(p_pkt_new + 1) + p_pkt_new->offset; 550 p_msg->hdr.ctype = p_msg->p_vendor_data[0] & AVRC_CTYPE_MASK; 551 /* 6 = ctype, subunit*, opcode & CO_ID */ 552 p_msg->p_vendor_data += AVRC_VENDOR_HDR_SIZE; 553 p_msg->vendor_len = p_pkt_new->len - AVRC_VENDOR_HDR_SIZE; 554 p_data = p_msg->p_vendor_data + 1; /* skip pdu */ 555 *p_data++ = AVRC_PKT_SINGLE; 556 UINT16_TO_BE_STREAM(p_data, 557 (p_msg->vendor_len - AVRC_MIN_META_HDR_SIZE)); 558 AVRC_TRACE_DEBUG("end frag:%d, total len:%d, offset:%d", p_pkt->len, 559 p_pkt_new->len, p_pkt_new->offset); 560 } else { 561 p_rcb->p_rmsg->offset += p_pkt->len; 562 p_rcb->p_rmsg->len += p_pkt->len; 563 p_pkt_new = NULL; 564 req_continue = true; 565 } 566 osi_free(p_pkt); 567 *pp_pkt = p_pkt_new; 568 } 569 } 570 571 if (cr == AVCT_CMD) { 572 p_rsp = avrc_proc_vendor_command(handle, label, *pp_pkt, p_msg); 573 if (p_rsp) { 574 AVCT_MsgReq(handle, label, AVCT_RSP, p_rsp); 575 osi_free_and_reset((void**)pp_pkt); 576 drop_code = 3; 577 } else if (p_msg->hdr.opcode == AVRC_OP_DROP) { 578 drop_code = 1; 579 } else if (p_msg->hdr.opcode == AVRC_OP_DROP_N_FREE) 580 drop_code = 4; 581 582 } else if (cr == AVCT_RSP) { 583 if (req_continue) { 584 avrc_cmd.pdu = AVRC_PDU_REQUEST_CONTINUATION_RSP; 585 drop_code = 2; 586 } else if (buf_overflow) { 587 /* Incoming message too big to fit in BT_DEFAULT_BUFFER_SIZE. Send abort 588 * to peer */ 589 avrc_cmd.pdu = AVRC_PDU_ABORT_CONTINUATION_RSP; 590 drop_code = 4; 591 } else { 592 return drop_code; 593 } 594 avrc_cmd.status = AVRC_STS_NO_ERROR; 595 avrc_cmd.target_pdu = p_rcb->rasm_pdu; 596 597 tAVRC_COMMAND avrc_command; 598 avrc_command.continu = avrc_cmd; 599 status = AVRC_BldCommand(&avrc_command, &p_cmd); 600 if (status == AVRC_STS_NO_ERROR) { 601 AVRC_MsgReq(handle, (uint8_t)(label), AVRC_CMD_CTRL, p_cmd); 602 } 603 } 604 605 return drop_code; 606 } 607 608 /****************************************************************************** 609 * 610 * Function avrc_msg_cback 611 * 612 * Description This is the callback function used by AVCTP to report 613 * received AV control messages. 614 * 615 * Returns Nothing. 616 * 617 *****************************************************************************/ 618 static void avrc_msg_cback(uint8_t handle, uint8_t label, uint8_t cr, 619 BT_HDR* p_pkt) { 620 uint8_t opcode; 621 tAVRC_MSG msg; 622 uint8_t* p_data; 623 uint8_t* p_begin; 624 bool drop = false; 625 bool do_free = true; 626 BT_HDR* p_rsp = NULL; 627 uint8_t* p_rsp_data; 628 int xx; 629 bool reject = false; 630 const char* p_drop_msg = "dropped"; 631 tAVRC_MSG_VENDOR* p_msg = &msg.vendor; 632 633 if (cr == AVCT_CMD && (p_pkt->layer_specific & AVCT_DATA_CTRL && 634 AVRC_PACKET_LEN < sizeof(p_pkt->len))) { 635 /* Ignore the invalid AV/C command frame */ 636 p_drop_msg = "dropped - too long AV/C cmd frame size"; 637 osi_free(p_pkt); 638 return; 639 } 640 641 if (cr == AVCT_REJ) { 642 /* The peer thinks that this PID is no longer open - remove this handle */ 643 /* */ 644 osi_free(p_pkt); 645 AVCT_RemoveConn(handle); 646 return; 647 } else if (cr == AVCT_RSP) { 648 /* Received response. Stop command timeout timer */ 649 AVRC_TRACE_DEBUG("AVRC: stopping timer (handle=0x%02x)", handle); 650 alarm_cancel(avrc_cb.ccb_int[handle].tle); 651 } 652 653 p_data = (uint8_t*)(p_pkt + 1) + p_pkt->offset; 654 memset(&msg, 0, sizeof(tAVRC_MSG)); 655 656 if (p_pkt->layer_specific == AVCT_DATA_BROWSE) { 657 opcode = AVRC_OP_BROWSE; 658 msg.browse.hdr.ctype = cr; 659 msg.browse.p_browse_data = p_data; 660 msg.browse.browse_len = p_pkt->len; 661 msg.browse.p_browse_pkt = p_pkt; 662 } else { 663 msg.hdr.ctype = p_data[0] & AVRC_CTYPE_MASK; 664 AVRC_TRACE_DEBUG("%s handle:%d, ctype:%d, offset:%d, len: %d", __func__, 665 handle, msg.hdr.ctype, p_pkt->offset, p_pkt->len); 666 msg.hdr.subunit_type = 667 (p_data[1] & AVRC_SUBTYPE_MASK) >> AVRC_SUBTYPE_SHIFT; 668 msg.hdr.subunit_id = p_data[1] & AVRC_SUBID_MASK; 669 opcode = p_data[2]; 670 } 671 672 if (((avrc_cb.ccb[handle].control & AVRC_CT_TARGET) && (cr == AVCT_CMD)) || 673 ((avrc_cb.ccb[handle].control & AVRC_CT_CONTROL) && (cr == AVCT_RSP))) { 674 switch (opcode) { 675 case AVRC_OP_UNIT_INFO: 676 if (cr == AVCT_CMD) { 677 /* send the response to the peer */ 678 p_rsp = avrc_copy_packet(p_pkt, AVRC_OP_UNIT_INFO_RSP_LEN); 679 p_rsp_data = avrc_get_data_ptr(p_rsp); 680 *p_rsp_data = AVRC_RSP_IMPL_STBL; 681 /* check & set the offset. set response code, set subunit_type & 682 subunit_id, 683 set AVRC_OP_UNIT_INFO */ 684 /* 3 bytes: ctype, subunit*, opcode */ 685 p_rsp_data += AVRC_AVC_HDR_SIZE; 686 *p_rsp_data++ = 7; 687 /* Panel subunit & id=0 */ 688 *p_rsp_data++ = (AVRC_SUB_PANEL << AVRC_SUBTYPE_SHIFT); 689 AVRC_CO_ID_TO_BE_STREAM(p_rsp_data, avrc_cb.ccb[handle].company_id); 690 p_rsp->len = 691 (uint16_t)(p_rsp_data - (uint8_t*)(p_rsp + 1) - p_rsp->offset); 692 cr = AVCT_RSP; 693 p_drop_msg = "auto respond"; 694 } else { 695 /* parse response */ 696 p_data += 4; /* 3 bytes: ctype, subunit*, opcode + octet 3 (is 7)*/ 697 msg.unit.unit_type = 698 (*p_data & AVRC_SUBTYPE_MASK) >> AVRC_SUBTYPE_SHIFT; 699 msg.unit.unit = *p_data & AVRC_SUBID_MASK; 700 p_data++; 701 AVRC_BE_STREAM_TO_CO_ID(msg.unit.company_id, p_data); 702 } 703 break; 704 705 case AVRC_OP_SUB_INFO: 706 if (cr == AVCT_CMD) { 707 /* send the response to the peer */ 708 p_rsp = avrc_copy_packet(p_pkt, AVRC_OP_SUB_UNIT_INFO_RSP_LEN); 709 p_rsp_data = avrc_get_data_ptr(p_rsp); 710 *p_rsp_data = AVRC_RSP_IMPL_STBL; 711 /* check & set the offset. set response code, set (subunit_type & 712 subunit_id), 713 set AVRC_OP_SUB_INFO, set (page & extention code) */ 714 p_rsp_data += 4; 715 /* Panel subunit & id=0 */ 716 *p_rsp_data++ = (AVRC_SUB_PANEL << AVRC_SUBTYPE_SHIFT); 717 memset(p_rsp_data, AVRC_CMD_OPRND_PAD, AVRC_SUBRSP_OPRND_BYTES); 718 p_rsp_data += AVRC_SUBRSP_OPRND_BYTES; 719 p_rsp->len = 720 (uint16_t)(p_rsp_data - (uint8_t*)(p_rsp + 1) - p_rsp->offset); 721 cr = AVCT_RSP; 722 p_drop_msg = "auto responded"; 723 } else { 724 /* parse response */ 725 p_data += AVRC_AVC_HDR_SIZE; /* 3 bytes: ctype, subunit*, opcode */ 726 msg.sub.page = 727 (*p_data++ >> AVRC_SUB_PAGE_SHIFT) & AVRC_SUB_PAGE_MASK; 728 xx = 0; 729 while (*p_data != AVRC_CMD_OPRND_PAD && xx < AVRC_SUB_TYPE_LEN) { 730 msg.sub.subunit_type[xx] = *p_data++ >> AVRC_SUBTYPE_SHIFT; 731 if (msg.sub.subunit_type[xx] == AVRC_SUB_PANEL) 732 msg.sub.panel = true; 733 xx++; 734 } 735 } 736 break; 737 738 case AVRC_OP_VENDOR: { 739 p_data = (uint8_t*)(p_pkt + 1) + p_pkt->offset; 740 p_begin = p_data; 741 if (p_pkt->len < 742 AVRC_VENDOR_HDR_SIZE) /* 6 = ctype, subunit*, opcode & CO_ID */ 743 { 744 if (cr == AVCT_CMD) 745 reject = true; 746 else 747 drop = true; 748 break; 749 } 750 p_data += AVRC_AVC_HDR_SIZE; /* skip the first 3 bytes: ctype, subunit*, 751 opcode */ 752 AVRC_BE_STREAM_TO_CO_ID(p_msg->company_id, p_data); 753 p_msg->p_vendor_data = p_data; 754 p_msg->vendor_len = p_pkt->len - (p_data - p_begin); 755 756 uint8_t drop_code = 0; 757 if (p_msg->company_id == AVRC_CO_METADATA) { 758 /* Validate length for metadata message */ 759 if (p_pkt->len < (AVRC_VENDOR_HDR_SIZE + AVRC_MIN_META_HDR_SIZE)) { 760 if (cr == AVCT_CMD) 761 reject = true; 762 else 763 drop = true; 764 break; 765 } 766 767 /* Check+handle fragmented messages */ 768 drop_code = avrc_proc_far_msg(handle, label, cr, &p_pkt, p_msg); 769 if (drop_code > 0) drop = true; 770 } 771 if (drop_code > 0) { 772 if (drop_code != 4) do_free = false; 773 switch (drop_code) { 774 case 1: 775 p_drop_msg = "sent_frag"; 776 break; 777 case 2: 778 p_drop_msg = "req_cont"; 779 break; 780 case 3: 781 p_drop_msg = "sent_frag3"; 782 break; 783 case 4: 784 p_drop_msg = "sent_frag_free"; 785 break; 786 default: 787 p_drop_msg = "sent_fragd"; 788 } 789 } 790 /* If vendor response received, and did not ask for continuation */ 791 /* then check queue for addition commands to send */ 792 if ((cr == AVCT_RSP) && (drop_code != 2)) { 793 avrc_send_next_vendor_cmd(handle); 794 } 795 } break; 796 797 case AVRC_OP_PASS_THRU: 798 if (p_pkt->len < 5) /* 3 bytes: ctype, subunit*, opcode & op_id & len */ 799 { 800 if (cr == AVCT_CMD) 801 reject = true; 802 else 803 drop = true; 804 break; 805 } 806 p_data += AVRC_AVC_HDR_SIZE; /* skip the first 3 bytes: ctype, subunit*, 807 opcode */ 808 msg.pass.op_id = (AVRC_PASS_OP_ID_MASK & *p_data); 809 if (AVRC_PASS_STATE_MASK & *p_data) 810 msg.pass.state = true; 811 else 812 msg.pass.state = false; 813 p_data++; 814 msg.pass.pass_len = *p_data++; 815 if (msg.pass.pass_len != p_pkt->len - 5) 816 msg.pass.pass_len = p_pkt->len - 5; 817 if (msg.pass.pass_len) 818 msg.pass.p_pass_data = p_data; 819 else 820 msg.pass.p_pass_data = NULL; 821 break; 822 823 case AVRC_OP_BROWSE: 824 /* If browse response received, then check queue for addition commands 825 * to send */ 826 if (cr == AVCT_RSP) { 827 avrc_send_next_vendor_cmd(handle); 828 } 829 break; 830 831 default: 832 if ((avrc_cb.ccb[handle].control & AVRC_CT_TARGET) && 833 (cr == AVCT_CMD)) { 834 /* reject unsupported opcode */ 835 reject = true; 836 } 837 drop = true; 838 break; 839 } 840 } else /* drop the event */ 841 { 842 if (opcode != AVRC_OP_BROWSE) drop = true; 843 } 844 845 if (reject) { 846 /* reject unsupported opcode */ 847 p_rsp = avrc_copy_packet(p_pkt, AVRC_OP_REJ_MSG_LEN); 848 p_rsp_data = avrc_get_data_ptr(p_rsp); 849 *p_rsp_data = AVRC_RSP_REJ; 850 p_drop_msg = "rejected"; 851 cr = AVCT_RSP; 852 drop = true; 853 } 854 855 if (p_rsp) { 856 /* set to send response right away */ 857 AVCT_MsgReq(handle, label, cr, p_rsp); 858 drop = true; 859 } 860 861 if (!drop) { 862 msg.hdr.opcode = opcode; 863 avrc_cb.ccb[handle].msg_cback.Run(handle, label, opcode, &msg); 864 } else { 865 AVRC_TRACE_WARNING("%s %s msg handle:%d, control:%d, cr:%d, opcode:x%x", 866 __func__, p_drop_msg, handle, 867 avrc_cb.ccb[handle].control, cr, opcode); 868 } 869 870 if (opcode == AVRC_OP_BROWSE && msg.browse.p_browse_pkt == NULL) { 871 do_free = false; 872 } 873 874 if (do_free) osi_free(p_pkt); 875 } 876 877 /****************************************************************************** 878 * 879 * Function avrc_pass_msg 880 * 881 * Description Compose a PASS THROUGH command according to p_msg 882 * 883 * Input Parameters: 884 * p_msg: Pointer to PASS THROUGH message structure. 885 * 886 * Output Parameters: 887 * None. 888 * 889 * Returns pointer to a valid GKI buffer if successful. 890 * NULL if p_msg is NULL. 891 * 892 *****************************************************************************/ 893 static BT_HDR* avrc_pass_msg(tAVRC_MSG_PASS* p_msg) { 894 CHECK(p_msg != NULL); 895 CHECK(AVRC_CMD_BUF_SIZE > (AVRC_MIN_CMD_LEN + p_msg->pass_len)); 896 897 BT_HDR* p_cmd = (BT_HDR*)osi_malloc(AVRC_CMD_BUF_SIZE); 898 p_cmd->offset = AVCT_MSG_OFFSET; 899 p_cmd->layer_specific = AVCT_DATA_CTRL; 900 901 uint8_t* p_data = (uint8_t*)(p_cmd + 1) + p_cmd->offset; 902 *p_data++ = (p_msg->hdr.ctype & AVRC_CTYPE_MASK); 903 *p_data++ = (AVRC_SUB_PANEL << AVRC_SUBTYPE_SHIFT); /* Panel subunit & id=0 */ 904 *p_data++ = AVRC_OP_PASS_THRU; 905 *p_data = (AVRC_PASS_OP_ID_MASK & p_msg->op_id); 906 if (p_msg->state) *p_data |= AVRC_PASS_STATE_MASK; 907 p_data++; 908 909 if (p_msg->op_id == AVRC_ID_VENDOR) { 910 *p_data++ = p_msg->pass_len; 911 if (p_msg->pass_len && p_msg->p_pass_data) { 912 memcpy(p_data, p_msg->p_pass_data, p_msg->pass_len); 913 p_data += p_msg->pass_len; 914 } 915 } else { 916 /* set msg len to 0 for other op_id */ 917 *p_data++ = 0; 918 } 919 p_cmd->len = (uint16_t)(p_data - (uint8_t*)(p_cmd + 1) - p_cmd->offset); 920 921 return p_cmd; 922 } 923 924 /****************************************************************************** 925 * 926 * Function AVRC_Open 927 * 928 * Description This function is called to open a connection to AVCTP. 929 * The connection can be either an initiator or acceptor, as 930 * determined by the p_ccb->stream parameter. 931 * The connection can be a target, a controller or for both 932 * role, as determined by the p_ccb->control parameter. 933 * By definition, a target connection is an acceptor connection 934 * that waits for an incoming AVCTP connection from the peer. 935 * The connection remains available to the application until 936 * the application closes it by calling AVRC_Close(). The 937 * application does not need to reopen the connection after an 938 * AVRC_CLOSE_IND_EVT is received. 939 * 940 * Input Parameters: 941 * p_ccb->company_id: Company Identifier. 942 * 943 * p_ccb->p_ctrl_cback: Pointer to control callback 944 * function. 945 * 946 * p_ccb->p_msg_cback: Pointer to message callback 947 * function. 948 * 949 * p_ccb->conn: AVCTP connection role. This is set to 950 * AVCTP_INT for initiator connections and AVCTP_ACP 951 * for acceptor connections. 952 * 953 * p_ccb->control: Control role. This is set to 954 * AVRC_CT_TARGET for target connections, AVRC_CT_CONTROL 955 * for control connections or 956 * (AVRC_CT_TARGET|AVRC_CT_CONTROL) 957 * for connections that support both roles. 958 * 959 * peer_addr: BD address of peer device. This value is 960 * only used for initiator connections; for acceptor 961 * connections it can be set to NULL. 962 * 963 * Output Parameters: 964 * p_handle: Pointer to handle. This parameter is only 965 * valid if AVRC_SUCCESS is returned. 966 * 967 * Returns AVRC_SUCCESS if successful. 968 * AVRC_NO_RESOURCES if there are not enough resources to open 969 * the connection. 970 * 971 *****************************************************************************/ 972 uint16_t AVRC_Open(uint8_t* p_handle, tAVRC_CONN_CB* p_ccb, 973 const RawAddress& peer_addr) { 974 uint16_t status; 975 tAVCT_CC cc; 976 977 cc.p_ctrl_cback = avrc_ctrl_cback; /* Control callback */ 978 cc.p_msg_cback = avrc_msg_cback; /* Message callback */ 979 cc.pid = UUID_SERVCLASS_AV_REMOTE_CONTROL; /* Profile ID */ 980 cc.role = p_ccb->conn; /* Initiator/acceptor role */ 981 cc.control = p_ccb->control; /* Control role (Control/Target) */ 982 983 status = AVCT_CreateConn(p_handle, &cc, peer_addr); 984 if (status == AVCT_SUCCESS) { 985 avrc_cb.ccb[*p_handle] = *p_ccb; 986 memset(&avrc_cb.ccb_int[*p_handle], 0, sizeof(tAVRC_CONN_INT_CB)); 987 memset(&avrc_cb.fcb[*p_handle], 0, sizeof(tAVRC_FRAG_CB)); 988 memset(&avrc_cb.rcb[*p_handle], 0, sizeof(tAVRC_RASM_CB)); 989 avrc_cb.ccb_int[*p_handle].tle = alarm_new("avrcp.commandTimer"); 990 avrc_cb.ccb_int[*p_handle].cmd_q = fixed_queue_new(SIZE_MAX); 991 } 992 AVRC_TRACE_DEBUG("%s role: %d, control:%d status:%d, handle:%d", __func__, 993 cc.role, cc.control, status, *p_handle); 994 995 return status; 996 } 997 998 /****************************************************************************** 999 * 1000 * Function AVRC_Close 1001 * 1002 * Description Close a connection opened with AVRC_Open(). 1003 * This function is called when the 1004 * application is no longer using a connection. 1005 * 1006 * Input Parameters: 1007 * handle: Handle of this connection. 1008 * 1009 * Output Parameters: 1010 * None. 1011 * 1012 * Returns AVRC_SUCCESS if successful. 1013 * AVRC_BAD_HANDLE if handle is invalid. 1014 * 1015 *****************************************************************************/ 1016 uint16_t AVRC_Close(uint8_t handle) { 1017 AVRC_TRACE_DEBUG("%s handle:%d", __func__, handle); 1018 avrc_flush_cmd_q(handle); 1019 return AVCT_RemoveConn(handle); 1020 } 1021 1022 /****************************************************************************** 1023 * 1024 * Function AVRC_OpenBrowse 1025 * 1026 * Description This function is called to open a browsing connection to 1027 * AVCTP. The connection can be either an initiator or 1028 * acceptor, as determined by the p_conn_role. 1029 * The handle is returned by a previous call to AVRC_Open. 1030 * 1031 * Returns AVRC_SUCCESS if successful. 1032 * AVRC_NO_RESOURCES if there are not enough resources to open 1033 * the connection. 1034 * 1035 *****************************************************************************/ 1036 uint16_t AVRC_OpenBrowse(uint8_t handle, uint8_t conn_role) { 1037 return AVCT_CreateBrowse(handle, conn_role); 1038 } 1039 1040 /****************************************************************************** 1041 * 1042 * Function AVRC_CloseBrowse 1043 * 1044 * Description Close a connection opened with AVRC_OpenBrowse(). 1045 * This function is called when the 1046 * application is no longer using a connection. 1047 * 1048 * Returns AVRC_SUCCESS if successful. 1049 * AVRC_BAD_HANDLE if handle is invalid. 1050 * 1051 *****************************************************************************/ 1052 uint16_t AVRC_CloseBrowse(uint8_t handle) { return AVCT_RemoveBrowse(handle); } 1053 1054 /****************************************************************************** 1055 * 1056 * Function AVRC_MsgReq 1057 * 1058 * Description This function is used to send the AVRCP byte stream in p_pkt 1059 * down to AVCTP. 1060 * 1061 * It is expected that p_pkt->offset is at least 1062 * AVCT_MSG_OFFSET 1063 * p_pkt->layer_specific is AVCT_DATA_CTRL or AVCT_DATA_BROWSE 1064 * p_pkt->event is AVRC_OP_VENDOR, AVRC_OP_PASS_THRU or 1065 * AVRC_OP_BROWSE 1066 * The above BT_HDR settings are set by the AVRC_Bld* 1067 * functions. 1068 * 1069 * Returns AVRC_SUCCESS if successful. 1070 * AVRC_BAD_HANDLE if handle is invalid. 1071 * 1072 *****************************************************************************/ 1073 uint16_t AVRC_MsgReq(uint8_t handle, uint8_t label, uint8_t ctype, 1074 BT_HDR* p_pkt) { 1075 uint8_t* p_data; 1076 uint8_t cr = AVCT_CMD; 1077 bool chk_frag = true; 1078 uint8_t* p_start = NULL; 1079 tAVRC_FRAG_CB* p_fcb; 1080 uint16_t len; 1081 uint16_t status; 1082 uint8_t msg_mask = 0; 1083 uint16_t peer_mtu; 1084 1085 if (!p_pkt) return AVRC_BAD_PARAM; 1086 1087 AVRC_TRACE_DEBUG("%s handle = %u label = %u ctype = %u len = %d", __func__, 1088 handle, label, ctype, p_pkt->len); 1089 1090 if (ctype >= AVRC_RSP_NOT_IMPL) cr = AVCT_RSP; 1091 1092 if (p_pkt->event == AVRC_OP_VENDOR) { 1093 /* add AVRCP Vendor Dependent headers */ 1094 p_start = ((uint8_t*)(p_pkt + 1) + p_pkt->offset); 1095 p_pkt->offset -= AVRC_VENDOR_HDR_SIZE; 1096 p_pkt->len += AVRC_VENDOR_HDR_SIZE; 1097 p_data = (uint8_t*)(p_pkt + 1) + p_pkt->offset; 1098 *p_data++ = (ctype & AVRC_CTYPE_MASK); 1099 *p_data++ = (AVRC_SUB_PANEL << AVRC_SUBTYPE_SHIFT); 1100 *p_data++ = AVRC_OP_VENDOR; 1101 AVRC_CO_ID_TO_BE_STREAM(p_data, AVRC_CO_METADATA); 1102 1103 /* Check if this is a AVRC_PDU_REQUEST_CONTINUATION_RSP */ 1104 if (cr == AVCT_CMD) { 1105 msg_mask |= AVRC_MSG_MASK_IS_VENDOR_CMD; 1106 1107 if ((*p_start == AVRC_PDU_REQUEST_CONTINUATION_RSP) || 1108 (*p_start == AVRC_PDU_ABORT_CONTINUATION_RSP)) { 1109 msg_mask |= AVRC_MSG_MASK_IS_CONTINUATION_RSP; 1110 } 1111 } 1112 } else if (p_pkt->event == AVRC_OP_PASS_THRU) { 1113 /* add AVRCP Pass Through headers */ 1114 p_start = ((uint8_t*)(p_pkt + 1) + p_pkt->offset); 1115 p_pkt->offset -= AVRC_PASS_THRU_SIZE; 1116 p_pkt->len += AVRC_PASS_THRU_SIZE; 1117 p_data = (uint8_t*)(p_pkt + 1) + p_pkt->offset; 1118 *p_data++ = (ctype & AVRC_CTYPE_MASK); 1119 *p_data++ = (AVRC_SUB_PANEL << AVRC_SUBTYPE_SHIFT); 1120 *p_data++ = AVRC_OP_PASS_THRU; /* opcode */ 1121 *p_data++ = AVRC_ID_VENDOR; /* operation id */ 1122 *p_data++ = 5; /* operation data len */ 1123 AVRC_CO_ID_TO_BE_STREAM(p_data, AVRC_CO_METADATA); 1124 } else { 1125 chk_frag = false; 1126 peer_mtu = AVCT_GetBrowseMtu(handle); 1127 if (p_pkt->len > (peer_mtu - AVCT_HDR_LEN_SINGLE)) { 1128 AVRC_TRACE_ERROR( 1129 "%s bigger than peer mtu (p_pkt->len(%d) > peer_mtu(%d-%d))", 1130 __func__, p_pkt->len, peer_mtu, AVCT_HDR_LEN_SINGLE); 1131 osi_free(p_pkt); 1132 return AVRC_MSG_TOO_BIG; 1133 } 1134 } 1135 1136 /* abandon previous fragments */ 1137 p_fcb = &avrc_cb.fcb[handle]; 1138 1139 if (p_fcb == NULL) { 1140 AVRC_TRACE_ERROR("%s p_fcb is NULL", __func__); 1141 osi_free(p_pkt); 1142 return AVRC_NOT_OPEN; 1143 } 1144 1145 if (p_fcb->frag_enabled) p_fcb->frag_enabled = false; 1146 1147 osi_free_and_reset((void**)&p_fcb->p_fmsg); 1148 1149 /* AVRCP spec has not defined any control channel commands that needs 1150 * fragmentation at this level 1151 * check for fragmentation only on the response */ 1152 if ((cr == AVCT_RSP) && (chk_frag)) { 1153 if (p_pkt->len > AVRC_MAX_CTRL_DATA_LEN) { 1154 int offset_len = MAX(AVCT_MSG_OFFSET, p_pkt->offset); 1155 BT_HDR* p_pkt_new = 1156 (BT_HDR*)osi_malloc(AVRC_PACKET_LEN + offset_len + BT_HDR_SIZE); 1157 if (p_start != NULL) { 1158 p_fcb->frag_enabled = true; 1159 p_fcb->p_fmsg = p_pkt; 1160 p_fcb->frag_pdu = *p_start; 1161 p_pkt = p_pkt_new; 1162 p_pkt_new = p_fcb->p_fmsg; 1163 p_pkt->len = AVRC_MAX_CTRL_DATA_LEN; 1164 p_pkt->offset = p_pkt_new->offset; 1165 p_pkt->layer_specific = p_pkt_new->layer_specific; 1166 p_pkt->event = p_pkt_new->event; 1167 p_data = (uint8_t*)(p_pkt + 1) + p_pkt->offset; 1168 p_start -= AVRC_VENDOR_HDR_SIZE; 1169 memcpy(p_data, p_start, AVRC_MAX_CTRL_DATA_LEN); 1170 /* use AVRC start packet type */ 1171 p_data += AVRC_VENDOR_HDR_SIZE; 1172 p_data++; /* pdu */ 1173 *p_data++ = AVRC_PKT_START; 1174 1175 /* 4 pdu, pkt_type & len */ 1176 len = (AVRC_MAX_CTRL_DATA_LEN - AVRC_VENDOR_HDR_SIZE - 1177 AVRC_MIN_META_HDR_SIZE); 1178 UINT16_TO_BE_STREAM(p_data, len); 1179 1180 /* prepare the left over for as an end fragment */ 1181 avrc_prep_end_frag(handle); 1182 AVRC_TRACE_DEBUG("%s p_pkt len:%d/%d, next len:%d", __func__, 1183 p_pkt->len, len, p_fcb->p_fmsg->len); 1184 } else { 1185 /* TODO: Is this "else" block valid? Remove it? */ 1186 AVRC_TRACE_ERROR("%s no buffers for fragmentation", __func__); 1187 osi_free(p_pkt); 1188 return AVRC_NO_RESOURCES; 1189 } 1190 } 1191 } else if ((p_pkt->event == AVRC_OP_VENDOR) && (cr == AVCT_CMD) && 1192 (avrc_cb.ccb_int[handle].flags & AVRC_CB_FLAGS_RSP_PENDING) && 1193 !(msg_mask & AVRC_MSG_MASK_IS_CONTINUATION_RSP)) { 1194 /* If we are sending a vendor specific command, and a response is pending, 1195 * then enqueue the command until the response has been received. 1196 * This is to interop with TGs that abort sending responses whenever a new 1197 * command 1198 * is received (exception is continuation request command 1199 * must sent that to get additional response frags) */ 1200 AVRC_TRACE_DEBUG( 1201 "AVRC: Enqueuing command 0x%08x (handle=0x%02x, label=0x%02x)", p_pkt, 1202 handle, label); 1203 1204 /* label in BT_HDR (will need this later when the command is dequeued) */ 1205 p_pkt->layer_specific = (label << 8) | (p_pkt->layer_specific & 0xFF); 1206 1207 /* Enqueue the command */ 1208 fixed_queue_enqueue(avrc_cb.ccb_int[handle].cmd_q, p_pkt); 1209 return AVRC_SUCCESS; 1210 } 1211 1212 /* Send the message */ 1213 status = AVCT_MsgReq(handle, label, cr, p_pkt); 1214 if ((status == AVCT_SUCCESS) && (cr == AVCT_CMD)) { 1215 /* If a command was successfully sent, indicate that a response is pending 1216 */ 1217 avrc_cb.ccb_int[handle].flags |= AVRC_CB_FLAGS_RSP_PENDING; 1218 1219 /* Start command timer to wait for response */ 1220 avrc_start_cmd_timer(handle, label, msg_mask); 1221 } 1222 1223 return status; 1224 } 1225 1226 /****************************************************************************** 1227 * 1228 * Function AVRC_PassCmd 1229 * 1230 * Description Send a PASS THROUGH command to the peer device. This 1231 * function can only be called for controller role connections. 1232 * Any response message from the peer is passed back through 1233 * the tAVRC_MSG_CBACK callback function. 1234 * 1235 * Input Parameters: 1236 * handle: Handle of this connection. 1237 * 1238 * label: Transaction label. 1239 * 1240 * p_msg: Pointer to PASS THROUGH message structure. 1241 * 1242 * Output Parameters: 1243 * None. 1244 * 1245 * Returns AVRC_SUCCESS if successful. 1246 * AVRC_BAD_HANDLE if handle is invalid. 1247 * 1248 *****************************************************************************/ 1249 uint16_t AVRC_PassCmd(uint8_t handle, uint8_t label, tAVRC_MSG_PASS* p_msg) { 1250 BT_HDR* p_buf; 1251 uint16_t status = AVRC_NO_RESOURCES; 1252 if (!p_msg) return AVRC_BAD_PARAM; 1253 1254 p_msg->hdr.ctype = AVRC_CMD_CTRL; 1255 p_buf = avrc_pass_msg(p_msg); 1256 if (p_buf) { 1257 status = AVCT_MsgReq(handle, label, AVCT_CMD, p_buf); 1258 if (status == AVCT_SUCCESS) { 1259 /* Start command timer to wait for response */ 1260 avrc_start_cmd_timer(handle, label, 0); 1261 } 1262 } 1263 return (status); 1264 } 1265 1266 /****************************************************************************** 1267 * 1268 * Function AVRC_PassRsp 1269 * 1270 * Description Send a PASS THROUGH response to the peer device. This 1271 * function can only be called for target role connections. 1272 * This function must be called when a PASS THROUGH command 1273 * message is received from the peer through the 1274 * tAVRC_MSG_CBACK callback function. 1275 * 1276 * Input Parameters: 1277 * handle: Handle of this connection. 1278 * 1279 * label: Transaction label. Must be the same value as 1280 * passed with the command message in the callback 1281 * function. 1282 * 1283 * p_msg: Pointer to PASS THROUGH message structure. 1284 * 1285 * Output Parameters: 1286 * None. 1287 * 1288 * Returns AVRC_SUCCESS if successful. 1289 * AVRC_BAD_HANDLE if handle is invalid. 1290 * 1291 *****************************************************************************/ 1292 uint16_t AVRC_PassRsp(uint8_t handle, uint8_t label, tAVRC_MSG_PASS* p_msg) { 1293 BT_HDR* p_buf; 1294 if (!p_msg) return AVRC_BAD_PARAM; 1295 1296 p_buf = avrc_pass_msg(p_msg); 1297 if (p_buf) return AVCT_MsgReq(handle, label, AVCT_RSP, p_buf); 1298 return AVRC_NO_RESOURCES; 1299 } 1300