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