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 ******************************************************************************/
245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <string.h>
255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "gki.h"
275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "avrc_api.h"
285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "avrc_int.h"
295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "wcassert.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
385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic const UINT8 avrc_ctrl_event_map[] =
395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    AVRC_OPEN_IND_EVT,  /* AVCT_CONNECT_CFM_EVT */
415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    AVRC_OPEN_IND_EVT,  /* AVCT_CONNECT_IND_EVT */
425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    AVRC_CLOSE_IND_EVT, /* AVCT_DISCONNECT_CFM_EVT */
435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    AVRC_CLOSE_IND_EVT, /* AVCT_DISCONNECT_IND_EVT */
445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    AVRC_CONG_IND_EVT,  /* AVCT_CONG_IND_EVT */
455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    AVRC_UNCONG_IND_EVT,/* AVCT_UNCONG_IND_EVT */
465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    AVRC_BROWSE_OPEN_IND_EVT,  /* AVCT_BROWSE_CONN_CFM_EVT   */
475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    AVRC_BROWSE_OPEN_IND_EVT,  /* AVCT_BROWSE_CONN_IND_EVT   */
485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    AVRC_BROWSE_CLOSE_IND_EVT, /* AVCT_BROWSE_DISCONN_CFM_EVT */
495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    AVRC_BROWSE_CLOSE_IND_EVT, /* AVCT_BROWSE_DISCONN_IND_EVT */
505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    AVRC_BROWSE_CONG_IND_EVT,  /* AVCT_BROWSE_CONG_IND_EVT    */
515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    AVRC_BROWSE_UNCONG_IND_EVT /* AVCT_BROWSE_UNCONG_IND_EVT  */
525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project};
535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define AVRC_OP_DROP        0xFE    /* use this unused opcode to indication no need to call the callback function */
555738f83aeb59361a0a2eda2460113f6dc919427The 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 */
565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************
585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         avrc_ctrl_cback
605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This is the callback function used by AVCTP to report
625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  received link events.
635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          Nothing.
655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project******************************************************************************/
675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void avrc_ctrl_cback(UINT8 handle, UINT8 event, UINT16 result,
685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                BD_ADDR peer_addr)
695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8   avrc_event;
715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (event <= AVRC_MAX_RCV_CTRL_EVT && avrc_cb.ccb[handle].p_ctrl_cback)
735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        avrc_event = avrc_ctrl_event_map[event];
755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (event == AVCT_CONNECT_CFM_EVT)
765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (result != 0) /* failed */
785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                avrc_event = AVRC_CLOSE_IND_EVT;
795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        (*avrc_cb.ccb[handle].p_ctrl_cback)(handle, avrc_event, result, peer_addr);
815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* else drop the unknown event*/
835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************
865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         avrc_get_data_ptr
885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      If the offset in the received buffer is smaller than required
905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  move the portion of data AVRC cares.
915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          Nothing.
935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project******************************************************************************/
955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic UINT8 * avrc_get_data_ptr(BT_HDR *p_pkt)
965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8   *p_data = (UINT8 *)(p_pkt+1) + p_pkt->offset;
985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int     i, gap;
995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_pkt->offset < AVCT_MSG_OFFSET)
1015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
1025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        gap = AVCT_MSG_OFFSET - p_pkt->offset;
1035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        for(i=p_pkt->len; i>0; i--)
1045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
1055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            *(p_data + i + gap) = *(p_data + i);
1065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
1075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_pkt->offset   += gap;
1085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_data          = (UINT8 *)(p_pkt+1) + p_pkt->offset;
1095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    *p_data         = AVRC_RSP_IMPL_STBL;
1115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return p_data;
1125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
1135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1149adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan#if (AVRC_METADATA_INCLUDED == TRUE)
1159adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan/******************************************************************************
1169adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan**
1179adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan** Function         avrc_prep_end_frag
1189adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan**
1199adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan** Description      This function prepares an end response fragment
1209adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan**
1219adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan** Returns          Nothing.
1229adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan**
1239adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan******************************************************************************/
1249adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajanstatic void avrc_prep_end_frag(UINT8 handle)
1259adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan{
1269adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    tAVRC_FRAG_CB   *p_fcb;
1279adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    BT_HDR  *p_pkt_new;
1289adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    UINT8   *p_data, *p_orig_data;
1299adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    UINT8   rsp_type;
1309adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan
131b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati    AVRC_TRACE_DEBUG ("avrc_prep_end_frag" );
1329adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    p_fcb = &avrc_cb.fcb[handle];
1339adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan
1349adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    /* The response type of the end fragment should be the same as the the PDU of "End Fragment
135247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji    ** Response" Errata: https://www.bluetooth.org/errata/errata_view.cfm?errata_id=4383
136247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji    */
1379adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    p_orig_data = ((UINT8 *)(p_fcb->p_fmsg + 1) + p_fcb->p_fmsg->offset);
1389adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    rsp_type = ((*p_orig_data) & AVRC_CTYPE_MASK);
1399adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan
1409adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    p_pkt_new           = p_fcb->p_fmsg;
1419adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    p_pkt_new->len      -= (AVRC_MAX_CTRL_DATA_LEN - AVRC_VENDOR_HDR_SIZE - AVRC_MIN_META_HDR_SIZE);
1429adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    p_pkt_new->offset   += (AVRC_MAX_CTRL_DATA_LEN - AVRC_VENDOR_HDR_SIZE - AVRC_MIN_META_HDR_SIZE);
1439adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    p_data = (UINT8 *)(p_pkt_new+1) + p_pkt_new->offset;
1449adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    *p_data++       = rsp_type;
1459adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    *p_data++       = (AVRC_SUB_PANEL << AVRC_SUBTYPE_SHIFT);
1469adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    *p_data++       = AVRC_OP_VENDOR;
1479adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    AVRC_CO_ID_TO_BE_STREAM(p_data, AVRC_CO_METADATA);
1489adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    *p_data++       = p_fcb->frag_pdu;
1499adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    *p_data++       = AVRC_PKT_END;
150247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji
1519adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    /* 4=pdu, pkt_type & len */
1529adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    UINT16_TO_BE_STREAM(p_data, (p_pkt_new->len - AVRC_VENDOR_HDR_SIZE - AVRC_MIN_META_HDR_SIZE));
1539adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan}
1549adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan
1559adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan/******************************************************************************
1569adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan**
1579adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan** Function         avrc_send_continue_frag
1589adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan**
1599adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan** Description      This function sends a continue response fragment
1609adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan**
1619adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan** Returns          Nothing.
1629adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan**
1639adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan******************************************************************************/
1649adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajanstatic void avrc_send_continue_frag(UINT8 handle, UINT8 label)
1659adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan{
1669adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    tAVRC_FRAG_CB   *p_fcb;
1679adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    BT_HDR  *p_pkt_old, *p_pkt;
1689adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    UINT8   *p_old, *p_data;
1699adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    UINT8   cr = AVCT_RSP;
1709adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    tAVRC_RSP   rej_rsp;
1719adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan
1729adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    p_fcb = &avrc_cb.fcb[handle];
1739adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    p_pkt = p_fcb->p_fmsg;
1749adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan
175b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati    AVRC_TRACE_DEBUG ("avrc_send_continue_frag len(%d) / AVRC_MAX_CTRL_DATA_LEN", p_pkt->len );
1769adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    if (p_pkt->len > AVRC_MAX_CTRL_DATA_LEN)
1779adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    {
1789adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        p_pkt_old = p_fcb->p_fmsg;
1799adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        p_pkt = (BT_HDR *)GKI_getbuf((UINT16)(AVRC_PACKET_LEN + AVCT_MSG_OFFSET + BT_HDR_SIZE));
1809adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        if (p_pkt)
1819adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        {
1829adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            p_pkt->len          = AVRC_MAX_CTRL_DATA_LEN;
1839adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            p_pkt->offset       = AVCT_MSG_OFFSET;
1849adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            p_pkt->layer_specific = p_pkt_old->layer_specific;
1859adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            p_pkt->event = p_pkt_old->event;
1869adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            p_old = (UINT8 *)(p_pkt_old+1) + p_pkt_old->offset;
1879adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            p_data = (UINT8 *)(p_pkt+1) + p_pkt->offset;
1889adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            memcpy (p_data, p_old, AVRC_MAX_CTRL_DATA_LEN);
1899adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            /* use AVRC continue packet type */
1909adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            p_data += AVRC_VENDOR_HDR_SIZE;
1919adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            p_data++; /* pdu */
1929adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            *p_data++ = AVRC_PKT_CONTINUE;
1939adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            /* 4=pdu, pkt_type & len */
1949adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            UINT16_TO_BE_STREAM(p_data, (AVRC_MAX_CTRL_DATA_LEN - AVRC_VENDOR_HDR_SIZE - 4));
1959adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan
1969adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            /* prepare the left over for as an end fragment */
1979adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            avrc_prep_end_frag (handle);
1989adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        }
1999adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        else
2009adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        {
2019adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            /* use the current GKI buffer to send Internal error status */
2029adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            p_pkt = p_fcb->p_fmsg;
2039adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            p_fcb->p_fmsg = NULL;
2049adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            p_fcb->frag_enabled = FALSE;
205b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati            AVRC_TRACE_ERROR ("AVRC_MsgReq no buffers for fragmentation - send internal error" );
2069adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            p_data = (UINT8 *)(p_pkt+1) + p_pkt->offset;
2079adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            *p_data++ = AVRC_PDU_REQUEST_CONTINUATION_RSP;
2089adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            *p_data++ = 0;
2099adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            UINT16_TO_BE_STREAM(p_data, 0);
2109adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            p_pkt->len = 4;
2119adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            rej_rsp.pdu = AVRC_PDU_REQUEST_CONTINUATION_RSP;
2129adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            rej_rsp.status = AVRC_STS_INTERNAL_ERR;
2139adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            AVRC_BldResponse( handle, (tAVRC_RESPONSE *)&rej_rsp, &p_pkt);
2149adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            cr = AVCT_RSP;
2159adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        }
2169adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    }
2179adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    else
2189adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    {
2199adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        /* end fragment. clean the control block */
2209adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        p_fcb->frag_enabled = FALSE;
2219adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        p_fcb->p_fmsg       = NULL;
2229adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    }
2239adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    AVCT_MsgReq( handle, label, cr, p_pkt);
2249adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan}
2259adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan
2269adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan/******************************************************************************
2279adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan**
2289adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan** Function         avrc_proc_vendor_command
2299adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan**
2309adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan** Description      This function processes received vendor command.
2319adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan**
2329adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan** Returns          if not NULL, the response to send right away.
2339adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan**
2349adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan******************************************************************************/
2359adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajanstatic BT_HDR * avrc_proc_vendor_command(UINT8 handle, UINT8 label,
2369adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                               BT_HDR *p_pkt, tAVRC_MSG_VENDOR *p_msg)
2379adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan{
2389adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    BT_HDR      *p_rsp = NULL;
2399adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    UINT8       *p_data;
2409adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    UINT8       *p_begin;
2419adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    UINT8       pkt_type;
2429adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    BOOLEAN     abort_frag = FALSE;
2439adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    tAVRC_STS   status = AVRC_STS_NO_ERROR;
2449adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    tAVRC_FRAG_CB   *p_fcb;
2459adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan
2469adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    p_begin  = (UINT8 *)(p_pkt+1) + p_pkt->offset;
2479adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    p_data   = p_begin + AVRC_VENDOR_HDR_SIZE;
2489adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    pkt_type = *(p_data + 1) & AVRC_PKT_TYPE_MASK;
2499adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan
2509adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    if (pkt_type != AVRC_PKT_SINGLE)
2519adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    {
2529adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        /* reject - commands can only be in single packets at AVRCP level */
253b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati        AVRC_TRACE_ERROR ("commands must be in single packet pdu:0x%x", *p_data );
2549adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        /* use the current GKI buffer to send the reject */
2559adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        status = AVRC_STS_BAD_CMD;
2569adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    }
2579adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    /* check if there are fragments waiting to be sent */
2589adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    else if (avrc_cb.fcb[handle].frag_enabled)
2599adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    {
2609adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        p_fcb = &avrc_cb.fcb[handle];
2619adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        if (p_msg->company_id == AVRC_CO_METADATA)
2629adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        {
2639adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            switch (*p_data)
2649adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            {
2659adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            case AVRC_PDU_ABORT_CONTINUATION_RSP:
2669adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                /* aborted by CT - send accept response */
2679adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                abort_frag = TRUE;
2689adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                p_begin = (UINT8 *)(p_pkt+1) + p_pkt->offset;
2699adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                *p_begin = (AVRC_RSP_ACCEPT & AVRC_CTYPE_MASK);
2709adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                if (*(p_data + 4) != p_fcb->frag_pdu)
2719adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                {
2729adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                    *p_begin = (AVRC_RSP_REJ & AVRC_CTYPE_MASK);
2739adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                    *(p_data + 4) = AVRC_STS_BAD_PARAM;
2749adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                }
2759adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                else
2769adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                {
2779adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                    p_data = (p_begin + AVRC_VENDOR_HDR_SIZE + 2);
2789adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                    UINT16_TO_BE_STREAM(p_data, 0);
2799adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                    p_pkt->len = (p_data - p_begin);
2809adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                }
2819adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                AVCT_MsgReq( handle, label, AVCT_RSP, p_pkt);
2829adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                p_msg->hdr.opcode = AVRC_OP_DROP; /* used the p_pkt to send response */
2839adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                break;
2849adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan
2859adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            case AVRC_PDU_REQUEST_CONTINUATION_RSP:
2869adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                if (*(p_data + 4) == p_fcb->frag_pdu)
2879adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                {
2889adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                    avrc_send_continue_frag(handle, label);
2899adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                    p_msg->hdr.opcode = AVRC_OP_DROP_N_FREE;
2909adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                }
2919adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                else
2929adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                {
2939adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                    /* the pdu id does not match - reject the command using the current GKI buffer */
294b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati                    AVRC_TRACE_ERROR("avrc_proc_vendor_command continue pdu: 0x%x does not match \
2959adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                    current re-assembly pdu: 0x%x",
2969adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                        *(p_data + 4), p_fcb->frag_pdu);
2979adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                    status = AVRC_STS_BAD_PARAM;
2989adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                    abort_frag = TRUE;
2999adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                }
3009adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                break;
3019adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan
3029adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            default:
3039adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                /* implicit abort */
3049adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                abort_frag = TRUE;
3059adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            }
3069adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        }
3079adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        else
3089adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        {
3099adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            abort_frag = TRUE;
3109adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            /* implicit abort */
3119adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        }
3129adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan
3139adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        if (abort_frag)
3149adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        {
3159adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            if (p_fcb->p_fmsg)
3169adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                GKI_freebuf(p_fcb->p_fmsg);
3179adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            p_fcb->p_fmsg = NULL;
3189adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            p_fcb->frag_enabled = FALSE;
3199adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        }
3209adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    }
3219adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan
3229adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    if (status != AVRC_STS_NO_ERROR)
3239adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    {
3249adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        /* use the current GKI buffer to build/send the reject message */
3259adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        p_data = (UINT8 *)(p_pkt+1) + p_pkt->offset;
3269adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        *p_data++ = AVRC_RSP_REJ;
3279adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        p_data += AVRC_VENDOR_HDR_SIZE; /* pdu */
3289adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        *p_data++ = 0;                  /* pkt_type */
3299adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        UINT16_TO_BE_STREAM(p_data, 1); /* len */
3309adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        *p_data++ = status;             /* error code */
3319adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        p_pkt->len = AVRC_VENDOR_HDR_SIZE + 5;
3329adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        p_rsp = p_pkt;
3339adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    }
3349adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan
3359adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    return p_rsp;
3369adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan}
3379adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan
3389adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan/******************************************************************************
3399adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan**
3409adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan** Function         avrc_proc_far_msg
3419adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan**
342247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji** Description      This function processes metadata fragmenation
3439adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan**                  and reassembly
3449adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan**
3459adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan** Returns          0, to report the message with msg_cback .
3469adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan**
3479adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan******************************************************************************/
3489adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajanstatic UINT8 avrc_proc_far_msg(UINT8 handle, UINT8 label, UINT8 cr, BT_HDR **pp_pkt,
3499adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    tAVRC_MSG_VENDOR *p_msg)
3509adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan{
3519adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    BT_HDR      *p_pkt = *pp_pkt;
3529adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    UINT8       *p_data;
3539adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    BOOLEAN     drop = FALSE;
3549adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    BT_HDR      *p_rsp = NULL;
3559adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    BT_HDR      *p_cmd = NULL;
3569adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    BOOLEAN     req_continue = FALSE;
3579adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    BT_HDR      *p_pkt_new = NULL;
3589adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    UINT8       pkt_type;
3599adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    UINT16      buf_len;
3609adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    tAVRC_RASM_CB   *p_rcb;
3619adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    tAVRC_NEXT_CMD   avrc_cmd;
3629adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan
3639adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    p_data  = (UINT8 *)(p_pkt+1) + p_pkt->offset;
364247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji
365247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji    /* Skip over vendor header (ctype, subunit*, opcode, CO_ID) */
366247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji    p_data += AVRC_VENDOR_HDR_SIZE;
367247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji
3689adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    pkt_type = *(p_data + 1) & AVRC_PKT_TYPE_MASK;
369b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati    AVRC_TRACE_DEBUG ("pkt_type %d", pkt_type );
3709adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    p_rcb = &avrc_cb.rcb[handle];
3719adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    if (p_msg->company_id == AVRC_CO_METADATA)
3729adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    {
3739adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        /* check if the message needs to be re-assembled */
3749adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        if (pkt_type == AVRC_PKT_SINGLE || pkt_type == AVRC_PKT_START)
3759adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        {
3769adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            /* previous fragments need to be dropped, when received another new message */
3779adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            p_rcb->rasm_offset = 0;
3789adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            if (p_rcb->p_rmsg)
3799adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            {
3809adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                GKI_freebuf(p_rcb->p_rmsg);
3819adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                p_rcb->p_rmsg = NULL;
3829adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            }
3839adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        }
3849adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan
3859adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        if (pkt_type != AVRC_PKT_SINGLE && cr == AVCT_RSP)
3869adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        {
3879adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            /* not a single response packet - need to re-assemble metadata messages */
3889adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            if (pkt_type == AVRC_PKT_START)
3899adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            {
390247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji                /* Allocate buffer for re-assembly */
391247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji                p_rcb->rasm_pdu = *p_data;
392247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji                if ((p_rcb->p_rmsg = (BT_HDR *)GKI_getbuf(GKI_MAX_BUF_SIZE)) != NULL)
393247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji                {
394247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji                    /* Copy START packet to buffer for re-assembling fragments*/
395247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji                    memcpy(p_rcb->p_rmsg, p_pkt, sizeof(BT_HDR));   /* Copy bt hdr */
396247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji
397247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji                    /* Copy metadata message */
398247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji                    memcpy((UINT8 *)(p_rcb->p_rmsg + 1),
399247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji                           (UINT8 *)(p_pkt+1) + p_pkt->offset, p_pkt->len);
400247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji
401247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji                    /* offset of start of metadata response in reassembly buffer */
402247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji                    p_rcb->p_rmsg->offset = p_rcb->rasm_offset = 0;
403247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji
404247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji                    /* Free original START packet, replace with pointer to reassembly buffer  */
405247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji                    GKI_freebuf(p_pkt);
406247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji                    *pp_pkt = p_rcb->p_rmsg;
407247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji                }
408247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji                else
409247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji                {
410247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji                    /* Unable to allocate buffer for fragmented avrc message. Reuse START
411247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji                                      buffer for reassembly (re-assembled message may fit into ACL buf) */
412b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati                    AVRC_TRACE_DEBUG ("Unable to allocate buffer for fragmented avrc message, \
413247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji                                       reusing START buffer for reassembly");
414247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji                    p_rcb->rasm_offset = p_pkt->offset;
415247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji                    p_rcb->p_rmsg = p_pkt;
416247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji                }
417247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji
4189adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                /* set offset to point to where to copy next - use the same re-asm logic as AVCT */
4199adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                p_rcb->p_rmsg->offset += p_rcb->p_rmsg->len;
4209adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                req_continue = TRUE;
4219adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            }
422247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji            else if (p_rcb->p_rmsg == NULL)
423247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji            {
424247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji                /* Received a CONTINUE/END, but no corresponding START
425247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji                              (or previous fragmented response was dropped) */
426b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati                AVRC_TRACE_DEBUG ("Received a CONTINUE/END without no corresponding START \
427247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji                                   (or previous fragmented response was dropped)");
428247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji                drop = 5;
429247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji                GKI_freebuf(p_pkt);
430247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji                *pp_pkt = NULL;
431247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji            }
4329adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            else
4339adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            {
4349adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                /* get size of buffer holding assembled message */
4359adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                buf_len = GKI_get_buf_size (p_rcb->p_rmsg) - sizeof(BT_HDR);
4369adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                /* adjust offset and len of fragment for header byte */
4379adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                p_pkt->offset += (AVRC_VENDOR_HDR_SIZE + AVRC_MIN_META_HDR_SIZE);
4389adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                p_pkt->len -= (AVRC_VENDOR_HDR_SIZE + AVRC_MIN_META_HDR_SIZE);
4399adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                /* verify length */
4409adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                if ((p_rcb->p_rmsg->offset + p_pkt->len) > buf_len)
4419adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                {
442b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati                    AVRC_TRACE_WARNING("Fragmented message too big! - report the partial message");
4439adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                    p_pkt->len = buf_len - p_rcb->p_rmsg->offset;
4449adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                    pkt_type = AVRC_PKT_END;
4459adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                }
4469adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan
4479adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                /* copy contents of p_pkt to p_rx_msg */
4489adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                memcpy((UINT8 *)(p_rcb->p_rmsg + 1) + p_rcb->p_rmsg->offset,
4499adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                       (UINT8 *)(p_pkt + 1) + p_pkt->offset, p_pkt->len);
4509adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan
4519adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                if (pkt_type == AVRC_PKT_END)
4529adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                {
4539adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                    p_rcb->p_rmsg->offset = p_rcb->rasm_offset;
4549adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                    p_rcb->p_rmsg->len += p_pkt->len;
4559adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                    p_pkt_new = p_rcb->p_rmsg;
4569adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                    p_rcb->rasm_offset = 0;
4579adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                    p_rcb->p_rmsg = NULL;
4589adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                    p_msg->p_vendor_data   = (UINT8 *)(p_pkt_new+1) + p_pkt_new->offset;
4599adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                    p_msg->hdr.ctype       = p_msg->p_vendor_data[0] & AVRC_CTYPE_MASK;
4609adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                    /* 6 = ctype, subunit*, opcode & CO_ID */
4619adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                    p_msg->p_vendor_data  += AVRC_VENDOR_HDR_SIZE;
4629adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                    p_msg->vendor_len      = p_pkt_new->len - AVRC_VENDOR_HDR_SIZE;
4639adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                    p_data = p_msg->p_vendor_data + 1; /* skip pdu */
4649adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                    *p_data++ = AVRC_PKT_SINGLE;
4659adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                    UINT16_TO_BE_STREAM(p_data, (p_msg->vendor_len - AVRC_MIN_META_HDR_SIZE));
466b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati                    AVRC_TRACE_DEBUG("end frag:%d, total len:%d, offset:%d", p_pkt->len,
4679adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                        p_pkt_new->len, p_pkt_new->offset);
4689adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                }
4699adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                else
4709adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                {
4719adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                    p_rcb->p_rmsg->offset += p_pkt->len;
4729adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                    p_rcb->p_rmsg->len += p_pkt->len;
4739adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                    p_pkt_new = NULL;
4749adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                    req_continue = TRUE;
4759adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                }
4769adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                GKI_freebuf(p_pkt);
4779adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                *pp_pkt = p_pkt_new;
4789adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            }
4799adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        }
4809adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan
4819adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        if (cr == AVCT_CMD)
4829adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        {
4839adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            p_rsp = avrc_proc_vendor_command(handle, label, *pp_pkt, p_msg);
4849adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            if (p_rsp)
4859adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            {
4869adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                AVCT_MsgReq( handle, label, AVCT_RSP, p_rsp);
4879adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                drop = 3;
4889adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            }
4899adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            else if (p_msg->hdr.opcode == AVRC_OP_DROP)
4909adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            {
4919adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                drop = 1;
4929adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            }
4939adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            else if (p_msg->hdr.opcode == AVRC_OP_DROP_N_FREE)
4949adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                drop = 4;
4959adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan
4969adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        }
497247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji        else if (cr == AVCT_RSP && req_continue == TRUE)
498247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji        {
499247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji            avrc_cmd.pdu    = AVRC_PDU_REQUEST_CONTINUATION_RSP;
500247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji            avrc_cmd.status = AVRC_STS_NO_ERROR;
501247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji            avrc_cmd.target_pdu = p_rcb->rasm_pdu;
502247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji            if (AVRC_BldCommand ((tAVRC_COMMAND *)&avrc_cmd, &p_cmd) == AVRC_STS_NO_ERROR)
503247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji            {
504247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji                drop = 2;
505247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji                AVRC_MsgReq (handle, (UINT8)(label), AVRC_CMD_CTRL, p_cmd);
506247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji            }
507247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji        }
5089adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    }
509247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji
5109adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    return drop;
5119adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan}
5129adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan#endif /* (AVRC_METADATA_INCLUDED == TRUE) */
5135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************
5155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         avrc_msg_cback
5175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This is the callback function used by AVCTP to report
5195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  received AV control messages.
5205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          Nothing.
5225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project******************************************************************************/
5245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void avrc_msg_cback(UINT8 handle, UINT8 label, UINT8 cr,
5255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                               BT_HDR *p_pkt)
5265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
5275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8       opcode;
5285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tAVRC_MSG   msg;
5295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8       *p_data;
5305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8       *p_begin;
5316dae552ef8d82b30fa66efab9c6f75644a805bbeSharvil Nanavati    UINT8       drop = 0;
5325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BOOLEAN     free = TRUE;
5335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BT_HDR      *p_rsp = NULL;
5345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8       *p_rsp_data;
5355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int         xx;
5365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BOOLEAN     reject = FALSE;
5375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (BT_USE_TRACES == TRUE)
5385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    char        *p_drop_msg = "dropped";
5395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
5405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tAVRC_MSG_VENDOR *p_msg = &msg.vendor;
5415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (cr == AVCT_CMD &&
5435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        (p_pkt->layer_specific & AVCT_DATA_CTRL && AVRC_PACKET_LEN < sizeof(p_pkt->len)))
5445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
5455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* Ignore the invalid AV/C command frame */
5465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (BT_USE_TRACES == TRUE)
5475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_drop_msg = "dropped - too long AV/C cmd frame size";
5485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
5495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        GKI_freebuf(p_pkt);
5505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
5515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
5525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (cr == AVCT_REJ)
5545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
5555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* The peer thinks that this PID is no longer open - remove this handle */
5565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /*  */
5575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        GKI_freebuf(p_pkt);
5585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        AVCT_RemoveConn(handle);
5595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
5605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
5615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_data  = (UINT8 *)(p_pkt+1) + p_pkt->offset;
5635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    memset(&msg, 0, sizeof(tAVRC_MSG) );
5645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
5655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        msg.hdr.ctype           = p_data[0] & AVRC_CTYPE_MASK;
566b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati        AVRC_TRACE_DEBUG("avrc_msg_cback handle:%d, ctype:%d, offset:%d, len: %d",
5675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                handle, msg.hdr.ctype, p_pkt->offset, p_pkt->len);
5685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        msg.hdr.subunit_type    = (p_data[1] & AVRC_SUBTYPE_MASK) >> AVRC_SUBTYPE_SHIFT;
5695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        msg.hdr.subunit_id      = p_data[1] & AVRC_SUBID_MASK;
5705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        opcode                  = p_data[2];
5715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
5725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ( ((avrc_cb.ccb[handle].control & AVRC_CT_TARGET) && (cr == AVCT_CMD)) ||
5745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        ((avrc_cb.ccb[handle].control & AVRC_CT_CONTROL) && (cr == AVCT_RSP)) )
5755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
5765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        switch(opcode)
5785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
5795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        case AVRC_OP_UNIT_INFO:
5805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (cr == AVCT_CMD)
5815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
5825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                /* send the response to the peer */
5835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_rsp           = p_pkt; /* this also sets free = FALSE, drop = TRUE */
5845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                /* check & set the offset. set response code, set subunit_type & subunit_id,
5855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                   set AVRC_OP_UNIT_INFO */
5869adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                /* 3 bytes: ctype, subunit*, opcode */
5879adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                p_rsp_data      = avrc_get_data_ptr(p_pkt) + AVRC_AVC_HDR_SIZE;
5885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                *p_rsp_data++   = 7;
5895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                /* Panel subunit & id=0 */
5905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                *p_rsp_data++   = (AVRC_SUB_PANEL << AVRC_SUBTYPE_SHIFT);
5915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                AVRC_CO_ID_TO_BE_STREAM(p_rsp_data, avrc_cb.ccb[handle].company_id);
5925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_rsp->len      = (UINT16) (p_rsp_data - (UINT8 *)(p_rsp + 1) - p_rsp->offset);
5935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                cr = AVCT_RSP;
5945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (BT_USE_TRACES == TRUE)
5955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_drop_msg = "auto respond";
5965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
5975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
5985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            else
5995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
6005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                /* parse response */
6015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_data += 4; /* 3 bytes: ctype, subunit*, opcode + octet 3 (is 7)*/
6025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                msg.unit.unit_type  = (*p_data & AVRC_SUBTYPE_MASK) >> AVRC_SUBTYPE_SHIFT;
6035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                msg.unit.unit       = *p_data & AVRC_SUBID_MASK;
6045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_data++;
6055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                AVRC_BE_STREAM_TO_CO_ID(msg.unit.company_id, p_data);
6065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
6075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            break;
6085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        case AVRC_OP_SUB_INFO:
6105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (cr == AVCT_CMD)
6115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
6125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                /* send the response to the peer */
6135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_rsp           = p_pkt; /* this also sets free = FALSE, drop = TRUE */
6145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                /* check & set the offset. set response code, set (subunit_type & subunit_id),
6155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                   set AVRC_OP_SUB_INFO, set (page & extention code) */
6165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_rsp_data      = avrc_get_data_ptr(p_pkt) + 4;
6175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                /* Panel subunit & id=0 */
6185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                *p_rsp_data++   = (AVRC_SUB_PANEL << AVRC_SUBTYPE_SHIFT);
6195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                memset(p_rsp_data, AVRC_CMD_OPRND_PAD, AVRC_SUBRSP_OPRND_BYTES);
6205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_rsp_data      += AVRC_SUBRSP_OPRND_BYTES;
6215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_rsp->len      = (UINT16) (p_rsp_data - (UINT8 *)(p_rsp + 1) - p_rsp->offset);
6225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                cr = AVCT_RSP;
6235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (BT_USE_TRACES == TRUE)
6245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_drop_msg = "auto responded";
6255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
6265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
6275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            else
6285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
6295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                /* parse response */
6305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_data += AVRC_AVC_HDR_SIZE; /* 3 bytes: ctype, subunit*, opcode */
6315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                msg.sub.page    = (*p_data++ >> AVRC_SUB_PAGE_SHIFT) & AVRC_SUB_PAGE_MASK;
6325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                xx      = 0;
6335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                while (*p_data != AVRC_CMD_OPRND_PAD && xx<AVRC_SUB_TYPE_LEN)
6345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
6355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    msg.sub.subunit_type[xx] = *p_data++ >> AVRC_SUBTYPE_SHIFT;
6365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    if (msg.sub.subunit_type[xx] == AVRC_SUB_PANEL)
6375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        msg.sub.panel   = TRUE;
6385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    xx++;
6395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
6405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
6415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            break;
6425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        case AVRC_OP_VENDOR:
6445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_data  = (UINT8 *)(p_pkt+1) + p_pkt->offset;
6455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_begin = p_data;
6465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (p_pkt->len < AVRC_VENDOR_HDR_SIZE) /* 6 = ctype, subunit*, opcode & CO_ID */
6475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
6485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                if (cr == AVCT_CMD)
6495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    reject = TRUE;
6505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                else
6515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    drop = TRUE;
6525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                break;
6535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
6545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_data += AVRC_AVC_HDR_SIZE; /* skip the first 3 bytes: ctype, subunit*, opcode */
6555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            AVRC_BE_STREAM_TO_CO_ID(p_msg->company_id, p_data);
6565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_msg->p_vendor_data   = p_data;
6575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_msg->vendor_len      = p_pkt->len - (p_data - p_begin);
6585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6599adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan#if (AVRC_METADATA_INCLUDED == TRUE)
660247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji            if (p_msg->company_id == AVRC_CO_METADATA)
661247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji            {
662247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji                /* Validate length for metadata message */
663247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji                if (p_pkt->len < (AVRC_VENDOR_HDR_SIZE + AVRC_MIN_META_HDR_SIZE))
664247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji                {
665247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji                    if (cr == AVCT_CMD)
666247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji                        reject = TRUE;
667247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji                    else
668247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji                        drop = TRUE;
669247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji                    break;
670247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji                }
671247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji
672247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji                /* Check+handle fragmented messages */
673247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji                drop = avrc_proc_far_msg(handle, label, cr, &p_pkt, p_msg);
674247c68fe6eee3660cbdcf4509195fe735ae25573Satya Calloji            }
6759adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            if (drop)
6769adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            {
6779adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                free = FALSE;
6789adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                if (drop == 4)
6799adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                    free = TRUE;
6809adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan#if (BT_USE_TRACES == TRUE)
6819adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                switch (drop)
6829adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                {
6839adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                case 1:
6849adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                    p_drop_msg = "sent_frag";
6859adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                    break;
6869adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                case 2:
6879adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                    p_drop_msg = "req_cont";
6889adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                    break;
6899adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                case 3:
6909adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                    p_drop_msg = "sent_frag3";
6919adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                    break;
6929adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                case 4:
6939adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                    p_drop_msg = "sent_frag_free";
6949adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                    break;
6959adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                default:
6969adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                    p_drop_msg = "sent_fragd";
6979adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                }
6989adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan#endif
6999adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            }
7009adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan#endif /* (AVRC_METADATA_INCLUDED == TRUE) */
7015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            break;
7025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        case AVRC_OP_PASS_THRU:
7045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (p_pkt->len < 5) /* 3 bytes: ctype, subunit*, opcode & op_id & len */
7055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
7065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                if (cr == AVCT_CMD)
7075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    reject = TRUE;
7085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                else
7095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    drop = TRUE;
7105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                break;
7115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
7125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_data += AVRC_AVC_HDR_SIZE; /* skip the first 3 bytes: ctype, subunit*, opcode */
7135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            msg.pass.op_id  = (AVRC_PASS_OP_ID_MASK & *p_data);
7145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (AVRC_PASS_STATE_MASK & *p_data)
7155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                msg.pass.state  = TRUE;
7165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            else
7175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                msg.pass.state  = FALSE;
7185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_data++;
7195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            msg.pass.pass_len    = *p_data++;
7205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (msg.pass.pass_len != p_pkt->len - 5)
7215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                msg.pass.pass_len = p_pkt->len - 5;
7225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (msg.pass.pass_len)
7235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                msg.pass.p_pass_data = p_data;
7245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            else
7255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                msg.pass.p_pass_data = NULL;
7265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            break;
7275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        default:
7305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if ((avrc_cb.ccb[handle].control & AVRC_CT_TARGET) && (cr == AVCT_CMD))
7315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
7325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                /* reject unsupported opcode */
7335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                reject = TRUE;
7345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
7355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            drop    = TRUE;
7365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            break;
7375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
7385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
7395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else /* drop the event */
7405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
7415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            drop    = TRUE;
7425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
7435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (reject)
7455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
7465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* reject unsupported opcode */
7475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_rsp           = p_pkt; /* this also sets free = FALSE, drop = TRUE */
7485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_rsp_data      = avrc_get_data_ptr(p_pkt);
7495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        *p_rsp_data     = AVRC_RSP_REJ;
7505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (BT_USE_TRACES == TRUE)
7515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_drop_msg = "rejected";
7525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
7535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        cr      = AVCT_RSP;
7545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        drop    = TRUE;
7555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
7565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_rsp)
7585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
7595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* set to send response right away */
7605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        AVCT_MsgReq( handle, label, cr, p_rsp);
7615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        free = FALSE;
7625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        drop = TRUE;
7635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
7645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (drop == FALSE)
7665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
7675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        msg.hdr.opcode = opcode;
7685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        (*avrc_cb.ccb[handle].p_msg_cback)(handle, label, opcode, &msg);
7695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
7705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (BT_USE_TRACES == TRUE)
7715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
7725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
773b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati        AVRC_TRACE_WARNING("avrc_msg_cback %s msg handle:%d, control:%d, cr:%d, opcode:x%x",
7745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_drop_msg,
7755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                handle, avrc_cb.ccb[handle].control, cr, opcode);
7765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
7775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
7785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (free)
7815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        GKI_freebuf(p_pkt);
7825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
7835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************
7885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
7895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         avrc_pass_msg
7905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
7915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Compose a PASS THROUGH command according to p_msg
7925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
7935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  Input Parameters:
7945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                      p_msg: Pointer to PASS THROUGH message structure.
7955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
7965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  Output Parameters:
7975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                      None.
7985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
7995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          pointer to a valid GKI buffer if successful.
8005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  NULL if p_msg is NULL.
8015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
8025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project******************************************************************************/
8035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic BT_HDR  * avrc_pass_msg(tAVRC_MSG_PASS *p_msg)
8045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
8055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BT_HDR  *p_cmd = NULL;
8065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8   *p_data;
8075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    WC_ASSERT(p_msg != NULL);
8095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    WC_ASSERT(AVRC_CMD_POOL_SIZE > (AVRC_MIN_CMD_LEN+p_msg->pass_len));
8105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((p_cmd = (BT_HDR *) GKI_getpoolbuf(AVRC_CMD_POOL_ID)) != NULL)
8125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
8135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_cmd->offset   = AVCT_MSG_OFFSET;
8145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_cmd->layer_specific   = AVCT_DATA_CTRL;
8155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_data          = (UINT8 *)(p_cmd + 1) + p_cmd->offset;
8165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        *p_data++       = (p_msg->hdr.ctype & AVRC_CTYPE_MASK);
8175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        *p_data++       = (AVRC_SUB_PANEL << AVRC_SUBTYPE_SHIFT); /* Panel subunit & id=0 */
8185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        *p_data++       = AVRC_OP_PASS_THRU;
8195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        *p_data         = (AVRC_PASS_OP_ID_MASK&p_msg->op_id);
8205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_msg->state)
8215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            *p_data     |= AVRC_PASS_STATE_MASK;
8225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_data++;
8235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_msg->op_id == AVRC_ID_VENDOR)
8255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
8265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            *p_data++       = p_msg->pass_len;
8275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (p_msg->pass_len && p_msg->p_pass_data)
8285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
8295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                memcpy(p_data, p_msg->p_pass_data, p_msg->pass_len);
8305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_data += p_msg->pass_len;
8315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
8325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
8335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else /* set msg len to 0 for other op_id */
8345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
8355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* set msg len to 0 for other op_id */
8365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            *p_data++       = 0;
8375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
8385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_cmd->len      = (UINT16) (p_data - (UINT8 *)(p_cmd + 1) - p_cmd->offset);
8395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
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    BT_HDR  *p_pkt_new;
9659adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan
9669adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    if (!p_pkt)
9679adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        return AVRC_BAD_PARAM;
9689adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan
9699adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    if (ctype >= AVRC_RSP_NOT_IMPL)
9709adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        cr = AVCT_RSP;
9719adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan
9729adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    if (p_pkt->event == AVRC_OP_VENDOR)
9739adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    {
9749adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        /* add AVRCP Vendor Dependent headers */
9759adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        p_start = ((UINT8 *)(p_pkt + 1) + p_pkt->offset);
9769adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        p_pkt->offset -= AVRC_VENDOR_HDR_SIZE;
9779adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        p_pkt->len += AVRC_VENDOR_HDR_SIZE;
9789adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        p_data = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
9799adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        *p_data++       = (ctype & AVRC_CTYPE_MASK);
9809adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        *p_data++       = (AVRC_SUB_PANEL << AVRC_SUBTYPE_SHIFT);
9819adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        *p_data++       = AVRC_OP_VENDOR;
9829adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        AVRC_CO_ID_TO_BE_STREAM(p_data, AVRC_CO_METADATA);
9839adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    }
9849adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    else if (p_pkt->event == AVRC_OP_PASS_THRU)
9859adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    {
9869adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        /* add AVRCP Pass Through headers */
9879adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        p_start = ((UINT8 *)(p_pkt + 1) + p_pkt->offset);
9889adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        p_pkt->offset -= AVRC_PASS_THRU_SIZE;
9899adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        p_pkt->len += AVRC_PASS_THRU_SIZE;
9909adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        p_data = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
9919adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        *p_data++       = (ctype & AVRC_CTYPE_MASK);
9929adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        *p_data++       = (AVRC_SUB_PANEL << AVRC_SUBTYPE_SHIFT);
9939adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        *p_data++       = AVRC_OP_PASS_THRU;/* opcode */
9949adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        *p_data++       = AVRC_ID_VENDOR;   /* operation id */
9959adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        *p_data++       = 5;                /* operation data len */
9969adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        AVRC_CO_ID_TO_BE_STREAM(p_data, AVRC_CO_METADATA);
9979adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    }
9989adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan
9999adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    /* abandon previous fragments */
10009adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    p_fcb = &avrc_cb.fcb[handle];
10019adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    if (p_fcb->frag_enabled)
10029adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        p_fcb->frag_enabled = FALSE;
10039adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan
10049adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    if (p_fcb->p_fmsg)
10059adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    {
10069adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        GKI_freebuf(p_fcb->p_fmsg);
10079adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        p_fcb->p_fmsg = NULL;
10089adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    }
10099adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan
10109adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    /* AVRCP spec has not defined any control channel commands that needs fragmentation at this level
10119adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan     * check for fragmentation only on the response */
10129adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    if ((cr == AVCT_RSP) && (chk_frag == TRUE))
10139adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    {
10149adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        if (p_pkt->len > AVRC_MAX_CTRL_DATA_LEN)
10159adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        {
1016b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati            AVRC_TRACE_DEBUG ("p_pkt->len(%d) > AVRC_MAX_CTRL_DATA_LEN", p_pkt->len );
10179adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            p_pkt_new = (BT_HDR *)GKI_getbuf((UINT16)(AVRC_PACKET_LEN + AVCT_MSG_OFFSET
10189adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                + BT_HDR_SIZE));
10199adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            if (p_pkt_new)
10209adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            {
10219adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                p_fcb->frag_enabled = TRUE;
10229adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                p_fcb->p_fmsg       = p_pkt;
10239adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                p_fcb->frag_pdu     = *p_start;
10249adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                p_pkt               = p_pkt_new;
10259adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                p_pkt_new           = p_fcb->p_fmsg;
10269adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                p_pkt->len          = AVRC_MAX_CTRL_DATA_LEN;
10279adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                p_pkt->offset       = p_pkt_new->offset;
10289adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                p_pkt->layer_specific = p_pkt_new->layer_specific;
10299adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                p_pkt->event = p_pkt_new->event;
10309adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                p_data = (UINT8 *)(p_pkt+1) + p_pkt->offset;
10319adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                p_start -= AVRC_VENDOR_HDR_SIZE;
10329adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                memcpy (p_data, p_start, AVRC_MAX_CTRL_DATA_LEN);
10339adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                /* use AVRC start packet type */
10349adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                p_data += AVRC_VENDOR_HDR_SIZE;
10359adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                p_data++; /* pdu */
10369adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                *p_data++ = AVRC_PKT_START;
10379adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                /* 4 pdu, pkt_type & len */
10389adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                len = (AVRC_MAX_CTRL_DATA_LEN - AVRC_VENDOR_HDR_SIZE - AVRC_MIN_META_HDR_SIZE);
10399adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                UINT16_TO_BE_STREAM(p_data, len);
10409adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan
10419adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                /* prepare the left over for as an end fragment */
10429adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                avrc_prep_end_frag (handle);
1043b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati                AVRC_TRACE_DEBUG ("p_pkt len:%d/%d, next len:%d", p_pkt->len, len, p_fcb->p_fmsg->len );
10449adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            }
10459adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            else
10469adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan            {
1047b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati                AVRC_TRACE_ERROR ("AVRC_MsgReq no buffers for fragmentation" );
10489adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan                GKI_freebuf(p_pkt);
10495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return AVRC_NO_RESOURCES;
10505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
10519adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan        }
10529adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    }
10539adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan
10549adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    return AVCT_MsgReq( handle, label, cr, p_pkt);
10559adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan#else
10569adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan    return AVRC_NO_RESOURCES;
10579adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan#endif
10589adddf4965e9ddb01e339b934c343fcbd842a977Ravi Nagarajan}
10595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************
10625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
10635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         AVRC_PassCmd
10645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
10655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Send a PASS THROUGH command to the peer device.  This
10665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  function can only be called for controller role connections.
10675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  Any response message from the peer is passed back through
10685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  the tAVRC_MSG_CBACK callback function.
10695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
10705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  Input Parameters:
10715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                      handle: Handle of this connection.
10725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
10735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                      label: Transaction label.
10745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
10755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                      p_msg: Pointer to PASS THROUGH message structure.
10765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
10775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  Output Parameters:
10785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                      None.
10795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
10805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          AVRC_SUCCESS if successful.
10815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  AVRC_BAD_HANDLE if handle is invalid.
10825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
10835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project******************************************************************************/
10845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjectUINT16 AVRC_PassCmd(UINT8 handle, UINT8 label, tAVRC_MSG_PASS *p_msg)
10855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
10865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BT_HDR *p_buf;
10875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    WC_ASSERT(p_msg != NULL);
10885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_msg)
10895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
10905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_msg->hdr.ctype    = AVRC_CMD_CTRL;
10915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_buf = avrc_pass_msg(p_msg);
10925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_buf)
10935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return AVCT_MsgReq( handle, label, AVCT_CMD, p_buf);
10945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
10955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return AVRC_NO_RESOURCES;
10965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
10975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************
10995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
11005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         AVRC_PassRsp
11015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
11025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Send a PASS THROUGH response to the peer device.  This
11035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  function can only be called for target role connections.
11045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  This function must be called when a PASS THROUGH command
11055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  message is received from the peer through the
11065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  tAVRC_MSG_CBACK callback function.
11075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
11085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  Input Parameters:
11095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                      handle: Handle of this connection.
11105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
11115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                      label: Transaction label.  Must be the same value as
11125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                      passed with the command message in the callback function.
11135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
11145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                      p_msg: Pointer to PASS THROUGH message structure.
11155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
11165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  Output Parameters:
11175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                      None.
11185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
11195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          AVRC_SUCCESS if successful.
11205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  AVRC_BAD_HANDLE if handle is invalid.
11215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
11225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project******************************************************************************/
11235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjectUINT16 AVRC_PassRsp(UINT8 handle, UINT8 label, tAVRC_MSG_PASS *p_msg)
11245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
11255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BT_HDR *p_buf;
11265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    WC_ASSERT(p_msg != NULL);
11275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_msg)
11285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
11295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_buf = avrc_pass_msg(p_msg);
11305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_buf)
11315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return AVCT_MsgReq( handle, label, AVCT_RSP, p_buf);
11325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
11335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return AVRC_NO_RESOURCES;
11345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
11355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1136