15738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************
25738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
35738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  Copyright (C) 2003-2012 Broadcom Corporation
45738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
55738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  Licensed under the Apache License, Version 2.0 (the "License");
65738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  you may not use this file except in compliance with the License.
75738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  You may obtain a copy of the License at:
85738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
95738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  http://www.apache.org/licenses/LICENSE-2.0
105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  Unless required by applicable law or agreed to in writing, software
125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  distributed under the License is distributed on an "AS IS" BASIS,
135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  See the License for the specific language governing permissions and
155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  limitations under the License.
165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ******************************************************************************/
185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************
205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
219adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan *  Interface to AVRCP mandatory commands
225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ******************************************************************************/
24181932fad8b91dc6831222e5b616574c39a21565Sharvil Nanavati#include <assert.h>
255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <string.h>
265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
27258c2538e3b62a8cdb403f2730c45d721e5292b4Pavlin Radoslavov#include "bt_common.h"
285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "avrc_api.h"
295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "avrc_int.h"
305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*****************************************************************************
325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**  Global data
335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*****************************************************************************/
345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define AVRC_MAX_RCV_CTRL_EVT   AVCT_BROWSE_UNCONG_IND_EVT
375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
383a2fa83dac1b07b661a20e2412aad9bf81492106Pavlin Radoslavov#ifndef MAX
393a2fa83dac1b07b661a20e2412aad9bf81492106Pavlin Radoslavov#define MAX(a, b) ((a) > (b) ? (a) : (b))
403a2fa83dac1b07b661a20e2412aad9bf81492106Pavlin Radoslavov#endif
413a2fa83dac1b07b661a20e2412aad9bf81492106Pavlin Radoslavov
425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic const UINT8 avrc_ctrl_event_map[] =
435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    AVRC_OPEN_IND_EVT,  /* AVCT_CONNECT_CFM_EVT */
455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    AVRC_OPEN_IND_EVT,  /* AVCT_CONNECT_IND_EVT */
465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    AVRC_CLOSE_IND_EVT, /* AVCT_DISCONNECT_CFM_EVT */
475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    AVRC_CLOSE_IND_EVT, /* AVCT_DISCONNECT_IND_EVT */
485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    AVRC_CONG_IND_EVT,  /* AVCT_CONG_IND_EVT */
495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    AVRC_UNCONG_IND_EVT,/* AVCT_UNCONG_IND_EVT */
505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    AVRC_BROWSE_OPEN_IND_EVT,  /* AVCT_BROWSE_CONN_CFM_EVT   */
515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    AVRC_BROWSE_OPEN_IND_EVT,  /* AVCT_BROWSE_CONN_IND_EVT   */
525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    AVRC_BROWSE_CLOSE_IND_EVT, /* AVCT_BROWSE_DISCONN_CFM_EVT */
535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    AVRC_BROWSE_CLOSE_IND_EVT, /* AVCT_BROWSE_DISCONN_IND_EVT */
545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    AVRC_BROWSE_CONG_IND_EVT,  /* AVCT_BROWSE_CONG_IND_EVT    */
555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    AVRC_BROWSE_UNCONG_IND_EVT /* AVCT_BROWSE_UNCONG_IND_EVT  */
565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project};
575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define AVRC_OP_DROP        0xFE    /* use this unused opcode to indication no need to call the callback function */
595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define AVRC_OP_DROP_N_FREE 0xFD    /* use this unused opcode to indication no need to call the callback function & free buffer */
605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
618d88b1b75c665772f714643a71e5974c7f6dd02cSatya Calloji#define AVRC_OP_UNIT_INFO_RSP_LEN       8
628d88b1b75c665772f714643a71e5974c7f6dd02cSatya Calloji#define AVRC_OP_SUB_UNIT_INFO_RSP_LEN   8
638d88b1b75c665772f714643a71e5974c7f6dd02cSatya Calloji#define AVRC_OP_REJ_MSG_LEN            11
648d88b1b75c665772f714643a71e5974c7f6dd02cSatya Calloji
655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************
665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         avrc_ctrl_cback
685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This is the callback function used by AVCTP to report
705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  received link events.
715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          Nothing.
735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project******************************************************************************/
755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void avrc_ctrl_cback(UINT8 handle, UINT8 event, UINT16 result,
765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                BD_ADDR peer_addr)
775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8   avrc_event;
795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (event <= AVRC_MAX_RCV_CTRL_EVT && avrc_cb.ccb[handle].p_ctrl_cback)
815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        avrc_event = avrc_ctrl_event_map[event];
835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (event == AVCT_CONNECT_CFM_EVT)
845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (result != 0) /* failed */
865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                avrc_event = AVRC_CLOSE_IND_EVT;
875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        (*avrc_cb.ccb[handle].p_ctrl_cback)(handle, avrc_event, result, peer_addr);
895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* else drop the unknown event*/
915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************
945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         avrc_get_data_ptr
965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
973a2fa83dac1b07b661a20e2412aad9bf81492106Pavlin Radoslavov** Description      Gets a pointer to the data payload in the packet.
985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
993a2fa83dac1b07b661a20e2412aad9bf81492106Pavlin Radoslavov** Returns          A pointer to the data payload.
1005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project******************************************************************************/
1025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic UINT8 * avrc_get_data_ptr(BT_HDR *p_pkt)
1035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
1043a2fa83dac1b07b661a20e2412aad9bf81492106Pavlin Radoslavov    return (UINT8 *)(p_pkt + 1) + p_pkt->offset;
1053a2fa83dac1b07b661a20e2412aad9bf81492106Pavlin Radoslavov}
1065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1073a2fa83dac1b07b661a20e2412aad9bf81492106Pavlin Radoslavov/******************************************************************************
1083a2fa83dac1b07b661a20e2412aad9bf81492106Pavlin Radoslavov**
1093a2fa83dac1b07b661a20e2412aad9bf81492106Pavlin Radoslavov** Function         avrc_copy_packet
1103a2fa83dac1b07b661a20e2412aad9bf81492106Pavlin Radoslavov**
1113a2fa83dac1b07b661a20e2412aad9bf81492106Pavlin Radoslavov** Description      Copies an AVRC packet to a new buffer. In the new buffer,
1123a2fa83dac1b07b661a20e2412aad9bf81492106Pavlin Radoslavov**                  the payload offset is at least AVCT_MSG_OFFSET octets.
1133a2fa83dac1b07b661a20e2412aad9bf81492106Pavlin Radoslavov**
1143a2fa83dac1b07b661a20e2412aad9bf81492106Pavlin Radoslavov** Returns          The buffer with the copied data.
1153a2fa83dac1b07b661a20e2412aad9bf81492106Pavlin Radoslavov**
1163a2fa83dac1b07b661a20e2412aad9bf81492106Pavlin Radoslavov******************************************************************************/
1178d88b1b75c665772f714643a71e5974c7f6dd02cSatya Callojistatic BT_HDR * avrc_copy_packet(BT_HDR *p_pkt, int rsp_pkt_len)
1183a2fa83dac1b07b661a20e2412aad9bf81492106Pavlin Radoslavov{
1193a2fa83dac1b07b661a20e2412aad9bf81492106Pavlin Radoslavov    const int offset = MAX(AVCT_MSG_OFFSET, p_pkt->offset);
1208d88b1b75c665772f714643a71e5974c7f6dd02cSatya Calloji    const int pkt_len = MAX(rsp_pkt_len, p_pkt->len);
121abd70abb5e42c9431df94fe9d2c4a78a0d8d9af9Pavlin Radoslavov    BT_HDR *p_pkt_copy = (BT_HDR *)osi_malloc(BT_HDR_SIZE + offset + pkt_len);
1223a2fa83dac1b07b661a20e2412aad9bf81492106Pavlin Radoslavov
1233a2fa83dac1b07b661a20e2412aad9bf81492106Pavlin Radoslavov    /* Copy the packet header, set the new offset, and copy the payload */
1245fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov    memcpy(p_pkt_copy, p_pkt, BT_HDR_SIZE);
1255fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov    p_pkt_copy->offset = offset;
1265fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov    UINT8 *p_data = avrc_get_data_ptr(p_pkt);
1275fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov    UINT8 *p_data_copy = avrc_get_data_ptr(p_pkt_copy);
1285fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov    memcpy(p_data_copy, p_data, p_pkt->len);
1293a2fa83dac1b07b661a20e2412aad9bf81492106Pavlin Radoslavov
1303a2fa83dac1b07b661a20e2412aad9bf81492106Pavlin Radoslavov    return p_pkt_copy;
1315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
1325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1339adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan#if (AVRC_METADATA_INCLUDED == TRUE)
1349adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan/******************************************************************************
1359adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan**
1369adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan** Function         avrc_prep_end_frag
1379adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan**
1389adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan** Description      This function prepares an end response fragment
1399adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan**
1409adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan** Returns          Nothing.
1419adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan**
1429adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan******************************************************************************/
1439adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajanstatic void avrc_prep_end_frag(UINT8 handle)
1449adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan{
1459adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    tAVRC_FRAG_CB   *p_fcb;
1469adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    BT_HDR  *p_pkt_new;
1479adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    UINT8   *p_data, *p_orig_data;
1489adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    UINT8   rsp_type;
1499adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan
150b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati    AVRC_TRACE_DEBUG ("avrc_prep_end_frag" );
1519adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    p_fcb = &avrc_cb.fcb[handle];
1529adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan
1539adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    /* The response type of the end fragment should be the same as the the PDU of "End Fragment
154247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji    ** Response" Errata: https://www.bluetooth.org/errata/errata_view.cfm?errata_id=4383
155247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji    */
1569adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    p_orig_data = ((UINT8 *)(p_fcb->p_fmsg + 1) + p_fcb->p_fmsg->offset);
1579adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    rsp_type = ((*p_orig_data) & AVRC_CTYPE_MASK);
1589adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan
1599adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    p_pkt_new           = p_fcb->p_fmsg;
1609adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    p_pkt_new->len      -= (AVRC_MAX_CTRL_DATA_LEN - AVRC_VENDOR_HDR_SIZE - AVRC_MIN_META_HDR_SIZE);
1619adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    p_pkt_new->offset   += (AVRC_MAX_CTRL_DATA_LEN - AVRC_VENDOR_HDR_SIZE - AVRC_MIN_META_HDR_SIZE);
1629adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    p_data = (UINT8 *)(p_pkt_new+1) + p_pkt_new->offset;
1639adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    *p_data++       = rsp_type;
1649adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    *p_data++       = (AVRC_SUB_PANEL << AVRC_SUBTYPE_SHIFT);
1659adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    *p_data++       = AVRC_OP_VENDOR;
1669adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    AVRC_CO_ID_TO_BE_STREAM(p_data, AVRC_CO_METADATA);
1679adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    *p_data++       = p_fcb->frag_pdu;
1689adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    *p_data++       = AVRC_PKT_END;
169247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji
1709adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    /* 4=pdu, pkt_type & len */
1719adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    UINT16_TO_BE_STREAM(p_data, (p_pkt_new->len - AVRC_VENDOR_HDR_SIZE - AVRC_MIN_META_HDR_SIZE));
1729adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan}
1739adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan
1749adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan/******************************************************************************
1759adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan**
1769adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan** Function         avrc_send_continue_frag
1779adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan**
1789adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan** Description      This function sends a continue response fragment
1799adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan**
1809adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan** Returns          Nothing.
1819adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan**
1829adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan******************************************************************************/
1839adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajanstatic void avrc_send_continue_frag(UINT8 handle, UINT8 label)
1849adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan{
1859adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    tAVRC_FRAG_CB   *p_fcb;
1869adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    BT_HDR  *p_pkt_old, *p_pkt;
1879adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    UINT8   *p_old, *p_data;
1889adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    UINT8   cr = AVCT_RSP;
1899adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan
1909adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    p_fcb = &avrc_cb.fcb[handle];
1919adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    p_pkt = p_fcb->p_fmsg;
1929adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan
1932ac9ae06be5091f6f2eef0022a3810752f127d04Anubhav Gupta    AVRC_TRACE_DEBUG("%s handle = %u label = %u len = %d",
1942ac9ae06be5091f6f2eef0022a3810752f127d04Anubhav Gupta                     __func__, handle, label, p_pkt->len);
1955fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov    if (p_pkt->len > AVRC_MAX_CTRL_DATA_LEN) {
1962ac9ae06be5091f6f2eef0022a3810752f127d04Anubhav Gupta        int offset_len = MAX(AVCT_MSG_OFFSET, p_pkt->offset);
1979adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        p_pkt_old = p_fcb->p_fmsg;
198abd70abb5e42c9431df94fe9d2c4a78a0d8d9af9Pavlin Radoslavov        p_pkt = (BT_HDR *)osi_malloc(AVRC_PACKET_LEN + offset_len + BT_HDR_SIZE);
1995fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov        p_pkt->len = AVRC_MAX_CTRL_DATA_LEN;
2005fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov        p_pkt->offset = AVCT_MSG_OFFSET;
2015fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov        p_pkt->layer_specific = p_pkt_old->layer_specific;
2025fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov        p_pkt->event = p_pkt_old->event;
2035fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov        p_old = (UINT8 *)(p_pkt_old + 1) + p_pkt_old->offset;
2045fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov        p_data = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
2055fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov        memcpy (p_data, p_old, AVRC_MAX_CTRL_DATA_LEN);
2065fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov        /* use AVRC continue packet type */
2075fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov        p_data += AVRC_VENDOR_HDR_SIZE;
2085fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov        p_data++; /* pdu */
2095fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov        *p_data++ = AVRC_PKT_CONTINUE;
2105fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov        /* 4=pdu, pkt_type & len */
2115fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov        UINT16_TO_BE_STREAM(p_data, (AVRC_MAX_CTRL_DATA_LEN - AVRC_VENDOR_HDR_SIZE - 4));
2125fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov
2135fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov        /* prepare the left over for as an end fragment */
2145fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov        avrc_prep_end_frag (handle);
2155fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov    } else {
2169adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        /* end fragment. clean the control block */
2179adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        p_fcb->frag_enabled = FALSE;
2189adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        p_fcb->p_fmsg       = NULL;
2199adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    }
2209adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    AVCT_MsgReq( handle, label, cr, p_pkt);
2219adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan}
2229adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan
2239adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan/******************************************************************************
2249adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan**
2259adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan** Function         avrc_proc_vendor_command
2269adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan**
2279adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan** Description      This function processes received vendor command.
2289adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan**
2299adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan** Returns          if not NULL, the response to send right away.
2309adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan**
2319adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan******************************************************************************/
2329adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajanstatic BT_HDR * avrc_proc_vendor_command(UINT8 handle, UINT8 label,
2339adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                               BT_HDR *p_pkt, tAVRC_MSG_VENDOR *p_msg)
2349adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan{
2359adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    BT_HDR      *p_rsp = NULL;
2369adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    UINT8       *p_data;
2379adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    UINT8       *p_begin;
2389adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    UINT8       pkt_type;
2399adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    BOOLEAN     abort_frag = FALSE;
2409adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    tAVRC_STS   status = AVRC_STS_NO_ERROR;
2419adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    tAVRC_FRAG_CB   *p_fcb;
2429adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan
2439adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    p_begin  = (UINT8 *)(p_pkt+1) + p_pkt->offset;
2449adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    p_data   = p_begin + AVRC_VENDOR_HDR_SIZE;
2459adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    pkt_type = *(p_data + 1) & AVRC_PKT_TYPE_MASK;
2469adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan
2479adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    if (pkt_type != AVRC_PKT_SINGLE)
2489adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    {
2499adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        /* reject - commands can only be in single packets at AVRCP level */
250b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati        AVRC_TRACE_ERROR ("commands must be in single packet pdu:0x%x", *p_data );
2519adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        /* use the current GKI buffer to send the reject */
2529adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        status = AVRC_STS_BAD_CMD;
2539adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    }
2549adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    /* check if there are fragments waiting to be sent */
2559adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    else if (avrc_cb.fcb[handle].frag_enabled)
2569adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    {
2579adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        p_fcb = &avrc_cb.fcb[handle];
2589adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        if (p_msg->company_id == AVRC_CO_METADATA)
2599adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        {
2609adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            switch (*p_data)
2619adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            {
2629adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            case AVRC_PDU_ABORT_CONTINUATION_RSP:
2639adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                /* aborted by CT - send accept response */
2649adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                abort_frag = TRUE;
2659adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                p_begin = (UINT8 *)(p_pkt+1) + p_pkt->offset;
2669adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                *p_begin = (AVRC_RSP_ACCEPT & AVRC_CTYPE_MASK);
2679adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                if (*(p_data + 4) != p_fcb->frag_pdu)
2689adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                {
2699adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                    *p_begin = (AVRC_RSP_REJ & AVRC_CTYPE_MASK);
2709adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                    *(p_data + 4) = AVRC_STS_BAD_PARAM;
2719adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                }
2729adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                else
2739adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                {
2749adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                    p_data = (p_begin + AVRC_VENDOR_HDR_SIZE + 2);
2759adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                    UINT16_TO_BE_STREAM(p_data, 0);
2769adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                    p_pkt->len = (p_data - p_begin);
2779adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                }
2789adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                AVCT_MsgReq( handle, label, AVCT_RSP, p_pkt);
2799adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                p_msg->hdr.opcode = AVRC_OP_DROP; /* used the p_pkt to send response */
2809adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                break;
2819adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan
2829adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            case AVRC_PDU_REQUEST_CONTINUATION_RSP:
2839adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                if (*(p_data + 4) == p_fcb->frag_pdu)
2849adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                {
2859adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                    avrc_send_continue_frag(handle, label);
2869adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                    p_msg->hdr.opcode = AVRC_OP_DROP_N_FREE;
2879adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                }
2889adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                else
2899adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                {
2909adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                    /* the pdu id does not match - reject the command using the current GKI buffer */
291b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati                    AVRC_TRACE_ERROR("avrc_proc_vendor_command continue pdu: 0x%x does not match \
2929adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                    current re-assembly pdu: 0x%x",
2939adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                        *(p_data + 4), p_fcb->frag_pdu);
2949adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                    status = AVRC_STS_BAD_PARAM;
2959adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                    abort_frag = TRUE;
2969adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                }
2979adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                break;
2989adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan
2999adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            default:
3009adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                /* implicit abort */
3019adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                abort_frag = TRUE;
3029adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            }
3039adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        }
3049adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        else
3059adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        {
3069adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            abort_frag = TRUE;
3079adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            /* implicit abort */
3089adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        }
3099adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan
3109adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        if (abort_frag)
3119adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        {
312abd70abb5e42c9431df94fe9d2c4a78a0d8d9af9Pavlin Radoslavov            osi_free_and_reset((void **)&p_fcb->p_fmsg);
3139adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            p_fcb->frag_enabled = FALSE;
3149adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        }
3159adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    }
3169adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan
3179adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    if (status != AVRC_STS_NO_ERROR)
3189adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    {
3199adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        /* use the current GKI buffer to build/send the reject message */
3209adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        p_data = (UINT8 *)(p_pkt+1) + p_pkt->offset;
3219adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        *p_data++ = AVRC_RSP_REJ;
3229adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        p_data += AVRC_VENDOR_HDR_SIZE; /* pdu */
3239adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        *p_data++ = 0;                  /* pkt_type */
3249adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        UINT16_TO_BE_STREAM(p_data, 1); /* len */
3259adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        *p_data++ = status;             /* error code */
3269adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        p_pkt->len = AVRC_VENDOR_HDR_SIZE + 5;
3279adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        p_rsp = p_pkt;
3289adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    }
3299adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan
3309adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    return p_rsp;
3319adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan}
3329adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan
3339adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan/******************************************************************************
3349adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan**
3359adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan** Function         avrc_proc_far_msg
3369adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan**
337247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji** Description      This function processes metadata fragmenation
3389adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan**                  and reassembly
3399adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan**
3409adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan** Returns          0, to report the message with msg_cback .
3419adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan**
3429adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan******************************************************************************/
3439adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajanstatic UINT8 avrc_proc_far_msg(UINT8 handle, UINT8 label, UINT8 cr, BT_HDR **pp_pkt,
3449adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    tAVRC_MSG_VENDOR *p_msg)
3459adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan{
3469adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    BT_HDR      *p_pkt = *pp_pkt;
3479adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    UINT8       *p_data;
3483a2fa83dac1b07b661a20e2412aad9bf81492106Pavlin Radoslavov    UINT8       drop_code = 0;
3496b84f291c4edce7e4102efd8d4052a63bcb4b9dcAnubhav Gupta    BOOLEAN     buf_overflow = FALSE;
3509adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    BT_HDR      *p_rsp = NULL;
3519adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    BT_HDR      *p_cmd = NULL;
3529adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    BOOLEAN     req_continue = FALSE;
3539adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    BT_HDR      *p_pkt_new = NULL;
3549adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    UINT8       pkt_type;
3559adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    tAVRC_RASM_CB   *p_rcb;
3569adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    tAVRC_NEXT_CMD   avrc_cmd;
3579adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan
3589adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    p_data  = (UINT8 *)(p_pkt+1) + p_pkt->offset;
359247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji
360247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji    /* Skip over vendor header (ctype, subunit*, opcode, CO_ID) */
361247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji    p_data += AVRC_VENDOR_HDR_SIZE;
362247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji
3639adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    pkt_type = *(p_data + 1) & AVRC_PKT_TYPE_MASK;
364b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati    AVRC_TRACE_DEBUG ("pkt_type %d", pkt_type );
3659adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    p_rcb = &avrc_cb.rcb[handle];
3669adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    if (p_msg->company_id == AVRC_CO_METADATA)
3679adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    {
3689adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        /* check if the message needs to be re-assembled */
3699adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        if (pkt_type == AVRC_PKT_SINGLE || pkt_type == AVRC_PKT_START)
3709adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        {
3719adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            /* previous fragments need to be dropped, when received another new message */
3729adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            p_rcb->rasm_offset = 0;
373abd70abb5e42c9431df94fe9d2c4a78a0d8d9af9Pavlin Radoslavov            osi_free_and_reset((void **)&p_rcb->p_rmsg);
3749adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        }
3759adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan
3769adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        if (pkt_type != AVRC_PKT_SINGLE && cr == AVCT_RSP)
3779adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        {
3789adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            /* not a single response packet - need to re-assemble metadata messages */
379ca57b25df827286c4996e17aefc251ecd79b33fcPavlin Radoslavov            if (pkt_type == AVRC_PKT_START) {
380247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji                /* Allocate buffer for re-assembly */
381247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji                p_rcb->rasm_pdu = *p_data;
382abd70abb5e42c9431df94fe9d2c4a78a0d8d9af9Pavlin Radoslavov                p_rcb->p_rmsg = (BT_HDR *)osi_malloc(BT_DEFAULT_BUFFER_SIZE);
383ca57b25df827286c4996e17aefc251ecd79b33fcPavlin Radoslavov                /* Copy START packet to buffer for re-assembling fragments */
384ca57b25df827286c4996e17aefc251ecd79b33fcPavlin Radoslavov                memcpy(p_rcb->p_rmsg, p_pkt, sizeof(BT_HDR)); /* Copy bt hdr */
385247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji
386ca57b25df827286c4996e17aefc251ecd79b33fcPavlin Radoslavov                /* Copy metadata message */
387ca57b25df827286c4996e17aefc251ecd79b33fcPavlin Radoslavov                memcpy((UINT8 *)(p_rcb->p_rmsg + 1),
388ca57b25df827286c4996e17aefc251ecd79b33fcPavlin Radoslavov                       (UINT8 *)(p_pkt+1) + p_pkt->offset, p_pkt->len);
389247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji
390ca57b25df827286c4996e17aefc251ecd79b33fcPavlin Radoslavov                /* offset of start of metadata response in reassembly buffer */
391ca57b25df827286c4996e17aefc251ecd79b33fcPavlin Radoslavov                p_rcb->p_rmsg->offset = p_rcb->rasm_offset = 0;
392247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji
393ca57b25df827286c4996e17aefc251ecd79b33fcPavlin Radoslavov                /*
394ca57b25df827286c4996e17aefc251ecd79b33fcPavlin Radoslavov                 * Free original START packet, replace with pointer to
395ca57b25df827286c4996e17aefc251ecd79b33fcPavlin Radoslavov                 * reassembly buffer.
396ca57b25df827286c4996e17aefc251ecd79b33fcPavlin Radoslavov                 */
397abd70abb5e42c9431df94fe9d2c4a78a0d8d9af9Pavlin Radoslavov                osi_free(p_pkt);
398ca57b25df827286c4996e17aefc251ecd79b33fcPavlin Radoslavov                *pp_pkt = p_rcb->p_rmsg;
399247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji
400ca57b25df827286c4996e17aefc251ecd79b33fcPavlin Radoslavov                /*
401ca57b25df827286c4996e17aefc251ecd79b33fcPavlin Radoslavov                 * Set offset to point to where to copy next - use the same
402ca57b25df827286c4996e17aefc251ecd79b33fcPavlin Radoslavov                 * reassembly logic as AVCT.
403ca57b25df827286c4996e17aefc251ecd79b33fcPavlin Radoslavov                 */
4049adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                p_rcb->p_rmsg->offset += p_rcb->p_rmsg->len;
4059adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                req_continue = TRUE;
406ca57b25df827286c4996e17aefc251ecd79b33fcPavlin Radoslavov            } else if (p_rcb->p_rmsg == NULL) {
407247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji                /* Received a CONTINUE/END, but no corresponding START
408247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji                              (or previous fragmented response was dropped) */
409b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati                AVRC_TRACE_DEBUG ("Received a CONTINUE/END without no corresponding START \
410247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji                                   (or previous fragmented response was dropped)");
4113a2fa83dac1b07b661a20e2412aad9bf81492106Pavlin Radoslavov                drop_code = 5;
412abd70abb5e42c9431df94fe9d2c4a78a0d8d9af9Pavlin Radoslavov                osi_free(p_pkt);
413247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji                *pp_pkt = NULL;
414247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji            }
4159adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            else
4169adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            {
4179adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                /* get size of buffer holding assembled message */
418ca57b25df827286c4996e17aefc251ecd79b33fcPavlin Radoslavov                /*
419ca57b25df827286c4996e17aefc251ecd79b33fcPavlin Radoslavov                 * NOTE: The buffer is allocated above at the beginning of the
420ca57b25df827286c4996e17aefc251ecd79b33fcPavlin Radoslavov                 * reassembly, and is always of size BT_DEFAULT_BUFFER_SIZE.
421ca57b25df827286c4996e17aefc251ecd79b33fcPavlin Radoslavov                 */
422ca57b25df827286c4996e17aefc251ecd79b33fcPavlin Radoslavov                UINT16 buf_len = BT_DEFAULT_BUFFER_SIZE - sizeof(BT_HDR);
4239adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                /* adjust offset and len of fragment for header byte */
4249adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                p_pkt->offset += (AVRC_VENDOR_HDR_SIZE + AVRC_MIN_META_HDR_SIZE);
4259adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                p_pkt->len -= (AVRC_VENDOR_HDR_SIZE + AVRC_MIN_META_HDR_SIZE);
4269adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                /* verify length */
4279adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                if ((p_rcb->p_rmsg->offset + p_pkt->len) > buf_len)
4289adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                {
429b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati                    AVRC_TRACE_WARNING("Fragmented message too big! - report the partial message");
4309adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                    p_pkt->len = buf_len - p_rcb->p_rmsg->offset;
4319adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                    pkt_type = AVRC_PKT_END;
4326b84f291c4edce7e4102efd8d4052a63bcb4b9dcAnubhav Gupta                    buf_overflow = true;
4339adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                }
4349adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan
4359adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                /* copy contents of p_pkt to p_rx_msg */
4369adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                memcpy((UINT8 *)(p_rcb->p_rmsg + 1) + p_rcb->p_rmsg->offset,
4379adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                       (UINT8 *)(p_pkt + 1) + p_pkt->offset, p_pkt->len);
4389adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan
4399adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                if (pkt_type == AVRC_PKT_END)
4409adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                {
4419adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                    p_rcb->p_rmsg->offset = p_rcb->rasm_offset;
4429adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                    p_rcb->p_rmsg->len += p_pkt->len;
4439adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                    p_pkt_new = p_rcb->p_rmsg;
4449adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                    p_rcb->rasm_offset = 0;
4459adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                    p_rcb->p_rmsg = NULL;
4469adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                    p_msg->p_vendor_data   = (UINT8 *)(p_pkt_new+1) + p_pkt_new->offset;
4479adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                    p_msg->hdr.ctype       = p_msg->p_vendor_data[0] & AVRC_CTYPE_MASK;
4489adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                    /* 6 = ctype, subunit*, opcode & CO_ID */
4499adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                    p_msg->p_vendor_data  += AVRC_VENDOR_HDR_SIZE;
4509adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                    p_msg->vendor_len      = p_pkt_new->len - AVRC_VENDOR_HDR_SIZE;
4519adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                    p_data = p_msg->p_vendor_data + 1; /* skip pdu */
4529adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                    *p_data++ = AVRC_PKT_SINGLE;
4539adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                    UINT16_TO_BE_STREAM(p_data, (p_msg->vendor_len - AVRC_MIN_META_HDR_SIZE));
454b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati                    AVRC_TRACE_DEBUG("end frag:%d, total len:%d, offset:%d", p_pkt->len,
4559adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                        p_pkt_new->len, p_pkt_new->offset);
4569adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                }
4579adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                else
4589adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                {
4599adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                    p_rcb->p_rmsg->offset += p_pkt->len;
4609adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                    p_rcb->p_rmsg->len += p_pkt->len;
4619adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                    p_pkt_new = NULL;
4629adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                    req_continue = TRUE;
4639adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                }
464abd70abb5e42c9431df94fe9d2c4a78a0d8d9af9Pavlin Radoslavov                osi_free(p_pkt);
4659adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                *pp_pkt = p_pkt_new;
4669adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            }
4679adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        }
4689adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan
4699adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        if (cr == AVCT_CMD)
4709adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        {
4719adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            p_rsp = avrc_proc_vendor_command(handle, label, *pp_pkt, p_msg);
4729adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            if (p_rsp)
4739adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            {
4749adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                AVCT_MsgReq( handle, label, AVCT_RSP, p_rsp);
4753a2fa83dac1b07b661a20e2412aad9bf81492106Pavlin Radoslavov                drop_code = 3;
4769adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            }
4779adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            else if (p_msg->hdr.opcode == AVRC_OP_DROP)
4789adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            {
4793a2fa83dac1b07b661a20e2412aad9bf81492106Pavlin Radoslavov                drop_code = 1;
4809adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            }
4819adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            else if (p_msg->hdr.opcode == AVRC_OP_DROP_N_FREE)
4823a2fa83dac1b07b661a20e2412aad9bf81492106Pavlin Radoslavov                drop_code = 4;
4839adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan
4849adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        }
485247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji        else if (cr == AVCT_RSP && req_continue == TRUE)
486247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji        {
487247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji            avrc_cmd.pdu    = AVRC_PDU_REQUEST_CONTINUATION_RSP;
488247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji            avrc_cmd.status = AVRC_STS_NO_ERROR;
489247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji            avrc_cmd.target_pdu = p_rcb->rasm_pdu;
490247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji            if (AVRC_BldCommand ((tAVRC_COMMAND *)&avrc_cmd, &p_cmd) == AVRC_STS_NO_ERROR)
491247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji            {
4923a2fa83dac1b07b661a20e2412aad9bf81492106Pavlin Radoslavov                drop_code = 2;
493247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji                AVRC_MsgReq (handle, (UINT8)(label), AVRC_CMD_CTRL, p_cmd);
494247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji            }
495247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji        }
4966b84f291c4edce7e4102efd8d4052a63bcb4b9dcAnubhav Gupta        /*
4976b84f291c4edce7e4102efd8d4052a63bcb4b9dcAnubhav Gupta         * Drop it if we are out of buffer
4986b84f291c4edce7e4102efd8d4052a63bcb4b9dcAnubhav Gupta         */
4996b84f291c4edce7e4102efd8d4052a63bcb4b9dcAnubhav Gupta        else if (cr == AVCT_RSP && req_continue == FALSE  && buf_overflow == TRUE)
5006b84f291c4edce7e4102efd8d4052a63bcb4b9dcAnubhav Gupta        {
5016b84f291c4edce7e4102efd8d4052a63bcb4b9dcAnubhav Gupta            avrc_cmd.pdu    = AVRC_PDU_ABORT_CONTINUATION_RSP;
5026b84f291c4edce7e4102efd8d4052a63bcb4b9dcAnubhav Gupta            avrc_cmd.status = AVRC_STS_NO_ERROR;
5036b84f291c4edce7e4102efd8d4052a63bcb4b9dcAnubhav Gupta            avrc_cmd.target_pdu = p_rcb->rasm_pdu;
5046b84f291c4edce7e4102efd8d4052a63bcb4b9dcAnubhav Gupta            if (AVRC_BldCommand ((tAVRC_COMMAND *)&avrc_cmd, &p_cmd) == AVRC_STS_NO_ERROR)
5056b84f291c4edce7e4102efd8d4052a63bcb4b9dcAnubhav Gupta            {
5066b84f291c4edce7e4102efd8d4052a63bcb4b9dcAnubhav Gupta                drop_code = 4;
5076b84f291c4edce7e4102efd8d4052a63bcb4b9dcAnubhav Gupta                AVRC_MsgReq (handle, (UINT8)(label), AVRC_CMD_CTRL, p_cmd);
5086b84f291c4edce7e4102efd8d4052a63bcb4b9dcAnubhav Gupta            }
5096b84f291c4edce7e4102efd8d4052a63bcb4b9dcAnubhav Gupta        }
5109adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    }
511247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji
5123a2fa83dac1b07b661a20e2412aad9bf81492106Pavlin Radoslavov    return drop_code;
5139adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan}
5149adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan#endif /* (AVRC_METADATA_INCLUDED == TRUE) */
5155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************
5175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         avrc_msg_cback
5195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This is the callback function used by AVCTP to report
5215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  received AV control messages.
5225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          Nothing.
5245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project******************************************************************************/
5265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void avrc_msg_cback(UINT8 handle, UINT8 label, UINT8 cr,
5275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                               BT_HDR *p_pkt)
5285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
5295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8       opcode;
5305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tAVRC_MSG   msg;
5315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8       *p_data;
5325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8       *p_begin;
5333a2fa83dac1b07b661a20e2412aad9bf81492106Pavlin Radoslavov    BOOLEAN     drop = FALSE;
53456a3be0d6eaa1bc264736e399fb32d3094f0b513Pavlin Radoslavov    BOOLEAN     do_free = TRUE;
5355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BT_HDR      *p_rsp = NULL;
5365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8       *p_rsp_data;
5375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int         xx;
5385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BOOLEAN     reject = FALSE;
5395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (BT_USE_TRACES == TRUE)
5405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    char        *p_drop_msg = "dropped";
5415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
5425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tAVRC_MSG_VENDOR *p_msg = &msg.vendor;
5435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (cr == AVCT_CMD &&
5455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        (p_pkt->layer_specific & AVCT_DATA_CTRL && AVRC_PACKET_LEN < sizeof(p_pkt->len)))
5465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
5475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* Ignore the invalid AV/C command frame */
5485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (BT_USE_TRACES == TRUE)
5495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_drop_msg = "dropped - too long AV/C cmd frame size";
5505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
551abd70abb5e42c9431df94fe9d2c4a78a0d8d9af9Pavlin Radoslavov        osi_free(p_pkt);
5525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
5535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
5545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (cr == AVCT_REJ)
5565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
5575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* The peer thinks that this PID is no longer open - remove this handle */
5585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /*  */
559abd70abb5e42c9431df94fe9d2c4a78a0d8d9af9Pavlin Radoslavov        osi_free(p_pkt);
5605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        AVCT_RemoveConn(handle);
5615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
5625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
5635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_data  = (UINT8 *)(p_pkt+1) + p_pkt->offset;
5655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    memset(&msg, 0, sizeof(tAVRC_MSG) );
5665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
5675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        msg.hdr.ctype           = p_data[0] & AVRC_CTYPE_MASK;
568b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati        AVRC_TRACE_DEBUG("avrc_msg_cback handle:%d, ctype:%d, offset:%d, len: %d",
5695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                handle, msg.hdr.ctype, p_pkt->offset, p_pkt->len);
5705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        msg.hdr.subunit_type    = (p_data[1] & AVRC_SUBTYPE_MASK) >> AVRC_SUBTYPE_SHIFT;
5715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        msg.hdr.subunit_id      = p_data[1] & AVRC_SUBID_MASK;
5725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        opcode                  = p_data[2];
5735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
5745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ( ((avrc_cb.ccb[handle].control & AVRC_CT_TARGET) && (cr == AVCT_CMD)) ||
5765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        ((avrc_cb.ccb[handle].control & AVRC_CT_CONTROL) && (cr == AVCT_RSP)) )
5775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
5785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        switch(opcode)
5805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
5815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        case AVRC_OP_UNIT_INFO:
5825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (cr == AVCT_CMD)
5835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
5845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                /* send the response to the peer */
5858d88b1b75c665772f714643a71e5974c7f6dd02cSatya Calloji                p_rsp = avrc_copy_packet(p_pkt, AVRC_OP_UNIT_INFO_RSP_LEN);
58608c08fc0015c3c5e864da080dba0712ee89a6712Pavlin Radoslavov                p_rsp_data = avrc_get_data_ptr(p_rsp);
5873a2fa83dac1b07b661a20e2412aad9bf81492106Pavlin Radoslavov                *p_rsp_data = AVRC_RSP_IMPL_STBL;
5885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                /* check & set the offset. set response code, set subunit_type & subunit_id,
5895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                   set AVRC_OP_UNIT_INFO */
5909adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                /* 3 bytes: ctype, subunit*, opcode */
5913a2fa83dac1b07b661a20e2412aad9bf81492106Pavlin Radoslavov                p_rsp_data      += AVRC_AVC_HDR_SIZE;
5925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                *p_rsp_data++   = 7;
5935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                /* Panel subunit & id=0 */
5945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                *p_rsp_data++   = (AVRC_SUB_PANEL << AVRC_SUBTYPE_SHIFT);
5955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                AVRC_CO_ID_TO_BE_STREAM(p_rsp_data, avrc_cb.ccb[handle].company_id);
5965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_rsp->len      = (UINT16) (p_rsp_data - (UINT8 *)(p_rsp + 1) - p_rsp->offset);
5975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                cr = AVCT_RSP;
5985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (BT_USE_TRACES == TRUE)
5995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_drop_msg = "auto respond";
6005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
6015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
6025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            else
6035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
6045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                /* parse response */
6055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_data += 4; /* 3 bytes: ctype, subunit*, opcode + octet 3 (is 7)*/
6065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                msg.unit.unit_type  = (*p_data & AVRC_SUBTYPE_MASK) >> AVRC_SUBTYPE_SHIFT;
6075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                msg.unit.unit       = *p_data & AVRC_SUBID_MASK;
6085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_data++;
6095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                AVRC_BE_STREAM_TO_CO_ID(msg.unit.company_id, p_data);
6105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
6115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            break;
6125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        case AVRC_OP_SUB_INFO:
6145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (cr == AVCT_CMD)
6155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
6165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                /* send the response to the peer */
6178d88b1b75c665772f714643a71e5974c7f6dd02cSatya Calloji                p_rsp = avrc_copy_packet(p_pkt, AVRC_OP_SUB_UNIT_INFO_RSP_LEN);
61808c08fc0015c3c5e864da080dba0712ee89a6712Pavlin Radoslavov                p_rsp_data = avrc_get_data_ptr(p_rsp);
6193a2fa83dac1b07b661a20e2412aad9bf81492106Pavlin Radoslavov                *p_rsp_data = AVRC_RSP_IMPL_STBL;
6205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                /* check & set the offset. set response code, set (subunit_type & subunit_id),
6215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                   set AVRC_OP_SUB_INFO, set (page & extention code) */
6223a2fa83dac1b07b661a20e2412aad9bf81492106Pavlin Radoslavov                p_rsp_data      += 4;
6235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                /* Panel subunit & id=0 */
6245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                *p_rsp_data++   = (AVRC_SUB_PANEL << AVRC_SUBTYPE_SHIFT);
6255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                memset(p_rsp_data, AVRC_CMD_OPRND_PAD, AVRC_SUBRSP_OPRND_BYTES);
6265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_rsp_data      += AVRC_SUBRSP_OPRND_BYTES;
6275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_rsp->len      = (UINT16) (p_rsp_data - (UINT8 *)(p_rsp + 1) - p_rsp->offset);
6285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                cr = AVCT_RSP;
6295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (BT_USE_TRACES == TRUE)
6305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_drop_msg = "auto responded";
6315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
6325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
6335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            else
6345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
6355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                /* parse response */
6365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_data += AVRC_AVC_HDR_SIZE; /* 3 bytes: ctype, subunit*, opcode */
6375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                msg.sub.page    = (*p_data++ >> AVRC_SUB_PAGE_SHIFT) & AVRC_SUB_PAGE_MASK;
6385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                xx      = 0;
6395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                while (*p_data != AVRC_CMD_OPRND_PAD && xx<AVRC_SUB_TYPE_LEN)
6405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
6415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    msg.sub.subunit_type[xx] = *p_data++ >> AVRC_SUBTYPE_SHIFT;
6425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    if (msg.sub.subunit_type[xx] == AVRC_SUB_PANEL)
6435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        msg.sub.panel   = TRUE;
6445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    xx++;
6455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
6465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
6475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            break;
6485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        case AVRC_OP_VENDOR:
6505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_data  = (UINT8 *)(p_pkt+1) + p_pkt->offset;
6515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_begin = p_data;
6525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (p_pkt->len < AVRC_VENDOR_HDR_SIZE) /* 6 = ctype, subunit*, opcode & CO_ID */
6535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
6545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                if (cr == AVCT_CMD)
6555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    reject = TRUE;
6565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                else
6575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    drop = TRUE;
6585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                break;
6595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
6605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_data += AVRC_AVC_HDR_SIZE; /* skip the first 3 bytes: ctype, subunit*, opcode */
6615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            AVRC_BE_STREAM_TO_CO_ID(p_msg->company_id, p_data);
6625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_msg->p_vendor_data   = p_data;
6635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_msg->vendor_len      = p_pkt->len - (p_data - p_begin);
6645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6659adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan#if (AVRC_METADATA_INCLUDED == TRUE)
6663a2fa83dac1b07b661a20e2412aad9bf81492106Pavlin Radoslavov            UINT8 drop_code = 0;
667247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji            if (p_msg->company_id == AVRC_CO_METADATA)
668247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji            {
669247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji                /* Validate length for metadata message */
670247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji                if (p_pkt->len < (AVRC_VENDOR_HDR_SIZE + AVRC_MIN_META_HDR_SIZE))
671247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji                {
672247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji                    if (cr == AVCT_CMD)
673247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji                        reject = TRUE;
674247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji                    else
675247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji                        drop = TRUE;
676247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji                    break;
677247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji                }
678247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji
679247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji                /* Check+handle fragmented messages */
6803a2fa83dac1b07b661a20e2412aad9bf81492106Pavlin Radoslavov                drop_code = avrc_proc_far_msg(handle, label, cr, &p_pkt, p_msg);
6813a2fa83dac1b07b661a20e2412aad9bf81492106Pavlin Radoslavov                if (drop_code > 0)
6823a2fa83dac1b07b661a20e2412aad9bf81492106Pavlin Radoslavov                    drop = TRUE;
683247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji            }
6843a2fa83dac1b07b661a20e2412aad9bf81492106Pavlin Radoslavov            if (drop_code > 0)
6859adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            {
6863a2fa83dac1b07b661a20e2412aad9bf81492106Pavlin Radoslavov                if (drop_code != 4)
6873a2fa83dac1b07b661a20e2412aad9bf81492106Pavlin Radoslavov                    do_free = FALSE;
6889adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan#if (BT_USE_TRACES == TRUE)
6893a2fa83dac1b07b661a20e2412aad9bf81492106Pavlin Radoslavov                switch (drop_code)
6909adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                {
6919adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                case 1:
6929adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                    p_drop_msg = "sent_frag";
6939adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                    break;
6949adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                case 2:
6959adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                    p_drop_msg = "req_cont";
6969adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                    break;
6979adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                case 3:
6989adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                    p_drop_msg = "sent_frag3";
6999adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                    break;
7009adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                case 4:
7019adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                    p_drop_msg = "sent_frag_free";
7029adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                    break;
7039adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                default:
7049adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                    p_drop_msg = "sent_fragd";
7059adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                }
7069adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan#endif
7079adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            }
7089adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan#endif /* (AVRC_METADATA_INCLUDED == TRUE) */
7095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            break;
7105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        case AVRC_OP_PASS_THRU:
7125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (p_pkt->len < 5) /* 3 bytes: ctype, subunit*, opcode & op_id & len */
7135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
7145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                if (cr == AVCT_CMD)
7155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    reject = TRUE;
7165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                else
7175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    drop = TRUE;
7185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                break;
7195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
7205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_data += AVRC_AVC_HDR_SIZE; /* skip the first 3 bytes: ctype, subunit*, opcode */
7215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            msg.pass.op_id  = (AVRC_PASS_OP_ID_MASK & *p_data);
7225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (AVRC_PASS_STATE_MASK & *p_data)
7235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                msg.pass.state  = TRUE;
7245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            else
7255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                msg.pass.state  = FALSE;
7265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_data++;
7275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            msg.pass.pass_len    = *p_data++;
7285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (msg.pass.pass_len != p_pkt->len - 5)
7295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                msg.pass.pass_len = p_pkt->len - 5;
7305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (msg.pass.pass_len)
7315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                msg.pass.p_pass_data = p_data;
7325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            else
7335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                msg.pass.p_pass_data = NULL;
7345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            break;
7355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        default:
7385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if ((avrc_cb.ccb[handle].control & AVRC_CT_TARGET) && (cr == AVCT_CMD))
7395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
7405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                /* reject unsupported opcode */
7415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                reject = TRUE;
7425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
7435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            drop    = TRUE;
7445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            break;
7455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
7465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
7475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else /* drop the event */
7485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
7495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            drop    = TRUE;
7505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
7515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (reject)
7535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
7545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* reject unsupported opcode */
7558d88b1b75c665772f714643a71e5974c7f6dd02cSatya Calloji        p_rsp = avrc_copy_packet(p_pkt, AVRC_OP_REJ_MSG_LEN);
75608c08fc0015c3c5e864da080dba0712ee89a6712Pavlin Radoslavov        p_rsp_data = avrc_get_data_ptr(p_rsp);
7573a2fa83dac1b07b661a20e2412aad9bf81492106Pavlin Radoslavov        *p_rsp_data = AVRC_RSP_REJ;
7585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (BT_USE_TRACES == TRUE)
7595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_drop_msg = "rejected";
7605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
7615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        cr      = AVCT_RSP;
7625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        drop    = TRUE;
7635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
7645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_rsp)
7665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
7675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* set to send response right away */
7685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        AVCT_MsgReq( handle, label, cr, p_rsp);
7695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        drop = TRUE;
7705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
7715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (drop == FALSE)
7735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
7745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        msg.hdr.opcode = opcode;
7755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        (*avrc_cb.ccb[handle].p_msg_cback)(handle, label, opcode, &msg);
7765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
7775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (BT_USE_TRACES == TRUE)
7785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
7795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
780b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati        AVRC_TRACE_WARNING("avrc_msg_cback %s msg handle:%d, control:%d, cr:%d, opcode:x%x",
7815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_drop_msg,
7825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                handle, avrc_cb.ccb[handle].control, cr, opcode);
7835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
7845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
7855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
78756a3be0d6eaa1bc264736e399fb32d3094f0b513Pavlin Radoslavov    if (do_free)
788abd70abb5e42c9431df94fe9d2c4a78a0d8d9af9Pavlin Radoslavov        osi_free(p_pkt);
7895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
7905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************
7955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
7965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         avrc_pass_msg
7975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
7985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Compose a PASS THROUGH command according to p_msg
7995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
8005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  Input Parameters:
8015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                      p_msg: Pointer to PASS THROUGH message structure.
8025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
8035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  Output Parameters:
8045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                      None.
8055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
8065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          pointer to a valid GKI buffer if successful.
8075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  NULL if p_msg is NULL.
8085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
8095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project******************************************************************************/
8105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic BT_HDR  * avrc_pass_msg(tAVRC_MSG_PASS *p_msg)
8115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
812181932fad8b91dc6831222e5b616574c39a21565Sharvil Nanavati    assert(p_msg != NULL);
81370ae7de9451e3dc074a048ba98b672a6ba3a4551Pavlin Radoslavov    assert(AVRC_CMD_BUF_SIZE > (AVRC_MIN_CMD_LEN+p_msg->pass_len));
8145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8155fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov    BT_HDR  *p_cmd = (BT_HDR *)osi_malloc(AVRC_CMD_BUF_SIZE);
8165fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov    p_cmd->offset = AVCT_MSG_OFFSET;
8175fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov    p_cmd->layer_specific = AVCT_DATA_CTRL;
8185fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov
8195fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov    UINT8 *p_data = (UINT8 *)(p_cmd + 1) + p_cmd->offset;
8205fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov    *p_data++ = (p_msg->hdr.ctype & AVRC_CTYPE_MASK);
8215fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov    *p_data++ = (AVRC_SUB_PANEL << AVRC_SUBTYPE_SHIFT); /* Panel subunit & id=0 */
8225fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov    *p_data++ = AVRC_OP_PASS_THRU;
8235fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov    *p_data = (AVRC_PASS_OP_ID_MASK&p_msg->op_id);
8245fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov    if (p_msg->state)
8255fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov        *p_data     |= AVRC_PASS_STATE_MASK;
8265fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov    p_data++;
8275fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov
8285fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov    if (p_msg->op_id == AVRC_ID_VENDOR) {
8295fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov        *p_data++ = p_msg->pass_len;
8305fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov        if (p_msg->pass_len && p_msg->p_pass_data) {
8315fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov            memcpy(p_data, p_msg->p_pass_data, p_msg->pass_len);
8325fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov            p_data += p_msg->pass_len;
8335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
8345fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov    } else {
8355fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov        /* set msg len to 0 for other op_id */
8365fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov        *p_data++       = 0;
8375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
8385fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov    p_cmd->len = (UINT16) (p_data - (UINT8 *)(p_cmd + 1) - p_cmd->offset);
8395fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov
8405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return p_cmd;
8415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
8425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************
8445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
8455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         AVRC_Open
8465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
8475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function is called to open a connection to AVCTP.
8485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  The connection can be either an initiator or acceptor, as
8495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  determined by the p_ccb->stream parameter.
8505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  The connection can be a target, a controller or for both role,
8515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  as determined by the p_ccb->control parameter.
8525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  By definition, a target connection is an acceptor connection
8535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  that waits for an incoming AVCTP connection from the peer.
8545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  The connection remains available to the application until
8555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  the application closes it by calling AVRC_Close().  The
8565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  application does not need to reopen the connection after an
8575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  AVRC_CLOSE_IND_EVT is received.
8585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
8595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  Input Parameters:
8605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                      p_ccb->company_id: Company Identifier.
8615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
8625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                      p_ccb->p_ctrl_cback:  Pointer to control callback function.
8635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
8645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                      p_ccb->p_msg_cback:  Pointer to message callback function.
8655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
8665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                      p_ccb->conn: AVCTP connection role.  This is set to
8675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                      AVCTP_INT for initiator connections and AVCTP_ACP
8685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                      for acceptor connections.
8695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
8705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                      p_ccb->control: Control role.  This is set to
8715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                      AVRC_CT_TARGET for target connections, AVRC_CT_CONTROL
8725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                      for control connections or (AVRC_CT_TARGET|AVRC_CT_CONTROL)
8735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                      for connections that support both roles.
8745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
8755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                      peer_addr: BD address of peer device.  This value is
8765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                      only used for initiator connections; for acceptor
8775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                      connections it can be set to NULL.
8785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
8795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  Output Parameters:
8805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                      p_handle: Pointer to handle.  This parameter is only
8815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                                valid if AVRC_SUCCESS is returned.
8825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
8835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          AVRC_SUCCESS if successful.
8845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  AVRC_NO_RESOURCES if there are not enough resources to open
8855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  the connection.
8865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
8875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project******************************************************************************/
8885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjectUINT16 AVRC_Open(UINT8 *p_handle, tAVRC_CONN_CB *p_ccb, BD_ADDR_PTR peer_addr)
8895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
8905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16      status;
8915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tAVCT_CC    cc;
8925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    cc.p_ctrl_cback = avrc_ctrl_cback;      /* Control callback */
8945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    cc.p_msg_cback  = avrc_msg_cback;       /* Message callback */
8955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    cc.pid          = UUID_SERVCLASS_AV_REMOTE_CONTROL;  /* Profile ID */
8965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    cc.role         = p_ccb->conn;          /* Initiator/acceptor role */
8975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    cc.control      = p_ccb->control;       /* Control role (Control/Target) */
8985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    status = AVCT_CreateConn(p_handle, &cc, peer_addr);
9005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (status == AVCT_SUCCESS)
9015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
9025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        memcpy(&avrc_cb.ccb[*p_handle], p_ccb, sizeof(tAVRC_CONN_CB));
9039adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan#if (AVRC_METADATA_INCLUDED == TRUE)
9049adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        memset(&avrc_cb.fcb[*p_handle], 0, sizeof(tAVRC_FRAG_CB));
9059adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        memset(&avrc_cb.rcb[*p_handle], 0, sizeof(tAVRC_RASM_CB));
9069adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan#endif
9075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
908b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati    AVRC_TRACE_DEBUG("AVRC_Open role: %d, control:%d status:%d, handle:%d", cc.role, cc.control,
9099adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        status, *p_handle);
9105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return status;
9125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
9135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************
9155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
9165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         AVRC_Close
9175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
9185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Close a connection opened with AVRC_Open().
9195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  This function is called when the
9205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  application is no longer using a connection.
9215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
9225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  Input Parameters:
9235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                      handle: Handle of this connection.
9245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
9255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  Output Parameters:
9265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                      None.
9275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
9285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          AVRC_SUCCESS if successful.
9295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  AVRC_BAD_HANDLE if handle is invalid.
9305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
9315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project******************************************************************************/
9325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjectUINT16 AVRC_Close(UINT8 handle)
9335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
934b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati    AVRC_TRACE_DEBUG("AVRC_Close handle:%d", handle);
9355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return AVCT_RemoveConn(handle);
9365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
9375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************
9405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
9415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         AVRC_MsgReq
9425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
9435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function is used to send the AVRCP byte stream in p_pkt
9445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  down to AVCTP.
9455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
9465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  It is expected that p_pkt->offset is at least AVCT_MSG_OFFSET
9475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  p_pkt->layer_specific is AVCT_DATA_CTRL or AVCT_DATA_BROWSE
9485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  p_pkt->event is AVRC_OP_VENDOR, AVRC_OP_PASS_THRU or AVRC_OP_BROWSE
9495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  The above BT_HDR settings are set by the AVRC_Bld* functions.
9505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
9515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          AVRC_SUCCESS if successful.
9525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  AVRC_BAD_HANDLE if handle is invalid.
9535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
9545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project******************************************************************************/
9555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjectUINT16 AVRC_MsgReq (UINT8 handle, UINT8 label, UINT8 ctype, BT_HDR *p_pkt)
9565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
9579adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan#if (AVRC_METADATA_INCLUDED == TRUE)
9589adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    UINT8   *p_data;
9599adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    UINT8   cr = AVCT_CMD;
9609adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    BOOLEAN chk_frag = TRUE;
9619adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    UINT8   *p_start = NULL;
9629adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    tAVRC_FRAG_CB   *p_fcb;
9639adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    UINT16  len;
9649adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan
9659adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    if (!p_pkt)
9669adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        return AVRC_BAD_PARAM;
9679adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan
9682ac9ae06be5091f6f2eef0022a3810752f127d04Anubhav Gupta    AVRC_TRACE_DEBUG("%s handle = %u label = %u ctype = %u len = %d",
9692ac9ae06be5091f6f2eef0022a3810752f127d04Anubhav Gupta                     __func__, handle, label, ctype, p_pkt->len);
9702ac9ae06be5091f6f2eef0022a3810752f127d04Anubhav Gupta
9719adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    if (ctype >= AVRC_RSP_NOT_IMPL)
9729adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        cr = AVCT_RSP;
9739adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan
9749adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    if (p_pkt->event == AVRC_OP_VENDOR)
9759adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    {
9769adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        /* add AVRCP Vendor Dependent headers */
9779adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        p_start = ((UINT8 *)(p_pkt + 1) + p_pkt->offset);
9789adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        p_pkt->offset -= AVRC_VENDOR_HDR_SIZE;
9799adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        p_pkt->len += AVRC_VENDOR_HDR_SIZE;
9809adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        p_data = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
9819adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        *p_data++       = (ctype & AVRC_CTYPE_MASK);
9829adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        *p_data++       = (AVRC_SUB_PANEL << AVRC_SUBTYPE_SHIFT);
9839adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        *p_data++       = AVRC_OP_VENDOR;
9849adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        AVRC_CO_ID_TO_BE_STREAM(p_data, AVRC_CO_METADATA);
9859adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    }
9869adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    else if (p_pkt->event == AVRC_OP_PASS_THRU)
9879adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    {
9889adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        /* add AVRCP Pass Through headers */
9899adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        p_start = ((UINT8 *)(p_pkt + 1) + p_pkt->offset);
9909adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        p_pkt->offset -= AVRC_PASS_THRU_SIZE;
9919adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        p_pkt->len += AVRC_PASS_THRU_SIZE;
9929adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        p_data = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
9939adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        *p_data++       = (ctype & AVRC_CTYPE_MASK);
9949adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        *p_data++       = (AVRC_SUB_PANEL << AVRC_SUBTYPE_SHIFT);
9959adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        *p_data++       = AVRC_OP_PASS_THRU;/* opcode */
9969adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        *p_data++       = AVRC_ID_VENDOR;   /* operation id */
9979adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        *p_data++       = 5;                /* operation data len */
9989adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        AVRC_CO_ID_TO_BE_STREAM(p_data, AVRC_CO_METADATA);
9999adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    }
10009adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan
10019adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    /* abandon previous fragments */
10029adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    p_fcb = &avrc_cb.fcb[handle];
10039adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    if (p_fcb->frag_enabled)
10049adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        p_fcb->frag_enabled = FALSE;
10059adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan
1006abd70abb5e42c9431df94fe9d2c4a78a0d8d9af9Pavlin Radoslavov    osi_free_and_reset((void **)&p_fcb->p_fmsg);
10079adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan
10089adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    /* AVRCP spec has not defined any control channel commands that needs fragmentation at this level
10099adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan     * check for fragmentation only on the response */
10109adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    if ((cr == AVCT_RSP) && (chk_frag == TRUE))
10119adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    {
10129adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        if (p_pkt->len > AVRC_MAX_CTRL_DATA_LEN)
10139adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        {
10142ac9ae06be5091f6f2eef0022a3810752f127d04Anubhav Gupta            int offset_len = MAX(AVCT_MSG_OFFSET, p_pkt->offset);
10155fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov            BT_HDR *p_pkt_new =
10165fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov                (BT_HDR *)osi_malloc(AVRC_PACKET_LEN + offset_len + BT_HDR_SIZE);
10175fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov            if (p_start != NULL) {
10189adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                p_fcb->frag_enabled = TRUE;
10199adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                p_fcb->p_fmsg       = p_pkt;
10209adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                p_fcb->frag_pdu     = *p_start;
10219adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                p_pkt               = p_pkt_new;
10229adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                p_pkt_new           = p_fcb->p_fmsg;
10239adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                p_pkt->len          = AVRC_MAX_CTRL_DATA_LEN;
10249adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                p_pkt->offset       = p_pkt_new->offset;
10259adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                p_pkt->layer_specific = p_pkt_new->layer_specific;
10269adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                p_pkt->event = p_pkt_new->event;
10279adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                p_data = (UINT8 *)(p_pkt+1) + p_pkt->offset;
10289adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                p_start -= AVRC_VENDOR_HDR_SIZE;
10299adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                memcpy (p_data, p_start, AVRC_MAX_CTRL_DATA_LEN);
10309adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                /* use AVRC start packet type */
10319adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                p_data += AVRC_VENDOR_HDR_SIZE;
10329adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                p_data++; /* pdu */
10339adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                *p_data++ = AVRC_PKT_START;
10349adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                /* 4 pdu, pkt_type & len */
10359adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                len = (AVRC_MAX_CTRL_DATA_LEN - AVRC_VENDOR_HDR_SIZE - AVRC_MIN_META_HDR_SIZE);
10369adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                UINT16_TO_BE_STREAM(p_data, len);
10379adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan
10389adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                /* prepare the left over for as an end fragment */
10399adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                avrc_prep_end_frag (handle);
10408d88b1b75c665772f714643a71e5974c7f6dd02cSatya Calloji                AVRC_TRACE_DEBUG ("%s p_pkt len:%d/%d, next len:%d", __func__,
10418d88b1b75c665772f714643a71e5974c7f6dd02cSatya Calloji                                  p_pkt->len, len, p_fcb->p_fmsg->len );
10425fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov            } else {
10435fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov                /* TODO: Is this "else" block valid? Remove it? */
1044b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati                AVRC_TRACE_ERROR ("AVRC_MsgReq no buffers for fragmentation" );
1045abd70abb5e42c9431df94fe9d2c4a78a0d8d9af9Pavlin Radoslavov                osi_free(p_pkt);
10468d88b1b75c665772f714643a71e5974c7f6dd02cSatya Calloji                return AVRC_NO_RESOURCES;
10478d88b1b75c665772f714643a71e5974c7f6dd02cSatya Calloji            }
10489adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        }
10499adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    }
10509adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan
10519adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    return AVCT_MsgReq( handle, label, cr, p_pkt);
10529adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan#else
10539adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    return AVRC_NO_RESOURCES;
10549adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan#endif
10559adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan}
10565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************
10595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
10605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         AVRC_PassCmd
10615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
10625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Send a PASS THROUGH command to the peer device.  This
10635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  function can only be called for controller role connections.
10645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  Any response message from the peer is passed back through
10655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  the tAVRC_MSG_CBACK callback function.
10665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
10675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  Input Parameters:
10685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                      handle: Handle of this connection.
10695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
10705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                      label: Transaction label.
10715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
10725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                      p_msg: Pointer to PASS THROUGH message structure.
10735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
10745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  Output Parameters:
10755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                      None.
10765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
10775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          AVRC_SUCCESS if successful.
10785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  AVRC_BAD_HANDLE if handle is invalid.
10795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
10805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project******************************************************************************/
10815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjectUINT16 AVRC_PassCmd(UINT8 handle, UINT8 label, tAVRC_MSG_PASS *p_msg)
10825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
10835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BT_HDR *p_buf;
1084181932fad8b91dc6831222e5b616574c39a21565Sharvil Nanavati    assert(p_msg != NULL);
10855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_msg)
10865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
10875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_msg->hdr.ctype    = AVRC_CMD_CTRL;
10885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_buf = avrc_pass_msg(p_msg);
10895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_buf)
10905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return AVCT_MsgReq( handle, label, AVCT_CMD, p_buf);
10915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
10925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return AVRC_NO_RESOURCES;
10935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
10945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************
10965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
10975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         AVRC_PassRsp
10985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
10995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Send a PASS THROUGH response to the peer device.  This
11005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  function can only be called for target role connections.
11015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  This function must be called when a PASS THROUGH command
11025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  message is received from the peer through the
11035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  tAVRC_MSG_CBACK callback function.
11045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
11055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  Input Parameters:
11065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                      handle: Handle of this connection.
11075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
11085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                      label: Transaction label.  Must be the same value as
11095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                      passed with the command message in the callback function.
11105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
11115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                      p_msg: Pointer to PASS THROUGH message structure.
11125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
11135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  Output Parameters:
11145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                      None.
11155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
11165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          AVRC_SUCCESS if successful.
11175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  AVRC_BAD_HANDLE if handle is invalid.
11185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
11195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project******************************************************************************/
11205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjectUINT16 AVRC_PassRsp(UINT8 handle, UINT8 label, tAVRC_MSG_PASS *p_msg)
11215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
11225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BT_HDR *p_buf;
1123181932fad8b91dc6831222e5b616574c39a21565Sharvil Nanavati    assert(p_msg != NULL);
11245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_msg)
11255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
11265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_buf = avrc_pass_msg(p_msg);
11275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_buf)
11285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return AVCT_MsgReq( handle, label, AVCT_RSP, p_buf);
11295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
11305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return AVRC_NO_RESOURCES;
11315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
11325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1133