btif_rc.c revision 7850a939f3c33a0bada9b9e2cd335189614a5ef9
105436638acc7c010349a69c3395f1a57c642dc62Ying Wang/******************************************************************************
205436638acc7c010349a69c3395f1a57c642dc62Ying Wang *
305436638acc7c010349a69c3395f1a57c642dc62Ying Wang *  Copyright (C) 2009-2012 Broadcom Corporation
405436638acc7c010349a69c3395f1a57c642dc62Ying Wang *
505436638acc7c010349a69c3395f1a57c642dc62Ying Wang *  Licensed under the Apache License, Version 2.0 (the "License");
605436638acc7c010349a69c3395f1a57c642dc62Ying Wang *  you may not use this file except in compliance with the License.
705436638acc7c010349a69c3395f1a57c642dc62Ying Wang *  You may obtain a copy of the License at:
805436638acc7c010349a69c3395f1a57c642dc62Ying Wang *
905436638acc7c010349a69c3395f1a57c642dc62Ying Wang *  http://www.apache.org/licenses/LICENSE-2.0
1005436638acc7c010349a69c3395f1a57c642dc62Ying Wang *
1105436638acc7c010349a69c3395f1a57c642dc62Ying Wang *  Unless required by applicable law or agreed to in writing, software
1205436638acc7c010349a69c3395f1a57c642dc62Ying Wang *  distributed under the License is distributed on an "AS IS" BASIS,
1305436638acc7c010349a69c3395f1a57c642dc62Ying Wang *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1405436638acc7c010349a69c3395f1a57c642dc62Ying Wang *  See the License for the specific language governing permissions and
1505436638acc7c010349a69c3395f1a57c642dc62Ying Wang *  limitations under the License.
1605436638acc7c010349a69c3395f1a57c642dc62Ying Wang *
1705436638acc7c010349a69c3395f1a57c642dc62Ying Wang ******************************************************************************/
1805436638acc7c010349a69c3395f1a57c642dc62Ying Wang
1905436638acc7c010349a69c3395f1a57c642dc62Ying Wang
2005436638acc7c010349a69c3395f1a57c642dc62Ying Wang/*****************************************************************************
2105436638acc7c010349a69c3395f1a57c642dc62Ying Wang *
2205436638acc7c010349a69c3395f1a57c642dc62Ying Wang *  Filename:      btif_rc.c
2305436638acc7c010349a69c3395f1a57c642dc62Ying Wang *
2405436638acc7c010349a69c3395f1a57c642dc62Ying Wang *  Description:   Bluetooth AVRC implementation
2505436638acc7c010349a69c3395f1a57c642dc62Ying Wang *
2605436638acc7c010349a69c3395f1a57c642dc62Ying Wang *****************************************************************************/
2705436638acc7c010349a69c3395f1a57c642dc62Ying Wang#include <hardware/bluetooth.h>
2805436638acc7c010349a69c3395f1a57c642dc62Ying Wang#include <fcntl.h>
2905436638acc7c010349a69c3395f1a57c642dc62Ying Wang#include "bta_api.h"
3005436638acc7c010349a69c3395f1a57c642dc62Ying Wang#include "bta_av_api.h"
3105436638acc7c010349a69c3395f1a57c642dc62Ying Wang#include "avrc_defs.h"
3205436638acc7c010349a69c3395f1a57c642dc62Ying Wang#include "bd.h"
3305436638acc7c010349a69c3395f1a57c642dc62Ying Wang#include "gki.h"
3405436638acc7c010349a69c3395f1a57c642dc62Ying Wang
3505436638acc7c010349a69c3395f1a57c642dc62Ying Wang#define LOG_TAG "BTIF_RC"
3605436638acc7c010349a69c3395f1a57c642dc62Ying Wang#include "btif_common.h"
3705436638acc7c010349a69c3395f1a57c642dc62Ying Wang#include "btif_util.h"
3805436638acc7c010349a69c3395f1a57c642dc62Ying Wang#include "btif_av.h"
3905436638acc7c010349a69c3395f1a57c642dc62Ying Wang#include "hardware/bt_rc.h"
4005436638acc7c010349a69c3395f1a57c642dc62Ying Wang#include "uinput.h"
4105436638acc7c010349a69c3395f1a57c642dc62Ying Wang
4205436638acc7c010349a69c3395f1a57c642dc62Ying Wang/*****************************************************************************
4305436638acc7c010349a69c3395f1a57c642dc62Ying Wang**  Constants & Macros
4405436638acc7c010349a69c3395f1a57c642dc62Ying Wang******************************************************************************/
4505436638acc7c010349a69c3395f1a57c642dc62Ying Wang
4605436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* cod value for Headsets */
4705436638acc7c010349a69c3395f1a57c642dc62Ying Wang#define COD_AV_HEADSETS        0x0404
4805436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* for AVRC 1.4 need to change this */
4905436638acc7c010349a69c3395f1a57c642dc62Ying Wang#define MAX_RC_NOTIFICATIONS AVRC_EVT_APP_SETTING_CHANGE
5005436638acc7c010349a69c3395f1a57c642dc62Ying Wang
5105436638acc7c010349a69c3395f1a57c642dc62Ying Wang#define IDX_GET_PLAY_STATUS_RSP   0
5205436638acc7c010349a69c3395f1a57c642dc62Ying Wang#define IDX_LIST_APP_ATTR_RSP     1
5305436638acc7c010349a69c3395f1a57c642dc62Ying Wang#define IDX_LIST_APP_VALUE_RSP    2
5405436638acc7c010349a69c3395f1a57c642dc62Ying Wang#define IDX_GET_CURR_APP_VAL_RSP  3
5505436638acc7c010349a69c3395f1a57c642dc62Ying Wang#define IDX_SET_APP_VAL_RSP       4
5605436638acc7c010349a69c3395f1a57c642dc62Ying Wang#define IDX_GET_APP_ATTR_TXT_RSP  5
5705436638acc7c010349a69c3395f1a57c642dc62Ying Wang#define IDX_GET_APP_VAL_TXT_RSP   6
5805436638acc7c010349a69c3395f1a57c642dc62Ying Wang#define IDX_GET_ELEMENT_ATTR_RSP  7
5905436638acc7c010349a69c3395f1a57c642dc62Ying Wang#define MAX_VOLUME 128
6005436638acc7c010349a69c3395f1a57c642dc62Ying Wang#define MAX_LABEL 16
6105436638acc7c010349a69c3395f1a57c642dc62Ying Wang#define MAX_TRANSACTIONS_PER_SESSION 16
6205436638acc7c010349a69c3395f1a57c642dc62Ying Wang#define MAX_CMD_QUEUE_LEN 8
6305436638acc7c010349a69c3395f1a57c642dc62Ying Wang
6405436638acc7c010349a69c3395f1a57c642dc62Ying Wang#define CHECK_RC_CONNECTED                                                                  \
6505436638acc7c010349a69c3395f1a57c642dc62Ying Wang    BTIF_TRACE_DEBUG1("## %s ##", __FUNCTION__);                                            \
6605436638acc7c010349a69c3395f1a57c642dc62Ying Wang    if(btif_rc_cb.rc_connected == FALSE)                                                    \
6705436638acc7c010349a69c3395f1a57c642dc62Ying Wang    {                                                                                       \
6805436638acc7c010349a69c3395f1a57c642dc62Ying Wang        BTIF_TRACE_WARNING1("Function %s() called when RC is not connected", __FUNCTION__); \
6905436638acc7c010349a69c3395f1a57c642dc62Ying Wang        return BT_STATUS_NOT_READY;                                                         \
7005436638acc7c010349a69c3395f1a57c642dc62Ying Wang    }
7105436638acc7c010349a69c3395f1a57c642dc62Ying Wang
7205436638acc7c010349a69c3395f1a57c642dc62Ying Wang#define FILL_PDU_QUEUE(index, ctype, label, pending)        \
7305436638acc7c010349a69c3395f1a57c642dc62Ying Wang{                                                           \
7405436638acc7c010349a69c3395f1a57c642dc62Ying Wang    btif_rc_cb.rc_pdu_info[index].ctype = ctype;            \
7505436638acc7c010349a69c3395f1a57c642dc62Ying Wang    btif_rc_cb.rc_pdu_info[index].label = label;            \
7605436638acc7c010349a69c3395f1a57c642dc62Ying Wang    btif_rc_cb.rc_pdu_info[index].is_rsp_pending = pending; \
7705436638acc7c010349a69c3395f1a57c642dc62Ying Wang}
7805436638acc7c010349a69c3395f1a57c642dc62Ying Wang
7905436638acc7c010349a69c3395f1a57c642dc62Ying Wang#define SEND_METAMSG_RSP(index, avrc_rsp)                                                      \
8005436638acc7c010349a69c3395f1a57c642dc62Ying Wang{                                                                                              \
8105436638acc7c010349a69c3395f1a57c642dc62Ying Wang    if(btif_rc_cb.rc_pdu_info[index].is_rsp_pending == FALSE)                                  \
8205436638acc7c010349a69c3395f1a57c642dc62Ying Wang    {                                                                                          \
8305436638acc7c010349a69c3395f1a57c642dc62Ying Wang        BTIF_TRACE_WARNING1("%s Not sending response as no PDU was registered", __FUNCTION__); \
8405436638acc7c010349a69c3395f1a57c642dc62Ying Wang        return BT_STATUS_UNHANDLED;                                                            \
8505436638acc7c010349a69c3395f1a57c642dc62Ying Wang    }                                                                                          \
8605436638acc7c010349a69c3395f1a57c642dc62Ying Wang    send_metamsg_rsp(btif_rc_cb.rc_handle, btif_rc_cb.rc_pdu_info[index].label,                \
8705436638acc7c010349a69c3395f1a57c642dc62Ying Wang        btif_rc_cb.rc_pdu_info[index].ctype, avrc_rsp);                                        \
8805436638acc7c010349a69c3395f1a57c642dc62Ying Wang    btif_rc_cb.rc_pdu_info[index].ctype = 0;                                                   \
8905436638acc7c010349a69c3395f1a57c642dc62Ying Wang    btif_rc_cb.rc_pdu_info[index].label = 0;                                                   \
9005436638acc7c010349a69c3395f1a57c642dc62Ying Wang    btif_rc_cb.rc_pdu_info[index].is_rsp_pending = FALSE;                                      \
9105436638acc7c010349a69c3395f1a57c642dc62Ying Wang}
9205436638acc7c010349a69c3395f1a57c642dc62Ying Wang
9305436638acc7c010349a69c3395f1a57c642dc62Ying Wang/*****************************************************************************
9405436638acc7c010349a69c3395f1a57c642dc62Ying Wang**  Local type definitions
9505436638acc7c010349a69c3395f1a57c642dc62Ying Wang******************************************************************************/
9605436638acc7c010349a69c3395f1a57c642dc62Ying Wangtypedef struct {
9705436638acc7c010349a69c3395f1a57c642dc62Ying Wang    UINT8 bNotify;
9805436638acc7c010349a69c3395f1a57c642dc62Ying Wang    UINT8 label;
9905436638acc7c010349a69c3395f1a57c642dc62Ying Wang} btif_rc_reg_notifications_t;
10005436638acc7c010349a69c3395f1a57c642dc62Ying Wang
10105436638acc7c010349a69c3395f1a57c642dc62Ying Wangtypedef struct
10205436638acc7c010349a69c3395f1a57c642dc62Ying Wang{
10305436638acc7c010349a69c3395f1a57c642dc62Ying Wang    UINT8   label;
10405436638acc7c010349a69c3395f1a57c642dc62Ying Wang    UINT8   ctype;
10505436638acc7c010349a69c3395f1a57c642dc62Ying Wang    BOOLEAN is_rsp_pending;
10605436638acc7c010349a69c3395f1a57c642dc62Ying Wang} btif_rc_cmd_ctxt_t;
10705436638acc7c010349a69c3395f1a57c642dc62Ying Wang
10805436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* TODO : Merge btif_rc_reg_notifications_t and btif_rc_cmd_ctxt_t to a single struct */
10905436638acc7c010349a69c3395f1a57c642dc62Ying Wangtypedef struct {
11005436638acc7c010349a69c3395f1a57c642dc62Ying Wang    BOOLEAN                     rc_connected;
11105436638acc7c010349a69c3395f1a57c642dc62Ying Wang    UINT8                       rc_handle;
11205436638acc7c010349a69c3395f1a57c642dc62Ying Wang    tBTA_AV_FEAT                rc_features;
11305436638acc7c010349a69c3395f1a57c642dc62Ying Wang    BD_ADDR                     rc_addr;
11405436638acc7c010349a69c3395f1a57c642dc62Ying Wang    UINT16                      rc_pending_play;
11505436638acc7c010349a69c3395f1a57c642dc62Ying Wang    btif_rc_cmd_ctxt_t          rc_pdu_info[MAX_CMD_QUEUE_LEN];
11605436638acc7c010349a69c3395f1a57c642dc62Ying Wang    btif_rc_reg_notifications_t rc_notif[MAX_RC_NOTIFICATIONS];
11705436638acc7c010349a69c3395f1a57c642dc62Ying Wang    unsigned int                rc_volume;
11805436638acc7c010349a69c3395f1a57c642dc62Ying Wang    uint8_t                     rc_vol_label;
11905436638acc7c010349a69c3395f1a57c642dc62Ying Wang} btif_rc_cb_t;
12005436638acc7c010349a69c3395f1a57c642dc62Ying Wang
12105436638acc7c010349a69c3395f1a57c642dc62Ying Wangtypedef struct {
12205436638acc7c010349a69c3395f1a57c642dc62Ying Wang    BOOLEAN in_use;
12305436638acc7c010349a69c3395f1a57c642dc62Ying Wang    UINT8 lbl;
12405436638acc7c010349a69c3395f1a57c642dc62Ying Wang    UINT8 handle;
12505436638acc7c010349a69c3395f1a57c642dc62Ying Wang} rc_transaction_t;
12605436638acc7c010349a69c3395f1a57c642dc62Ying Wang
12705436638acc7c010349a69c3395f1a57c642dc62Ying Wangtypedef struct
12805436638acc7c010349a69c3395f1a57c642dc62Ying Wang{
12905436638acc7c010349a69c3395f1a57c642dc62Ying Wang    pthread_mutex_t lbllock;
13005436638acc7c010349a69c3395f1a57c642dc62Ying Wang    rc_transaction_t transaction[MAX_TRANSACTIONS_PER_SESSION];
13105436638acc7c010349a69c3395f1a57c642dc62Ying Wang} rc_device_t;
13205436638acc7c010349a69c3395f1a57c642dc62Ying Wang
13305436638acc7c010349a69c3395f1a57c642dc62Ying Wang
13405436638acc7c010349a69c3395f1a57c642dc62Ying Wangrc_device_t device;
13505436638acc7c010349a69c3395f1a57c642dc62Ying Wang
13605436638acc7c010349a69c3395f1a57c642dc62Ying Wang#define MAX_UINPUT_PATHS 3
13705436638acc7c010349a69c3395f1a57c642dc62Ying Wangstatic const char* uinput_dev_path[] =
13805436638acc7c010349a69c3395f1a57c642dc62Ying Wang                       {"/dev/uinput", "/dev/input/uinput", "/dev/misc/uinput" };
13905436638acc7c010349a69c3395f1a57c642dc62Ying Wangstatic int uinput_fd = -1;
14005436638acc7c010349a69c3395f1a57c642dc62Ying Wang
14105436638acc7c010349a69c3395f1a57c642dc62Ying Wangstatic int  send_event (int fd, uint16_t type, uint16_t code, int32_t value);
14205436638acc7c010349a69c3395f1a57c642dc62Ying Wangstatic void send_key (int fd, uint16_t key, int pressed);
14305436638acc7c010349a69c3395f1a57c642dc62Ying Wangstatic int  uinput_driver_check();
14405436638acc7c010349a69c3395f1a57c642dc62Ying Wangstatic int  uinput_create(char *name);
14505436638acc7c010349a69c3395f1a57c642dc62Ying Wangstatic int  init_uinput (void);
14605436638acc7c010349a69c3395f1a57c642dc62Ying Wangstatic void close_uinput (void);
14705436638acc7c010349a69c3395f1a57c642dc62Ying Wangstatic BOOLEAN dev_blacklisted_for_absolute_volume(BD_ADDR peer_dev);
14805436638acc7c010349a69c3395f1a57c642dc62Ying Wang
14905436638acc7c010349a69c3395f1a57c642dc62Ying Wangstatic const struct {
15005436638acc7c010349a69c3395f1a57c642dc62Ying Wang    const char *name;
15105436638acc7c010349a69c3395f1a57c642dc62Ying Wang    uint8_t avrcp;
15205436638acc7c010349a69c3395f1a57c642dc62Ying Wang    uint16_t mapped_id;
15305436638acc7c010349a69c3395f1a57c642dc62Ying Wang    uint8_t release_quirk;
15405436638acc7c010349a69c3395f1a57c642dc62Ying Wang} key_map[] = {
15505436638acc7c010349a69c3395f1a57c642dc62Ying Wang    { "PLAY",         AVRC_ID_PLAY,     KEY_PLAYCD,       1 },
15605436638acc7c010349a69c3395f1a57c642dc62Ying Wang    { "STOP",         AVRC_ID_STOP,     KEY_STOPCD,       0 },
15705436638acc7c010349a69c3395f1a57c642dc62Ying Wang    { "PAUSE",        AVRC_ID_PAUSE,    KEY_PAUSECD,      1 },
158    { "FORWARD",      AVRC_ID_FORWARD,  KEY_NEXTSONG,     0 },
159    { "BACKWARD",     AVRC_ID_BACKWARD, KEY_PREVIOUSSONG, 0 },
160    { "REWIND",       AVRC_ID_REWIND,   KEY_REWIND,       0 },
161    { "FAST FORWARD", AVRC_ID_FAST_FOR, KEY_FAST_FORWARD, 0 },
162    { NULL,           0,                0,                0 }
163};
164
165/* the rc_black_addr_prefix and rc_white_addr_prefix are used to correct
166 * IOP issues of absolute volume feature
167 * We encoutered A2DP headsets/carkits advertising absolute volume but buggy.
168 * We would like to blacklist those devices.
169 * But we donot have a full list of the bad devices. So as a temp fix, we
170 * are blacklisting all the devices except the devices we have well tested,
171 * the ones in the whitelist.
172 *
173 * For now, only the rc_white_addr_prefix is used in the code while
174 * rc_black_addr_prefix is kept here for future long term solution.
175 */
176static const UINT8 rc_black_addr_prefix[][3] = {
177    {0x0, 0x18, 0x6B}, // LG HBS-730
178    {0x0, 0x26, 0x7E}  // VW Passat
179};
180
181static const UINT8 rc_white_addr_prefix[][3] = {
182    {0x94, 0xCE, 0x2C}, // Sony SBH50
183    {0x30, 0x17, 0xC8}  // Sony wm600
184};
185
186static void send_reject_response (UINT8 rc_handle, UINT8 label,
187    UINT8 pdu, UINT8 status);
188static UINT8 opcode_from_pdu(UINT8 pdu);
189static void send_metamsg_rsp (UINT8 rc_handle, UINT8 label,
190    tBTA_AV_CODE code, tAVRC_RESPONSE *pmetamsg_resp);
191static void register_volumechange(UINT8 label);
192static void lbl_init();
193static void lbl_destroy();
194static void init_all_transactions();
195static bt_status_t  get_transaction(rc_transaction_t **ptransaction);
196static void release_transaction(UINT8 label);
197static rc_transaction_t* get_transaction_by_lbl(UINT8 label);
198static void handle_rc_metamsg_rsp(tBTA_AV_META_MSG *pmeta_msg);
199static void btif_rc_upstreams_evt(UINT16 event, tAVRC_COMMAND* p_param, UINT8 ctype, UINT8 label);
200static void btif_rc_upstreams_rsp_evt(UINT16 event, tAVRC_RESPONSE *pavrc_resp, UINT8 ctype, UINT8 label);
201
202/*****************************************************************************
203**  Static variables
204******************************************************************************/
205static btif_rc_cb_t btif_rc_cb;
206static btrc_callbacks_t *bt_rc_callbacks = NULL;
207
208/*****************************************************************************
209**  Static functions
210******************************************************************************/
211
212/*****************************************************************************
213**  Externs
214******************************************************************************/
215extern BOOLEAN btif_hf_call_terminated_recently();
216extern BOOLEAN check_cod(const bt_bdaddr_t *remote_bdaddr, uint32_t cod);
217
218
219/*****************************************************************************
220**  Functions
221******************************************************************************/
222
223/*****************************************************************************
224**   Local uinput helper functions
225******************************************************************************/
226int send_event (int fd, uint16_t type, uint16_t code, int32_t value)
227{
228    struct uinput_event event;
229    BTIF_TRACE_DEBUG4("%s type:%u code:%u value:%d", __FUNCTION__,
230        type, code, value);
231    memset(&event, 0, sizeof(event));
232    event.type  = type;
233    event.code  = code;
234    event.value = value;
235
236    return write(fd, &event, sizeof(event));
237}
238
239void send_key (int fd, uint16_t key, int pressed)
240{
241    BTIF_TRACE_DEBUG4("%s fd:%d key:%u pressed:%d", __FUNCTION__,
242        fd, key, pressed);
243
244    if (fd < 0)
245    {
246        return;
247    }
248
249    BTIF_TRACE_DEBUG3("AVRCP: Send key %d (%d) fd=%d", key, pressed, fd);
250    send_event(fd, EV_KEY, key, pressed);
251    send_event(fd, EV_SYN, SYN_REPORT, 0);
252}
253
254/************** uinput related functions **************/
255int uinput_driver_check()
256{
257    uint32_t i;
258    for (i=0; i < MAX_UINPUT_PATHS; i++)
259    {
260        if (access(uinput_dev_path[i], O_RDWR) == 0) {
261           return 0;
262        }
263    }
264    BTIF_TRACE_ERROR1("%s ERROR: uinput device is not in the system", __FUNCTION__);
265    return -1;
266}
267
268int uinput_create(char *name)
269{
270    struct uinput_dev dev;
271    int fd, err, x = 0;
272
273    for(x=0; x < MAX_UINPUT_PATHS; x++)
274    {
275        fd = open(uinput_dev_path[x], O_RDWR);
276        if (fd < 0)
277            continue;
278        break;
279    }
280    if (x == MAX_UINPUT_PATHS) {
281        BTIF_TRACE_ERROR1("%s ERROR: uinput device open failed", __FUNCTION__);
282        return -1;
283    }
284    memset(&dev, 0, sizeof(dev));
285    if (name)
286        strncpy(dev.name, name, UINPUT_MAX_NAME_SIZE);
287
288    dev.id.bustype = BUS_BLUETOOTH;
289    dev.id.vendor  = 0x0000;
290    dev.id.product = 0x0000;
291    dev.id.version = 0x0000;
292
293    if (write(fd, &dev, sizeof(dev)) < 0) {
294        BTIF_TRACE_ERROR1("%s Unable to write device information", __FUNCTION__);
295        close(fd);
296        return -1;
297    }
298
299    ioctl(fd, UI_SET_EVBIT, EV_KEY);
300    ioctl(fd, UI_SET_EVBIT, EV_REL);
301    ioctl(fd, UI_SET_EVBIT, EV_SYN);
302
303    for (x = 0; key_map[x].name != NULL; x++)
304        ioctl(fd, UI_SET_KEYBIT, key_map[x].mapped_id);
305
306    for(x = 0; x < KEY_MAX; x++)
307        ioctl(fd, UI_SET_KEYBIT, x);
308
309    if (ioctl(fd, UI_DEV_CREATE, NULL) < 0) {
310        BTIF_TRACE_ERROR1("%s Unable to create uinput device", __FUNCTION__);
311        close(fd);
312        return -1;
313    }
314    return fd;
315}
316
317int init_uinput (void)
318{
319    char *name = "AVRCP";
320
321    BTIF_TRACE_DEBUG1("%s", __FUNCTION__);
322    uinput_fd = uinput_create(name);
323    if (uinput_fd < 0) {
324        BTIF_TRACE_ERROR3("%s AVRCP: Failed to initialize uinput for %s (%d)",
325                          __FUNCTION__, name, uinput_fd);
326    } else {
327        BTIF_TRACE_DEBUG3("%s AVRCP: Initialized uinput for %s (fd=%d)",
328                          __FUNCTION__, name, uinput_fd);
329    }
330    return uinput_fd;
331}
332
333void close_uinput (void)
334{
335    BTIF_TRACE_DEBUG1("%s", __FUNCTION__);
336    if (uinput_fd > 0) {
337        ioctl(uinput_fd, UI_DEV_DESTROY);
338
339        close(uinput_fd);
340        uinput_fd = -1;
341    }
342}
343
344void handle_rc_features()
345{
346    btrc_remote_features_t rc_features = BTRC_FEAT_NONE;
347    bt_bdaddr_t rc_addr;
348    bdcpy(rc_addr.address, btif_rc_cb.rc_addr);
349
350    if (dev_blacklisted_for_absolute_volume(btif_rc_cb.rc_addr))
351    {
352        btif_rc_cb.rc_features &= ~BTA_AV_FEAT_ADV_CTRL;
353    }
354
355    if (btif_rc_cb.rc_features & BTA_AV_FEAT_BROWSE)
356    {
357        rc_features |= BTRC_FEAT_BROWSE;
358    }
359    if ( (btif_rc_cb.rc_features & BTA_AV_FEAT_ADV_CTRL) &&
360         (btif_rc_cb.rc_features & BTA_AV_FEAT_RCTG))
361    {
362        rc_features |= BTRC_FEAT_ABSOLUTE_VOLUME;
363    }
364    if (btif_rc_cb.rc_features & BTA_AV_FEAT_METADATA)
365    {
366        rc_features |= BTRC_FEAT_METADATA;
367    }
368    BTIF_TRACE_DEBUG2("%s: rc_features=0x%x", __FUNCTION__, rc_features);
369    HAL_CBACK(bt_rc_callbacks, remote_features_cb, &rc_addr, rc_features)
370
371#if (AVRC_ADV_CTRL_INCLUDED == TRUE)
372     BTIF_TRACE_DEBUG1("Checking for feature flags in btif_rc_handler with label %d",
373                        btif_rc_cb.rc_vol_label);
374     // Register for volume change on connect
375      if(btif_rc_cb.rc_features & BTA_AV_FEAT_ADV_CTRL &&
376         btif_rc_cb.rc_features & BTA_AV_FEAT_RCTG)
377      {
378         rc_transaction_t *p_transaction=NULL;
379         bt_status_t status = BT_STATUS_NOT_READY;
380         if(MAX_LABEL==btif_rc_cb.rc_vol_label)
381         {
382            status=get_transaction(&p_transaction);
383         }
384         else
385         {
386            p_transaction=get_transaction_by_lbl(btif_rc_cb.rc_vol_label);
387            if(NULL!=p_transaction)
388            {
389               BTIF_TRACE_DEBUG1("register_volumechange already in progress for label %d",
390                                  btif_rc_cb.rc_vol_label);
391               return;
392            }
393            else
394              status=get_transaction(&p_transaction);
395         }
396
397         if(BT_STATUS_SUCCESS == status && NULL!=p_transaction)
398         {
399            btif_rc_cb.rc_vol_label=p_transaction->lbl;
400            register_volumechange(btif_rc_cb.rc_vol_label);
401         }
402       }
403#endif
404}
405
406
407/***************************************************************************
408 *  Function       handle_rc_connect
409 *
410 *  - Argument:    tBTA_AV_RC_OPEN  RC open data structure
411 *
412 *  - Description: RC connection event handler
413 *
414 ***************************************************************************/
415void handle_rc_connect (tBTA_AV_RC_OPEN *p_rc_open)
416{
417    BTIF_TRACE_DEBUG2("%s: rc_handle: %d", __FUNCTION__, p_rc_open->rc_handle);
418    bt_status_t result = BT_STATUS_SUCCESS;
419    int i;
420    char bd_str[18];
421
422    if(p_rc_open->status == BTA_AV_SUCCESS)
423    {
424        memcpy(btif_rc_cb.rc_addr, p_rc_open->peer_addr, sizeof(BD_ADDR));
425        btif_rc_cb.rc_features = p_rc_open->peer_features;
426        btif_rc_cb.rc_vol_label=MAX_LABEL;
427        btif_rc_cb.rc_volume=MAX_VOLUME;
428
429        btif_rc_cb.rc_connected = TRUE;
430        btif_rc_cb.rc_handle = p_rc_open->rc_handle;
431
432        /* on locally initiated connection we will get remote features as part of connect */
433        if (btif_rc_cb.rc_features != 0)
434            handle_rc_features();
435
436        result = uinput_driver_check();
437        if(result == BT_STATUS_SUCCESS)
438        {
439            init_uinput();
440        }
441    }
442    else
443    {
444        BTIF_TRACE_ERROR2("%s Connect failed with error code: %d",
445            __FUNCTION__, p_rc_open->status);
446        btif_rc_cb.rc_connected = FALSE;
447    }
448}
449
450/***************************************************************************
451 *  Function       handle_rc_disconnect
452 *
453 *  - Argument:    tBTA_AV_RC_CLOSE     RC close data structure
454 *
455 *  - Description: RC disconnection event handler
456 *
457 ***************************************************************************/
458void handle_rc_disconnect (tBTA_AV_RC_CLOSE *p_rc_close)
459{
460    BTIF_TRACE_DEBUG2("%s: rc_handle: %d", __FUNCTION__, p_rc_close->rc_handle);
461
462    btif_rc_cb.rc_handle = 0;
463    btif_rc_cb.rc_connected = FALSE;
464    memset(btif_rc_cb.rc_addr, 0, sizeof(BD_ADDR));
465    btif_rc_cb.rc_features = 0;
466    btif_rc_cb.rc_vol_label=MAX_LABEL;
467    btif_rc_cb.rc_volume=MAX_VOLUME;
468    init_all_transactions();
469    close_uinput();
470}
471
472/***************************************************************************
473 *  Function       handle_rc_passthrough_cmd
474 *
475 *  - Argument:    tBTA_AV_RC rc_id   remote control command ID
476 *                 tBTA_AV_STATE key_state status of key press
477 *
478 *  - Description: Remote control command handler
479 *
480 ***************************************************************************/
481void handle_rc_passthrough_cmd ( tBTA_AV_REMOTE_CMD *p_remote_cmd)
482{
483    const char *status;
484    int pressed, i;
485
486    BTIF_TRACE_DEBUG2("%s: p_remote_cmd->rc_id=%d", __FUNCTION__, p_remote_cmd->rc_id);
487
488    /* If AVRC is open and peer sends PLAY but there is no AVDT, then we queue-up this PLAY */
489    if (p_remote_cmd)
490    {
491        /* queue AVRC PLAY if GAVDTP Open notification to app is pending (2 second timer) */
492        if ((p_remote_cmd->rc_id == BTA_AV_RC_PLAY) && (!btif_av_is_connected()))
493        {
494            if (p_remote_cmd->key_state == AVRC_STATE_PRESS)
495            {
496                APPL_TRACE_WARNING1("%s: AVDT not open, queuing the PLAY command", __FUNCTION__);
497                btif_rc_cb.rc_pending_play = TRUE;
498            }
499            return;
500        }
501
502        if ((p_remote_cmd->rc_id == BTA_AV_RC_PAUSE) && (btif_rc_cb.rc_pending_play))
503        {
504            APPL_TRACE_WARNING1("%s: Clear the pending PLAY on PAUSE received", __FUNCTION__);
505            btif_rc_cb.rc_pending_play = FALSE;
506            return;
507        }
508    }
509    if (p_remote_cmd->key_state == AVRC_STATE_RELEASE) {
510        status = "released";
511        pressed = 0;
512    } else {
513        status = "pressed";
514        pressed = 1;
515    }
516
517    /* If this is Play/Pause command (press or release)  before processing, check the following
518     * a voice call has ended recently
519     * the remote device is not of type headset
520     * If the above conditions meet, drop the Play/Pause command
521     * This fix is to interop with certain carkits which sends an automatic  PLAY  or PAUSE
522     * commands right after call ends
523     */
524    if((p_remote_cmd->rc_id == BTA_AV_RC_PLAY || p_remote_cmd->rc_id == BTA_AV_RC_PAUSE)&&
525       (btif_hf_call_terminated_recently() == TRUE) &&
526       (check_cod( (const bt_bdaddr_t*)&(btif_rc_cb.rc_addr), COD_AV_HEADSETS) != TRUE))
527    {
528        BTIF_TRACE_DEBUG2("%s:Dropping the play/Pause command received right after call end cmd:%d",
529                           __FUNCTION__,p_remote_cmd->rc_id);
530        return;
531    }
532
533    if (p_remote_cmd->rc_id == BTA_AV_RC_FAST_FOR || p_remote_cmd->rc_id == BTA_AV_RC_REWIND) {
534        HAL_CBACK(bt_rc_callbacks, passthrough_cmd_cb, p_remote_cmd->rc_id, pressed);
535        return;
536    }
537
538    for (i = 0; key_map[i].name != NULL; i++) {
539        if (p_remote_cmd->rc_id == key_map[i].avrcp) {
540            BTIF_TRACE_DEBUG3("%s: %s %s", __FUNCTION__, key_map[i].name, status);
541
542           /* MusicPlayer uses a long_press_timeout of 1 second for PLAYPAUSE button
543            * and maps that to autoshuffle. So if for some reason release for PLAY/PAUSE
544            * comes 1 second after the press, the MediaPlayer UI goes into a bad state.
545            * The reason for the delay could be sniff mode exit or some AVDTP procedure etc.
546            * The fix is to generate a release right after the press and drown the 'actual'
547            * release.
548            */
549            if ((key_map[i].release_quirk == 1) && (pressed == 0))
550            {
551                BTIF_TRACE_DEBUG2("%s: AVRC %s Release Faked earlier, drowned now",
552                                  __FUNCTION__, key_map[i].name);
553                return;
554            }
555            send_key(uinput_fd, key_map[i].mapped_id, pressed);
556            if ((key_map[i].release_quirk == 1) && (pressed == 1))
557            {
558                GKI_delay(30); // 30ms
559                BTIF_TRACE_DEBUG2("%s: AVRC %s Release quirk enabled, send release now",
560                                  __FUNCTION__, key_map[i].name);
561                send_key(uinput_fd, key_map[i].mapped_id, 0);
562            }
563            break;
564        }
565    }
566
567    if (key_map[i].name == NULL)
568        BTIF_TRACE_ERROR3("%s AVRCP: unknown button 0x%02X %s", __FUNCTION__,
569                        p_remote_cmd->rc_id, status);
570}
571
572void handle_uid_changed_notification(tBTA_AV_META_MSG *pmeta_msg, tAVRC_COMMAND *pavrc_command)
573{
574    tAVRC_RESPONSE avrc_rsp = {0};
575    avrc_rsp.rsp.pdu = pavrc_command->pdu;
576    avrc_rsp.rsp.status = AVRC_STS_NO_ERROR;
577    avrc_rsp.rsp.opcode = pavrc_command->cmd.opcode;
578
579    avrc_rsp.reg_notif.event_id = pavrc_command->reg_notif.event_id;
580    avrc_rsp.reg_notif.param.uid_counter = 0;
581
582    send_metamsg_rsp(pmeta_msg->rc_handle, pmeta_msg->label, AVRC_RSP_INTERIM, &avrc_rsp);
583    send_metamsg_rsp(pmeta_msg->rc_handle, pmeta_msg->label, AVRC_RSP_CHANGED, &avrc_rsp);
584
585}
586
587
588/***************************************************************************
589 *  Function       handle_rc_metamsg_cmd
590 *
591 *  - Argument:    tBTA_AV_VENDOR Structure containing the received
592 *                          metamsg command
593 *
594 *  - Description: Remote control metamsg command handler (AVRCP 1.3)
595 *
596 ***************************************************************************/
597void handle_rc_metamsg_cmd (tBTA_AV_META_MSG *pmeta_msg)
598{
599    /* Parse the metamsg command and pass it on to BTL-IFS */
600    UINT8             scratch_buf[512] = {0};
601    tAVRC_COMMAND    avrc_command = {0};
602    tAVRC_STS status;
603    int param_len;
604
605    BTIF_TRACE_EVENT1("+ %s", __FUNCTION__);
606
607    if (pmeta_msg->p_msg->hdr.opcode != AVRC_OP_VENDOR)
608    {
609        BTIF_TRACE_WARNING1("Invalid opcode: %x", pmeta_msg->p_msg->hdr.opcode);
610        return;
611    }
612    if (pmeta_msg->len < 3)
613    {
614        BTIF_TRACE_WARNING2("Invalid length.Opcode: 0x%x, len: 0x%x", pmeta_msg->p_msg->hdr.opcode,
615            pmeta_msg->len);
616        return;
617    }
618
619    if (pmeta_msg->code >= AVRC_RSP_NOT_IMPL)
620    {
621#if (AVRC_ADV_CTRL_INCLUDED == TRUE)
622{
623     rc_transaction_t *transaction=NULL;
624     transaction=get_transaction_by_lbl(pmeta_msg->label);
625     if(NULL!=transaction)
626     {
627        handle_rc_metamsg_rsp(pmeta_msg);
628     }
629     else
630     {
631         BTIF_TRACE_DEBUG3("%s:Discard vendor dependent rsp. code: %d label:%d.",
632             __FUNCTION__, pmeta_msg->code, pmeta_msg->label);
633     }
634     return;
635}
636#else
637{
638        BTIF_TRACE_DEBUG3("%s:Received vendor dependent rsp. code: %d len: %d. Not processing it.",
639            __FUNCTION__, pmeta_msg->code, pmeta_msg->len);
640        return;
641}
642#endif
643      }
644
645    status=AVRC_ParsCommand(pmeta_msg->p_msg, &avrc_command, scratch_buf, sizeof(scratch_buf));
646    BTIF_TRACE_DEBUG3("Received vendor command.code,PDU and label: %d, %d,%d",pmeta_msg->code,
647                       avrc_command.cmd.pdu, pmeta_msg->label);
648
649    if (status != AVRC_STS_NO_ERROR)
650    {
651        /* return error */
652        BTIF_TRACE_WARNING2("%s: Error in parsing received metamsg command. status: 0x%02x",
653            __FUNCTION__, status);
654        send_reject_response(pmeta_msg->rc_handle, pmeta_msg->label, avrc_command.pdu, status);
655    }
656    else
657    {
658        /* if RegisterNotification, add it to our registered queue */
659
660        if (avrc_command.cmd.pdu == AVRC_PDU_REGISTER_NOTIFICATION)
661        {
662            UINT8 event_id = avrc_command.reg_notif.event_id;
663            param_len = sizeof(tAVRC_REG_NOTIF_CMD);
664            BTIF_TRACE_EVENT4("%s:New register notification received.event_id:%s,label:0x%x,code:%x",
665            __FUNCTION__,dump_rc_notification_event_id(event_id), pmeta_msg->label,pmeta_msg->code);
666            btif_rc_cb.rc_notif[event_id-1].bNotify = TRUE;
667            btif_rc_cb.rc_notif[event_id-1].label = pmeta_msg->label;
668
669            if(event_id == AVRC_EVT_UIDS_CHANGE)
670            {
671                handle_uid_changed_notification(pmeta_msg, &avrc_command);
672                return;
673            }
674
675        }
676
677        BTIF_TRACE_EVENT2("%s: Passing received metamsg command to app. pdu: %s",
678            __FUNCTION__, dump_rc_pdu(avrc_command.cmd.pdu));
679
680        /* Since handle_rc_metamsg_cmd() itself is called from
681            *btif context, no context switching is required. Invoke
682            * btif_rc_upstreams_evt directly from here. */
683        btif_rc_upstreams_evt((uint16_t)avrc_command.cmd.pdu, &avrc_command, pmeta_msg->code,
684                               pmeta_msg->label);
685    }
686}
687
688/***************************************************************************
689 **
690 ** Function       btif_rc_handler
691 **
692 ** Description    RC event handler
693 **
694 ***************************************************************************/
695void btif_rc_handler(tBTA_AV_EVT event, tBTA_AV *p_data)
696{
697    BTIF_TRACE_DEBUG2 ("%s event:%s", __FUNCTION__, dump_rc_event(event));
698    switch (event)
699    {
700        case BTA_AV_RC_OPEN_EVT:
701        {
702            BTIF_TRACE_DEBUG1("Peer_features:%x", p_data->rc_open.peer_features);
703            handle_rc_connect( &(p_data->rc_open) );
704        }break;
705
706        case BTA_AV_RC_CLOSE_EVT:
707        {
708            handle_rc_disconnect( &(p_data->rc_close) );
709        }break;
710
711        case BTA_AV_REMOTE_CMD_EVT:
712        {
713            BTIF_TRACE_DEBUG2("rc_id:0x%x key_state:%d", p_data->remote_cmd.rc_id,
714                               p_data->remote_cmd.key_state);
715            handle_rc_passthrough_cmd( (&p_data->remote_cmd) );
716        }
717        break;
718        case BTA_AV_RC_FEAT_EVT:
719        {
720            BTIF_TRACE_DEBUG1("Peer_features:%x", p_data->rc_feat.peer_features);
721            btif_rc_cb.rc_features = p_data->rc_feat.peer_features;
722            handle_rc_features();
723        }
724        break;
725        case BTA_AV_META_MSG_EVT:
726        {
727            BTIF_TRACE_DEBUG2("BTA_AV_META_MSG_EVT  code:%d label:%d", p_data->meta_msg.code,
728                p_data->meta_msg.label);
729            BTIF_TRACE_DEBUG3("  company_id:0x%x len:%d handle:%d", p_data->meta_msg.company_id,
730                p_data->meta_msg.len, p_data->meta_msg.rc_handle);
731            /* handle the metamsg command */
732            handle_rc_metamsg_cmd(&(p_data->meta_msg));
733        }
734        break;
735        default:
736            BTIF_TRACE_DEBUG1("Unhandled RC event : 0x%x", event);
737    }
738}
739
740/***************************************************************************
741 **
742 ** Function       btif_rc_get_connected_peer
743 **
744 ** Description    Fetches the connected headset's BD_ADDR if any
745 **
746 ***************************************************************************/
747BOOLEAN btif_rc_get_connected_peer(BD_ADDR peer_addr)
748{
749    if (btif_rc_cb.rc_connected == TRUE) {
750        bdcpy(peer_addr, btif_rc_cb.rc_addr);
751        return TRUE;
752    }
753    return FALSE;
754}
755
756/***************************************************************************
757 **
758 ** Function       btif_rc_check_handle_pending_play
759 **
760 ** Description    Clears the queued PLAY command. if bSend is TRUE, forwards to app
761 **
762 ***************************************************************************/
763
764/* clear the queued PLAY command. if bSend is TRUE, forward to app */
765void btif_rc_check_handle_pending_play (BD_ADDR peer_addr, BOOLEAN bSendToApp)
766{
767    BTIF_TRACE_DEBUG2("%s: bSendToApp=%d", __FUNCTION__, bSendToApp);
768    if (btif_rc_cb.rc_pending_play)
769    {
770        if (bSendToApp)
771        {
772            tBTA_AV_REMOTE_CMD remote_cmd;
773            APPL_TRACE_DEBUG1("%s: Sending queued PLAYED event to app", __FUNCTION__);
774
775            memset (&remote_cmd, 0, sizeof(tBTA_AV_REMOTE_CMD));
776            remote_cmd.rc_handle  = btif_rc_cb.rc_handle;
777            remote_cmd.rc_id      = AVRC_ID_PLAY;
778            remote_cmd.hdr.ctype  = AVRC_CMD_CTRL;
779            remote_cmd.hdr.opcode = AVRC_OP_PASS_THRU;
780
781            /* delay sending to app, else there is a timing issue in the framework,
782             ** which causes the audio to be on th device's speaker. Delay between
783             ** OPEN & RC_PLAYs
784            */
785            GKI_delay (200);
786            /* send to app - both PRESSED & RELEASED */
787            remote_cmd.key_state  = AVRC_STATE_PRESS;
788            handle_rc_passthrough_cmd( &remote_cmd );
789
790            GKI_delay (100);
791
792            remote_cmd.key_state  = AVRC_STATE_RELEASE;
793            handle_rc_passthrough_cmd( &remote_cmd );
794        }
795        btif_rc_cb.rc_pending_play = FALSE;
796    }
797}
798
799/* Generic reject response */
800static void send_reject_response (UINT8 rc_handle, UINT8 label, UINT8 pdu, UINT8 status)
801{
802    UINT8 ctype = AVRC_RSP_REJ;
803    tAVRC_RESPONSE avrc_rsp;
804    BT_HDR *p_msg = NULL;
805    memset (&avrc_rsp, 0, sizeof(tAVRC_RESPONSE));
806
807    avrc_rsp.rsp.opcode = opcode_from_pdu(pdu);
808    avrc_rsp.rsp.pdu    = pdu;
809    avrc_rsp.rsp.status = status;
810
811    if (AVRC_STS_NO_ERROR == (status = AVRC_BldResponse(rc_handle, &avrc_rsp, &p_msg)) )
812    {
813        BTIF_TRACE_DEBUG4("%s:Sending error notification to handle:%d. pdu:%s,status:0x%02x",
814            __FUNCTION__, rc_handle, dump_rc_pdu(pdu), status);
815        BTA_AvMetaRsp(rc_handle, label, ctype, p_msg);
816    }
817}
818
819/***************************************************************************
820 *  Function       send_metamsg_rsp
821 *
822 *  - Argument:
823 *                  rc_handle     RC handle corresponding to the connected RC
824 *                  label            Label of the RC response
825 *                  code            Response type
826 *                  pmetamsg_resp    Vendor response
827 *
828 *  - Description: Remote control metamsg response handler (AVRCP 1.3)
829 *
830 ***************************************************************************/
831static void send_metamsg_rsp (UINT8 rc_handle, UINT8 label, tBTA_AV_CODE code,
832    tAVRC_RESPONSE *pmetamsg_resp)
833{
834    UINT8 ctype;
835    tAVRC_STS status;
836
837    if (!pmetamsg_resp)
838    {
839        BTIF_TRACE_WARNING1("%s: Invalid response received from application", __FUNCTION__);
840        return;
841    }
842
843    BTIF_TRACE_EVENT5("+%s: rc_handle: %d, label: %d, code: 0x%02x, pdu: %s", __FUNCTION__,
844        rc_handle, label, code, dump_rc_pdu(pmetamsg_resp->rsp.pdu));
845
846    if (pmetamsg_resp->rsp.status != AVRC_STS_NO_ERROR)
847    {
848        ctype = AVRC_RSP_REJ;
849    }
850    else
851    {
852        if ( code < AVRC_RSP_NOT_IMPL)
853        {
854            if (code == AVRC_CMD_NOTIF)
855            {
856               ctype = AVRC_RSP_INTERIM;
857            }
858            else if (code == AVRC_CMD_STATUS)
859            {
860               ctype = AVRC_RSP_IMPL_STBL;
861            }
862            else
863            {
864               ctype = AVRC_RSP_ACCEPT;
865            }
866        }
867        else
868        {
869            ctype = code;
870        }
871    }
872    /* if response is for register_notification, make sure the rc has
873    actually registered for this */
874    if((pmetamsg_resp->rsp.pdu == AVRC_PDU_REGISTER_NOTIFICATION) && (code == AVRC_RSP_CHANGED))
875    {
876        BOOLEAN bSent = FALSE;
877        UINT8   event_id = pmetamsg_resp->reg_notif.event_id;
878        BOOLEAN bNotify = (btif_rc_cb.rc_connected) && (btif_rc_cb.rc_notif[event_id-1].bNotify);
879
880        /* de-register this notification for a CHANGED response */
881        btif_rc_cb.rc_notif[event_id-1].bNotify = FALSE;
882        BTIF_TRACE_DEBUG4("%s rc_handle: %d. event_id: 0x%02d bNotify:%u", __FUNCTION__,
883             btif_rc_cb.rc_handle, event_id, bNotify);
884        if (bNotify)
885        {
886            BT_HDR *p_msg = NULL;
887            tAVRC_STS status;
888
889            if (AVRC_STS_NO_ERROR == (status = AVRC_BldResponse(btif_rc_cb.rc_handle,
890                pmetamsg_resp, &p_msg)) )
891            {
892                BTIF_TRACE_DEBUG3("%s Sending notification to rc_handle: %d. event_id: 0x%02d",
893                     __FUNCTION__, btif_rc_cb.rc_handle, event_id);
894                bSent = TRUE;
895                BTA_AvMetaRsp(btif_rc_cb.rc_handle, btif_rc_cb.rc_notif[event_id-1].label,
896                    ctype, p_msg);
897            }
898            else
899            {
900                BTIF_TRACE_WARNING2("%s failed to build metamsg response. status: 0x%02x",
901                    __FUNCTION__, status);
902            }
903
904        }
905
906        if (!bSent)
907        {
908            BTIF_TRACE_DEBUG2("%s: Notification not sent, as there are no RC connections or the \
909                CT has not subscribed for event_id: %s", __FUNCTION__, dump_rc_notification_event_id(event_id));
910        }
911    }
912    else
913    {
914        /* All other commands go here */
915
916        BT_HDR *p_msg = NULL;
917        tAVRC_STS status;
918
919        status = AVRC_BldResponse(rc_handle, pmetamsg_resp, &p_msg);
920
921        if (status == AVRC_STS_NO_ERROR)
922        {
923            BTA_AvMetaRsp(rc_handle, label, ctype, p_msg);
924        }
925        else
926        {
927            BTIF_TRACE_ERROR2("%s: failed to build metamsg response. status: 0x%02x",
928                __FUNCTION__, status);
929        }
930    }
931}
932
933static UINT8 opcode_from_pdu(UINT8 pdu)
934{
935    UINT8 opcode = 0;
936
937    switch (pdu)
938    {
939    case AVRC_PDU_NEXT_GROUP:
940    case AVRC_PDU_PREV_GROUP: /* pass thru */
941        opcode  = AVRC_OP_PASS_THRU;
942        break;
943
944    default: /* vendor */
945        opcode  = AVRC_OP_VENDOR;
946        break;
947    }
948
949    return opcode;
950}
951
952/*******************************************************************************
953**
954** Function         btif_rc_upstreams_evt
955**
956** Description      Executes AVRC UPSTREAMS events in btif context.
957**
958** Returns          void
959**
960*******************************************************************************/
961static void btif_rc_upstreams_evt(UINT16 event, tAVRC_COMMAND *pavrc_cmd, UINT8 ctype, UINT8 label)
962{
963    BTIF_TRACE_EVENT5("%s pdu: %s handle: 0x%x ctype:%x label:%x", __FUNCTION__,
964        dump_rc_pdu(pavrc_cmd->pdu), btif_rc_cb.rc_handle, ctype, label);
965
966    switch (event)
967    {
968        case AVRC_PDU_GET_PLAY_STATUS:
969        {
970            FILL_PDU_QUEUE(IDX_GET_PLAY_STATUS_RSP, ctype, label, TRUE)
971            HAL_CBACK(bt_rc_callbacks, get_play_status_cb);
972        }
973        break;
974        case AVRC_PDU_LIST_PLAYER_APP_ATTR:
975        case AVRC_PDU_LIST_PLAYER_APP_VALUES:
976        case AVRC_PDU_GET_CUR_PLAYER_APP_VALUE:
977        case AVRC_PDU_SET_PLAYER_APP_VALUE:
978        case AVRC_PDU_GET_PLAYER_APP_ATTR_TEXT:
979        case AVRC_PDU_GET_PLAYER_APP_VALUE_TEXT:
980        {
981            /* TODO: Add support for Application Settings */
982            send_reject_response (btif_rc_cb.rc_handle, label, pavrc_cmd->pdu, AVRC_STS_BAD_CMD);
983        }
984        break;
985        case AVRC_PDU_GET_ELEMENT_ATTR:
986        {
987            btrc_media_attr_t element_attrs[BTRC_MAX_ELEM_ATTR_SIZE];
988            UINT8 num_attr;
989             memset(&element_attrs, 0, sizeof(element_attrs));
990            if (pavrc_cmd->get_elem_attrs.num_attr == 0)
991            {
992                /* CT requests for all attributes */
993                int attr_cnt;
994                num_attr = BTRC_MAX_ELEM_ATTR_SIZE;
995                for (attr_cnt = 0; attr_cnt < BTRC_MAX_ELEM_ATTR_SIZE; attr_cnt++)
996                {
997                    element_attrs[attr_cnt] = attr_cnt + 1;
998                }
999            }
1000            else if (pavrc_cmd->get_elem_attrs.num_attr == 0xFF)
1001            {
1002                /* 0xff indicates, no attributes requested - reject */
1003                send_reject_response (btif_rc_cb.rc_handle, label, pavrc_cmd->pdu,
1004                    AVRC_STS_BAD_PARAM);
1005                return;
1006            }
1007            else
1008            {
1009                num_attr = pavrc_cmd->get_elem_attrs.num_attr;
1010                memcpy(element_attrs, pavrc_cmd->get_elem_attrs.attrs, sizeof(UINT32)
1011                    *pavrc_cmd->get_elem_attrs.num_attr);
1012            }
1013            FILL_PDU_QUEUE(IDX_GET_ELEMENT_ATTR_RSP, ctype, label, TRUE);
1014            HAL_CBACK(bt_rc_callbacks, get_element_attr_cb, num_attr, element_attrs);
1015        }
1016        break;
1017        case AVRC_PDU_REGISTER_NOTIFICATION:
1018        {
1019            if(pavrc_cmd->reg_notif.event_id == BTRC_EVT_PLAY_POS_CHANGED &&
1020                pavrc_cmd->reg_notif.param == 0)
1021            {
1022                BTIF_TRACE_WARNING1("%s Device registering position changed with illegal param 0.",
1023                    __FUNCTION__);
1024                send_reject_response (btif_rc_cb.rc_handle, label, pavrc_cmd->pdu, AVRC_STS_BAD_PARAM);
1025                /* de-register this notification for a rejected response */
1026                btif_rc_cb.rc_notif[BTRC_EVT_PLAY_POS_CHANGED - 1].bNotify = FALSE;
1027                return;
1028            }
1029            HAL_CBACK(bt_rc_callbacks, register_notification_cb, pavrc_cmd->reg_notif.event_id,
1030                pavrc_cmd->reg_notif.param);
1031        }
1032        break;
1033        case AVRC_PDU_INFORM_DISPLAY_CHARSET:
1034        {
1035            tAVRC_RESPONSE avrc_rsp;
1036            BTIF_TRACE_EVENT1("%s() AVRC_PDU_INFORM_DISPLAY_CHARSET", __FUNCTION__);
1037            if(btif_rc_cb.rc_connected == TRUE)
1038            {
1039                memset(&(avrc_rsp.inform_charset), 0, sizeof(tAVRC_RSP));
1040                avrc_rsp.inform_charset.opcode=opcode_from_pdu(AVRC_PDU_INFORM_DISPLAY_CHARSET);
1041                avrc_rsp.inform_charset.pdu=AVRC_PDU_INFORM_DISPLAY_CHARSET;
1042                avrc_rsp.inform_charset.status=AVRC_STS_NO_ERROR;
1043                send_metamsg_rsp(btif_rc_cb.rc_handle, label, ctype, &avrc_rsp);
1044            }
1045        }
1046        break;
1047        default:
1048        {
1049        send_reject_response (btif_rc_cb.rc_handle, label, pavrc_cmd->pdu,
1050            (pavrc_cmd->pdu == AVRC_PDU_SEARCH)?AVRC_STS_SEARCH_NOT_SUP:AVRC_STS_BAD_CMD);
1051        return;
1052        }
1053        break;
1054    }
1055
1056}
1057
1058
1059/*******************************************************************************
1060**
1061** Function         btif_rc_upstreams_rsp_evt
1062**
1063** Description      Executes AVRC UPSTREAMS response events in btif context.
1064**
1065** Returns          void
1066**
1067*******************************************************************************/
1068static void btif_rc_upstreams_rsp_evt(UINT16 event, tAVRC_RESPONSE *pavrc_resp, UINT8 ctype, UINT8 label)
1069{
1070    BTIF_TRACE_EVENT5("%s pdu: %s handle: 0x%x ctype:%x label:%x", __FUNCTION__,
1071        dump_rc_pdu(pavrc_resp->pdu), btif_rc_cb.rc_handle, ctype, label);
1072
1073#if (AVRC_ADV_CTRL_INCLUDED == TRUE)
1074    switch (event)
1075    {
1076        case AVRC_PDU_REGISTER_NOTIFICATION:
1077        {
1078             if(AVRC_RSP_CHANGED==ctype)
1079                 btif_rc_cb.rc_volume=pavrc_resp->reg_notif.param.volume;
1080             HAL_CBACK(bt_rc_callbacks, volume_change_cb, pavrc_resp->reg_notif.param.volume,ctype)
1081        }
1082        break;
1083
1084        case AVRC_PDU_SET_ABSOLUTE_VOLUME:
1085        {
1086            BTIF_TRACE_DEBUG2("Set absolute volume change event received: volume %d,ctype %d",
1087                pavrc_resp->volume.volume,ctype);
1088            if(AVRC_RSP_ACCEPT==ctype)
1089                btif_rc_cb.rc_volume=pavrc_resp->volume.volume;
1090            HAL_CBACK(bt_rc_callbacks,volume_change_cb,pavrc_resp->volume.volume,ctype)
1091        }
1092        break;
1093
1094        default:
1095            return;
1096    }
1097#endif
1098}
1099
1100/************************************************************************************
1101**  AVRCP API Functions
1102************************************************************************************/
1103
1104/*******************************************************************************
1105**
1106** Function         init
1107**
1108** Description      Initializes the AVRC interface
1109**
1110** Returns          bt_status_t
1111**
1112*******************************************************************************/
1113static bt_status_t init(btrc_callbacks_t* callbacks )
1114{
1115    BTIF_TRACE_EVENT1("## %s ##", __FUNCTION__);
1116    bt_status_t result = BT_STATUS_SUCCESS;
1117
1118    if (bt_rc_callbacks)
1119        return BT_STATUS_DONE;
1120
1121    bt_rc_callbacks = callbacks;
1122    memset (&btif_rc_cb, 0, sizeof(btif_rc_cb));
1123    btif_rc_cb.rc_vol_label=MAX_LABEL;
1124    btif_rc_cb.rc_volume=MAX_VOLUME;
1125    lbl_init();
1126
1127    return result;
1128}
1129
1130/***************************************************************************
1131**
1132** Function         get_play_status_rsp
1133**
1134** Description      Returns the current play status.
1135**                      This method is called in response to
1136**                      GetPlayStatus request.
1137**
1138** Returns          bt_status_t
1139**
1140***************************************************************************/
1141static bt_status_t get_play_status_rsp(btrc_play_status_t play_status, uint32_t song_len,
1142    uint32_t song_pos)
1143{
1144    tAVRC_RESPONSE avrc_rsp;
1145    UINT32 i;
1146    CHECK_RC_CONNECTED
1147    memset(&(avrc_rsp.get_play_status), 0, sizeof(tAVRC_GET_PLAY_STATUS_RSP));
1148    avrc_rsp.get_play_status.song_len = song_len;
1149    avrc_rsp.get_play_status.song_pos = song_pos;
1150    avrc_rsp.get_play_status.play_status = play_status;
1151
1152    avrc_rsp.get_play_status.pdu = AVRC_PDU_GET_PLAY_STATUS;
1153    avrc_rsp.get_play_status.opcode = opcode_from_pdu(AVRC_PDU_GET_PLAY_STATUS);
1154    avrc_rsp.get_play_status.status = AVRC_STS_NO_ERROR;
1155    /* Send the response */
1156    SEND_METAMSG_RSP(IDX_GET_PLAY_STATUS_RSP, &avrc_rsp);
1157    return BT_STATUS_SUCCESS;
1158}
1159
1160/***************************************************************************
1161**
1162** Function         get_element_attr_rsp
1163**
1164** Description      Returns the current songs' element attributes
1165**                      in text.
1166**
1167** Returns          bt_status_t
1168**
1169***************************************************************************/
1170static bt_status_t get_element_attr_rsp(uint8_t num_attr, btrc_element_attr_val_t *p_attrs)
1171{
1172    tAVRC_RESPONSE avrc_rsp;
1173    UINT32 i;
1174    uint8_t j;
1175    tAVRC_ATTR_ENTRY element_attrs[BTRC_MAX_ELEM_ATTR_SIZE];
1176    CHECK_RC_CONNECTED
1177    memset(element_attrs, 0, sizeof(tAVRC_ATTR_ENTRY) * num_attr);
1178
1179    if (num_attr == 0)
1180    {
1181        avrc_rsp.get_play_status.status = AVRC_STS_BAD_PARAM;
1182    }
1183    else
1184    {
1185        for (i=0; i<num_attr; i++) {
1186            element_attrs[i].attr_id = p_attrs[i].attr_id;
1187            element_attrs[i].name.charset_id = AVRC_CHARSET_ID_UTF8;
1188            element_attrs[i].name.str_len = (UINT16)strlen((char *)p_attrs[i].text);
1189            element_attrs[i].name.p_str = p_attrs[i].text;
1190            BTIF_TRACE_DEBUG5("%s attr_id:0x%x, charset_id:0x%x, str_len:%d, str:%s",
1191                __FUNCTION__, (unsigned int)element_attrs[i].attr_id,
1192                element_attrs[i].name.charset_id, element_attrs[i].name.str_len,
1193                element_attrs[i].name.p_str);
1194        }
1195        avrc_rsp.get_play_status.status = AVRC_STS_NO_ERROR;
1196    }
1197    avrc_rsp.get_elem_attrs.num_attr = num_attr;
1198    avrc_rsp.get_elem_attrs.p_attrs = element_attrs;
1199    avrc_rsp.get_elem_attrs.pdu = AVRC_PDU_GET_ELEMENT_ATTR;
1200    avrc_rsp.get_elem_attrs.opcode = opcode_from_pdu(AVRC_PDU_GET_ELEMENT_ATTR);
1201    /* Send the response */
1202    SEND_METAMSG_RSP(IDX_GET_ELEMENT_ATTR_RSP, &avrc_rsp);
1203    return BT_STATUS_SUCCESS;
1204}
1205
1206/***************************************************************************
1207**
1208** Function         register_notification_rsp
1209**
1210** Description      Response to the register notification request.
1211**                      in text.
1212**
1213** Returns          bt_status_t
1214**
1215***************************************************************************/
1216static bt_status_t register_notification_rsp(btrc_event_id_t event_id,
1217    btrc_notification_type_t type, btrc_register_notification_t *p_param)
1218{
1219    tAVRC_RESPONSE avrc_rsp;
1220    CHECK_RC_CONNECTED
1221    BTIF_TRACE_EVENT2("## %s ## event_id:%s", __FUNCTION__, dump_rc_notification_event_id(event_id));
1222    memset(&(avrc_rsp.reg_notif), 0, sizeof(tAVRC_REG_NOTIF_RSP));
1223    avrc_rsp.reg_notif.event_id = event_id;
1224
1225    switch(event_id)
1226    {
1227        case BTRC_EVT_PLAY_STATUS_CHANGED:
1228            avrc_rsp.reg_notif.param.play_status = p_param->play_status;
1229            break;
1230        case BTRC_EVT_TRACK_CHANGE:
1231            memcpy(&(avrc_rsp.reg_notif.param.track), &(p_param->track), sizeof(btrc_uid_t));
1232            break;
1233        case BTRC_EVT_PLAY_POS_CHANGED:
1234            avrc_rsp.reg_notif.param.play_pos = p_param->song_pos;
1235            break;
1236        default:
1237            BTIF_TRACE_WARNING2("%s : Unhandled event ID : 0x%x", __FUNCTION__, event_id);
1238            return BT_STATUS_UNHANDLED;
1239    }
1240
1241    avrc_rsp.reg_notif.pdu = AVRC_PDU_REGISTER_NOTIFICATION;
1242    avrc_rsp.reg_notif.opcode = opcode_from_pdu(AVRC_PDU_REGISTER_NOTIFICATION);
1243    avrc_rsp.get_play_status.status = AVRC_STS_NO_ERROR;
1244
1245    /* Send the response. */
1246    send_metamsg_rsp(btif_rc_cb.rc_handle, btif_rc_cb.rc_notif[event_id-1].label,
1247        ((type == BTRC_NOTIFICATION_TYPE_INTERIM)?AVRC_CMD_NOTIF:AVRC_RSP_CHANGED), &avrc_rsp);
1248    return BT_STATUS_SUCCESS;
1249}
1250
1251/***************************************************************************
1252**
1253** Function         set_volume
1254**
1255** Description      Send current volume setting to remote side.
1256**                  Support limited to SetAbsoluteVolume
1257**                  This can be enhanced to support Relative Volume (AVRCP 1.0).
1258**                  With RelateVolume, we will send VOLUME_UP/VOLUME_DOWN
1259**                  as opposed to absolute volume level
1260** volume: Should be in the range 0-127. bit7 is reseved and cannot be set
1261**
1262** Returns          bt_status_t
1263**
1264***************************************************************************/
1265static bt_status_t set_volume(uint8_t volume)
1266{
1267    BTIF_TRACE_DEBUG1("%s", __FUNCTION__);
1268    CHECK_RC_CONNECTED
1269    tAVRC_STS status = BT_STATUS_UNSUPPORTED;
1270    rc_transaction_t *p_transaction=NULL;
1271
1272    if(btif_rc_cb.rc_volume==volume)
1273    {
1274        status=BT_STATUS_DONE;
1275        BTIF_TRACE_ERROR2("%s: volume value already set earlier: 0x%02x",__FUNCTION__, volume);
1276        return status;
1277    }
1278
1279    if ((btif_rc_cb.rc_features & BTA_AV_FEAT_RCTG) &&
1280        (btif_rc_cb.rc_features & BTA_AV_FEAT_ADV_CTRL))
1281    {
1282        tAVRC_COMMAND avrc_cmd = {0};
1283        BT_HDR *p_msg = NULL;
1284
1285        BTIF_TRACE_DEBUG2("%s: Peer supports absolute volume. newVolume=%d", __FUNCTION__, volume);
1286        avrc_cmd.volume.opcode = AVRC_OP_VENDOR;
1287        avrc_cmd.volume.pdu = AVRC_PDU_SET_ABSOLUTE_VOLUME;
1288        avrc_cmd.volume.status = AVRC_STS_NO_ERROR;
1289        avrc_cmd.volume.volume = volume;
1290
1291        if (AVRC_BldCommand(&avrc_cmd, &p_msg) == AVRC_STS_NO_ERROR)
1292        {
1293            bt_status_t tran_status=get_transaction(&p_transaction);
1294            if(BT_STATUS_SUCCESS == tran_status && NULL!=p_transaction)
1295            {
1296                BTIF_TRACE_DEBUG2("%s msgreq being sent out with label %d",
1297                                   __FUNCTION__,p_transaction->lbl);
1298                BTA_AvMetaCmd(btif_rc_cb.rc_handle,p_transaction->lbl, AVRC_CMD_CTRL, p_msg);
1299                status =  BT_STATUS_SUCCESS;
1300            }
1301            else
1302            {
1303                if(NULL!=p_msg)
1304                   GKI_freebuf(p_msg);
1305                BTIF_TRACE_ERROR2("%s: failed to obtain transaction details. status: 0x%02x",
1306                                    __FUNCTION__, tran_status);
1307                status = BT_STATUS_FAIL;
1308            }
1309        }
1310        else
1311        {
1312            BTIF_TRACE_ERROR2("%s: failed to build absolute volume command. status: 0x%02x",
1313                                __FUNCTION__, status);
1314            status = BT_STATUS_FAIL;
1315        }
1316    }
1317    else
1318        status=BT_STATUS_NOT_READY;
1319    return status;
1320}
1321
1322
1323/***************************************************************************
1324**
1325** Function         register_volumechange
1326**
1327** Description     Register for volume change notification from remote side.
1328**
1329** Returns          void
1330**
1331***************************************************************************/
1332
1333static void register_volumechange (UINT8 lbl)
1334{
1335    tAVRC_COMMAND avrc_cmd = {0};
1336    BT_HDR *p_msg = NULL;
1337    tAVRC_STS BldResp=AVRC_STS_BAD_CMD;
1338    UINT16 rv = 0;
1339    bt_status_t tran_status;
1340    rc_transaction_t *p_transaction=NULL;
1341
1342    BTIF_TRACE_DEBUG2("%s called with label:%d",__FUNCTION__,lbl);
1343
1344    avrc_cmd.cmd.opcode=0x00;
1345    avrc_cmd.pdu = AVRC_PDU_REGISTER_NOTIFICATION;
1346    avrc_cmd.reg_notif.event_id = AVRC_EVT_VOLUME_CHANGE;
1347    avrc_cmd.reg_notif.status = AVRC_STS_NO_ERROR;
1348
1349    BldResp=AVRC_BldCommand(&avrc_cmd, &p_msg);
1350    if(AVRC_STS_NO_ERROR==BldResp && p_msg)
1351    {
1352         p_transaction=get_transaction_by_lbl(lbl);
1353         if(NULL!=p_transaction)
1354         {
1355             BTA_AvMetaCmd(btif_rc_cb.rc_handle,p_transaction->lbl, AVRC_CMD_NOTIF, p_msg);
1356             BTIF_TRACE_DEBUG1("%s:BTA_AvMetaCmd called",__FUNCTION__);
1357         }
1358         else
1359         {
1360            if(NULL!=p_msg)
1361               GKI_freebuf(p_msg);
1362            BTIF_TRACE_ERROR2("%s transaction not obtained with label: %d",__FUNCTION__,lbl);
1363         }
1364    }
1365    else
1366        BTIF_TRACE_ERROR2("%s failed to build command:%d",__FUNCTION__,BldResp);
1367}
1368
1369
1370/***************************************************************************
1371**
1372** Function         handle_rc_metamsg_rsp
1373**
1374** Description      Handle RC metamessage response
1375**
1376** Returns          void
1377**
1378***************************************************************************/
1379static void handle_rc_metamsg_rsp(tBTA_AV_META_MSG *pmeta_msg)
1380{
1381    tAVRC_RESPONSE    avrc_response = {0};
1382    UINT8             scratch_buf[512] = {0};
1383    tAVRC_STS status = BT_STATUS_UNSUPPORTED;
1384
1385    if(AVRC_OP_VENDOR==pmeta_msg->p_msg->hdr.opcode &&(AVRC_RSP_CHANGED==pmeta_msg->code
1386      || AVRC_RSP_INTERIM==pmeta_msg->code || AVRC_RSP_ACCEPT==pmeta_msg->code
1387      || AVRC_RSP_REJ==pmeta_msg->code || AVRC_RSP_NOT_IMPL==pmeta_msg->code))
1388    {
1389        status=AVRC_ParsResponse(pmeta_msg->p_msg, &avrc_response, scratch_buf, sizeof(scratch_buf));
1390        BTIF_TRACE_DEBUG6("%s: code %d,event ID %d,PDU %x,parsing status %d, label:%d",
1391          __FUNCTION__,pmeta_msg->code,avrc_response.reg_notif.event_id,avrc_response.reg_notif.pdu,
1392          status, pmeta_msg->label);
1393
1394        if (status != AVRC_STS_NO_ERROR)
1395        {
1396            if(AVRC_PDU_REGISTER_NOTIFICATION==avrc_response.rsp.pdu
1397                && AVRC_EVT_VOLUME_CHANGE==avrc_response.reg_notif.event_id
1398                && btif_rc_cb.rc_vol_label==pmeta_msg->label)
1399            {
1400                btif_rc_cb.rc_vol_label=MAX_LABEL;
1401                release_transaction(btif_rc_cb.rc_vol_label);
1402            }
1403            else if(AVRC_PDU_SET_ABSOLUTE_VOLUME==avrc_response.rsp.pdu)
1404            {
1405                release_transaction(pmeta_msg->label);
1406            }
1407            return;
1408        }
1409        else if(AVRC_PDU_REGISTER_NOTIFICATION==avrc_response.rsp.pdu
1410            && AVRC_EVT_VOLUME_CHANGE==avrc_response.reg_notif.event_id
1411            && btif_rc_cb.rc_vol_label!=pmeta_msg->label)
1412            {
1413                // Just discard the message, if the device sends back with an incorrect label
1414                BTIF_TRACE_DEBUG3("%s:Discarding register notfn in rsp.code: %d and label %d",
1415                __FUNCTION__, pmeta_msg->code, pmeta_msg->label);
1416                return;
1417            }
1418    }
1419    else
1420    {
1421        BTIF_TRACE_DEBUG3("%s:Received vendor dependent in adv ctrl rsp. code: %d len: %d. Not processing it.",
1422        __FUNCTION__, pmeta_msg->code, pmeta_msg->len);
1423        return;
1424    }
1425
1426    if(AVRC_PDU_REGISTER_NOTIFICATION==avrc_response.rsp.pdu
1427        && AVRC_EVT_VOLUME_CHANGE==avrc_response.reg_notif.event_id
1428        && AVRC_RSP_CHANGED==pmeta_msg->code)
1429     {
1430         /* re-register for volume change notification */
1431         // Do not re-register for rejected case, as it might get into endless loop
1432         register_volumechange(btif_rc_cb.rc_vol_label);
1433     }
1434     else if(AVRC_PDU_SET_ABSOLUTE_VOLUME==avrc_response.rsp.pdu)
1435     {
1436          /* free up the label here */
1437          release_transaction(pmeta_msg->label);
1438     }
1439
1440     BTIF_TRACE_EVENT2("%s: Passing received metamsg response to app. pdu: %s",
1441             __FUNCTION__, dump_rc_pdu(avrc_response.pdu));
1442     btif_rc_upstreams_rsp_evt((uint16_t)avrc_response.rsp.pdu, &avrc_response, pmeta_msg->code,
1443                                pmeta_msg->label);
1444}
1445
1446
1447/***************************************************************************
1448**
1449** Function         cleanup
1450**
1451** Description      Closes the AVRC interface
1452**
1453** Returns          void
1454**
1455***************************************************************************/
1456static void cleanup()
1457{
1458    BTIF_TRACE_EVENT1("## %s ##", __FUNCTION__);
1459    close_uinput();
1460    if (bt_rc_callbacks)
1461    {
1462        bt_rc_callbacks = NULL;
1463    }
1464    memset(&btif_rc_cb, 0, sizeof(btif_rc_cb_t));
1465    lbl_destroy();
1466}
1467
1468
1469static const btrc_interface_t bt_rc_interface = {
1470    sizeof(bt_rc_interface),
1471    init,
1472    get_play_status_rsp,
1473    NULL, /* list_player_app_attr_rsp */
1474    NULL, /* list_player_app_value_rsp */
1475    NULL, /* get_player_app_value_rsp */
1476    NULL, /* get_player_app_attr_text_rsp */
1477    NULL, /* get_player_app_value_text_rsp */
1478    get_element_attr_rsp,
1479    NULL, /* set_player_app_value_rsp */
1480    register_notification_rsp,
1481    set_volume,
1482    cleanup,
1483};
1484
1485/*******************************************************************************
1486**
1487** Function         btif_rc_get_interface
1488**
1489** Description      Get the AVRCP callback interface
1490**
1491** Returns          btav_interface_t
1492**
1493*******************************************************************************/
1494const btrc_interface_t *btif_rc_get_interface(void)
1495{
1496    BTIF_TRACE_EVENT1("%s", __FUNCTION__);
1497    return &bt_rc_interface;
1498}
1499
1500/*******************************************************************************
1501**      Function         initialize_transaction
1502**
1503**      Description    Initializes fields of the transaction structure
1504**
1505**      Returns          void
1506*******************************************************************************/
1507static void initialize_transaction(int lbl)
1508{
1509    pthread_mutex_lock(&device.lbllock);
1510    if(lbl < MAX_TRANSACTIONS_PER_SESSION)
1511    {
1512       device.transaction[lbl].lbl = lbl;
1513       device.transaction[lbl].in_use=FALSE;
1514       device.transaction[lbl].handle=0;
1515    }
1516    pthread_mutex_unlock(&device.lbllock);
1517}
1518
1519/*******************************************************************************
1520**      Function         lbl_init
1521**
1522**      Description    Initializes label structures and mutexes.
1523**
1524**      Returns         void
1525*******************************************************************************/
1526void lbl_init()
1527{
1528    memset(&device,0,sizeof(rc_device_t));
1529    pthread_mutexattr_t attr;
1530    pthread_mutexattr_init(&attr);
1531    pthread_mutex_init(&(device.lbllock), &attr);
1532    pthread_mutexattr_destroy(&attr);
1533    init_all_transactions();
1534}
1535
1536/*******************************************************************************
1537**
1538** Function         init_all_transactions
1539**
1540** Description    Initializes all transactions
1541**
1542** Returns          void
1543*******************************************************************************/
1544void init_all_transactions()
1545{
1546    UINT8 txn_indx=0;
1547    for(txn_indx=0; txn_indx < MAX_TRANSACTIONS_PER_SESSION; txn_indx++)
1548    {
1549        initialize_transaction(txn_indx);
1550    }
1551}
1552
1553/*******************************************************************************
1554**
1555** Function         get_transaction_by_lbl
1556**
1557** Description    Will return a transaction based on the label. If not inuse
1558**                     will return an error.
1559**
1560** Returns          bt_status_t
1561*******************************************************************************/
1562rc_transaction_t *get_transaction_by_lbl(UINT8 lbl)
1563{
1564    rc_transaction_t *transaction = NULL;
1565    pthread_mutex_lock(&device.lbllock);
1566
1567    /* Determine if this is a valid label */
1568    if (lbl < MAX_TRANSACTIONS_PER_SESSION)
1569    {
1570        if (FALSE==device.transaction[lbl].in_use)
1571        {
1572            transaction = NULL;
1573        }
1574        else
1575        {
1576            transaction = &(device.transaction[lbl]);
1577            BTIF_TRACE_DEBUG2("%s: Got transaction.label: %d",__FUNCTION__,lbl);
1578        }
1579    }
1580
1581    pthread_mutex_unlock(&device.lbllock);
1582    return transaction;
1583}
1584
1585/*******************************************************************************
1586**
1587** Function         get_transaction
1588**
1589** Description    Obtains the transaction details.
1590**
1591** Returns          bt_status_t
1592*******************************************************************************/
1593
1594bt_status_t  get_transaction(rc_transaction_t **ptransaction)
1595{
1596    bt_status_t result = BT_STATUS_NOMEM;
1597    UINT8 i=0;
1598    pthread_mutex_lock(&device.lbllock);
1599
1600    // Check for unused transactions
1601    for (i=0; i<MAX_TRANSACTIONS_PER_SESSION; i++)
1602    {
1603        if (FALSE==device.transaction[i].in_use)
1604        {
1605            BTIF_TRACE_DEBUG2("%s:Got transaction.label: %d",__FUNCTION__,device.transaction[i].lbl);
1606            device.transaction[i].in_use = TRUE;
1607            *ptransaction = &(device.transaction[i]);
1608            result = BT_STATUS_SUCCESS;
1609            break;
1610        }
1611    }
1612
1613    pthread_mutex_unlock(&device.lbllock);
1614    return result;
1615}
1616
1617
1618/*******************************************************************************
1619**
1620** Function         release_transaction
1621**
1622** Description    Will release a transaction for reuse
1623**
1624** Returns          bt_status_t
1625*******************************************************************************/
1626void release_transaction(UINT8 lbl)
1627{
1628    rc_transaction_t *transaction = get_transaction_by_lbl(lbl);
1629
1630    /* If the transaction is in use... */
1631    if (transaction != NULL)
1632    {
1633        BTIF_TRACE_DEBUG2("%s: lbl: %d", __FUNCTION__, lbl);
1634        initialize_transaction(lbl);
1635    }
1636}
1637
1638/*******************************************************************************
1639**
1640** Function         lbl_destroy
1641**
1642** Description    Cleanup of the mutex
1643**
1644** Returns          void
1645*******************************************************************************/
1646void lbl_destroy()
1647{
1648    pthread_mutex_destroy(&(device.lbllock));
1649}
1650
1651/*******************************************************************************
1652**      Function       dev_blacklisted_for_absolute_volume
1653**
1654**      Description    Blacklist Devices that donot handle absolute volume well
1655**                     We are blacklisting all the devices that are not in whitelist
1656**
1657**      Returns        True if the device is in the list
1658*******************************************************************************/
1659static BOOLEAN dev_blacklisted_for_absolute_volume(BD_ADDR peer_dev)
1660{
1661    int i;
1662    int whitelist_size = sizeof(rc_white_addr_prefix)/sizeof(rc_white_addr_prefix[0]);
1663    for (i = 0; i < whitelist_size; i++) {
1664        if (rc_white_addr_prefix[i][0] == peer_dev[0] &&
1665            rc_white_addr_prefix[i][1] == peer_dev[1] &&
1666            rc_white_addr_prefix[i][2] == peer_dev[2]) {
1667            BTIF_TRACE_DEBUG3("whitelist absolute volume for %02x:%02x:%02x",
1668                                peer_dev[0], peer_dev[1], peer_dev[2]);
1669            return FALSE;
1670        }
1671    }
1672    BTIF_TRACE_WARNING3("blacklist absolute volume for %02x:%02x:%02x",
1673                        peer_dev[0], peer_dev[1], peer_dev[2]);
1674    return TRUE;
1675}
1676