1/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17/*****************************************************************************
18 *
19 *  Filename:      btif_rc.c
20 *
21 *  Description:   Bluetooth AVRC implementation
22 *
23 *****************************************************************************/
24
25#define LOG_TAG "bt_btif_avrc"
26
27#include <errno.h>
28#include <fcntl.h>
29#include <pthread.h>
30#include <string.h>
31#include <time.h>
32#include <unistd.h>
33
34#include <hardware/bluetooth.h>
35#include <hardware/bt_rc.h>
36
37#include "avrc_defs.h"
38#include "bta_api.h"
39#include "bta_av_api.h"
40#include "btif_av.h"
41#include "btif_common.h"
42#include "btif_util.h"
43#include "bt_common.h"
44#include "device/include/interop.h"
45#include "uinput.h"
46#include "bdaddr.h"
47#include "osi/include/list.h"
48#include "osi/include/properties.h"
49#include "btu.h"
50#define RC_INVALID_TRACK_ID (0xFFFFFFFFFFFFFFFFULL)
51
52/*****************************************************************************
53**  Constants & Macros
54******************************************************************************/
55
56/* cod value for Headsets */
57#define COD_AV_HEADSETS        0x0404
58/* for AVRC 1.4 need to change this */
59#define MAX_RC_NOTIFICATIONS AVRC_EVT_VOLUME_CHANGE
60
61#define IDX_GET_PLAY_STATUS_RSP   0
62#define IDX_LIST_APP_ATTR_RSP     1
63#define IDX_LIST_APP_VALUE_RSP    2
64#define IDX_GET_CURR_APP_VAL_RSP  3
65#define IDX_SET_APP_VAL_RSP       4
66#define IDX_GET_APP_ATTR_TXT_RSP  5
67#define IDX_GET_APP_VAL_TXT_RSP   6
68#define IDX_GET_ELEMENT_ATTR_RSP  7
69#define MAX_VOLUME 128
70#define MAX_LABEL 16
71#define MAX_TRANSACTIONS_PER_SESSION 16
72#define MAX_CMD_QUEUE_LEN 8
73#define PLAY_STATUS_PLAYING 1
74
75#define CHECK_RC_CONNECTED                                                                  \
76    BTIF_TRACE_DEBUG("## %s ##", __FUNCTION__);                                            \
77    if (btif_rc_cb.rc_connected == FALSE)                                                    \
78    {                                                                                       \
79        BTIF_TRACE_WARNING("Function %s() called when RC is not connected", __FUNCTION__); \
80        return BT_STATUS_NOT_READY;                                                         \
81    }
82
83#define FILL_PDU_QUEUE(index, ctype, label, pending)        \
84{                                                           \
85    btif_rc_cb.rc_pdu_info[index].ctype = ctype;            \
86    btif_rc_cb.rc_pdu_info[index].label = label;            \
87    btif_rc_cb.rc_pdu_info[index].is_rsp_pending = pending; \
88}
89
90#define SEND_METAMSG_RSP(index, avrc_rsp)                                                      \
91{                                                                                              \
92    if (btif_rc_cb.rc_pdu_info[index].is_rsp_pending == FALSE)                                  \
93    {                                                                                          \
94        BTIF_TRACE_WARNING("%s Not sending response as no PDU was registered", __FUNCTION__); \
95        return BT_STATUS_UNHANDLED;                                                            \
96    }                                                                                          \
97    send_metamsg_rsp(btif_rc_cb.rc_handle, btif_rc_cb.rc_pdu_info[index].label,                \
98        btif_rc_cb.rc_pdu_info[index].ctype, avrc_rsp);                                        \
99    btif_rc_cb.rc_pdu_info[index].ctype = 0;                                                   \
100    btif_rc_cb.rc_pdu_info[index].label = 0;                                                   \
101    btif_rc_cb.rc_pdu_info[index].is_rsp_pending = FALSE;                                      \
102}
103
104/*****************************************************************************
105**  Local type definitions
106******************************************************************************/
107typedef struct {
108    UINT8 bNotify;
109    UINT8 label;
110} btif_rc_reg_notifications_t;
111
112typedef struct
113{
114    UINT8   label;
115    UINT8   ctype;
116    BOOLEAN is_rsp_pending;
117} btif_rc_cmd_ctxt_t;
118
119/* 2 second timeout to get interim response */
120#define BTIF_TIMEOUT_RC_INTERIM_RSP_MS     (2 * 1000)
121#define BTIF_TIMEOUT_RC_STATUS_CMD_MS      (2 * 1000)
122#define BTIF_TIMEOUT_RC_CONTROL_CMD_MS     (2 * 1000)
123
124
125typedef enum
126{
127    eNOT_REGISTERED,
128    eREGISTERED,
129    eINTERIM
130} btif_rc_nfn_reg_status_t;
131
132typedef struct {
133    UINT8                       event_id;
134    UINT8                       label;
135    btif_rc_nfn_reg_status_t    status;
136} btif_rc_supported_event_t;
137
138#define BTIF_RC_STS_TIMEOUT     0xFE
139typedef struct {
140    UINT8   label;
141    UINT8   pdu_id;
142} btif_rc_status_cmd_timer_t;
143
144typedef struct {
145    UINT8   label;
146    UINT8   pdu_id;
147} btif_rc_control_cmd_timer_t;
148
149typedef struct {
150    union {
151        btif_rc_status_cmd_timer_t rc_status_cmd;
152        btif_rc_control_cmd_timer_t rc_control_cmd;
153    };
154} btif_rc_timer_context_t;
155
156typedef struct {
157    BOOLEAN  query_started;
158    UINT8 num_attrs;
159    UINT8 num_ext_attrs;
160
161    UINT8 attr_index;
162    UINT8 ext_attr_index;
163    UINT8 ext_val_index;
164    btrc_player_app_attr_t attrs[AVRC_MAX_APP_ATTR_SIZE];
165    btrc_player_app_ext_attr_t ext_attrs[AVRC_MAX_APP_ATTR_SIZE];
166} btif_rc_player_app_settings_t;
167
168/* TODO : Merge btif_rc_reg_notifications_t and btif_rc_cmd_ctxt_t to a single struct */
169typedef struct {
170    BOOLEAN                     rc_connected;
171    UINT8                       rc_handle;
172    tBTA_AV_FEAT                rc_features;
173    BD_ADDR                     rc_addr;
174    UINT16                      rc_pending_play;
175    btif_rc_cmd_ctxt_t          rc_pdu_info[MAX_CMD_QUEUE_LEN];
176    btif_rc_reg_notifications_t rc_notif[MAX_RC_NOTIFICATIONS];
177    unsigned int                rc_volume;
178    uint8_t                     rc_vol_label;
179    list_t                      *rc_supported_event_list;
180    btif_rc_player_app_settings_t   rc_app_settings;
181    alarm_t                     *rc_play_status_timer;
182    BOOLEAN                     rc_features_processed;
183    UINT64                      rc_playing_uid;
184    BOOLEAN                     rc_procedure_complete;
185} btif_rc_cb_t;
186
187typedef struct {
188    BOOLEAN in_use;
189    UINT8 lbl;
190    UINT8 handle;
191    btif_rc_timer_context_t txn_timer_context;
192    alarm_t *txn_timer;
193} rc_transaction_t;
194
195typedef struct
196{
197    pthread_mutex_t lbllock;
198    rc_transaction_t transaction[MAX_TRANSACTIONS_PER_SESSION];
199} rc_device_t;
200
201rc_device_t device;
202
203#define MAX_UINPUT_PATHS 3
204static const char* uinput_dev_path[] =
205                       {"/dev/uinput", "/dev/input/uinput", "/dev/misc/uinput" };
206static int uinput_fd = -1;
207
208static int  send_event (int fd, uint16_t type, uint16_t code, int32_t value);
209static void send_key (int fd, uint16_t key, int pressed);
210static int  uinput_driver_check();
211static int  uinput_create(char *name);
212static int  init_uinput (void);
213static void close_uinput (void);
214static void sleep_ms(period_ms_t timeout_ms);
215
216static const struct {
217    const char *name;
218    uint8_t avrcp;
219    uint16_t mapped_id;
220    uint8_t release_quirk;
221} key_map[] = {
222    { "PLAY",         AVRC_ID_PLAY,     KEY_PLAYCD,       1 },
223    { "STOP",         AVRC_ID_STOP,     KEY_STOPCD,       0 },
224    { "PAUSE",        AVRC_ID_PAUSE,    KEY_PAUSECD,      1 },
225    { "FORWARD",      AVRC_ID_FORWARD,  KEY_NEXTSONG,     0 },
226    { "BACKWARD",     AVRC_ID_BACKWARD, KEY_PREVIOUSSONG, 0 },
227    { "REWIND",       AVRC_ID_REWIND,   KEY_REWIND,       0 },
228    { "FAST FORWARD", AVRC_ID_FAST_FOR, KEY_FAST_FORWARD, 0 },
229    { NULL,           0,                0,                0 }
230};
231
232static void send_reject_response (UINT8 rc_handle, UINT8 label,
233    UINT8 pdu, UINT8 status);
234static UINT8 opcode_from_pdu(UINT8 pdu);
235static void send_metamsg_rsp (UINT8 rc_handle, UINT8 label,
236    tBTA_AV_CODE code, tAVRC_RESPONSE *pmetamsg_resp);
237#if (AVRC_ADV_CTRL_INCLUDED == TRUE)
238static void register_volumechange(UINT8 label);
239#endif
240static void lbl_init();
241static void lbl_destroy();
242static void init_all_transactions();
243static bt_status_t  get_transaction(rc_transaction_t **ptransaction);
244static void release_transaction(UINT8 label);
245static rc_transaction_t* get_transaction_by_lbl(UINT8 label);
246#if (AVRC_ADV_CTRL_INCLUDED == TRUE)
247static void handle_rc_metamsg_rsp(tBTA_AV_META_MSG *pmeta_msg);
248#endif
249#if (AVRC_CTLR_INCLUDED == TRUE)
250static void handle_avk_rc_metamsg_cmd(tBTA_AV_META_MSG *pmeta_msg);
251static void handle_avk_rc_metamsg_rsp(tBTA_AV_META_MSG *pmeta_msg);
252static void btif_rc_ctrl_upstreams_rsp_cmd(
253    UINT8 event, tAVRC_COMMAND *pavrc_cmd, UINT8 label);
254static void rc_ctrl_procedure_complete();
255static void rc_stop_play_status_timer();
256static void register_for_event_notification (btif_rc_supported_event_t *p_event);
257static void handle_get_capability_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_GET_CAPS_RSP *p_rsp);
258static void handle_app_attr_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_LIST_APP_ATTR_RSP *p_rsp);
259static void handle_app_val_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_LIST_APP_VALUES_RSP *p_rsp);
260static void handle_app_cur_val_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_GET_CUR_APP_VALUE_RSP *p_rsp);
261static void handle_app_attr_txt_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_GET_APP_ATTR_TXT_RSP *p_rsp);
262static void handle_app_attr_val_txt_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_GET_APP_ATTR_TXT_RSP *p_rsp);
263static void handle_get_playstatus_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_GET_PLAY_STATUS_RSP *p_rsp);
264static void handle_get_elem_attr_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_GET_ELEM_ATTRS_RSP *p_rsp);
265static void handle_set_app_attr_val_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_RSP *p_rsp);
266static bt_status_t get_play_status_cmd(void);
267static bt_status_t get_player_app_setting_attr_text_cmd (UINT8 *attrs, UINT8 num_attrs);
268static bt_status_t get_player_app_setting_value_text_cmd (UINT8 *vals, UINT8 num_vals);
269static bt_status_t register_notification_cmd (UINT8 label, UINT8 event_id, UINT32 event_value);
270static bt_status_t get_element_attribute_cmd (uint8_t num_attribute, uint32_t *p_attr_ids);
271static bt_status_t getcapabilities_cmd (uint8_t cap_id);
272static bt_status_t list_player_app_setting_attrib_cmd(void);
273static bt_status_t list_player_app_setting_value_cmd(uint8_t attrib_id);
274static bt_status_t get_player_app_setting_cmd(uint8_t num_attrib, uint8_t* attrib_ids);
275#endif
276static void btif_rc_upstreams_evt(UINT16 event, tAVRC_COMMAND* p_param, UINT8 ctype, UINT8 label);
277#if (AVRC_ADV_CTRL_INCLUDED == TRUE)
278static void btif_rc_upstreams_rsp_evt(UINT16 event, tAVRC_RESPONSE *pavrc_resp, UINT8 ctype, UINT8 label);
279#endif
280static void rc_start_play_status_timer(void);
281static bool absolute_volume_disabled(void);
282
283/*****************************************************************************
284**  Static variables
285******************************************************************************/
286static btif_rc_cb_t btif_rc_cb;
287static btrc_callbacks_t *bt_rc_callbacks = NULL;
288static btrc_ctrl_callbacks_t *bt_rc_ctrl_callbacks = NULL;
289
290/*****************************************************************************
291**  Static functions
292******************************************************************************/
293
294/*****************************************************************************
295**  Externs
296******************************************************************************/
297extern BOOLEAN btif_hf_call_terminated_recently();
298extern BOOLEAN check_cod(const bt_bdaddr_t *remote_bdaddr, uint32_t cod);
299
300extern fixed_queue_t *btu_general_alarm_queue;
301
302/*****************************************************************************
303**  Functions
304******************************************************************************/
305
306/*****************************************************************************
307**   Local uinput helper functions
308******************************************************************************/
309int send_event (int fd, uint16_t type, uint16_t code, int32_t value)
310{
311    struct uinput_event event;
312    BTIF_TRACE_DEBUG("%s type:%u code:%u value:%d", __FUNCTION__,
313        type, code, value);
314    memset(&event, 0, sizeof(event));
315    event.type  = type;
316    event.code  = code;
317    event.value = value;
318
319    ssize_t ret;
320    OSI_NO_INTR(ret = write(fd, &event, sizeof(event)));
321    return (int)ret;
322}
323
324void send_key (int fd, uint16_t key, int pressed)
325{
326    BTIF_TRACE_DEBUG("%s fd:%d key:%u pressed:%d", __FUNCTION__,
327        fd, key, pressed);
328
329    if (fd < 0)
330    {
331        return;
332    }
333
334    BTIF_TRACE_DEBUG("AVRCP: Send key %d (%d) fd=%d", key, pressed, fd);
335    send_event(fd, EV_KEY, key, pressed);
336    send_event(fd, EV_SYN, SYN_REPORT, 0);
337}
338
339/************** uinput related functions **************/
340int uinput_driver_check()
341{
342    uint32_t i;
343    for (i=0; i < MAX_UINPUT_PATHS; i++)
344    {
345        if (access(uinput_dev_path[i], O_RDWR) == 0) {
346           return 0;
347        }
348    }
349    BTIF_TRACE_ERROR("%s ERROR: uinput device is not in the system", __FUNCTION__);
350    return -1;
351}
352
353int uinput_create(char *name)
354{
355    struct uinput_dev dev;
356    int fd, x = 0;
357
358    for(x=0; x < MAX_UINPUT_PATHS; x++)
359    {
360        fd = open(uinput_dev_path[x], O_RDWR);
361        if (fd < 0)
362            continue;
363        break;
364    }
365    if (x == MAX_UINPUT_PATHS) {
366        BTIF_TRACE_ERROR("%s ERROR: uinput device open failed", __FUNCTION__);
367        return -1;
368    }
369    memset(&dev, 0, sizeof(dev));
370    if (name)
371        strncpy(dev.name, name, UINPUT_MAX_NAME_SIZE-1);
372
373    dev.id.bustype = BUS_BLUETOOTH;
374    dev.id.vendor  = 0x0000;
375    dev.id.product = 0x0000;
376    dev.id.version = 0x0000;
377
378    ssize_t ret;
379    OSI_NO_INTR(ret = write(fd, &dev, sizeof(dev)));
380    if (ret < 0) {
381        BTIF_TRACE_ERROR("%s Unable to write device information", __FUNCTION__);
382        close(fd);
383        return -1;
384    }
385
386    ioctl(fd, UI_SET_EVBIT, EV_KEY);
387    ioctl(fd, UI_SET_EVBIT, EV_REL);
388    ioctl(fd, UI_SET_EVBIT, EV_SYN);
389
390    for (x = 0; key_map[x].name != NULL; x++)
391        ioctl(fd, UI_SET_KEYBIT, key_map[x].mapped_id);
392
393    if (ioctl(fd, UI_DEV_CREATE, NULL) < 0) {
394        BTIF_TRACE_ERROR("%s Unable to create uinput device", __FUNCTION__);
395        close(fd);
396        return -1;
397    }
398    return fd;
399}
400
401int init_uinput (void)
402{
403    char *name = "AVRCP";
404
405    BTIF_TRACE_DEBUG("%s", __FUNCTION__);
406    uinput_fd = uinput_create(name);
407    if (uinput_fd < 0) {
408        BTIF_TRACE_ERROR("%s AVRCP: Failed to initialize uinput for %s (%d)",
409                          __FUNCTION__, name, uinput_fd);
410    } else {
411        BTIF_TRACE_DEBUG("%s AVRCP: Initialized uinput for %s (fd=%d)",
412                          __FUNCTION__, name, uinput_fd);
413    }
414    return uinput_fd;
415}
416
417void close_uinput (void)
418{
419    BTIF_TRACE_DEBUG("%s", __FUNCTION__);
420    if (uinput_fd > 0) {
421        ioctl(uinput_fd, UI_DEV_DESTROY);
422
423        close(uinput_fd);
424        uinput_fd = -1;
425    }
426}
427
428#if (AVRC_CTLR_INCLUDED == TRUE)
429void rc_cleanup_sent_cmd (void *p_data)
430{
431    BTIF_TRACE_DEBUG("%s", __FUNCTION__);
432
433}
434
435void handle_rc_ctrl_features(BD_ADDR bd_addr)
436{
437    if ((btif_rc_cb.rc_features & BTA_AV_FEAT_RCTG)||
438       ((btif_rc_cb.rc_features & BTA_AV_FEAT_RCCT)&&
439        (btif_rc_cb.rc_features & BTA_AV_FEAT_ADV_CTRL)))
440    {
441        bt_bdaddr_t rc_addr;
442        int rc_features = 0;
443        bdcpy(rc_addr.address,bd_addr);
444
445        if ((btif_rc_cb.rc_features & BTA_AV_FEAT_ADV_CTRL)&&
446             (btif_rc_cb.rc_features & BTA_AV_FEAT_RCCT))
447        {
448            rc_features |= BTRC_FEAT_ABSOLUTE_VOLUME;
449        }
450        if ((btif_rc_cb.rc_features & BTA_AV_FEAT_METADATA)&&
451            (btif_rc_cb.rc_features & BTA_AV_FEAT_VENDOR)&&
452            (btif_rc_cb.rc_features_processed != TRUE))
453        {
454            rc_features |= BTRC_FEAT_METADATA;
455            /* Mark rc features processed to avoid repeating
456             * the AVRCP procedure every time on receiving this
457             * update.
458             */
459            btif_rc_cb.rc_features_processed = TRUE;
460
461            if (btif_av_is_sink_enabled())
462                getcapabilities_cmd (AVRC_CAP_COMPANY_ID);
463        }
464        BTIF_TRACE_DEBUG("%s Update rc features to CTRL %d", __FUNCTION__, rc_features);
465        HAL_CBACK(bt_rc_ctrl_callbacks, getrcfeatures_cb, &rc_addr, rc_features);
466    }
467}
468#endif
469
470void handle_rc_features(BD_ADDR bd_addr)
471{
472    if (bt_rc_callbacks != NULL)
473    {
474    btrc_remote_features_t rc_features = BTRC_FEAT_NONE;
475    bt_bdaddr_t rc_addr;
476
477    bdcpy(rc_addr.address, btif_rc_cb.rc_addr);
478    bt_bdaddr_t avdtp_addr  = btif_av_get_addr();
479
480    bdstr_t addr1, addr2;
481    BTIF_TRACE_DEBUG("%s: AVDTP Address: %s AVCTP address: %s", __func__,
482                     bdaddr_to_string(&avdtp_addr, addr1, sizeof(addr1)),
483                     bdaddr_to_string(&rc_addr, addr2, sizeof(addr2)));
484
485    if (interop_match_addr(INTEROP_DISABLE_ABSOLUTE_VOLUME, &rc_addr)
486        || absolute_volume_disabled()
487        || bdcmp(avdtp_addr.address, rc_addr.address))
488        btif_rc_cb.rc_features &= ~BTA_AV_FEAT_ADV_CTRL;
489
490    if (btif_rc_cb.rc_features & BTA_AV_FEAT_BROWSE)
491    {
492        rc_features |= BTRC_FEAT_BROWSE;
493    }
494
495#if (AVRC_ADV_CTRL_INCLUDED == TRUE)
496    if ( (btif_rc_cb.rc_features & BTA_AV_FEAT_ADV_CTRL) &&
497         (btif_rc_cb.rc_features & BTA_AV_FEAT_RCTG))
498    {
499        rc_features |= BTRC_FEAT_ABSOLUTE_VOLUME;
500    }
501#endif
502
503    if (btif_rc_cb.rc_features & BTA_AV_FEAT_METADATA)
504    {
505        rc_features |= BTRC_FEAT_METADATA;
506    }
507
508    BTIF_TRACE_DEBUG("%s: rc_features=0x%x", __FUNCTION__, rc_features);
509    HAL_CBACK(bt_rc_callbacks, remote_features_cb, &rc_addr, rc_features)
510
511#if (AVRC_ADV_CTRL_INCLUDED == TRUE)
512     BTIF_TRACE_DEBUG("%s Checking for feature flags in btif_rc_handler with label %d",
513                        __FUNCTION__, btif_rc_cb.rc_vol_label);
514     // Register for volume change on connect
515      if (btif_rc_cb.rc_features & BTA_AV_FEAT_ADV_CTRL &&
516         btif_rc_cb.rc_features & BTA_AV_FEAT_RCTG)
517      {
518         rc_transaction_t *p_transaction=NULL;
519         bt_status_t status = BT_STATUS_NOT_READY;
520         if (MAX_LABEL==btif_rc_cb.rc_vol_label)
521         {
522            status=get_transaction(&p_transaction);
523         }
524         else
525         {
526            p_transaction=get_transaction_by_lbl(btif_rc_cb.rc_vol_label);
527            if (NULL!=p_transaction)
528            {
529               BTIF_TRACE_DEBUG("%s register_volumechange already in progress for label %d",
530                                  __FUNCTION__, btif_rc_cb.rc_vol_label);
531               return;
532            }
533            else
534              status=get_transaction(&p_transaction);
535         }
536
537         if (BT_STATUS_SUCCESS == status && NULL!=p_transaction)
538         {
539            btif_rc_cb.rc_vol_label=p_transaction->lbl;
540            register_volumechange(btif_rc_cb.rc_vol_label);
541         }
542       }
543#endif
544    }
545}
546
547/***************************************************************************
548 *  Function       handle_rc_connect
549 *
550 *  - Argument:    tBTA_AV_RC_OPEN  RC open data structure
551 *
552 *  - Description: RC connection event handler
553 *
554 ***************************************************************************/
555void handle_rc_connect (tBTA_AV_RC_OPEN *p_rc_open)
556{
557    BTIF_TRACE_DEBUG("%s: rc_handle: %d", __FUNCTION__, p_rc_open->rc_handle);
558    bt_status_t result = BT_STATUS_SUCCESS;
559#if (AVRC_CTLR_INCLUDED == TRUE)
560    bt_bdaddr_t rc_addr;
561#endif
562
563    if (p_rc_open->status == BTA_AV_SUCCESS)
564    {
565        //check if already some RC is connected
566        if (btif_rc_cb.rc_connected)
567        {
568            BTIF_TRACE_ERROR("%s Got RC OPEN in connected state, Connected RC: %d \
569                and Current RC: %d", __FUNCTION__, btif_rc_cb.rc_handle,p_rc_open->rc_handle );
570            if ((btif_rc_cb.rc_handle != p_rc_open->rc_handle)
571                && (bdcmp(btif_rc_cb.rc_addr, p_rc_open->peer_addr)))
572            {
573                BTIF_TRACE_DEBUG("%s Got RC connected for some other handle", __FUNCTION__);
574                BTA_AvCloseRc(p_rc_open->rc_handle);
575                return;
576            }
577        }
578        memcpy(btif_rc_cb.rc_addr, p_rc_open->peer_addr, sizeof(BD_ADDR));
579        btif_rc_cb.rc_features = p_rc_open->peer_features;
580        btif_rc_cb.rc_vol_label=MAX_LABEL;
581        btif_rc_cb.rc_volume=MAX_VOLUME;
582
583        btif_rc_cb.rc_connected = TRUE;
584        btif_rc_cb.rc_handle = p_rc_open->rc_handle;
585
586        /* on locally initiated connection we will get remote features as part of connect */
587        if (btif_rc_cb.rc_features != 0)
588            handle_rc_features(btif_rc_cb.rc_addr);
589        if (bt_rc_callbacks)
590        {
591            result = uinput_driver_check();
592            if (result == BT_STATUS_SUCCESS)
593            {
594                init_uinput();
595            }
596        }
597        else
598        {
599            BTIF_TRACE_WARNING("%s Avrcp TG role not enabled, not initializing UInput",
600                               __FUNCTION__);
601        }
602        BTIF_TRACE_DEBUG("%s handle_rc_connect features %d ",__FUNCTION__, btif_rc_cb.rc_features);
603#if (AVRC_CTLR_INCLUDED == TRUE)
604        btif_rc_cb.rc_playing_uid = RC_INVALID_TRACK_ID;
605        bdcpy(rc_addr.address, btif_rc_cb.rc_addr);
606        if (bt_rc_ctrl_callbacks != NULL)
607        {
608            HAL_CBACK(bt_rc_ctrl_callbacks, connection_state_cb, TRUE, &rc_addr);
609        }
610        /* report connection state if remote device is AVRCP target */
611        if ((btif_rc_cb.rc_features & BTA_AV_FEAT_RCTG)||
612           ((btif_rc_cb.rc_features & BTA_AV_FEAT_RCCT)&&
613            (btif_rc_cb.rc_features & BTA_AV_FEAT_ADV_CTRL)))
614        {
615            handle_rc_ctrl_features(btif_rc_cb.rc_addr);
616        }
617#endif
618    }
619    else
620    {
621        BTIF_TRACE_ERROR("%s Connect failed with error code: %d",
622            __FUNCTION__, p_rc_open->status);
623        btif_rc_cb.rc_connected = FALSE;
624    }
625}
626
627/***************************************************************************
628 *  Function       handle_rc_disconnect
629 *
630 *  - Argument:    tBTA_AV_RC_CLOSE     RC close data structure
631 *
632 *  - Description: RC disconnection event handler
633 *
634 ***************************************************************************/
635void handle_rc_disconnect (tBTA_AV_RC_CLOSE *p_rc_close)
636{
637#if (AVRC_CTLR_INCLUDED == TRUE)
638    bt_bdaddr_t rc_addr;
639    tBTA_AV_FEAT features;
640#endif
641    BTIF_TRACE_DEBUG("%s: rc_handle: %d", __FUNCTION__, p_rc_close->rc_handle);
642    if ((p_rc_close->rc_handle != btif_rc_cb.rc_handle)
643        && (bdcmp(btif_rc_cb.rc_addr, p_rc_close->peer_addr)))
644    {
645        BTIF_TRACE_ERROR("Got disconnect of unknown device");
646        return;
647    }
648#if (AVRC_CTLR_INCLUDED == TRUE)
649    bdcpy(rc_addr.address, btif_rc_cb.rc_addr);
650    features = btif_rc_cb.rc_features;
651        /* Clean up AVRCP procedure flags */
652    memset(&btif_rc_cb.rc_app_settings, 0,
653        sizeof(btif_rc_player_app_settings_t));
654    btif_rc_cb.rc_features_processed = FALSE;
655    btif_rc_cb.rc_procedure_complete = FALSE;
656    rc_stop_play_status_timer();
657    /* Check and clear the notification event list */
658    if (btif_rc_cb.rc_supported_event_list != NULL)
659    {
660        list_clear(btif_rc_cb.rc_supported_event_list);
661        btif_rc_cb.rc_supported_event_list = NULL;
662    }
663#endif
664    btif_rc_cb.rc_handle = 0;
665    btif_rc_cb.rc_connected = FALSE;
666    memset(btif_rc_cb.rc_addr, 0, sizeof(BD_ADDR));
667    memset(btif_rc_cb.rc_notif, 0, sizeof(btif_rc_cb.rc_notif));
668
669    btif_rc_cb.rc_features = 0;
670    btif_rc_cb.rc_vol_label=MAX_LABEL;
671    btif_rc_cb.rc_volume=MAX_VOLUME;
672    init_all_transactions();
673    if (bt_rc_callbacks != NULL)
674    {
675        close_uinput();
676    }
677    else
678    {
679        BTIF_TRACE_WARNING("%s Avrcp TG role not enabled, not closing UInput", __FUNCTION__);
680    }
681
682    memset(btif_rc_cb.rc_addr, 0, sizeof(BD_ADDR));
683#if (AVRC_CTLR_INCLUDED == TRUE)
684    /* report connection state if device is AVRCP target */
685    if (bt_rc_ctrl_callbacks != NULL)
686   {
687        HAL_CBACK(bt_rc_ctrl_callbacks, connection_state_cb, FALSE, &rc_addr);
688   }
689#endif
690}
691
692/***************************************************************************
693 *  Function       handle_rc_passthrough_cmd
694 *
695 *  - Argument:    tBTA_AV_RC rc_id   remote control command ID
696 *                 tBTA_AV_STATE key_state status of key press
697 *
698 *  - Description: Remote control command handler
699 *
700 ***************************************************************************/
701void handle_rc_passthrough_cmd ( tBTA_AV_REMOTE_CMD *p_remote_cmd)
702{
703    const char *status;
704    int pressed, i;
705
706    BTIF_TRACE_DEBUG("%s: p_remote_cmd->rc_id=%d", __FUNCTION__, p_remote_cmd->rc_id);
707
708    /* If AVRC is open and peer sends PLAY but there is no AVDT, then we queue-up this PLAY */
709    if (p_remote_cmd)
710    {
711        /* queue AVRC PLAY if GAVDTP Open notification to app is pending (2 second timer) */
712        if ((p_remote_cmd->rc_id == BTA_AV_RC_PLAY) && (!btif_av_is_connected()))
713        {
714            if (p_remote_cmd->key_state == AVRC_STATE_PRESS)
715            {
716                APPL_TRACE_WARNING("%s: AVDT not open, queuing the PLAY command", __FUNCTION__);
717                btif_rc_cb.rc_pending_play = TRUE;
718            }
719            return;
720        }
721
722        if ((p_remote_cmd->rc_id == BTA_AV_RC_PAUSE) && (btif_rc_cb.rc_pending_play))
723        {
724            APPL_TRACE_WARNING("%s: Clear the pending PLAY on PAUSE received", __FUNCTION__);
725            btif_rc_cb.rc_pending_play = FALSE;
726            return;
727        }
728        if ((p_remote_cmd->rc_id == BTA_AV_RC_VOL_UP)||(p_remote_cmd->rc_id == BTA_AV_RC_VOL_DOWN))
729            return; // this command is not to be sent to UINPUT, only needed for PTS
730    }
731
732    if ((p_remote_cmd->rc_id == BTA_AV_RC_STOP) && (!btif_av_stream_started_ready()))
733    {
734        APPL_TRACE_WARNING("%s: Stream suspended, ignore STOP cmd",__FUNCTION__);
735        return;
736    }
737
738    if (p_remote_cmd->key_state == AVRC_STATE_RELEASE) {
739        status = "released";
740        pressed = 0;
741    } else {
742        status = "pressed";
743        pressed = 1;
744    }
745
746    if (p_remote_cmd->rc_id == BTA_AV_RC_FAST_FOR || p_remote_cmd->rc_id == BTA_AV_RC_REWIND) {
747        HAL_CBACK(bt_rc_callbacks, passthrough_cmd_cb, p_remote_cmd->rc_id, pressed);
748        return;
749    }
750
751    for (i = 0; key_map[i].name != NULL; i++) {
752        if (p_remote_cmd->rc_id == key_map[i].avrcp) {
753            BTIF_TRACE_DEBUG("%s: %s %s", __FUNCTION__, key_map[i].name, status);
754
755           /* MusicPlayer uses a long_press_timeout of 1 second for PLAYPAUSE button
756            * and maps that to autoshuffle. So if for some reason release for PLAY/PAUSE
757            * comes 1 second after the press, the MediaPlayer UI goes into a bad state.
758            * The reason for the delay could be sniff mode exit or some AVDTP procedure etc.
759            * The fix is to generate a release right after the press and drown the 'actual'
760            * release.
761            */
762            if ((key_map[i].release_quirk == 1) && (pressed == 0))
763            {
764                BTIF_TRACE_DEBUG("%s: AVRC %s Release Faked earlier, drowned now",
765                                  __FUNCTION__, key_map[i].name);
766                return;
767            }
768            send_key(uinput_fd, key_map[i].mapped_id, pressed);
769            if ((key_map[i].release_quirk == 1) && (pressed == 1))
770            {
771                sleep_ms(30);
772                BTIF_TRACE_DEBUG("%s: AVRC %s Release quirk enabled, send release now",
773                                  __FUNCTION__, key_map[i].name);
774                send_key(uinput_fd, key_map[i].mapped_id, 0);
775            }
776            break;
777        }
778    }
779
780    if (key_map[i].name == NULL)
781        BTIF_TRACE_ERROR("%s AVRCP: unknown button 0x%02X %s", __FUNCTION__,
782                        p_remote_cmd->rc_id, status);
783}
784
785/***************************************************************************
786 *  Function       handle_rc_passthrough_rsp
787 *
788 *  - Argument:    tBTA_AV_REMOTE_RSP passthrough command response
789 *
790 *  - Description: Remote control passthrough response handler
791 *
792 ***************************************************************************/
793void handle_rc_passthrough_rsp ( tBTA_AV_REMOTE_RSP *p_remote_rsp)
794{
795#if (AVRC_CTLR_INCLUDED == TRUE)
796    const char *status;
797    if (btif_rc_cb.rc_features & BTA_AV_FEAT_RCTG)
798    {
799        int key_state;
800        if (p_remote_rsp->key_state == AVRC_STATE_RELEASE)
801        {
802            status = "released";
803            key_state = 1;
804        }
805        else
806        {
807            status = "pressed";
808            key_state = 0;
809        }
810
811        BTIF_TRACE_DEBUG("%s: rc_id=%d status=%s", __FUNCTION__, p_remote_rsp->rc_id, status);
812
813        release_transaction(p_remote_rsp->label);
814        if (bt_rc_ctrl_callbacks != NULL) {
815            HAL_CBACK(bt_rc_ctrl_callbacks, passthrough_rsp_cb, p_remote_rsp->rc_id, key_state);
816        }
817    }
818    else
819    {
820        BTIF_TRACE_ERROR("%s DUT does not support AVRCP controller role", __FUNCTION__);
821    }
822#else
823    BTIF_TRACE_ERROR("%s AVRCP controller role is not enabled", __FUNCTION__);
824#endif
825}
826
827/***************************************************************************
828 *  Function       handle_rc_vendorunique_rsp
829 *
830 *  - Argument:    tBTA_AV_REMOTE_RSP  command response
831 *
832 *  - Description: Remote control vendor unique response handler
833 *
834 ***************************************************************************/
835void handle_rc_vendorunique_rsp ( tBTA_AV_REMOTE_RSP *p_remote_rsp)
836{
837#if (AVRC_CTLR_INCLUDED == TRUE)
838    const char *status;
839    UINT8 vendor_id = 0;
840    if (btif_rc_cb.rc_features & BTA_AV_FEAT_RCTG)
841    {
842        int key_state;
843        if (p_remote_rsp->key_state == AVRC_STATE_RELEASE)
844        {
845            status = "released";
846            key_state = 1;
847        }
848        else
849        {
850            status = "pressed";
851            key_state = 0;
852        }
853
854        if (p_remote_rsp->len > 0)
855        {
856            if (p_remote_rsp->len >= AVRC_PASS_THRU_GROUP_LEN)
857                vendor_id = p_remote_rsp->p_data[AVRC_PASS_THRU_GROUP_LEN -1];
858            osi_free_and_reset((void **)&p_remote_rsp->p_data);
859        }
860        BTIF_TRACE_DEBUG("%s: vendor_id=%d status=%s", __FUNCTION__, vendor_id, status);
861
862        release_transaction(p_remote_rsp->label);
863        HAL_CBACK(bt_rc_ctrl_callbacks, groupnavigation_rsp_cb, vendor_id, key_state);
864    }
865    else
866    {
867        BTIF_TRACE_ERROR("%s Remote does not support AVRCP TG role", __FUNCTION__);
868    }
869#else
870    BTIF_TRACE_ERROR("%s AVRCP controller role is not enabled", __FUNCTION__);
871#endif
872}
873
874void handle_uid_changed_notification(tBTA_AV_META_MSG *pmeta_msg, tAVRC_COMMAND *pavrc_command)
875{
876    tAVRC_RESPONSE avrc_rsp = {0};
877    avrc_rsp.rsp.pdu = pavrc_command->pdu;
878    avrc_rsp.rsp.status = AVRC_STS_NO_ERROR;
879    avrc_rsp.rsp.opcode = pavrc_command->cmd.opcode;
880
881    avrc_rsp.reg_notif.event_id = pavrc_command->reg_notif.event_id;
882    avrc_rsp.reg_notif.param.uid_counter = 0;
883
884    send_metamsg_rsp(pmeta_msg->rc_handle, pmeta_msg->label, AVRC_RSP_INTERIM, &avrc_rsp);
885    send_metamsg_rsp(pmeta_msg->rc_handle, pmeta_msg->label, AVRC_RSP_CHANGED, &avrc_rsp);
886
887}
888
889/***************************************************************************
890 *  Function       handle_rc_metamsg_cmd
891 *
892 *  - Argument:    tBTA_AV_VENDOR Structure containing the received
893 *                          metamsg command
894 *
895 *  - Description: Remote control metamsg command handler (AVRCP 1.3)
896 *
897 ***************************************************************************/
898void handle_rc_metamsg_cmd (tBTA_AV_META_MSG *pmeta_msg)
899{
900    /* Parse the metamsg command and pass it on to BTL-IFS */
901    UINT8             scratch_buf[512] = {0};
902    tAVRC_COMMAND    avrc_command = {0};
903    tAVRC_STS status;
904
905    BTIF_TRACE_EVENT("+ %s", __FUNCTION__);
906
907    if (pmeta_msg->p_msg->hdr.opcode != AVRC_OP_VENDOR)
908    {
909        BTIF_TRACE_WARNING("Invalid opcode: %x", pmeta_msg->p_msg->hdr.opcode);
910        return;
911    }
912    if (pmeta_msg->len < 3)
913    {
914        BTIF_TRACE_WARNING("Invalid length.Opcode: 0x%x, len: 0x%x", pmeta_msg->p_msg->hdr.opcode,
915            pmeta_msg->len);
916        return;
917    }
918
919    if (pmeta_msg->code >= AVRC_RSP_NOT_IMPL)
920    {
921#if (AVRC_ADV_CTRL_INCLUDED == TRUE)
922{
923     rc_transaction_t *transaction=NULL;
924     transaction=get_transaction_by_lbl(pmeta_msg->label);
925     if (NULL!=transaction)
926     {
927        handle_rc_metamsg_rsp(pmeta_msg);
928     }
929     else
930     {
931         BTIF_TRACE_DEBUG("%s:Discard vendor dependent rsp. code: %d label:%d.",
932             __FUNCTION__, pmeta_msg->code, pmeta_msg->label);
933     }
934     return;
935}
936#else
937{
938        BTIF_TRACE_DEBUG("%s:Received vendor dependent rsp. code: %d len: %d. Not processing it.",
939            __FUNCTION__, pmeta_msg->code, pmeta_msg->len);
940        return;
941}
942#endif
943      }
944
945    status=AVRC_ParsCommand(pmeta_msg->p_msg, &avrc_command, scratch_buf, sizeof(scratch_buf));
946    BTIF_TRACE_DEBUG("%s Received vendor command.code,PDU and label: %d, %d,%d",
947                     __FUNCTION__, pmeta_msg->code, avrc_command.cmd.pdu, pmeta_msg->label);
948
949    if (status != AVRC_STS_NO_ERROR)
950    {
951        /* return error */
952        BTIF_TRACE_WARNING("%s: Error in parsing received metamsg command. status: 0x%02x",
953            __FUNCTION__, status);
954        send_reject_response(pmeta_msg->rc_handle, pmeta_msg->label, avrc_command.pdu, status);
955    }
956    else
957    {
958        /* if RegisterNotification, add it to our registered queue */
959
960        if (avrc_command.cmd.pdu == AVRC_PDU_REGISTER_NOTIFICATION)
961        {
962            UINT8 event_id = avrc_command.reg_notif.event_id;
963            BTIF_TRACE_EVENT("%s:New register notification received.event_id:%s,label:0x%x,code:%x",
964            __FUNCTION__,dump_rc_notification_event_id(event_id), pmeta_msg->label,pmeta_msg->code);
965            btif_rc_cb.rc_notif[event_id-1].bNotify = TRUE;
966            btif_rc_cb.rc_notif[event_id-1].label = pmeta_msg->label;
967
968            if (event_id == AVRC_EVT_UIDS_CHANGE)
969            {
970                handle_uid_changed_notification(pmeta_msg, &avrc_command);
971                return;
972            }
973
974        }
975
976        BTIF_TRACE_EVENT("%s: Passing received metamsg command to app. pdu: %s",
977            __FUNCTION__, dump_rc_pdu(avrc_command.cmd.pdu));
978
979        /* Since handle_rc_metamsg_cmd() itself is called from
980            *btif context, no context switching is required. Invoke
981            * btif_rc_upstreams_evt directly from here. */
982        btif_rc_upstreams_evt((uint16_t)avrc_command.cmd.pdu, &avrc_command, pmeta_msg->code,
983                               pmeta_msg->label);
984    }
985}
986
987/***************************************************************************
988 **
989 ** Function       btif_rc_handler
990 **
991 ** Description    RC event handler
992 **
993 ***************************************************************************/
994void btif_rc_handler(tBTA_AV_EVT event, tBTA_AV *p_data)
995{
996    BTIF_TRACE_DEBUG ("%s event:%s", __FUNCTION__, dump_rc_event(event));
997    switch (event)
998    {
999        case BTA_AV_RC_OPEN_EVT:
1000        {
1001            BTIF_TRACE_DEBUG("%s Peer_features:%x", __FUNCTION__, p_data->rc_open.peer_features);
1002            handle_rc_connect( &(p_data->rc_open) );
1003        }break;
1004
1005        case BTA_AV_RC_CLOSE_EVT:
1006        {
1007            handle_rc_disconnect( &(p_data->rc_close) );
1008        }break;
1009
1010        case BTA_AV_REMOTE_CMD_EVT:
1011        {
1012            if (bt_rc_callbacks != NULL)
1013            {
1014              BTIF_TRACE_DEBUG("%s rc_id:0x%x key_state:%d",
1015                               __FUNCTION__, p_data->remote_cmd.rc_id,
1016                               p_data->remote_cmd.key_state);
1017                /** In race conditions just after 2nd AVRCP is connected
1018                 *  remote might send pass through commands, so check for
1019                 *  Rc handle before processing pass through commands
1020                 **/
1021                if (btif_rc_cb.rc_handle == p_data->remote_cmd.rc_handle)
1022                {
1023                    handle_rc_passthrough_cmd( (&p_data->remote_cmd) );
1024                }
1025                else
1026                {
1027                    BTIF_TRACE_DEBUG("%s Pass-through command for Invalid rc handle", __FUNCTION__);
1028                }
1029            }
1030            else
1031            {
1032                BTIF_TRACE_ERROR("AVRCP TG role not up, drop passthrough commands");
1033            }
1034        }
1035        break;
1036
1037#if (AVRC_CTLR_INCLUDED == TRUE)
1038        case BTA_AV_REMOTE_RSP_EVT:
1039        {
1040            BTIF_TRACE_DEBUG("%s RSP: rc_id:0x%x key_state:%d",
1041                             __FUNCTION__, p_data->remote_rsp.rc_id, p_data->remote_rsp.key_state);
1042            if (p_data->remote_rsp.rc_id == AVRC_ID_VENDOR)
1043            {
1044                handle_rc_vendorunique_rsp(&p_data->remote_rsp);
1045            }
1046            else
1047            {
1048                handle_rc_passthrough_rsp(&p_data->remote_rsp);
1049            }
1050        }
1051        break;
1052
1053#endif
1054        case BTA_AV_RC_FEAT_EVT:
1055        {
1056            BTIF_TRACE_DEBUG("%s Peer_features:%x", __FUNCTION__, p_data->rc_feat.peer_features);
1057            btif_rc_cb.rc_features = p_data->rc_feat.peer_features;
1058            handle_rc_features(p_data->rc_feat.peer_addr);
1059#if (AVRC_CTLR_INCLUDED == TRUE)
1060            if ((btif_rc_cb.rc_connected) && (bt_rc_ctrl_callbacks != NULL))
1061            {
1062                handle_rc_ctrl_features(btif_rc_cb.rc_addr);
1063            }
1064#endif
1065        }
1066        break;
1067
1068        case BTA_AV_META_MSG_EVT:
1069        {
1070            if (bt_rc_callbacks != NULL)
1071            {
1072                BTIF_TRACE_DEBUG("%s BTA_AV_META_MSG_EVT  code:%d label:%d",
1073                                 __FUNCTION__,
1074                                 p_data->meta_msg.code,
1075                                 p_data->meta_msg.label);
1076                BTIF_TRACE_DEBUG("%s company_id:0x%x len:%d handle:%d",
1077                                 __FUNCTION__,
1078                                 p_data->meta_msg.company_id,
1079                                 p_data->meta_msg.len,
1080                                 p_data->meta_msg.rc_handle);
1081                /* handle the metamsg command */
1082                handle_rc_metamsg_cmd(&(p_data->meta_msg));
1083                /* Free the Memory allocated for tAVRC_MSG */
1084            }
1085#if (AVRC_CTLR_INCLUDED == TRUE)
1086            else if ((bt_rc_callbacks == NULL)&&(bt_rc_ctrl_callbacks != NULL))
1087            {
1088                /* This is case of Sink + CT + TG(for abs vol)) */
1089                BTIF_TRACE_DEBUG("%s BTA_AV_META_MSG_EVT  code:%d label:%d",
1090                                 __FUNCTION__,
1091                                 p_data->meta_msg.code,
1092                                 p_data->meta_msg.label);
1093                BTIF_TRACE_DEBUG("%s company_id:0x%x len:%d handle:%d",
1094                                 __FUNCTION__,
1095                                 p_data->meta_msg.company_id,
1096                                 p_data->meta_msg.len,
1097                                 p_data->meta_msg.rc_handle);
1098                if ((p_data->meta_msg.code >= AVRC_RSP_NOT_IMPL)&&
1099                    (p_data->meta_msg.code <= AVRC_RSP_INTERIM))
1100                {
1101                    /* Its a response */
1102                    handle_avk_rc_metamsg_rsp(&(p_data->meta_msg));
1103                }
1104                else if (p_data->meta_msg.code <= AVRC_CMD_GEN_INQ)
1105                {
1106                    /* Its a command  */
1107                    handle_avk_rc_metamsg_cmd(&(p_data->meta_msg));
1108                }
1109
1110            }
1111#endif
1112            else
1113            {
1114                BTIF_TRACE_ERROR("Neither CTRL, nor TG is up, drop meta commands");
1115            }
1116        }
1117        break;
1118
1119        default:
1120            BTIF_TRACE_DEBUG("%s Unhandled RC event : 0x%x", __FUNCTION__, event);
1121    }
1122}
1123
1124/***************************************************************************
1125 **
1126 ** Function       btif_rc_get_connected_peer
1127 **
1128 ** Description    Fetches the connected headset's BD_ADDR if any
1129 **
1130 ***************************************************************************/
1131BOOLEAN btif_rc_get_connected_peer(BD_ADDR peer_addr)
1132{
1133    if (btif_rc_cb.rc_connected == TRUE) {
1134        bdcpy(peer_addr, btif_rc_cb.rc_addr);
1135        return TRUE;
1136    }
1137    return FALSE;
1138}
1139
1140/***************************************************************************
1141 **
1142 ** Function       btif_rc_get_connected_peer_handle
1143 **
1144 ** Description    Fetches the connected headset's handle if any
1145 **
1146 ***************************************************************************/
1147UINT8 btif_rc_get_connected_peer_handle(void)
1148{
1149    return btif_rc_cb.rc_handle;
1150}
1151
1152/***************************************************************************
1153 **
1154 ** Function       btif_rc_check_handle_pending_play
1155 **
1156 ** Description    Clears the queued PLAY command. if bSend is TRUE, forwards to app
1157 **
1158 ***************************************************************************/
1159
1160/* clear the queued PLAY command. if bSend is TRUE, forward to app */
1161void btif_rc_check_handle_pending_play (BD_ADDR peer_addr, BOOLEAN bSendToApp)
1162{
1163    UNUSED(peer_addr);
1164
1165    BTIF_TRACE_DEBUG("%s: bSendToApp=%d", __FUNCTION__, bSendToApp);
1166    if (btif_rc_cb.rc_pending_play)
1167    {
1168        if (bSendToApp)
1169        {
1170            tBTA_AV_REMOTE_CMD remote_cmd;
1171            APPL_TRACE_DEBUG("%s: Sending queued PLAYED event to app", __FUNCTION__);
1172
1173            memset (&remote_cmd, 0, sizeof(tBTA_AV_REMOTE_CMD));
1174            remote_cmd.rc_handle  = btif_rc_cb.rc_handle;
1175            remote_cmd.rc_id      = AVRC_ID_PLAY;
1176            remote_cmd.hdr.ctype  = AVRC_CMD_CTRL;
1177            remote_cmd.hdr.opcode = AVRC_OP_PASS_THRU;
1178
1179            /* delay sending to app, else there is a timing issue in the framework,
1180             ** which causes the audio to be on th device's speaker. Delay between
1181             ** OPEN & RC_PLAYs
1182            */
1183            sleep_ms(200);
1184            /* send to app - both PRESSED & RELEASED */
1185            remote_cmd.key_state  = AVRC_STATE_PRESS;
1186            handle_rc_passthrough_cmd( &remote_cmd );
1187
1188            sleep_ms(100);
1189
1190            remote_cmd.key_state  = AVRC_STATE_RELEASE;
1191            handle_rc_passthrough_cmd( &remote_cmd );
1192        }
1193        btif_rc_cb.rc_pending_play = FALSE;
1194    }
1195}
1196
1197/* Generic reject response */
1198static void send_reject_response (UINT8 rc_handle, UINT8 label, UINT8 pdu, UINT8 status)
1199{
1200    UINT8 ctype = AVRC_RSP_REJ;
1201    tAVRC_RESPONSE avrc_rsp;
1202    BT_HDR *p_msg = NULL;
1203    memset (&avrc_rsp, 0, sizeof(tAVRC_RESPONSE));
1204
1205    avrc_rsp.rsp.opcode = opcode_from_pdu(pdu);
1206    avrc_rsp.rsp.pdu    = pdu;
1207    avrc_rsp.rsp.status = status;
1208
1209    if (AVRC_STS_NO_ERROR == (status = AVRC_BldResponse(rc_handle, &avrc_rsp, &p_msg)) )
1210    {
1211        BTIF_TRACE_DEBUG("%s:Sending error notification to handle:%d. pdu:%s,status:0x%02x",
1212            __FUNCTION__, rc_handle, dump_rc_pdu(pdu), status);
1213        BTA_AvMetaRsp(rc_handle, label, ctype, p_msg);
1214    }
1215}
1216
1217/***************************************************************************
1218 *  Function       send_metamsg_rsp
1219 *
1220 *  - Argument:
1221 *                  rc_handle     RC handle corresponding to the connected RC
1222 *                  label            Label of the RC response
1223 *                  code            Response type
1224 *                  pmetamsg_resp    Vendor response
1225 *
1226 *  - Description: Remote control metamsg response handler (AVRCP 1.3)
1227 *
1228 ***************************************************************************/
1229static void send_metamsg_rsp (UINT8 rc_handle, UINT8 label, tBTA_AV_CODE code,
1230    tAVRC_RESPONSE *pmetamsg_resp)
1231{
1232    UINT8 ctype;
1233
1234    if (!pmetamsg_resp)
1235    {
1236        BTIF_TRACE_WARNING("%s: Invalid response received from application", __FUNCTION__);
1237        return;
1238    }
1239
1240    BTIF_TRACE_EVENT("+%s: rc_handle: %d, label: %d, code: 0x%02x, pdu: %s", __FUNCTION__,
1241        rc_handle, label, code, dump_rc_pdu(pmetamsg_resp->rsp.pdu));
1242
1243    if (pmetamsg_resp->rsp.status != AVRC_STS_NO_ERROR)
1244    {
1245        ctype = AVRC_RSP_REJ;
1246    }
1247    else
1248    {
1249        if ( code < AVRC_RSP_NOT_IMPL)
1250        {
1251            if (code == AVRC_CMD_NOTIF)
1252            {
1253               ctype = AVRC_RSP_INTERIM;
1254            }
1255            else if (code == AVRC_CMD_STATUS)
1256            {
1257               ctype = AVRC_RSP_IMPL_STBL;
1258            }
1259            else
1260            {
1261               ctype = AVRC_RSP_ACCEPT;
1262            }
1263        }
1264        else
1265        {
1266            ctype = code;
1267        }
1268    }
1269    /* if response is for register_notification, make sure the rc has
1270    actually registered for this */
1271    if ((pmetamsg_resp->rsp.pdu == AVRC_PDU_REGISTER_NOTIFICATION) && (code == AVRC_RSP_CHANGED))
1272    {
1273        BOOLEAN bSent = FALSE;
1274        UINT8   event_id = pmetamsg_resp->reg_notif.event_id;
1275        BOOLEAN bNotify = (btif_rc_cb.rc_connected) && (btif_rc_cb.rc_notif[event_id-1].bNotify);
1276
1277        /* de-register this notification for a CHANGED response */
1278        btif_rc_cb.rc_notif[event_id-1].bNotify = FALSE;
1279        BTIF_TRACE_DEBUG("%s rc_handle: %d. event_id: 0x%02d bNotify:%u", __FUNCTION__,
1280             btif_rc_cb.rc_handle, event_id, bNotify);
1281        if (bNotify)
1282        {
1283            BT_HDR *p_msg = NULL;
1284            tAVRC_STS status;
1285
1286            if (AVRC_STS_NO_ERROR == (status = AVRC_BldResponse(btif_rc_cb.rc_handle,
1287                pmetamsg_resp, &p_msg)) )
1288            {
1289                BTIF_TRACE_DEBUG("%s Sending notification to rc_handle: %d. event_id: 0x%02d",
1290                     __FUNCTION__, btif_rc_cb.rc_handle, event_id);
1291                bSent = TRUE;
1292                BTA_AvMetaRsp(btif_rc_cb.rc_handle, btif_rc_cb.rc_notif[event_id-1].label,
1293                    ctype, p_msg);
1294            }
1295            else
1296            {
1297                BTIF_TRACE_WARNING("%s failed to build metamsg response. status: 0x%02x",
1298                    __FUNCTION__, status);
1299            }
1300
1301        }
1302
1303        if (!bSent)
1304        {
1305            BTIF_TRACE_DEBUG("%s: Notification not sent, as there are no RC connections or the \
1306                CT has not subscribed for event_id: %s", __FUNCTION__, dump_rc_notification_event_id(event_id));
1307        }
1308    }
1309    else
1310    {
1311        /* All other commands go here */
1312
1313        BT_HDR *p_msg = NULL;
1314        tAVRC_STS status;
1315
1316        status = AVRC_BldResponse(rc_handle, pmetamsg_resp, &p_msg);
1317
1318        if (status == AVRC_STS_NO_ERROR)
1319        {
1320            BTA_AvMetaRsp(rc_handle, label, ctype, p_msg);
1321        }
1322        else
1323        {
1324            BTIF_TRACE_ERROR("%s: failed to build metamsg response. status: 0x%02x",
1325                __FUNCTION__, status);
1326        }
1327    }
1328}
1329
1330static UINT8 opcode_from_pdu(UINT8 pdu)
1331{
1332    UINT8 opcode = 0;
1333
1334    switch (pdu)
1335    {
1336    case AVRC_PDU_NEXT_GROUP:
1337    case AVRC_PDU_PREV_GROUP: /* pass thru */
1338        opcode  = AVRC_OP_PASS_THRU;
1339        break;
1340
1341    default: /* vendor */
1342        opcode  = AVRC_OP_VENDOR;
1343        break;
1344    }
1345
1346    return opcode;
1347}
1348
1349/*******************************************************************************
1350**
1351** Function         btif_rc_upstreams_evt
1352**
1353** Description      Executes AVRC UPSTREAMS events in btif context.
1354**
1355** Returns          void
1356**
1357*******************************************************************************/
1358static void btif_rc_upstreams_evt(UINT16 event, tAVRC_COMMAND *pavrc_cmd, UINT8 ctype, UINT8 label)
1359{
1360    BTIF_TRACE_EVENT("%s pdu: %s handle: 0x%x ctype:%x label:%x", __FUNCTION__,
1361        dump_rc_pdu(pavrc_cmd->pdu), btif_rc_cb.rc_handle, ctype, label);
1362
1363    switch (event)
1364    {
1365        case AVRC_PDU_GET_PLAY_STATUS:
1366        {
1367            FILL_PDU_QUEUE(IDX_GET_PLAY_STATUS_RSP, ctype, label, TRUE)
1368            HAL_CBACK(bt_rc_callbacks, get_play_status_cb);
1369        }
1370        break;
1371        case AVRC_PDU_LIST_PLAYER_APP_ATTR:
1372        case AVRC_PDU_LIST_PLAYER_APP_VALUES:
1373        case AVRC_PDU_GET_CUR_PLAYER_APP_VALUE:
1374        case AVRC_PDU_SET_PLAYER_APP_VALUE:
1375        case AVRC_PDU_GET_PLAYER_APP_ATTR_TEXT:
1376        case AVRC_PDU_GET_PLAYER_APP_VALUE_TEXT:
1377        {
1378            /* TODO: Add support for Application Settings */
1379            send_reject_response (btif_rc_cb.rc_handle, label, pavrc_cmd->pdu, AVRC_STS_BAD_CMD);
1380        }
1381        break;
1382        case AVRC_PDU_GET_ELEMENT_ATTR:
1383        {
1384            btrc_media_attr_t element_attrs[BTRC_MAX_ELEM_ATTR_SIZE];
1385            UINT8 num_attr;
1386             memset(&element_attrs, 0, sizeof(element_attrs));
1387            if (pavrc_cmd->get_elem_attrs.num_attr == 0)
1388            {
1389                /* CT requests for all attributes */
1390                int attr_cnt;
1391                num_attr = BTRC_MAX_ELEM_ATTR_SIZE;
1392                for (attr_cnt = 0; attr_cnt < BTRC_MAX_ELEM_ATTR_SIZE; attr_cnt++)
1393                {
1394                    element_attrs[attr_cnt] = attr_cnt + 1;
1395                }
1396            }
1397            else if (pavrc_cmd->get_elem_attrs.num_attr == 0xFF)
1398            {
1399                /* 0xff indicates, no attributes requested - reject */
1400                send_reject_response (btif_rc_cb.rc_handle, label, pavrc_cmd->pdu,
1401                    AVRC_STS_BAD_PARAM);
1402                return;
1403            }
1404            else
1405            {
1406                int attr_cnt, filled_attr_count;
1407
1408                num_attr = 0;
1409                /* Attribute IDs from 1 to AVRC_MAX_NUM_MEDIA_ATTR_ID are only valid,
1410                 * hence HAL definition limits the attributes to AVRC_MAX_NUM_MEDIA_ATTR_ID.
1411                 * Fill only valid entries.
1412                 */
1413                for (attr_cnt = 0; (attr_cnt < pavrc_cmd->get_elem_attrs.num_attr) &&
1414                    (num_attr < AVRC_MAX_NUM_MEDIA_ATTR_ID); attr_cnt++)
1415                {
1416                    if ((pavrc_cmd->get_elem_attrs.attrs[attr_cnt] > 0) &&
1417                        (pavrc_cmd->get_elem_attrs.attrs[attr_cnt] <= AVRC_MAX_NUM_MEDIA_ATTR_ID))
1418                    {
1419                        /* Skip the duplicate entries : PTS sends duplicate entries for Fragment cases
1420                         */
1421                        for (filled_attr_count = 0; filled_attr_count < num_attr; filled_attr_count++)
1422                        {
1423                            if (element_attrs[filled_attr_count] == pavrc_cmd->get_elem_attrs.attrs[attr_cnt])
1424                                break;
1425                        }
1426                        if (filled_attr_count == num_attr)
1427                        {
1428                            element_attrs[num_attr] = pavrc_cmd->get_elem_attrs.attrs[attr_cnt];
1429                            num_attr++;
1430                        }
1431                    }
1432                }
1433            }
1434            FILL_PDU_QUEUE(IDX_GET_ELEMENT_ATTR_RSP, ctype, label, TRUE);
1435            HAL_CBACK(bt_rc_callbacks, get_element_attr_cb, num_attr, element_attrs);
1436        }
1437        break;
1438        case AVRC_PDU_REGISTER_NOTIFICATION:
1439        {
1440            if (pavrc_cmd->reg_notif.event_id == BTRC_EVT_PLAY_POS_CHANGED &&
1441                pavrc_cmd->reg_notif.param == 0)
1442            {
1443                BTIF_TRACE_WARNING("%s Device registering position changed with illegal param 0.",
1444                    __FUNCTION__);
1445                send_reject_response (btif_rc_cb.rc_handle, label, pavrc_cmd->pdu, AVRC_STS_BAD_PARAM);
1446                /* de-register this notification for a rejected response */
1447                btif_rc_cb.rc_notif[BTRC_EVT_PLAY_POS_CHANGED - 1].bNotify = FALSE;
1448                return;
1449            }
1450            HAL_CBACK(bt_rc_callbacks, register_notification_cb, pavrc_cmd->reg_notif.event_id,
1451                pavrc_cmd->reg_notif.param);
1452        }
1453        break;
1454        case AVRC_PDU_INFORM_DISPLAY_CHARSET:
1455        {
1456            tAVRC_RESPONSE avrc_rsp;
1457            BTIF_TRACE_EVENT("%s() AVRC_PDU_INFORM_DISPLAY_CHARSET", __FUNCTION__);
1458            if (btif_rc_cb.rc_connected == TRUE)
1459            {
1460                memset(&(avrc_rsp.inform_charset), 0, sizeof(tAVRC_RSP));
1461                avrc_rsp.inform_charset.opcode=opcode_from_pdu(AVRC_PDU_INFORM_DISPLAY_CHARSET);
1462                avrc_rsp.inform_charset.pdu=AVRC_PDU_INFORM_DISPLAY_CHARSET;
1463                avrc_rsp.inform_charset.status=AVRC_STS_NO_ERROR;
1464                send_metamsg_rsp(btif_rc_cb.rc_handle, label, ctype, &avrc_rsp);
1465            }
1466        }
1467        break;
1468        default:
1469        {
1470        send_reject_response (btif_rc_cb.rc_handle, label, pavrc_cmd->pdu,
1471            (pavrc_cmd->pdu == AVRC_PDU_SEARCH)?AVRC_STS_SEARCH_NOT_SUP:AVRC_STS_BAD_CMD);
1472        return;
1473        }
1474        break;
1475    }
1476}
1477
1478#if (AVRC_CTLR_INCLUDED == TRUE)
1479/*******************************************************************************
1480**
1481** Function         btif_rc_ctrl_upstreams_rsp_cmd
1482**
1483** Description      Executes AVRC UPSTREAMS response events in btif context.
1484**
1485** Returns          void
1486**
1487*******************************************************************************/
1488static void btif_rc_ctrl_upstreams_rsp_cmd(UINT8 event, tAVRC_COMMAND *pavrc_cmd,
1489        UINT8 label)
1490{
1491    BTIF_TRACE_DEBUG("%s pdu: %s handle: 0x%x", __FUNCTION__,
1492        dump_rc_pdu(pavrc_cmd->pdu), btif_rc_cb.rc_handle);
1493    bt_bdaddr_t rc_addr;
1494    bdcpy(rc_addr.address, btif_rc_cb.rc_addr);
1495#if (AVRC_CTLR_INCLUDED == TRUE)
1496    switch (event)
1497    {
1498    case AVRC_PDU_SET_ABSOLUTE_VOLUME:
1499         HAL_CBACK(bt_rc_ctrl_callbacks,setabsvol_cmd_cb, &rc_addr,
1500                 pavrc_cmd->volume.volume, label);
1501         break;
1502    case AVRC_PDU_REGISTER_NOTIFICATION:
1503         if (pavrc_cmd->reg_notif.event_id == AVRC_EVT_VOLUME_CHANGE)
1504         {
1505             HAL_CBACK(bt_rc_ctrl_callbacks, registernotification_absvol_cb,
1506                    &rc_addr, label);
1507         }
1508         break;
1509    }
1510#endif
1511}
1512#endif
1513
1514#if (AVRC_ADV_CTRL_INCLUDED == TRUE)
1515/*******************************************************************************
1516**
1517** Function         btif_rc_upstreams_rsp_evt
1518**
1519** Description      Executes AVRC UPSTREAMS response events in btif context.
1520**
1521** Returns          void
1522**
1523*******************************************************************************/
1524static void btif_rc_upstreams_rsp_evt(UINT16 event, tAVRC_RESPONSE *pavrc_resp, UINT8 ctype, UINT8 label)
1525{
1526    BTIF_TRACE_EVENT("%s pdu: %s handle: 0x%x ctype:%x label:%x", __FUNCTION__,
1527        dump_rc_pdu(pavrc_resp->pdu), btif_rc_cb.rc_handle, ctype, label);
1528
1529    switch (event)
1530    {
1531        case AVRC_PDU_REGISTER_NOTIFICATION:
1532        {
1533             if (AVRC_RSP_CHANGED==ctype)
1534                 btif_rc_cb.rc_volume=pavrc_resp->reg_notif.param.volume;
1535             HAL_CBACK(bt_rc_callbacks, volume_change_cb, pavrc_resp->reg_notif.param.volume,ctype)
1536        }
1537        break;
1538
1539        case AVRC_PDU_SET_ABSOLUTE_VOLUME:
1540        {
1541            BTIF_TRACE_DEBUG("%s Set absolute volume change event received: volume %d,ctype %d",
1542                             __FUNCTION__, pavrc_resp->volume.volume,ctype);
1543            if (AVRC_RSP_ACCEPT==ctype)
1544                btif_rc_cb.rc_volume=pavrc_resp->volume.volume;
1545            HAL_CBACK(bt_rc_callbacks,volume_change_cb,pavrc_resp->volume.volume,ctype)
1546        }
1547        break;
1548
1549        default:
1550            return;
1551    }
1552}
1553#endif
1554
1555/************************************************************************************
1556**  AVRCP API Functions
1557************************************************************************************/
1558
1559/*******************************************************************************
1560**
1561** Function         init
1562**
1563** Description      Initializes the AVRC interface
1564**
1565** Returns          bt_status_t
1566**
1567*******************************************************************************/
1568static bt_status_t init(btrc_callbacks_t* callbacks )
1569{
1570    BTIF_TRACE_EVENT("## %s ##", __FUNCTION__);
1571    bt_status_t result = BT_STATUS_SUCCESS;
1572
1573    if (bt_rc_callbacks)
1574        return BT_STATUS_DONE;
1575
1576    bt_rc_callbacks = callbacks;
1577    memset (&btif_rc_cb, 0, sizeof(btif_rc_cb));
1578    btif_rc_cb.rc_vol_label=MAX_LABEL;
1579    btif_rc_cb.rc_volume=MAX_VOLUME;
1580    lbl_init();
1581
1582    return result;
1583}
1584
1585/*******************************************************************************
1586**
1587** Function         init_ctrl
1588**
1589** Description      Initializes the AVRC interface
1590**
1591** Returns          bt_status_t
1592**
1593*******************************************************************************/
1594static bt_status_t init_ctrl(btrc_ctrl_callbacks_t* callbacks )
1595{
1596    BTIF_TRACE_EVENT("## %s ##", __FUNCTION__);
1597    bt_status_t result = BT_STATUS_SUCCESS;
1598
1599    if (bt_rc_ctrl_callbacks)
1600        return BT_STATUS_DONE;
1601
1602    bt_rc_ctrl_callbacks = callbacks;
1603    memset (&btif_rc_cb, 0, sizeof(btif_rc_cb));
1604    btif_rc_cb.rc_vol_label=MAX_LABEL;
1605    btif_rc_cb.rc_volume=MAX_VOLUME;
1606    lbl_init();
1607
1608    return result;
1609}
1610
1611static void rc_ctrl_procedure_complete ()
1612{
1613    if (btif_rc_cb.rc_procedure_complete == TRUE)
1614    {
1615        return;
1616    }
1617    btif_rc_cb.rc_procedure_complete = TRUE;
1618    UINT32 attr_list[] = {
1619            AVRC_MEDIA_ATTR_ID_TITLE,
1620            AVRC_MEDIA_ATTR_ID_ARTIST,
1621            AVRC_MEDIA_ATTR_ID_ALBUM,
1622            AVRC_MEDIA_ATTR_ID_TRACK_NUM,
1623            AVRC_MEDIA_ATTR_ID_NUM_TRACKS,
1624            AVRC_MEDIA_ATTR_ID_GENRE,
1625            AVRC_MEDIA_ATTR_ID_PLAYING_TIME
1626            };
1627    get_element_attribute_cmd (AVRC_MAX_NUM_MEDIA_ATTR_ID, attr_list);
1628}
1629
1630/***************************************************************************
1631**
1632** Function         get_play_status_rsp
1633**
1634** Description      Returns the current play status.
1635**                      This method is called in response to
1636**                      GetPlayStatus request.
1637**
1638** Returns          bt_status_t
1639**
1640***************************************************************************/
1641static bt_status_t get_play_status_rsp(btrc_play_status_t play_status, uint32_t song_len,
1642    uint32_t song_pos)
1643{
1644    tAVRC_RESPONSE avrc_rsp;
1645    CHECK_RC_CONNECTED
1646    memset(&(avrc_rsp.get_play_status), 0, sizeof(tAVRC_GET_PLAY_STATUS_RSP));
1647    avrc_rsp.get_play_status.song_len = song_len;
1648    avrc_rsp.get_play_status.song_pos = song_pos;
1649    avrc_rsp.get_play_status.play_status = play_status;
1650
1651    avrc_rsp.get_play_status.pdu = AVRC_PDU_GET_PLAY_STATUS;
1652    avrc_rsp.get_play_status.opcode = opcode_from_pdu(AVRC_PDU_GET_PLAY_STATUS);
1653    avrc_rsp.get_play_status.status = AVRC_STS_NO_ERROR;
1654    /* Send the response */
1655    SEND_METAMSG_RSP(IDX_GET_PLAY_STATUS_RSP, &avrc_rsp);
1656    return BT_STATUS_SUCCESS;
1657}
1658
1659/***************************************************************************
1660**
1661** Function         get_element_attr_rsp
1662**
1663** Description      Returns the current songs' element attributes
1664**                      in text.
1665**
1666** Returns          bt_status_t
1667**
1668***************************************************************************/
1669static bt_status_t get_element_attr_rsp(uint8_t num_attr, btrc_element_attr_val_t *p_attrs)
1670{
1671    tAVRC_RESPONSE avrc_rsp;
1672    UINT32 i;
1673    tAVRC_ATTR_ENTRY element_attrs[BTRC_MAX_ELEM_ATTR_SIZE];
1674    CHECK_RC_CONNECTED
1675    memset(element_attrs, 0, sizeof(tAVRC_ATTR_ENTRY) * num_attr);
1676
1677    if (num_attr == 0)
1678    {
1679        avrc_rsp.get_play_status.status = AVRC_STS_BAD_PARAM;
1680    }
1681    else
1682    {
1683        for (i=0; i<num_attr; i++) {
1684            element_attrs[i].attr_id = p_attrs[i].attr_id;
1685            element_attrs[i].name.charset_id = AVRC_CHARSET_ID_UTF8;
1686            element_attrs[i].name.str_len = (UINT16)strlen((char *)p_attrs[i].text);
1687            element_attrs[i].name.p_str = p_attrs[i].text;
1688            BTIF_TRACE_DEBUG("%s attr_id:0x%x, charset_id:0x%x, str_len:%d, str:%s",
1689                             __FUNCTION__, (unsigned int)element_attrs[i].attr_id,
1690                             element_attrs[i].name.charset_id, element_attrs[i].name.str_len,
1691                             element_attrs[i].name.p_str);
1692        }
1693        avrc_rsp.get_play_status.status = AVRC_STS_NO_ERROR;
1694    }
1695    avrc_rsp.get_elem_attrs.num_attr = num_attr;
1696    avrc_rsp.get_elem_attrs.p_attrs = element_attrs;
1697    avrc_rsp.get_elem_attrs.pdu = AVRC_PDU_GET_ELEMENT_ATTR;
1698    avrc_rsp.get_elem_attrs.opcode = opcode_from_pdu(AVRC_PDU_GET_ELEMENT_ATTR);
1699    /* Send the response */
1700    SEND_METAMSG_RSP(IDX_GET_ELEMENT_ATTR_RSP, &avrc_rsp);
1701    return BT_STATUS_SUCCESS;
1702}
1703
1704/***************************************************************************
1705**
1706** Function         register_notification_rsp
1707**
1708** Description      Response to the register notification request.
1709**                      in text.
1710**
1711** Returns          bt_status_t
1712**
1713***************************************************************************/
1714static bt_status_t register_notification_rsp(btrc_event_id_t event_id,
1715    btrc_notification_type_t type, btrc_register_notification_t *p_param)
1716{
1717    tAVRC_RESPONSE avrc_rsp;
1718    CHECK_RC_CONNECTED
1719    BTIF_TRACE_EVENT("## %s ## event_id:%s", __FUNCTION__, dump_rc_notification_event_id(event_id));
1720    if (btif_rc_cb.rc_notif[event_id-1].bNotify == FALSE)
1721    {
1722        BTIF_TRACE_ERROR("Avrcp Event id not registered: event_id = %x", event_id);
1723        return BT_STATUS_NOT_READY;
1724    }
1725    memset(&(avrc_rsp.reg_notif), 0, sizeof(tAVRC_REG_NOTIF_RSP));
1726    avrc_rsp.reg_notif.event_id = event_id;
1727
1728    switch(event_id)
1729    {
1730        case BTRC_EVT_PLAY_STATUS_CHANGED:
1731            avrc_rsp.reg_notif.param.play_status = p_param->play_status;
1732            if (avrc_rsp.reg_notif.param.play_status == PLAY_STATUS_PLAYING)
1733                btif_av_clear_remote_suspend_flag();
1734            break;
1735        case BTRC_EVT_TRACK_CHANGE:
1736            memcpy(&(avrc_rsp.reg_notif.param.track), &(p_param->track), sizeof(btrc_uid_t));
1737            break;
1738        case BTRC_EVT_PLAY_POS_CHANGED:
1739            avrc_rsp.reg_notif.param.play_pos = p_param->song_pos;
1740            break;
1741        default:
1742            BTIF_TRACE_WARNING("%s : Unhandled event ID : 0x%x", __FUNCTION__, event_id);
1743            return BT_STATUS_UNHANDLED;
1744    }
1745
1746    avrc_rsp.reg_notif.pdu = AVRC_PDU_REGISTER_NOTIFICATION;
1747    avrc_rsp.reg_notif.opcode = opcode_from_pdu(AVRC_PDU_REGISTER_NOTIFICATION);
1748    avrc_rsp.get_play_status.status = AVRC_STS_NO_ERROR;
1749
1750    /* Send the response. */
1751    send_metamsg_rsp(btif_rc_cb.rc_handle, btif_rc_cb.rc_notif[event_id-1].label,
1752        ((type == BTRC_NOTIFICATION_TYPE_INTERIM)?AVRC_CMD_NOTIF:AVRC_RSP_CHANGED), &avrc_rsp);
1753    return BT_STATUS_SUCCESS;
1754}
1755
1756/***************************************************************************
1757**
1758** Function         set_volume
1759**
1760** Description      Send current volume setting to remote side.
1761**                  Support limited to SetAbsoluteVolume
1762**                  This can be enhanced to support Relative Volume (AVRCP 1.0).
1763**                  With RelateVolume, we will send VOLUME_UP/VOLUME_DOWN
1764**                  as opposed to absolute volume level
1765** volume: Should be in the range 0-127. bit7 is reseved and cannot be set
1766**
1767** Returns          bt_status_t
1768**
1769***************************************************************************/
1770static bt_status_t set_volume(uint8_t volume)
1771{
1772    BTIF_TRACE_DEBUG("%s", __FUNCTION__);
1773    CHECK_RC_CONNECTED
1774    tAVRC_STS status = BT_STATUS_UNSUPPORTED;
1775    rc_transaction_t *p_transaction=NULL;
1776
1777    if (btif_rc_cb.rc_volume==volume)
1778    {
1779        status=BT_STATUS_DONE;
1780        BTIF_TRACE_ERROR("%s: volume value already set earlier: 0x%02x",__FUNCTION__, volume);
1781        return status;
1782    }
1783
1784    if ((btif_rc_cb.rc_features & BTA_AV_FEAT_RCTG) &&
1785        (btif_rc_cb.rc_features & BTA_AV_FEAT_ADV_CTRL))
1786    {
1787        tAVRC_COMMAND avrc_cmd = {0};
1788        BT_HDR *p_msg = NULL;
1789
1790        BTIF_TRACE_DEBUG("%s: Peer supports absolute volume. newVolume=%d", __FUNCTION__, volume);
1791        avrc_cmd.volume.opcode = AVRC_OP_VENDOR;
1792        avrc_cmd.volume.pdu = AVRC_PDU_SET_ABSOLUTE_VOLUME;
1793        avrc_cmd.volume.status = AVRC_STS_NO_ERROR;
1794        avrc_cmd.volume.volume = volume;
1795
1796        if (AVRC_BldCommand(&avrc_cmd, &p_msg) == AVRC_STS_NO_ERROR)
1797        {
1798            bt_status_t tran_status=get_transaction(&p_transaction);
1799            if (BT_STATUS_SUCCESS == tran_status && NULL!=p_transaction)
1800            {
1801                BTIF_TRACE_DEBUG("%s msgreq being sent out with label %d",
1802                                   __FUNCTION__,p_transaction->lbl);
1803                BTA_AvMetaCmd(btif_rc_cb.rc_handle,p_transaction->lbl, AVRC_CMD_CTRL, p_msg);
1804                status =  BT_STATUS_SUCCESS;
1805            }
1806            else
1807            {
1808                osi_free(p_msg);
1809                BTIF_TRACE_ERROR("%s: failed to obtain transaction details. status: 0x%02x",
1810                                    __FUNCTION__, tran_status);
1811                status = BT_STATUS_FAIL;
1812            }
1813        }
1814        else
1815        {
1816            BTIF_TRACE_ERROR("%s: failed to build absolute volume command. status: 0x%02x",
1817                                __FUNCTION__, status);
1818            status = BT_STATUS_FAIL;
1819        }
1820    }
1821    else
1822        status=BT_STATUS_NOT_READY;
1823    return status;
1824}
1825
1826#if (AVRC_ADV_CTRL_INCLUDED == TRUE)
1827/***************************************************************************
1828**
1829** Function         register_volumechange
1830**
1831** Description     Register for volume change notification from remote side.
1832**
1833** Returns          void
1834**
1835***************************************************************************/
1836
1837static void register_volumechange (UINT8 lbl)
1838{
1839    tAVRC_COMMAND avrc_cmd = {0};
1840    BT_HDR *p_msg = NULL;
1841    tAVRC_STS BldResp=AVRC_STS_BAD_CMD;
1842    rc_transaction_t *p_transaction=NULL;
1843
1844    BTIF_TRACE_DEBUG("%s called with label:%d",__FUNCTION__,lbl);
1845
1846    avrc_cmd.cmd.opcode=0x00;
1847    avrc_cmd.pdu = AVRC_PDU_REGISTER_NOTIFICATION;
1848    avrc_cmd.reg_notif.event_id = AVRC_EVT_VOLUME_CHANGE;
1849    avrc_cmd.reg_notif.status = AVRC_STS_NO_ERROR;
1850    avrc_cmd.reg_notif.param = 0;
1851
1852    BldResp=AVRC_BldCommand(&avrc_cmd, &p_msg);
1853    if (AVRC_STS_NO_ERROR == BldResp && p_msg) {
1854        p_transaction = get_transaction_by_lbl(lbl);
1855        if (p_transaction != NULL) {
1856            BTA_AvMetaCmd(btif_rc_cb.rc_handle, p_transaction->lbl,
1857                          AVRC_CMD_NOTIF, p_msg);
1858            BTIF_TRACE_DEBUG("%s:BTA_AvMetaCmd called", __func__);
1859         } else {
1860            osi_free(p_msg);
1861            BTIF_TRACE_ERROR("%s transaction not obtained with label: %d",
1862                             __func__, lbl);
1863         }
1864    } else {
1865        BTIF_TRACE_ERROR("%s failed to build command:%d", __func__, BldResp);
1866    }
1867}
1868
1869/***************************************************************************
1870**
1871** Function         handle_rc_metamsg_rsp
1872**
1873** Description      Handle RC metamessage response
1874**
1875** Returns          void
1876**
1877***************************************************************************/
1878static void handle_rc_metamsg_rsp(tBTA_AV_META_MSG *pmeta_msg)
1879{
1880    tAVRC_RESPONSE    avrc_response = {0};
1881    UINT8             scratch_buf[512] = {0};
1882    tAVRC_STS status = BT_STATUS_UNSUPPORTED;
1883
1884    if (AVRC_OP_VENDOR==pmeta_msg->p_msg->hdr.opcode &&(AVRC_RSP_CHANGED==pmeta_msg->code
1885      || AVRC_RSP_INTERIM==pmeta_msg->code || AVRC_RSP_ACCEPT==pmeta_msg->code
1886      || AVRC_RSP_REJ==pmeta_msg->code || AVRC_RSP_NOT_IMPL==pmeta_msg->code))
1887    {
1888        status=AVRC_ParsResponse(pmeta_msg->p_msg, &avrc_response, scratch_buf, sizeof(scratch_buf));
1889        BTIF_TRACE_DEBUG("%s: code %d,event ID %d,PDU %x,parsing status %d, label:%d",
1890          __FUNCTION__,pmeta_msg->code,avrc_response.reg_notif.event_id,avrc_response.reg_notif.pdu,
1891          status, pmeta_msg->label);
1892
1893        if (status != AVRC_STS_NO_ERROR)
1894        {
1895            if (AVRC_PDU_REGISTER_NOTIFICATION==avrc_response.rsp.pdu
1896                && AVRC_EVT_VOLUME_CHANGE==avrc_response.reg_notif.event_id
1897                && btif_rc_cb.rc_vol_label==pmeta_msg->label)
1898            {
1899                btif_rc_cb.rc_vol_label=MAX_LABEL;
1900                release_transaction(btif_rc_cb.rc_vol_label);
1901            }
1902            else if (AVRC_PDU_SET_ABSOLUTE_VOLUME==avrc_response.rsp.pdu)
1903            {
1904                release_transaction(pmeta_msg->label);
1905            }
1906            return;
1907        }
1908        else if (AVRC_PDU_REGISTER_NOTIFICATION==avrc_response.rsp.pdu
1909            && AVRC_EVT_VOLUME_CHANGE==avrc_response.reg_notif.event_id
1910            && btif_rc_cb.rc_vol_label!=pmeta_msg->label)
1911            {
1912                // Just discard the message, if the device sends back with an incorrect label
1913                BTIF_TRACE_DEBUG("%s:Discarding register notfn in rsp.code: %d and label %d",
1914                __FUNCTION__, pmeta_msg->code, pmeta_msg->label);
1915                return;
1916            }
1917    }
1918    else
1919    {
1920        BTIF_TRACE_DEBUG("%s:Received vendor dependent in adv ctrl rsp. code: %d len: %d. Not processing it.",
1921        __FUNCTION__, pmeta_msg->code, pmeta_msg->len);
1922        return;
1923    }
1924
1925    if (AVRC_PDU_REGISTER_NOTIFICATION==avrc_response.rsp.pdu
1926        && AVRC_EVT_VOLUME_CHANGE==avrc_response.reg_notif.event_id
1927        && AVRC_RSP_CHANGED==pmeta_msg->code)
1928     {
1929         /* re-register for volume change notification */
1930         // Do not re-register for rejected case, as it might get into endless loop
1931         register_volumechange(btif_rc_cb.rc_vol_label);
1932     }
1933     else if (AVRC_PDU_SET_ABSOLUTE_VOLUME==avrc_response.rsp.pdu)
1934     {
1935          /* free up the label here */
1936          release_transaction(pmeta_msg->label);
1937     }
1938
1939     BTIF_TRACE_EVENT("%s: Passing received metamsg response to app. pdu: %s",
1940             __FUNCTION__, dump_rc_pdu(avrc_response.pdu));
1941     btif_rc_upstreams_rsp_evt((uint16_t)avrc_response.rsp.pdu, &avrc_response, pmeta_msg->code,
1942                                pmeta_msg->label);
1943}
1944#endif
1945
1946#if (AVRC_CTLR_INCLUDED == TRUE)
1947/***************************************************************************
1948**
1949** Function         iterate_supported_event_list_for_interim_rsp
1950**
1951** Description      iterator callback function to match the event and handle
1952**                  timer cleanup
1953** Returns          true to continue iterating, false to stop
1954**
1955***************************************************************************/
1956bool iterate_supported_event_list_for_interim_rsp(void *data, void *cb_data)
1957{
1958    UINT8 *p_event_id;
1959    btif_rc_supported_event_t *p_event = (btif_rc_supported_event_t *)data;
1960
1961    p_event_id = (UINT8*)cb_data;
1962
1963    if (p_event->event_id == *p_event_id)
1964    {
1965        p_event->status = eINTERIM;
1966        return false;
1967    }
1968    return true;
1969}
1970
1971/***************************************************************************
1972**
1973** Function         iterate_supported_event_list_for_timeout
1974**
1975** Description      Iterator callback function for timeout handling.
1976**                  As part of the failure handling, it releases the
1977**                  transaction label and removes the event from list,
1978**                  this event will not be requested again during
1979**                  the lifetime of the connection.
1980** Returns          false to stop iterating, true to continue
1981**
1982***************************************************************************/
1983bool iterate_supported_event_list_for_timeout(void *data, void *cb_data)
1984{
1985    UINT8 label;
1986    btif_rc_supported_event_t *p_event = (btif_rc_supported_event_t *)data;
1987
1988    label = (*(UINT8*)cb_data) & 0xFF;
1989
1990    if (p_event->label == label)
1991    {
1992        list_remove(btif_rc_cb.rc_supported_event_list, p_event);
1993        return false;
1994    }
1995    return true;
1996}
1997
1998/***************************************************************************
1999**
2000** Function         rc_notification_interim_timout
2001**
2002** Description      Interim response timeout handler.
2003**                  Runs the iterator to check and clear the timed out event.
2004**                  Proceeds to register for the unregistered events.
2005** Returns          None
2006**
2007***************************************************************************/
2008static void rc_notification_interim_timout (UINT8 label)
2009{
2010    list_node_t *node;
2011
2012    list_foreach(btif_rc_cb.rc_supported_event_list,
2013                     iterate_supported_event_list_for_timeout, &label);
2014    /* Timeout happened for interim response for the registered event,
2015     * check if there are any pending for registration
2016     */
2017    node = list_begin(btif_rc_cb.rc_supported_event_list);
2018    while (node != NULL)
2019    {
2020        btif_rc_supported_event_t *p_event;
2021
2022        p_event = (btif_rc_supported_event_t *)list_node(node);
2023        if ((p_event != NULL) && (p_event->status == eNOT_REGISTERED))
2024        {
2025            register_for_event_notification(p_event);
2026            break;
2027        }
2028        node = list_next (node);
2029    }
2030    /* Todo. Need to initiate application settings query if this
2031     * is the last event registration.
2032     */
2033}
2034
2035/***************************************************************************
2036**
2037** Function         btif_rc_status_cmd_timeout_handler
2038**
2039** Description      RC status command timeout handler (Runs in BTIF context).
2040** Returns          None
2041**
2042***************************************************************************/
2043static void btif_rc_status_cmd_timeout_handler(UNUSED_ATTR uint16_t event,
2044                                               char *data)
2045{
2046    btif_rc_timer_context_t *p_context;
2047    tAVRC_RESPONSE      avrc_response = {0};
2048    tBTA_AV_META_MSG    meta_msg;
2049
2050    p_context = (btif_rc_timer_context_t *)data;
2051    memset(&meta_msg, 0, sizeof(tBTA_AV_META_MSG));
2052    meta_msg.rc_handle = btif_rc_cb.rc_handle;
2053
2054    switch (p_context->rc_status_cmd.pdu_id) {
2055    case AVRC_PDU_REGISTER_NOTIFICATION:
2056        rc_notification_interim_timout(p_context->rc_status_cmd.label);
2057        break;
2058
2059    case AVRC_PDU_GET_CAPABILITIES:
2060        avrc_response.get_caps.status = BTIF_RC_STS_TIMEOUT;
2061        handle_get_capability_response(&meta_msg, &avrc_response.get_caps);
2062        break;
2063
2064    case AVRC_PDU_LIST_PLAYER_APP_ATTR:
2065        avrc_response.list_app_attr.status = BTIF_RC_STS_TIMEOUT;
2066        handle_app_attr_response(&meta_msg, &avrc_response.list_app_attr);
2067        break;
2068
2069    case AVRC_PDU_LIST_PLAYER_APP_VALUES:
2070        avrc_response.list_app_values.status = BTIF_RC_STS_TIMEOUT;
2071        handle_app_val_response(&meta_msg, &avrc_response.list_app_values);
2072        break;
2073
2074    case AVRC_PDU_GET_CUR_PLAYER_APP_VALUE:
2075        avrc_response.get_cur_app_val.status = BTIF_RC_STS_TIMEOUT;
2076        handle_app_cur_val_response(&meta_msg, &avrc_response.get_cur_app_val);
2077        break;
2078
2079    case AVRC_PDU_GET_PLAYER_APP_ATTR_TEXT:
2080        avrc_response.get_app_attr_txt.status = BTIF_RC_STS_TIMEOUT;
2081        handle_app_attr_txt_response(&meta_msg, &avrc_response.get_app_attr_txt);
2082        break;
2083
2084    case AVRC_PDU_GET_PLAYER_APP_VALUE_TEXT:
2085        avrc_response.get_app_val_txt.status = BTIF_RC_STS_TIMEOUT;
2086        handle_app_attr_txt_response(&meta_msg, &avrc_response.get_app_val_txt);
2087        break;
2088
2089    case AVRC_PDU_GET_ELEMENT_ATTR:
2090        avrc_response.get_elem_attrs.status = BTIF_RC_STS_TIMEOUT;
2091        handle_get_elem_attr_response(&meta_msg, &avrc_response.get_elem_attrs);
2092        break;
2093
2094    case AVRC_PDU_GET_PLAY_STATUS:
2095        avrc_response.get_play_status.status = BTIF_RC_STS_TIMEOUT;
2096        handle_get_playstatus_response(&meta_msg, &avrc_response.get_play_status);
2097        break;
2098    }
2099    release_transaction(p_context->rc_status_cmd.label);
2100}
2101
2102/***************************************************************************
2103**
2104** Function         btif_rc_status_cmd_timer_timeout
2105**
2106** Description      RC status command timeout callback.
2107**                  This is called from BTU context and switches to BTIF
2108**                  context to handle the timeout events
2109** Returns          None
2110**
2111***************************************************************************/
2112static void btif_rc_status_cmd_timer_timeout(void *data)
2113{
2114    btif_rc_timer_context_t *p_data = (btif_rc_timer_context_t *)data;
2115
2116    btif_transfer_context(btif_rc_status_cmd_timeout_handler, 0,
2117                          (char *)p_data, sizeof(btif_rc_timer_context_t),
2118                          NULL);
2119}
2120
2121/***************************************************************************
2122**
2123** Function         btif_rc_control_cmd_timeout_handler
2124**
2125** Description      RC control command timeout handler (Runs in BTIF context).
2126** Returns          None
2127**
2128***************************************************************************/
2129static void btif_rc_control_cmd_timeout_handler(UNUSED_ATTR uint16_t event,
2130                                                char *data)
2131{
2132    btif_rc_timer_context_t *p_context = (btif_rc_timer_context_t *)data;
2133    tAVRC_RESPONSE      avrc_response = {0};
2134    tBTA_AV_META_MSG    meta_msg;
2135
2136    memset(&meta_msg, 0, sizeof(tBTA_AV_META_MSG));
2137    meta_msg.rc_handle = btif_rc_cb.rc_handle;
2138
2139    switch (p_context->rc_control_cmd.pdu_id) {
2140    case AVRC_PDU_SET_PLAYER_APP_VALUE:
2141        avrc_response.set_app_val.status = BTIF_RC_STS_TIMEOUT;
2142        handle_set_app_attr_val_response(&meta_msg,
2143                                         &avrc_response.set_app_val);
2144        break;
2145    }
2146    release_transaction(p_context->rc_control_cmd.label);
2147}
2148
2149/***************************************************************************
2150**
2151** Function         btif_rc_control_cmd_timer_timeout
2152**
2153** Description      RC control command timeout callback.
2154**                  This is called from BTU context and switches to BTIF
2155**                  context to handle the timeout events
2156** Returns          None
2157**
2158***************************************************************************/
2159static void btif_rc_control_cmd_timer_timeout(void *data)
2160{
2161    btif_rc_timer_context_t *p_data = (btif_rc_timer_context_t *)data;
2162
2163    btif_transfer_context(btif_rc_control_cmd_timeout_handler, 0,
2164                          (char *)p_data, sizeof(btif_rc_timer_context_t),
2165                          NULL);
2166}
2167
2168/***************************************************************************
2169**
2170** Function         btif_rc_play_status_timeout_handler
2171**
2172** Description      RC play status timeout handler (Runs in BTIF context).
2173** Returns          None
2174**
2175***************************************************************************/
2176static void btif_rc_play_status_timeout_handler(UNUSED_ATTR uint16_t event,
2177                                                UNUSED_ATTR char *p_data)
2178{
2179    get_play_status_cmd();
2180    rc_start_play_status_timer();
2181}
2182
2183/***************************************************************************
2184**
2185** Function         btif_rc_play_status_timer_timeout
2186**
2187** Description      RC play status timeout callback.
2188**                  This is called from BTU context and switches to BTIF
2189**                  context to handle the timeout events
2190** Returns          None
2191**
2192***************************************************************************/
2193static void btif_rc_play_status_timer_timeout(UNUSED_ATTR void *data)
2194{
2195    btif_transfer_context(btif_rc_play_status_timeout_handler, 0, 0, 0, NULL);
2196}
2197
2198/***************************************************************************
2199**
2200** Function         rc_start_play_status_timer
2201**
2202** Description      Helper function to start the timer to fetch play status.
2203** Returns          None
2204**
2205***************************************************************************/
2206static void rc_start_play_status_timer(void)
2207{
2208    /* Start the Play status timer only if it is not started */
2209    if (!alarm_is_scheduled(btif_rc_cb.rc_play_status_timer)) {
2210        if (btif_rc_cb.rc_play_status_timer == NULL) {
2211            btif_rc_cb.rc_play_status_timer =
2212                alarm_new("btif_rc.rc_play_status_timer");
2213        }
2214        alarm_set_on_queue(btif_rc_cb.rc_play_status_timer,
2215                           BTIF_TIMEOUT_RC_INTERIM_RSP_MS,
2216                           btif_rc_play_status_timer_timeout, NULL,
2217                           btu_general_alarm_queue);
2218    }
2219}
2220
2221/***************************************************************************
2222**
2223** Function         rc_stop_play_status_timer
2224**
2225** Description      Helper function to stop the play status timer.
2226** Returns          None
2227**
2228***************************************************************************/
2229void rc_stop_play_status_timer()
2230{
2231    if (btif_rc_cb.rc_play_status_timer != NULL)
2232        alarm_cancel(btif_rc_cb.rc_play_status_timer);
2233}
2234
2235/***************************************************************************
2236**
2237** Function         register_for_event_notification
2238**
2239** Description      Helper function registering notification events
2240**                  sets an interim response timeout to handle if the remote
2241**                  does not respond.
2242** Returns          None
2243**
2244***************************************************************************/
2245static void register_for_event_notification(btif_rc_supported_event_t *p_event)
2246{
2247    bt_status_t status;
2248    rc_transaction_t *p_transaction;
2249
2250    status = get_transaction(&p_transaction);
2251    if (status == BT_STATUS_SUCCESS)
2252    {
2253        btif_rc_timer_context_t *p_context = &p_transaction->txn_timer_context;
2254
2255        status = register_notification_cmd (p_transaction->lbl, p_event->event_id, 0);
2256        if (status != BT_STATUS_SUCCESS)
2257        {
2258            BTIF_TRACE_ERROR("%s Error in Notification registration %d",
2259                __FUNCTION__, status);
2260            release_transaction (p_transaction->lbl);
2261            return;
2262        }
2263        p_event->label = p_transaction->lbl;
2264        p_event->status = eREGISTERED;
2265        p_context->rc_status_cmd.label = p_transaction->lbl;
2266        p_context->rc_status_cmd.pdu_id = AVRC_PDU_REGISTER_NOTIFICATION;
2267
2268        alarm_free(p_transaction->txn_timer);
2269        p_transaction->txn_timer =
2270            alarm_new("btif_rc.status_command_txn_timer");
2271        alarm_set_on_queue(p_transaction->txn_timer,
2272                           BTIF_TIMEOUT_RC_INTERIM_RSP_MS,
2273                           btif_rc_status_cmd_timer_timeout, p_context,
2274                           btu_general_alarm_queue);
2275    }
2276    else
2277    {
2278        BTIF_TRACE_ERROR("%s Error No more Transaction label %d",
2279            __FUNCTION__, status);
2280    }
2281}
2282
2283static void start_status_command_timer(UINT8 pdu_id, rc_transaction_t *p_txn)
2284{
2285    btif_rc_timer_context_t *p_context = &p_txn->txn_timer_context;
2286    p_context->rc_status_cmd.label = p_txn->lbl;
2287    p_context->rc_status_cmd.pdu_id = pdu_id;
2288
2289    alarm_free(p_txn->txn_timer);
2290    p_txn->txn_timer = alarm_new("btif_rc.status_command_txn_timer");
2291    alarm_set_on_queue(p_txn->txn_timer, BTIF_TIMEOUT_RC_STATUS_CMD_MS,
2292                       btif_rc_status_cmd_timer_timeout, p_context,
2293                       btu_general_alarm_queue);
2294}
2295
2296static void start_control_command_timer(UINT8 pdu_id, rc_transaction_t *p_txn)
2297{
2298    btif_rc_timer_context_t *p_context = &p_txn->txn_timer_context;
2299    p_context->rc_control_cmd.label = p_txn->lbl;
2300    p_context->rc_control_cmd.pdu_id = pdu_id;
2301
2302    alarm_free(p_txn->txn_timer);
2303    p_txn->txn_timer = alarm_new("btif_rc.control_command_txn_timer");
2304    alarm_set_on_queue(p_txn->txn_timer,
2305                       BTIF_TIMEOUT_RC_CONTROL_CMD_MS,
2306                       btif_rc_control_cmd_timer_timeout, p_context,
2307                       btu_general_alarm_queue);
2308}
2309
2310/***************************************************************************
2311**
2312** Function         handle_get_capability_response
2313**
2314** Description      Handles the get_cap_response to populate company id info
2315**                  and query the supported events.
2316**                  Initiates Notification registration for events supported
2317** Returns          None
2318**
2319***************************************************************************/
2320static void handle_get_capability_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_GET_CAPS_RSP *p_rsp)
2321{
2322    int xx = 0;
2323
2324    /* Todo: Do we need to retry on command timeout */
2325    if (p_rsp->status != AVRC_STS_NO_ERROR)
2326    {
2327        BTIF_TRACE_ERROR("%s Error capability response 0x%02X",
2328                __FUNCTION__, p_rsp->status);
2329        return;
2330    }
2331
2332    if (p_rsp->capability_id == AVRC_CAP_EVENTS_SUPPORTED)
2333    {
2334        btif_rc_supported_event_t *p_event;
2335
2336        /* Todo: Check if list can be active when we hit here */
2337        btif_rc_cb.rc_supported_event_list = list_new(osi_free);
2338        for (xx = 0; xx < p_rsp->count; xx++)
2339        {
2340            /* Skip registering for Play position change notification */
2341            if ((p_rsp->param.event_id[xx] == AVRC_EVT_PLAY_STATUS_CHANGE)||
2342                (p_rsp->param.event_id[xx] == AVRC_EVT_TRACK_CHANGE)||
2343                (p_rsp->param.event_id[xx] == AVRC_EVT_APP_SETTING_CHANGE))
2344            {
2345                p_event = (btif_rc_supported_event_t *)osi_malloc(sizeof(btif_rc_supported_event_t));
2346                p_event->event_id = p_rsp->param.event_id[xx];
2347                p_event->status = eNOT_REGISTERED;
2348                list_append(btif_rc_cb.rc_supported_event_list, p_event);
2349            }
2350        }
2351        p_event = list_front(btif_rc_cb.rc_supported_event_list);
2352        if (p_event != NULL)
2353        {
2354            register_for_event_notification(p_event);
2355        }
2356    }
2357    else if (p_rsp->capability_id == AVRC_CAP_COMPANY_ID)
2358    {
2359        getcapabilities_cmd (AVRC_CAP_EVENTS_SUPPORTED);
2360        BTIF_TRACE_EVENT("%s AVRC_CAP_COMPANY_ID: ", __FUNCTION__);
2361        for (xx = 0; xx < p_rsp->count; xx++)
2362        {
2363            BTIF_TRACE_EVENT("%s    : %d", __FUNCTION__, p_rsp->param.company_id[xx]);
2364        }
2365    }
2366}
2367
2368bool rc_is_track_id_valid (tAVRC_UID uid)
2369{
2370    tAVRC_UID invalid_uid = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
2371
2372    if (memcmp(uid, invalid_uid, sizeof(tAVRC_UID)) == 0)
2373    {
2374        return false;
2375    }
2376    else
2377    {
2378        return true;
2379    }
2380}
2381
2382/***************************************************************************
2383**
2384** Function         handle_notification_response
2385**
2386** Description      Main handler for notification responses to registered events
2387**                  1. Register for unregistered event(in interim response path)
2388**                  2. After registering for all supported events, start
2389**                     retrieving application settings and values
2390**                  3. Reregister for events on getting changed response
2391**                  4. Run play status timer for getting position when the
2392**                     status changes to playing
2393**                  5. Get the Media details when the track change happens
2394**                     or track change interim response is received with
2395**                     valid track id
2396**                  6. HAL callback for play status change and application
2397**                     setting change
2398** Returns          None
2399**
2400***************************************************************************/
2401static void handle_notification_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_REG_NOTIF_RSP *p_rsp)
2402{
2403    bt_bdaddr_t rc_addr;
2404    UINT32 attr_list[] = {
2405        AVRC_MEDIA_ATTR_ID_TITLE,
2406        AVRC_MEDIA_ATTR_ID_ARTIST,
2407        AVRC_MEDIA_ATTR_ID_ALBUM,
2408        AVRC_MEDIA_ATTR_ID_TRACK_NUM,
2409        AVRC_MEDIA_ATTR_ID_NUM_TRACKS,
2410        AVRC_MEDIA_ATTR_ID_GENRE,
2411        AVRC_MEDIA_ATTR_ID_PLAYING_TIME
2412        };
2413
2414
2415    bdcpy(rc_addr.address, btif_rc_cb.rc_addr);
2416
2417    if (pmeta_msg->code == AVRC_RSP_INTERIM)
2418    {
2419        btif_rc_supported_event_t *p_event;
2420        list_node_t *node;
2421
2422        BTIF_TRACE_DEBUG("%s Interim response : 0x%2X ", __FUNCTION__, p_rsp->event_id);
2423        switch (p_rsp->event_id)
2424        {
2425            case AVRC_EVT_PLAY_STATUS_CHANGE:
2426                /* Start timer to get play status periodically
2427                 * if the play state is playing.
2428                 */
2429                if (p_rsp->param.play_status == AVRC_PLAYSTATE_PLAYING)
2430                {
2431                    rc_start_play_status_timer();
2432                }
2433                HAL_CBACK(bt_rc_ctrl_callbacks, play_status_changed_cb,
2434                    &rc_addr, p_rsp->param.play_status);
2435                break;
2436
2437            case AVRC_EVT_TRACK_CHANGE:
2438                if (rc_is_track_id_valid (p_rsp->param.track) != true)
2439                {
2440                    break;
2441                }
2442                else
2443                {
2444                    UINT8 *p_data = p_rsp->param.track;
2445                    /* Update the UID for current track
2446                     * Attributes will be fetched after the AVRCP procedure
2447                     */
2448                    BE_STREAM_TO_UINT64(btif_rc_cb.rc_playing_uid, p_data);
2449                }
2450                break;
2451
2452            case AVRC_EVT_APP_SETTING_CHANGE:
2453                break;
2454
2455            case AVRC_EVT_NOW_PLAYING_CHANGE:
2456                break;
2457
2458            case AVRC_EVT_AVAL_PLAYERS_CHANGE:
2459                break;
2460
2461            case AVRC_EVT_ADDR_PLAYER_CHANGE:
2462                break;
2463
2464            case AVRC_EVT_UIDS_CHANGE:
2465                break;
2466
2467            case AVRC_EVT_TRACK_REACHED_END:
2468            case AVRC_EVT_TRACK_REACHED_START:
2469            case AVRC_EVT_PLAY_POS_CHANGED:
2470            case AVRC_EVT_BATTERY_STATUS_CHANGE:
2471            case AVRC_EVT_SYSTEM_STATUS_CHANGE:
2472            default:
2473                BTIF_TRACE_ERROR("%s  Unhandled interim response 0x%2X", __FUNCTION__,
2474                    p_rsp->event_id);
2475                return;
2476        }
2477        list_foreach(btif_rc_cb.rc_supported_event_list,
2478                iterate_supported_event_list_for_interim_rsp,
2479                &p_rsp->event_id);
2480
2481        node = list_begin(btif_rc_cb.rc_supported_event_list);
2482        while (node != NULL)
2483        {
2484            p_event = (btif_rc_supported_event_t *)list_node(node);
2485            if ((p_event != NULL) && (p_event->status == eNOT_REGISTERED))
2486            {
2487                register_for_event_notification(p_event);
2488                break;
2489            }
2490            node = list_next (node);
2491            p_event = NULL;
2492        }
2493        /* Registered for all events, we can request application settings */
2494        if ((p_event == NULL) && (btif_rc_cb.rc_app_settings.query_started == false))
2495        {
2496            /* we need to do this only if remote TG supports
2497             * player application settings
2498             */
2499            btif_rc_cb.rc_app_settings.query_started = TRUE;
2500            if (btif_rc_cb.rc_features & BTA_AV_FEAT_APP_SETTING)
2501            {
2502                list_player_app_setting_attrib_cmd();
2503            }
2504            else
2505            {
2506                BTIF_TRACE_DEBUG("%s App setting not supported, complete procedure", __FUNCTION__);
2507                rc_ctrl_procedure_complete();
2508            }
2509        }
2510    }
2511    else if (pmeta_msg->code == AVRC_RSP_CHANGED)
2512    {
2513        btif_rc_supported_event_t *p_event;
2514        list_node_t *node;
2515
2516        BTIF_TRACE_DEBUG("%s Notification completed : 0x%2X ", __FUNCTION__,
2517            p_rsp->event_id);
2518
2519        node = list_begin(btif_rc_cb.rc_supported_event_list);
2520        while (node != NULL)
2521        {
2522            p_event = (btif_rc_supported_event_t *)list_node(node);
2523            if ((p_event != NULL) && (p_event->event_id == p_rsp->event_id))
2524            {
2525                p_event->status = eNOT_REGISTERED;
2526                register_for_event_notification(p_event);
2527                break;
2528            }
2529            node = list_next (node);
2530        }
2531
2532        switch (p_rsp->event_id)
2533        {
2534            case AVRC_EVT_PLAY_STATUS_CHANGE:
2535                /* Start timer to get play status periodically
2536                 * if the play state is playing.
2537                 */
2538                if (p_rsp->param.play_status == AVRC_PLAYSTATE_PLAYING)
2539                {
2540                    rc_start_play_status_timer();
2541                }
2542                else
2543                {
2544                    rc_stop_play_status_timer();
2545                }
2546                HAL_CBACK(bt_rc_ctrl_callbacks, play_status_changed_cb,
2547                    &rc_addr, p_rsp->param.play_status);
2548                break;
2549
2550            case AVRC_EVT_TRACK_CHANGE:
2551                if (rc_is_track_id_valid (p_rsp->param.track) != true)
2552                {
2553                    break;
2554                }
2555                get_element_attribute_cmd (AVRC_MAX_NUM_MEDIA_ATTR_ID, attr_list);
2556                break;
2557
2558            case AVRC_EVT_APP_SETTING_CHANGE:
2559            {
2560                btrc_player_settings_t app_settings;
2561                UINT16 xx;
2562
2563                app_settings.num_attr = p_rsp->param.player_setting.num_attr;
2564                for (xx = 0; xx < app_settings.num_attr; xx++)
2565                {
2566                    app_settings.attr_ids[xx] = p_rsp->param.player_setting.attr_id[xx];
2567                    app_settings.attr_values[xx] = p_rsp->param.player_setting.attr_value[xx];
2568                }
2569                HAL_CBACK(bt_rc_ctrl_callbacks, playerapplicationsetting_changed_cb,
2570                    &rc_addr, &app_settings);
2571            }
2572                break;
2573
2574            case AVRC_EVT_NOW_PLAYING_CHANGE:
2575                break;
2576
2577            case AVRC_EVT_AVAL_PLAYERS_CHANGE:
2578                break;
2579
2580            case AVRC_EVT_ADDR_PLAYER_CHANGE:
2581                break;
2582
2583            case AVRC_EVT_UIDS_CHANGE:
2584                break;
2585
2586            case AVRC_EVT_TRACK_REACHED_END:
2587            case AVRC_EVT_TRACK_REACHED_START:
2588            case AVRC_EVT_PLAY_POS_CHANGED:
2589            case AVRC_EVT_BATTERY_STATUS_CHANGE:
2590            case AVRC_EVT_SYSTEM_STATUS_CHANGE:
2591            default:
2592                BTIF_TRACE_ERROR("%s  Unhandled completion response 0x%2X",
2593                    __FUNCTION__, p_rsp->event_id);
2594                return;
2595        }
2596    }
2597}
2598
2599/***************************************************************************
2600**
2601** Function         handle_app_attr_response
2602**
2603** Description      handles the the application attributes response and
2604**                  initiates procedure to fetch the attribute values
2605** Returns          None
2606**
2607***************************************************************************/
2608static void handle_app_attr_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_LIST_APP_ATTR_RSP *p_rsp)
2609{
2610    UINT8 xx;
2611
2612    if (p_rsp->status != AVRC_STS_NO_ERROR)
2613    {
2614        BTIF_TRACE_ERROR("%s Error getting Player application settings: 0x%2X",
2615                __FUNCTION__, p_rsp->status);
2616        rc_ctrl_procedure_complete();
2617        return;
2618    }
2619
2620    for (xx = 0; xx < p_rsp->num_attr; xx++)
2621    {
2622        UINT8 st_index;
2623
2624        if (p_rsp->attrs[xx] > AVRC_PLAYER_SETTING_LOW_MENU_EXT)
2625        {
2626            st_index = btif_rc_cb.rc_app_settings.num_ext_attrs;
2627            btif_rc_cb.rc_app_settings.ext_attrs[st_index].attr_id = p_rsp->attrs[xx];
2628            btif_rc_cb.rc_app_settings.num_ext_attrs++;
2629        }
2630        else
2631        {
2632            st_index = btif_rc_cb.rc_app_settings.num_attrs;
2633            btif_rc_cb.rc_app_settings.attrs[st_index].attr_id = p_rsp->attrs[xx];
2634            btif_rc_cb.rc_app_settings.num_attrs++;
2635        }
2636    }
2637    btif_rc_cb.rc_app_settings.attr_index = 0;
2638    btif_rc_cb.rc_app_settings.ext_attr_index = 0;
2639    btif_rc_cb.rc_app_settings.ext_val_index = 0;
2640    if (p_rsp->num_attr)
2641    {
2642        list_player_app_setting_value_cmd (btif_rc_cb.rc_app_settings.attrs[0].attr_id);
2643    }
2644    else
2645    {
2646        BTIF_TRACE_ERROR("%s No Player application settings found",
2647                __FUNCTION__);
2648    }
2649}
2650
2651/***************************************************************************
2652**
2653** Function         handle_app_val_response
2654**
2655** Description      handles the the attributes value response and if extended
2656**                  menu is available, it initiates query for the attribute
2657**                  text. If not, it initiates procedure to get the current
2658**                  attribute values and calls the HAL callback for provding
2659**                  application settings information.
2660** Returns          None
2661**
2662***************************************************************************/
2663static void handle_app_val_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_LIST_APP_VALUES_RSP *p_rsp)
2664{
2665    UINT8 xx, attr_index;
2666    UINT8 attrs[AVRC_MAX_APP_ATTR_SIZE];
2667    btif_rc_player_app_settings_t *p_app_settings;
2668    bt_bdaddr_t rc_addr;
2669
2670    /* Todo: Do we need to retry on command timeout */
2671    if (p_rsp->status != AVRC_STS_NO_ERROR)
2672    {
2673        BTIF_TRACE_ERROR("%s Error fetching attribute values 0x%02X",
2674                __FUNCTION__, p_rsp->status);
2675        return;
2676    }
2677
2678    p_app_settings = &btif_rc_cb.rc_app_settings;
2679    bdcpy(rc_addr.address, btif_rc_cb.rc_addr);
2680
2681    if (p_app_settings->attr_index < p_app_settings->num_attrs)
2682    {
2683        attr_index = p_app_settings->attr_index;
2684        p_app_settings->attrs[attr_index].num_val = p_rsp->num_val;
2685        for (xx = 0; xx < p_rsp->num_val; xx++)
2686        {
2687            p_app_settings->attrs[attr_index].attr_val[xx] = p_rsp->vals[xx];
2688        }
2689        attr_index++;
2690        p_app_settings->attr_index++;
2691        if (attr_index < p_app_settings->num_attrs)
2692        {
2693            list_player_app_setting_value_cmd (p_app_settings->attrs[p_app_settings->attr_index].attr_id);
2694        }
2695        else if (p_app_settings->ext_attr_index < p_app_settings->num_ext_attrs)
2696        {
2697            attr_index = 0;
2698            p_app_settings->ext_attr_index = 0;
2699            list_player_app_setting_value_cmd (p_app_settings->ext_attrs[attr_index].attr_id);
2700        }
2701        else
2702        {
2703            for (xx = 0; xx < p_app_settings->num_attrs; xx++)
2704            {
2705                attrs[xx] = p_app_settings->attrs[xx].attr_id;
2706            }
2707            get_player_app_setting_cmd (p_app_settings->num_attrs, attrs);
2708            HAL_CBACK (bt_rc_ctrl_callbacks, playerapplicationsetting_cb, &rc_addr,
2709                        p_app_settings->num_attrs, p_app_settings->attrs, 0, NULL);
2710        }
2711    }
2712    else if (p_app_settings->ext_attr_index < p_app_settings->num_ext_attrs)
2713    {
2714        attr_index = p_app_settings->ext_attr_index;
2715        p_app_settings->ext_attrs[attr_index].num_val = p_rsp->num_val;
2716        for (xx = 0; xx < p_rsp->num_val; xx++)
2717        {
2718            p_app_settings->ext_attrs[attr_index].ext_attr_val[xx].val = p_rsp->vals[xx];
2719        }
2720        attr_index++;
2721        p_app_settings->ext_attr_index++;
2722        if (attr_index < p_app_settings->num_ext_attrs)
2723        {
2724            list_player_app_setting_value_cmd (p_app_settings->ext_attrs[p_app_settings->ext_attr_index].attr_id);
2725        }
2726        else
2727        {
2728            UINT8 attr[AVRC_MAX_APP_ATTR_SIZE];
2729            UINT8 xx;
2730
2731            for (xx = 0; xx < p_app_settings->num_ext_attrs; xx++)
2732            {
2733                attr[xx] = p_app_settings->ext_attrs[xx].attr_id;
2734            }
2735            get_player_app_setting_attr_text_cmd(attr, xx);
2736        }
2737    }
2738}
2739
2740/***************************************************************************
2741**
2742** Function         handle_app_cur_val_response
2743**
2744** Description      handles the the get attributes value response.
2745**
2746** Returns          None
2747**
2748***************************************************************************/
2749static void handle_app_cur_val_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_GET_CUR_APP_VALUE_RSP *p_rsp)
2750{
2751    btrc_player_settings_t app_settings;
2752    bt_bdaddr_t rc_addr;
2753    UINT16 xx;
2754
2755    /* Todo: Do we need to retry on command timeout */
2756    if (p_rsp->status != AVRC_STS_NO_ERROR)
2757    {
2758        BTIF_TRACE_ERROR("%s Error fetching current settings: 0x%02X",
2759                __FUNCTION__, p_rsp->status);
2760        return;
2761    }
2762
2763    bdcpy(rc_addr.address, btif_rc_cb.rc_addr);
2764
2765    app_settings.num_attr = p_rsp->num_val;
2766    for (xx = 0; xx < app_settings.num_attr; xx++)
2767    {
2768        app_settings.attr_ids[xx] = p_rsp->p_vals[xx].attr_id;
2769        app_settings.attr_values[xx] = p_rsp->p_vals[xx].attr_val;
2770    }
2771    HAL_CBACK(bt_rc_ctrl_callbacks, playerapplicationsetting_changed_cb,
2772        &rc_addr, &app_settings);
2773    /* Application settings are fetched only once for initial values
2774     * initiate anything that follows after RC procedure.
2775     * Defer it if browsing is supported till players query
2776     */
2777    rc_ctrl_procedure_complete ();
2778    osi_free_and_reset((void **)&p_rsp->p_vals);
2779}
2780
2781/***************************************************************************
2782**
2783** Function         handle_app_attr_txt_response
2784**
2785** Description      handles the the get attributes text response, if fails
2786**                  calls HAL callback with just normal settings and initiates
2787**                  query for current settings else initiates query for value text
2788** Returns          None
2789**
2790***************************************************************************/
2791static void handle_app_attr_txt_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_GET_APP_ATTR_TXT_RSP *p_rsp)
2792{
2793    UINT8 xx;
2794    UINT8 vals[AVRC_MAX_APP_ATTR_SIZE];
2795    btif_rc_player_app_settings_t *p_app_settings;
2796    bt_bdaddr_t rc_addr;
2797
2798    p_app_settings = &btif_rc_cb.rc_app_settings;
2799    bdcpy(rc_addr.address, btif_rc_cb.rc_addr);
2800
2801    /* Todo: Do we need to retry on command timeout */
2802    if (p_rsp->status != AVRC_STS_NO_ERROR)
2803    {
2804        UINT8 attrs[AVRC_MAX_APP_ATTR_SIZE];
2805
2806        BTIF_TRACE_ERROR("%s Error fetching attribute text: 0x%02X",
2807                __FUNCTION__, p_rsp->status);
2808        /* Not able to fetch Text for extended Menu, skip the process
2809         * and cleanup used memory. Proceed to get the current settings
2810         * for standard attributes.
2811         */
2812        p_app_settings->num_ext_attrs = 0;
2813        for (xx = 0; xx < p_app_settings->ext_attr_index; xx++)
2814            osi_free_and_reset((void **)&p_app_settings->ext_attrs[xx].p_str);
2815        p_app_settings->ext_attr_index = 0;
2816
2817        for (xx = 0; xx < p_app_settings->num_attrs; xx++)
2818        {
2819            attrs[xx] = p_app_settings->attrs[xx].attr_id;
2820        }
2821        HAL_CBACK (bt_rc_ctrl_callbacks, playerapplicationsetting_cb, &rc_addr,
2822                    p_app_settings->num_attrs, p_app_settings->attrs, 0, NULL);
2823
2824        get_player_app_setting_cmd (xx, attrs);
2825        return;
2826    }
2827
2828    for (xx = 0; xx < p_rsp->num_attr; xx++)
2829    {
2830        UINT8 x;
2831        for (x = 0; x < p_app_settings->num_ext_attrs; x++)
2832        {
2833            if (p_app_settings->ext_attrs[x].attr_id == p_rsp->p_attrs[xx].attr_id)
2834            {
2835                p_app_settings->ext_attrs[x].charset_id = p_rsp->p_attrs[xx].charset_id;
2836                p_app_settings->ext_attrs[x].str_len = p_rsp->p_attrs[xx].str_len;
2837                p_app_settings->ext_attrs[x].p_str = p_rsp->p_attrs[xx].p_str;
2838                break;
2839            }
2840        }
2841    }
2842
2843    for (xx = 0; xx < p_app_settings->ext_attrs[0].num_val; xx++)
2844    {
2845        vals[xx] = p_app_settings->ext_attrs[0].ext_attr_val[xx].val;
2846    }
2847    get_player_app_setting_value_text_cmd(vals, xx);
2848}
2849
2850
2851/***************************************************************************
2852**
2853** Function         handle_app_attr_val_txt_response
2854**
2855** Description      handles the the get attributes value text response, if fails
2856**                  calls HAL callback with just normal settings and initiates
2857**                  query for current settings
2858** Returns          None
2859**
2860***************************************************************************/
2861static void handle_app_attr_val_txt_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_GET_APP_ATTR_TXT_RSP *p_rsp)
2862{
2863    UINT8 xx, attr_index;
2864    UINT8 vals[AVRC_MAX_APP_ATTR_SIZE];
2865    UINT8 attrs[AVRC_MAX_APP_ATTR_SIZE];
2866    btif_rc_player_app_settings_t *p_app_settings;
2867    bt_bdaddr_t rc_addr;
2868
2869    bdcpy(rc_addr.address, btif_rc_cb.rc_addr);
2870    p_app_settings = &btif_rc_cb.rc_app_settings;
2871
2872    /* Todo: Do we need to retry on command timeout */
2873    if (p_rsp->status != AVRC_STS_NO_ERROR)
2874    {
2875        UINT8 attrs[AVRC_MAX_APP_ATTR_SIZE];
2876
2877        BTIF_TRACE_ERROR("%s Error fetching attribute value text: 0x%02X",
2878                __FUNCTION__, p_rsp->status);
2879
2880        /* Not able to fetch Text for extended Menu, skip the process
2881         * and cleanup used memory. Proceed to get the current settings
2882         * for standard attributes.
2883         */
2884        p_app_settings->num_ext_attrs = 0;
2885        for (xx = 0; xx < p_app_settings->ext_attr_index; xx++)
2886        {
2887            int x;
2888            btrc_player_app_ext_attr_t *p_ext_attr = &p_app_settings->ext_attrs[xx];
2889
2890            for (x = 0; x < p_ext_attr->num_val; x++)
2891                osi_free_and_reset((void **)&p_ext_attr->ext_attr_val[x].p_str);
2892            p_ext_attr->num_val = 0;
2893            osi_free_and_reset((void **)&p_app_settings->ext_attrs[xx].p_str);
2894        }
2895        p_app_settings->ext_attr_index = 0;
2896
2897        for (xx = 0; xx < p_app_settings->num_attrs; xx++)
2898        {
2899            attrs[xx] = p_app_settings->attrs[xx].attr_id;
2900        }
2901        HAL_CBACK (bt_rc_ctrl_callbacks, playerapplicationsetting_cb, &rc_addr,
2902                    p_app_settings->num_attrs, p_app_settings->attrs, 0, NULL);
2903
2904        get_player_app_setting_cmd (xx, attrs);
2905        return;
2906    }
2907
2908    for (xx = 0; xx < p_rsp->num_attr; xx++)
2909    {
2910        UINT8 x;
2911        btrc_player_app_ext_attr_t *p_ext_attr;
2912        p_ext_attr = &p_app_settings->ext_attrs[p_app_settings->ext_val_index];
2913        for (x = 0; x < p_rsp->num_attr; x++)
2914        {
2915            if (p_ext_attr->ext_attr_val[x].val == p_rsp->p_attrs[xx].attr_id)
2916            {
2917                p_ext_attr->ext_attr_val[x].charset_id = p_rsp->p_attrs[xx].charset_id;
2918                p_ext_attr->ext_attr_val[x].str_len = p_rsp->p_attrs[xx].str_len;
2919                p_ext_attr->ext_attr_val[x].p_str = p_rsp->p_attrs[xx].p_str;
2920                break;
2921            }
2922        }
2923    }
2924    p_app_settings->ext_val_index++;
2925
2926    if (p_app_settings->ext_val_index < p_app_settings->num_ext_attrs)
2927    {
2928        attr_index = p_app_settings->ext_val_index;
2929        for (xx = 0; xx < p_app_settings->ext_attrs[attr_index].num_val; xx++)
2930        {
2931            vals[xx] = p_app_settings->ext_attrs[attr_index].ext_attr_val[xx].val;
2932        }
2933        get_player_app_setting_value_text_cmd(vals, xx);
2934    }
2935    else
2936    {
2937        UINT8 x;
2938
2939        for (xx = 0; xx < p_app_settings->num_attrs; xx++)
2940        {
2941            attrs[xx] = p_app_settings->attrs[xx].attr_id;
2942        }
2943        for (x = 0; x < p_app_settings->num_ext_attrs; x++)
2944        {
2945            attrs[xx+x] = p_app_settings->ext_attrs[x].attr_id;
2946        }
2947        HAL_CBACK (bt_rc_ctrl_callbacks, playerapplicationsetting_cb, &rc_addr,
2948                    p_app_settings->num_attrs, p_app_settings->attrs,
2949                    p_app_settings->num_ext_attrs, p_app_settings->ext_attrs);
2950        get_player_app_setting_cmd (xx + x, attrs);
2951
2952        /* Free the application settings information after sending to
2953         * application.
2954         */
2955        for (xx = 0; xx < p_app_settings->ext_attr_index; xx++)
2956        {
2957            int x;
2958            btrc_player_app_ext_attr_t *p_ext_attr = &p_app_settings->ext_attrs[xx];
2959
2960            for (x = 0; x < p_ext_attr->num_val; x++)
2961                osi_free_and_reset((void **)&p_ext_attr->ext_attr_val[x].p_str);
2962            p_ext_attr->num_val = 0;
2963            osi_free_and_reset((void **)&p_app_settings->ext_attrs[xx].p_str);
2964        }
2965        p_app_settings->num_attrs = 0;
2966    }
2967}
2968
2969/***************************************************************************
2970**
2971** Function         handle_set_app_attr_val_response
2972**
2973** Description      handles the the set attributes value response, if fails
2974**                  calls HAL callback to indicate the failure
2975** Returns          None
2976**
2977***************************************************************************/
2978static void handle_set_app_attr_val_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_RSP *p_rsp)
2979{
2980    uint8_t accepted = 0;
2981    bt_bdaddr_t rc_addr;
2982
2983    bdcpy(rc_addr.address, btif_rc_cb.rc_addr);
2984
2985    /* For timeout pmeta_msg will be NULL, else we need to
2986     * check if this is accepted by TG
2987     */
2988    if (pmeta_msg && (pmeta_msg->code == AVRC_RSP_ACCEPT))
2989    {
2990        accepted = 1;
2991    }
2992    HAL_CBACK(bt_rc_ctrl_callbacks, setplayerappsetting_rsp_cb, &rc_addr, accepted);
2993}
2994
2995/***************************************************************************
2996**
2997** Function         handle_get_elem_attr_response
2998**
2999** Description      handles the the element attributes response, calls
3000**                  HAL callback to update track change information.
3001** Returns          None
3002**
3003***************************************************************************/
3004static void handle_get_elem_attr_response (tBTA_AV_META_MSG *pmeta_msg,
3005                                           tAVRC_GET_ELEM_ATTRS_RSP *p_rsp)
3006{
3007    if (p_rsp->status == AVRC_STS_NO_ERROR) {
3008        bt_bdaddr_t rc_addr;
3009        size_t buf_size = p_rsp->num_attr * sizeof(btrc_element_attr_val_t);
3010        btrc_element_attr_val_t *p_attr =
3011            (btrc_element_attr_val_t *)osi_calloc(buf_size);
3012
3013        bdcpy(rc_addr.address, btif_rc_cb.rc_addr);
3014
3015        for (int i = 0; i < p_rsp->num_attr; i++) {
3016            p_attr[i].attr_id = p_rsp->p_attrs[i].attr_id;
3017            /* Todo. Legth limit check to include null */
3018            if (p_rsp->p_attrs[i].name.str_len &&
3019                p_rsp->p_attrs[i].name.p_str) {
3020                memcpy(p_attr[i].text, p_rsp->p_attrs[i].name.p_str,
3021                       p_rsp->p_attrs[i].name.str_len);
3022                osi_free_and_reset((void **)&p_rsp->p_attrs[i].name.p_str);
3023            }
3024        }
3025        HAL_CBACK(bt_rc_ctrl_callbacks, track_changed_cb,
3026                  &rc_addr, p_rsp->num_attr, p_attr);
3027        osi_free(p_attr);
3028    } else if (p_rsp->status == BTIF_RC_STS_TIMEOUT) {
3029        /* Retry for timeout case, this covers error handling
3030         * for continuation failure also.
3031         */
3032        UINT32 attr_list[] = {
3033            AVRC_MEDIA_ATTR_ID_TITLE,
3034            AVRC_MEDIA_ATTR_ID_ARTIST,
3035            AVRC_MEDIA_ATTR_ID_ALBUM,
3036            AVRC_MEDIA_ATTR_ID_TRACK_NUM,
3037            AVRC_MEDIA_ATTR_ID_NUM_TRACKS,
3038            AVRC_MEDIA_ATTR_ID_GENRE,
3039            AVRC_MEDIA_ATTR_ID_PLAYING_TIME
3040            };
3041        get_element_attribute_cmd (AVRC_MAX_NUM_MEDIA_ATTR_ID, attr_list);
3042    } else {
3043        BTIF_TRACE_ERROR("%s: Error in get element attr procedure %d",
3044                         __func__, p_rsp->status);
3045    }
3046}
3047
3048/***************************************************************************
3049**
3050** Function         handle_get_playstatus_response
3051**
3052** Description      handles the the play status response, calls
3053**                  HAL callback to update play position.
3054** Returns          None
3055**
3056***************************************************************************/
3057static void handle_get_playstatus_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_GET_PLAY_STATUS_RSP *p_rsp)
3058{
3059    bt_bdaddr_t rc_addr;
3060
3061    bdcpy(rc_addr.address, btif_rc_cb.rc_addr);
3062
3063    if (p_rsp->status == AVRC_STS_NO_ERROR)
3064    {
3065        HAL_CBACK(bt_rc_ctrl_callbacks, play_position_changed_cb,
3066            &rc_addr, p_rsp->song_len, p_rsp->song_pos);
3067    }
3068    else
3069    {
3070        BTIF_TRACE_ERROR("%s: Error in get play status procedure %d",
3071            __FUNCTION__, p_rsp->status);
3072    }
3073}
3074
3075/***************************************************************************
3076**
3077** Function         clear_cmd_timeout
3078**
3079** Description      helper function to stop the command timeout timer
3080** Returns          None
3081**
3082***************************************************************************/
3083static void clear_cmd_timeout (UINT8 label)
3084{
3085    rc_transaction_t *p_txn;
3086
3087    p_txn = get_transaction_by_lbl (label);
3088    if (p_txn == NULL)
3089    {
3090        BTIF_TRACE_ERROR("%s: Error in transaction label lookup", __FUNCTION__);
3091        return;
3092    }
3093
3094    if (p_txn->txn_timer != NULL)
3095        alarm_cancel(p_txn->txn_timer);
3096}
3097
3098/***************************************************************************
3099**
3100** Function         handle_avk_rc_metamsg_rsp
3101**
3102** Description      Handle RC metamessage response
3103**
3104** Returns          void
3105**
3106***************************************************************************/
3107static void handle_avk_rc_metamsg_rsp(tBTA_AV_META_MSG *pmeta_msg)
3108{
3109    tAVRC_RESPONSE    avrc_response = {0};
3110    UINT8             scratch_buf[512] = {0};// this variable is unused
3111    UINT16            buf_len;
3112    tAVRC_STS         status;
3113
3114    BTIF_TRACE_DEBUG("%s opcode = %d rsp_code = %d  ", __FUNCTION__,
3115                        pmeta_msg->p_msg->hdr.opcode, pmeta_msg->code);
3116
3117    if ((AVRC_OP_VENDOR == pmeta_msg->p_msg->hdr.opcode)&&
3118                (pmeta_msg->code >= AVRC_RSP_NOT_IMPL)&&
3119                (pmeta_msg->code <= AVRC_RSP_INTERIM))
3120    {
3121        status = AVRC_Ctrl_ParsResponse(pmeta_msg->p_msg, &avrc_response, scratch_buf, &buf_len);
3122        BTIF_TRACE_DEBUG("%s parse status %d pdu = %d rsp_status = %d",
3123                         __FUNCTION__, status, avrc_response.pdu,
3124                         pmeta_msg->p_msg->vendor.hdr.ctype);
3125
3126        switch (avrc_response.pdu)
3127        {
3128            case AVRC_PDU_REGISTER_NOTIFICATION:
3129                handle_notification_response(pmeta_msg, &avrc_response.reg_notif);
3130                if (pmeta_msg->code == AVRC_RSP_INTERIM)
3131                {
3132                    /* Don't free the transaction Id */
3133                    clear_cmd_timeout (pmeta_msg->label);
3134                    return;
3135                }
3136                break;
3137
3138            case AVRC_PDU_GET_CAPABILITIES:
3139                handle_get_capability_response(pmeta_msg, &avrc_response.get_caps);
3140                break;
3141
3142            case AVRC_PDU_LIST_PLAYER_APP_ATTR:
3143                handle_app_attr_response(pmeta_msg, &avrc_response.list_app_attr);
3144                break;
3145
3146            case AVRC_PDU_LIST_PLAYER_APP_VALUES:
3147                handle_app_val_response(pmeta_msg, &avrc_response.list_app_values);
3148                break;
3149
3150            case AVRC_PDU_GET_CUR_PLAYER_APP_VALUE:
3151                handle_app_cur_val_response(pmeta_msg, &avrc_response.get_cur_app_val);
3152                break;
3153
3154            case AVRC_PDU_GET_PLAYER_APP_ATTR_TEXT:
3155                handle_app_attr_txt_response(pmeta_msg, &avrc_response.get_app_attr_txt);
3156                break;
3157
3158            case AVRC_PDU_GET_PLAYER_APP_VALUE_TEXT:
3159                handle_app_attr_val_txt_response(pmeta_msg, &avrc_response.get_app_val_txt);
3160                break;
3161
3162            case AVRC_PDU_SET_PLAYER_APP_VALUE:
3163                handle_set_app_attr_val_response(pmeta_msg, &avrc_response.set_app_val);
3164                break;
3165
3166            case AVRC_PDU_GET_ELEMENT_ATTR:
3167                handle_get_elem_attr_response(pmeta_msg, &avrc_response.get_elem_attrs);
3168                break;
3169
3170            case AVRC_PDU_GET_PLAY_STATUS:
3171                handle_get_playstatus_response(pmeta_msg, &avrc_response.get_play_status);
3172                break;
3173        }
3174        release_transaction(pmeta_msg->label);
3175    }
3176    else
3177    {
3178        BTIF_TRACE_DEBUG("%s:Invalid Vendor Command  code: %d len: %d. Not processing it.",
3179            __FUNCTION__, pmeta_msg->code, pmeta_msg->len);
3180        return;
3181    }
3182}
3183
3184/***************************************************************************
3185**
3186** Function         handle_avk_rc_metamsg_cmd
3187**
3188** Description      Handle RC metamessage response
3189**
3190** Returns          void
3191**
3192***************************************************************************/
3193static void handle_avk_rc_metamsg_cmd(tBTA_AV_META_MSG *pmeta_msg)
3194{
3195    tAVRC_COMMAND    avrc_cmd = {0};
3196    tAVRC_STS status = BT_STATUS_UNSUPPORTED;
3197    BTIF_TRACE_DEBUG("%s opcode = %d rsp_code = %d  ",__FUNCTION__,
3198                     pmeta_msg->p_msg->hdr.opcode,pmeta_msg->code);
3199    if ((AVRC_OP_VENDOR==pmeta_msg->p_msg->hdr.opcode)&&
3200                (pmeta_msg->code <= AVRC_CMD_GEN_INQ))
3201    {
3202        status = AVRC_Ctrl_ParsCommand(pmeta_msg->p_msg, &avrc_cmd);
3203        BTIF_TRACE_DEBUG("%s Received vendor command.code %d, PDU %d label %d",
3204                         __FUNCTION__, pmeta_msg->code, avrc_cmd.pdu, pmeta_msg->label);
3205
3206        if (status != AVRC_STS_NO_ERROR)
3207        {
3208            /* return error */
3209            BTIF_TRACE_WARNING("%s: Error in parsing received metamsg command. status: 0x%02x",
3210                __FUNCTION__, status);
3211            send_reject_response(pmeta_msg->rc_handle, pmeta_msg->label, avrc_cmd.pdu, status);
3212        }
3213        else
3214        {
3215            if (avrc_cmd.pdu == AVRC_PDU_REGISTER_NOTIFICATION)
3216            {
3217                UINT8 event_id = avrc_cmd.reg_notif.event_id;
3218                BTIF_TRACE_EVENT("%s:Register notification event_id: %s",
3219                        __FUNCTION__, dump_rc_notification_event_id(event_id));
3220            }
3221            else if (avrc_cmd.pdu == AVRC_PDU_SET_ABSOLUTE_VOLUME)
3222            {
3223                BTIF_TRACE_EVENT("%s: Abs Volume Cmd Recvd", __FUNCTION__);
3224            }
3225            btif_rc_ctrl_upstreams_rsp_cmd(avrc_cmd.pdu, &avrc_cmd, pmeta_msg->label);
3226        }
3227    }
3228    else
3229    {
3230      BTIF_TRACE_DEBUG("%s:Invalid Vendor Command  code: %d len: %d. Not processing it.",
3231                       __FUNCTION__, pmeta_msg->code, pmeta_msg->len);
3232        return;
3233    }
3234}
3235#endif
3236
3237/***************************************************************************
3238**
3239** Function         cleanup
3240**
3241** Description      Closes the AVRC interface
3242**
3243** Returns          void
3244**
3245***************************************************************************/
3246static void cleanup()
3247{
3248    BTIF_TRACE_EVENT("## %s ##", __FUNCTION__);
3249    close_uinput();
3250    if (bt_rc_callbacks)
3251    {
3252        bt_rc_callbacks = NULL;
3253    }
3254    alarm_free(btif_rc_cb.rc_play_status_timer);
3255    memset(&btif_rc_cb, 0, sizeof(btif_rc_cb_t));
3256    lbl_destroy();
3257    BTIF_TRACE_EVENT("## %s ## completed", __FUNCTION__);
3258}
3259
3260/***************************************************************************
3261**
3262** Function         cleanup_ctrl
3263**
3264** Description      Closes the AVRC Controller interface
3265**
3266** Returns          void
3267**
3268***************************************************************************/
3269static void cleanup_ctrl()
3270{
3271    BTIF_TRACE_EVENT("## %s ##", __FUNCTION__);
3272
3273    if (bt_rc_ctrl_callbacks)
3274    {
3275        bt_rc_ctrl_callbacks = NULL;
3276    }
3277    alarm_free(btif_rc_cb.rc_play_status_timer);
3278    memset(&btif_rc_cb, 0, sizeof(btif_rc_cb_t));
3279    lbl_destroy();
3280    BTIF_TRACE_EVENT("## %s ## completed", __FUNCTION__);
3281}
3282
3283/***************************************************************************
3284**
3285** Function         getcapabilities_cmd
3286**
3287** Description      GetCapabilties from Remote(Company_ID, Events_Supported)
3288**
3289** Returns          void
3290**
3291***************************************************************************/
3292static bt_status_t getcapabilities_cmd (uint8_t cap_id)
3293{
3294    tAVRC_STS status = BT_STATUS_UNSUPPORTED;
3295    rc_transaction_t *p_transaction = NULL;
3296#if (AVRC_CTLR_INCLUDED == TRUE)
3297    BTIF_TRACE_DEBUG("%s: cap_id %d", __FUNCTION__, cap_id);
3298    CHECK_RC_CONNECTED
3299    bt_status_t tran_status=get_transaction(&p_transaction);
3300    if (BT_STATUS_SUCCESS != tran_status)
3301        return BT_STATUS_FAIL;
3302
3303     tAVRC_COMMAND avrc_cmd = {0};
3304     BT_HDR *p_msg = NULL;
3305     avrc_cmd.get_caps.opcode = AVRC_OP_VENDOR;
3306     avrc_cmd.get_caps.capability_id = cap_id;
3307     avrc_cmd.get_caps.pdu = AVRC_PDU_GET_CAPABILITIES;
3308     avrc_cmd.get_caps.status = AVRC_STS_NO_ERROR;
3309     status = AVRC_BldCommand(&avrc_cmd, &p_msg);
3310     if ((status == AVRC_STS_NO_ERROR)&&(p_msg != NULL))
3311     {
3312         UINT8* data_start = (UINT8*)(p_msg + 1) + p_msg->offset;
3313         BTIF_TRACE_DEBUG("%s msgreq being sent out with label %d",
3314                            __FUNCTION__,p_transaction->lbl);
3315         BTA_AvVendorCmd(btif_rc_cb.rc_handle,p_transaction->lbl,AVRC_CMD_STATUS,
3316                                                          data_start, p_msg->len);
3317         status =  BT_STATUS_SUCCESS;
3318         start_status_command_timer (AVRC_PDU_GET_CAPABILITIES, p_transaction);
3319     }
3320     else
3321     {
3322         BTIF_TRACE_ERROR("%s: failed to build command. status: 0x%02x",
3323                             __FUNCTION__, status);
3324     }
3325     osi_free(p_msg);
3326#else
3327    BTIF_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__);
3328#endif
3329    return status;
3330}
3331
3332/***************************************************************************
3333**
3334** Function         list_player_app_setting_attrib_cmd
3335**
3336** Description      Get supported List Player Attributes
3337**
3338** Returns          void
3339**
3340***************************************************************************/
3341static bt_status_t list_player_app_setting_attrib_cmd(void)
3342{
3343    tAVRC_STS status = BT_STATUS_UNSUPPORTED;
3344    rc_transaction_t *p_transaction = NULL;
3345#if (AVRC_CTLR_INCLUDED == TRUE)
3346    BTIF_TRACE_DEBUG("%s: ", __FUNCTION__);
3347    CHECK_RC_CONNECTED
3348    bt_status_t tran_status=get_transaction(&p_transaction);
3349    if (BT_STATUS_SUCCESS != tran_status)
3350        return BT_STATUS_FAIL;
3351
3352     tAVRC_COMMAND avrc_cmd = {0};
3353     BT_HDR *p_msg = NULL;
3354     avrc_cmd.list_app_attr.opcode = AVRC_OP_VENDOR;
3355     avrc_cmd.list_app_attr.pdu = AVRC_PDU_LIST_PLAYER_APP_ATTR;
3356     avrc_cmd.list_app_attr.status = AVRC_STS_NO_ERROR;
3357     status = AVRC_BldCommand(&avrc_cmd, &p_msg);
3358     if ((status == AVRC_STS_NO_ERROR)&&(p_msg != NULL))
3359     {
3360         UINT8* data_start = (UINT8*)(p_msg + 1) + p_msg->offset;
3361         BTIF_TRACE_DEBUG("%s msgreq being sent out with label %d",
3362                            __FUNCTION__,p_transaction->lbl);
3363         BTA_AvVendorCmd(btif_rc_cb.rc_handle,p_transaction->lbl,AVRC_CMD_STATUS,
3364                                                          data_start, p_msg->len);
3365         status =  BT_STATUS_SUCCESS;
3366         start_status_command_timer (AVRC_PDU_LIST_PLAYER_APP_ATTR, p_transaction);
3367     }
3368     else
3369     {
3370
3371         BTIF_TRACE_ERROR("%s: failed to build command. status: 0x%02x",
3372                            __FUNCTION__, status);
3373     }
3374     osi_free(p_msg);
3375#else
3376    BTIF_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__);
3377#endif
3378    return status;
3379}
3380
3381/***************************************************************************
3382**
3383** Function         list_player_app_setting_value_cmd
3384**
3385** Description      Get values of supported Player Attributes
3386**
3387** Returns          void
3388**
3389***************************************************************************/
3390static bt_status_t list_player_app_setting_value_cmd(uint8_t attrib_id)
3391{
3392    tAVRC_STS status = BT_STATUS_UNSUPPORTED;
3393    rc_transaction_t *p_transaction=NULL;
3394#if (AVRC_CTLR_INCLUDED == TRUE)
3395    BTIF_TRACE_DEBUG("%s: attrib_id %d", __FUNCTION__, attrib_id);
3396    CHECK_RC_CONNECTED
3397    bt_status_t tran_status=get_transaction(&p_transaction);
3398    if (BT_STATUS_SUCCESS != tran_status)
3399        return BT_STATUS_FAIL;
3400
3401     tAVRC_COMMAND avrc_cmd = {0};
3402     BT_HDR *p_msg = NULL;
3403     avrc_cmd.list_app_values.attr_id = attrib_id;
3404     avrc_cmd.list_app_values.opcode = AVRC_OP_VENDOR;
3405     avrc_cmd.list_app_values.pdu = AVRC_PDU_LIST_PLAYER_APP_VALUES;
3406     avrc_cmd.list_app_values.status = AVRC_STS_NO_ERROR;
3407     status = AVRC_BldCommand(&avrc_cmd, &p_msg);
3408     if ((status == AVRC_STS_NO_ERROR) && (p_msg != NULL))
3409     {
3410         UINT8* data_start = (UINT8*)(p_msg + 1) + p_msg->offset;
3411         BTIF_TRACE_DEBUG("%s msgreq being sent out with label %d",
3412                            __FUNCTION__,p_transaction->lbl);
3413         BTA_AvVendorCmd(btif_rc_cb.rc_handle,p_transaction->lbl,AVRC_CMD_STATUS,
3414                               data_start, p_msg->len);
3415         status =  BT_STATUS_SUCCESS;
3416         start_status_command_timer (AVRC_PDU_LIST_PLAYER_APP_VALUES, p_transaction);
3417     }
3418     else
3419     {
3420         BTIF_TRACE_ERROR("%s: failed to build command. status: 0x%02x", __FUNCTION__, status);
3421     }
3422     osi_free(p_msg);
3423#else
3424    BTIF_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__);
3425#endif
3426    return status;
3427}
3428
3429/***************************************************************************
3430**
3431** Function         get_player_app_setting_cmd
3432**
3433** Description      Get current values of Player Attributes
3434**
3435** Returns          void
3436**
3437***************************************************************************/
3438static bt_status_t get_player_app_setting_cmd(uint8_t num_attrib, uint8_t* attrib_ids)
3439{
3440    tAVRC_STS status = BT_STATUS_UNSUPPORTED;
3441    rc_transaction_t *p_transaction = NULL;
3442    int count  = 0;
3443#if (AVRC_CTLR_INCLUDED == TRUE)
3444    BTIF_TRACE_DEBUG("%s: num attrib_id %d", __FUNCTION__, num_attrib);
3445    CHECK_RC_CONNECTED
3446    bt_status_t tran_status=get_transaction(&p_transaction);
3447    if (BT_STATUS_SUCCESS != tran_status)
3448        return BT_STATUS_FAIL;
3449
3450     tAVRC_COMMAND avrc_cmd = {0};
3451     BT_HDR *p_msg = NULL;
3452     avrc_cmd.get_cur_app_val.opcode = AVRC_OP_VENDOR;
3453     avrc_cmd.get_cur_app_val.status = AVRC_STS_NO_ERROR;
3454     avrc_cmd.get_cur_app_val.num_attr = num_attrib;
3455     avrc_cmd.get_cur_app_val.pdu = AVRC_PDU_GET_CUR_PLAYER_APP_VALUE;
3456
3457     for (count = 0; count < num_attrib; count++)
3458     {
3459         avrc_cmd.get_cur_app_val.attrs[count] = attrib_ids[count];
3460     }
3461     status = AVRC_BldCommand(&avrc_cmd, &p_msg);
3462     if ((status == AVRC_STS_NO_ERROR) && (p_msg != NULL))
3463     {
3464         UINT8* data_start = (UINT8*)(p_msg + 1) + p_msg->offset;
3465         BTIF_TRACE_DEBUG("%s msgreq being sent out with label %d",
3466                            __FUNCTION__,p_transaction->lbl);
3467         BTA_AvVendorCmd(btif_rc_cb.rc_handle,p_transaction->lbl,AVRC_CMD_STATUS,
3468                          data_start, p_msg->len);
3469         status =  BT_STATUS_SUCCESS;
3470         start_status_command_timer (AVRC_PDU_GET_CUR_PLAYER_APP_VALUE, p_transaction);
3471     }
3472     else
3473     {
3474         BTIF_TRACE_ERROR("%s: failed to build command. status: 0x%02x",
3475                            __FUNCTION__, status);
3476     }
3477     osi_free(p_msg);
3478#else
3479    BTIF_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__);
3480#endif
3481    return status;
3482}
3483
3484/***************************************************************************
3485**
3486** Function         change_player_app_setting
3487**
3488** Description      Set current values of Player Attributes
3489**
3490** Returns          void
3491**
3492***************************************************************************/
3493static bt_status_t change_player_app_setting(bt_bdaddr_t *bd_addr, uint8_t num_attrib, uint8_t* attrib_ids, uint8_t* attrib_vals)
3494{
3495    tAVRC_STS status = BT_STATUS_UNSUPPORTED;
3496    rc_transaction_t *p_transaction = NULL;
3497    int count  = 0;
3498#if (AVRC_CTLR_INCLUDED == TRUE)
3499    BTIF_TRACE_DEBUG("%s: num attrib_id %d", __FUNCTION__, num_attrib);
3500    CHECK_RC_CONNECTED
3501    bt_status_t tran_status=get_transaction(&p_transaction);
3502    if (BT_STATUS_SUCCESS != tran_status)
3503        return BT_STATUS_FAIL;
3504
3505     tAVRC_COMMAND avrc_cmd = {0};
3506     BT_HDR *p_msg = NULL;
3507     avrc_cmd.set_app_val.opcode = AVRC_OP_VENDOR;
3508     avrc_cmd.set_app_val.status = AVRC_STS_NO_ERROR;
3509     avrc_cmd.set_app_val.num_val = num_attrib;
3510     avrc_cmd.set_app_val.pdu = AVRC_PDU_SET_PLAYER_APP_VALUE;
3511     avrc_cmd.set_app_val.p_vals =
3512           (tAVRC_APP_SETTING *)osi_malloc(sizeof(tAVRC_APP_SETTING) * num_attrib);
3513     for (count = 0; count < num_attrib; count++)
3514     {
3515         avrc_cmd.set_app_val.p_vals[count].attr_id = attrib_ids[count];
3516         avrc_cmd.set_app_val.p_vals[count].attr_val = attrib_vals[count];
3517     }
3518     status = AVRC_BldCommand(&avrc_cmd, &p_msg);
3519     if ((status == AVRC_STS_NO_ERROR) && (p_msg != NULL))
3520     {
3521         UINT8* data_start = (UINT8*)(p_msg + 1) + p_msg->offset;
3522         BTIF_TRACE_DEBUG("%s msgreq being sent out with label %d",
3523                            __FUNCTION__,p_transaction->lbl);
3524         BTA_AvVendorCmd(btif_rc_cb.rc_handle,p_transaction->lbl,AVRC_CMD_CTRL,
3525                              data_start, p_msg->len);
3526         status =  BT_STATUS_SUCCESS;
3527         start_control_command_timer (AVRC_PDU_SET_PLAYER_APP_VALUE, p_transaction);
3528     }
3529     else
3530     {
3531         BTIF_TRACE_ERROR("%s: failed to build command. status: 0x%02x",
3532                            __FUNCTION__, status);
3533     }
3534     osi_free(p_msg);
3535     osi_free_and_reset((void **)&avrc_cmd.set_app_val.p_vals);
3536#else
3537    BTIF_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__);
3538#endif
3539    return status;
3540}
3541
3542/***************************************************************************
3543**
3544** Function         get_player_app_setting_attr_text_cmd
3545**
3546** Description      Get text description for app attribute
3547**
3548** Returns          void
3549**
3550***************************************************************************/
3551static bt_status_t get_player_app_setting_attr_text_cmd (UINT8 *attrs, UINT8 num_attrs)
3552{
3553    tAVRC_STS status = BT_STATUS_UNSUPPORTED;
3554    rc_transaction_t *p_transaction = NULL;
3555    int count  = 0;
3556#if (AVRC_CTLR_INCLUDED == TRUE)
3557    tAVRC_COMMAND avrc_cmd = {0};
3558    BT_HDR *p_msg = NULL;
3559    bt_status_t tran_status;
3560    CHECK_RC_CONNECTED
3561
3562    BTIF_TRACE_DEBUG("%s: num attrs %d", __FUNCTION__, num_attrs);
3563
3564    tran_status = get_transaction(&p_transaction);
3565    if (BT_STATUS_SUCCESS != tran_status)
3566        return BT_STATUS_FAIL;
3567
3568    avrc_cmd.pdu = AVRC_PDU_GET_PLAYER_APP_ATTR_TEXT;
3569    avrc_cmd.get_app_attr_txt.opcode = AVRC_OP_VENDOR;
3570    avrc_cmd.get_app_attr_txt.num_attr = num_attrs;
3571
3572    for (count = 0; count < num_attrs; count++)
3573    {
3574        avrc_cmd.get_app_attr_txt.attrs[count] = attrs[count];
3575    }
3576    status = AVRC_BldCommand(&avrc_cmd, &p_msg);
3577    if (status == AVRC_STS_NO_ERROR)
3578    {
3579        UINT8* data_start = (UINT8*)(p_msg + 1) + p_msg->offset;
3580                BTIF_TRACE_DEBUG("%s msgreq being sent out with label %d",
3581                __FUNCTION__, p_transaction->lbl);
3582        BTA_AvVendorCmd(btif_rc_cb.rc_handle, p_transaction->lbl,
3583                AVRC_CMD_STATUS, data_start, p_msg->len);
3584        osi_free(p_msg);
3585        status =  BT_STATUS_SUCCESS;
3586        start_status_command_timer (AVRC_PDU_GET_PLAYER_APP_ATTR_TEXT, p_transaction);
3587    }
3588    else
3589    {
3590        BTIF_TRACE_ERROR("%s: failed to build command. status: 0x%02x", __FUNCTION__, status);
3591    }
3592    osi_free(p_msg);
3593#else
3594    BTIF_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__);
3595#endif
3596    return status;
3597}
3598
3599/***************************************************************************
3600**
3601** Function         get_player_app_setting_val_text_cmd
3602**
3603** Description      Get text description for app attribute values
3604**
3605** Returns          void
3606**
3607***************************************************************************/
3608static bt_status_t get_player_app_setting_value_text_cmd (UINT8 *vals, UINT8 num_vals)
3609{
3610    tAVRC_STS status = BT_STATUS_UNSUPPORTED;
3611    rc_transaction_t *p_transaction = NULL;
3612    int count  = 0;
3613#if (AVRC_CTLR_INCLUDED == TRUE)
3614    tAVRC_COMMAND avrc_cmd = {0};
3615    BT_HDR *p_msg = NULL;
3616    bt_status_t tran_status;
3617    CHECK_RC_CONNECTED
3618
3619    BTIF_TRACE_DEBUG("%s: num_vals %d", __FUNCTION__, num_vals);
3620
3621    tran_status = get_transaction(&p_transaction);
3622    if (BT_STATUS_SUCCESS != tran_status)
3623        return BT_STATUS_FAIL;
3624
3625    avrc_cmd.pdu = AVRC_PDU_GET_PLAYER_APP_VALUE_TEXT;
3626    avrc_cmd.get_app_val_txt.opcode = AVRC_OP_VENDOR;
3627    avrc_cmd.get_app_val_txt.num_val = num_vals;
3628
3629    for (count = 0; count < num_vals; count++)
3630    {
3631        avrc_cmd.get_app_val_txt.vals[count] = vals[count];
3632    }
3633    status = AVRC_BldCommand(&avrc_cmd, &p_msg);
3634    if (status == AVRC_STS_NO_ERROR)
3635    {
3636        UINT8* data_start = (UINT8*)(p_msg + 1) + p_msg->offset;
3637        BTIF_TRACE_DEBUG("%s msgreq being sent out with label %d",
3638                         __FUNCTION__, p_transaction->lbl);
3639        if (p_msg != NULL)
3640        {
3641            BTA_AvVendorCmd(btif_rc_cb.rc_handle, p_transaction->lbl,
3642                    AVRC_CMD_STATUS, data_start, p_msg->len);
3643            status =  BT_STATUS_SUCCESS;
3644            start_status_command_timer (AVRC_PDU_GET_PLAYER_APP_VALUE_TEXT, p_transaction);
3645        }
3646    }
3647    else
3648    {
3649        BTIF_TRACE_ERROR("%s: failed to build command. status: 0x%02x",
3650                __FUNCTION__, status);
3651    }
3652    osi_free(p_msg);
3653#else
3654    BTIF_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__);
3655#endif
3656    return status;
3657}
3658
3659/***************************************************************************
3660**
3661** Function         register_notification_cmd
3662**
3663** Description      Send Command to register for a Notification ID
3664**
3665** Returns          void
3666**
3667***************************************************************************/
3668static bt_status_t register_notification_cmd (UINT8 label, UINT8 event_id, UINT32 event_value)
3669{
3670
3671    tAVRC_STS status = BT_STATUS_UNSUPPORTED;
3672#if (AVRC_CTLR_INCLUDED == TRUE)
3673    tAVRC_COMMAND avrc_cmd = {0};
3674    BT_HDR *p_msg = NULL;
3675    CHECK_RC_CONNECTED
3676
3677
3678    BTIF_TRACE_DEBUG("%s: event_id %d  event_value", __FUNCTION__, event_id, event_value);
3679
3680    avrc_cmd.reg_notif.opcode = AVRC_OP_VENDOR;
3681    avrc_cmd.reg_notif.status = AVRC_STS_NO_ERROR;
3682    avrc_cmd.reg_notif.event_id = event_id;
3683    avrc_cmd.reg_notif.pdu = AVRC_PDU_REGISTER_NOTIFICATION;
3684    avrc_cmd.reg_notif.param = event_value;
3685    status = AVRC_BldCommand(&avrc_cmd, &p_msg);
3686    if (status == AVRC_STS_NO_ERROR)
3687    {
3688        UINT8* data_start = (UINT8*)(p_msg + 1) + p_msg->offset;
3689        BTIF_TRACE_DEBUG("%s msgreq being sent out with label %d",
3690                __FUNCTION__, label);
3691        if (p_msg != NULL)
3692        {
3693            BTA_AvVendorCmd(btif_rc_cb.rc_handle, label, AVRC_CMD_NOTIF,
3694                    data_start, p_msg->len);
3695            status =  BT_STATUS_SUCCESS;
3696        }
3697    }
3698    else
3699    {
3700         BTIF_TRACE_ERROR("%s: failed to build command. status: 0x%02x",
3701                            __FUNCTION__, status);
3702    }
3703    osi_free(p_msg);
3704#else
3705    BTIF_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__);
3706#endif
3707    return status;
3708}
3709
3710/***************************************************************************
3711**
3712** Function         get_element_attribute_cmd
3713**
3714** Description      Get Element Attribute for  attributeIds
3715**
3716** Returns          void
3717**
3718***************************************************************************/
3719static bt_status_t get_element_attribute_cmd (uint8_t num_attribute, uint32_t *p_attr_ids)
3720{
3721    tAVRC_STS status = BT_STATUS_UNSUPPORTED;
3722    rc_transaction_t *p_transaction=NULL;
3723    int count  = 0;
3724#if (AVRC_CTLR_INCLUDED == TRUE)
3725    tAVRC_COMMAND avrc_cmd = {0};
3726    BT_HDR *p_msg = NULL;
3727    bt_status_t tran_status;
3728    CHECK_RC_CONNECTED
3729
3730    BTIF_TRACE_DEBUG("%s: num_attribute  %d attribute_id %d",
3731                   __FUNCTION__, num_attribute, p_attr_ids[0]);
3732
3733    tran_status = get_transaction(&p_transaction);
3734    if (BT_STATUS_SUCCESS != tran_status)
3735        return BT_STATUS_FAIL;
3736
3737    avrc_cmd.get_elem_attrs.opcode = AVRC_OP_VENDOR;
3738    avrc_cmd.get_elem_attrs.status = AVRC_STS_NO_ERROR;
3739    avrc_cmd.get_elem_attrs.num_attr = num_attribute;
3740    avrc_cmd.get_elem_attrs.pdu = AVRC_PDU_GET_ELEMENT_ATTR;
3741    for (count = 0; count < num_attribute; count++)
3742    {
3743        avrc_cmd.get_elem_attrs.attrs[count] = p_attr_ids[count];
3744    }
3745
3746    status = AVRC_BldCommand(&avrc_cmd, &p_msg);
3747    if (status == AVRC_STS_NO_ERROR)
3748    {
3749        UINT8* data_start = (UINT8*)(p_msg + 1) + p_msg->offset;
3750        BTIF_TRACE_DEBUG("%s msgreq being sent out with label %d",
3751                __FUNCTION__, p_transaction->lbl);
3752        if (p_msg != NULL)
3753        {
3754            BTA_AvVendorCmd(btif_rc_cb.rc_handle, p_transaction->lbl,
3755                    AVRC_CMD_STATUS, data_start, p_msg->len);
3756            status =  BT_STATUS_SUCCESS;
3757            start_status_command_timer (AVRC_PDU_GET_ELEMENT_ATTR,
3758                    p_transaction);
3759        }
3760    }
3761    else
3762    {
3763         BTIF_TRACE_ERROR("%s: failed to build command. status: 0x%02x",
3764                            __FUNCTION__, status);
3765    }
3766    osi_free(p_msg);
3767#else
3768    BTIF_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__);
3769#endif
3770    return status;
3771}
3772
3773/***************************************************************************
3774**
3775** Function         get_play_status_cmd
3776**
3777** Description      Get Element Attribute for  attributeIds
3778**
3779** Returns          void
3780**
3781***************************************************************************/
3782static bt_status_t get_play_status_cmd(void)
3783{
3784    tAVRC_STS status = BT_STATUS_UNSUPPORTED;
3785    rc_transaction_t *p_transaction = NULL;
3786#if (AVRC_CTLR_INCLUDED == TRUE)
3787    tAVRC_COMMAND avrc_cmd = {0};
3788    BT_HDR *p_msg = NULL;
3789    bt_status_t tran_status;
3790    CHECK_RC_CONNECTED
3791
3792    BTIF_TRACE_DEBUG("%s: ", __FUNCTION__);
3793    tran_status = get_transaction(&p_transaction);
3794    if (BT_STATUS_SUCCESS != tran_status)
3795        return BT_STATUS_FAIL;
3796
3797    avrc_cmd.get_play_status.opcode = AVRC_OP_VENDOR;
3798    avrc_cmd.get_play_status.pdu = AVRC_PDU_GET_PLAY_STATUS;
3799    avrc_cmd.get_play_status.status = AVRC_STS_NO_ERROR;
3800    status = AVRC_BldCommand(&avrc_cmd, &p_msg);
3801    if (status == AVRC_STS_NO_ERROR)
3802    {
3803        UINT8* data_start = (UINT8*)(p_msg + 1) + p_msg->offset;
3804        BTIF_TRACE_DEBUG("%s msgreq being sent out with label %d",
3805                __FUNCTION__, p_transaction->lbl);
3806        if (p_msg != NULL)
3807        {
3808            BTA_AvVendorCmd(btif_rc_cb.rc_handle,p_transaction->lbl,
3809                    AVRC_CMD_STATUS, data_start, p_msg->len);
3810            status =  BT_STATUS_SUCCESS;
3811            start_status_command_timer (AVRC_PDU_GET_PLAY_STATUS, p_transaction);
3812        }
3813    }
3814    else
3815    {
3816         BTIF_TRACE_ERROR("%s: failed to build command. status: 0x%02x",
3817                            __FUNCTION__, status);
3818    }
3819    osi_free(p_msg);
3820#else
3821    BTIF_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__);
3822#endif
3823    return status;
3824
3825}
3826
3827/***************************************************************************
3828**
3829** Function         set_volume_rsp
3830**
3831** Description      Rsp for SetAbsoluteVolume Command
3832**
3833** Returns          void
3834**
3835***************************************************************************/
3836static bt_status_t set_volume_rsp(bt_bdaddr_t *bd_addr, uint8_t abs_vol, uint8_t label)
3837{
3838    tAVRC_STS status = BT_STATUS_UNSUPPORTED;
3839#if (AVRC_CTLR_INCLUDED == TRUE)
3840    tAVRC_RESPONSE avrc_rsp;
3841    BT_HDR *p_msg = NULL;
3842    CHECK_RC_CONNECTED
3843
3844    BTIF_TRACE_DEBUG("%s: abs_vol %d", __FUNCTION__, abs_vol);
3845
3846    avrc_rsp.volume.opcode = AVRC_OP_VENDOR;
3847    avrc_rsp.volume.pdu = AVRC_PDU_SET_ABSOLUTE_VOLUME;
3848    avrc_rsp.volume.status = AVRC_STS_NO_ERROR;
3849    avrc_rsp.volume.volume = abs_vol;
3850    status = AVRC_BldResponse(btif_rc_cb.rc_handle, &avrc_rsp, &p_msg);
3851    if (status == AVRC_STS_NO_ERROR)
3852    {
3853        UINT8* data_start = (UINT8*)(p_msg + 1) + p_msg->offset;
3854        BTIF_TRACE_DEBUG("%s msgreq being sent out with label %d",
3855                __FUNCTION__, btif_rc_cb.rc_vol_label);
3856        if (p_msg != NULL)
3857        {
3858            BTA_AvVendorRsp(btif_rc_cb.rc_handle, label,
3859                    BTA_AV_RSP_ACCEPT, data_start, p_msg->len, 0);
3860            status =  BT_STATUS_SUCCESS;
3861        }
3862    }
3863    else
3864    {
3865         BTIF_TRACE_ERROR("%s: failed to build command. status: 0x%02x",
3866                            __FUNCTION__, status);
3867    }
3868    osi_free(p_msg);
3869#else
3870    BTIF_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__);
3871#endif
3872    return status;
3873}
3874
3875/***************************************************************************
3876**
3877** Function         send_register_abs_vol_rsp
3878**
3879** Description      Rsp for Notification of Absolute Volume
3880**
3881** Returns          void
3882**
3883***************************************************************************/
3884static bt_status_t volume_change_notification_rsp(bt_bdaddr_t *bd_addr, btrc_notification_type_t rsp_type,
3885            uint8_t abs_vol, uint8_t label)
3886{
3887    tAVRC_STS status = BT_STATUS_UNSUPPORTED;
3888    tAVRC_RESPONSE avrc_rsp;
3889    BT_HDR *p_msg = NULL;
3890#if (AVRC_CTLR_INCLUDED == TRUE)
3891    BTIF_TRACE_DEBUG("%s: rsp_type  %d abs_vol %d", __func__, rsp_type, abs_vol);
3892    CHECK_RC_CONNECTED
3893
3894    avrc_rsp.reg_notif.opcode = AVRC_OP_VENDOR;
3895    avrc_rsp.reg_notif.pdu = AVRC_PDU_REGISTER_NOTIFICATION;
3896    avrc_rsp.reg_notif.status = AVRC_STS_NO_ERROR;
3897    avrc_rsp.reg_notif.param.volume = abs_vol;
3898    avrc_rsp.reg_notif.event_id = AVRC_EVT_VOLUME_CHANGE;
3899
3900    status = AVRC_BldResponse(btif_rc_cb.rc_handle, &avrc_rsp, &p_msg);
3901    if (status == AVRC_STS_NO_ERROR) {
3902        BTIF_TRACE_DEBUG("%s msgreq being sent out with label %d",
3903                         __func__, label);
3904        UINT8* data_start = (UINT8*)(p_msg + 1) + p_msg->offset;
3905        BTA_AvVendorRsp(btif_rc_cb.rc_handle, label,
3906                        (rsp_type == BTRC_NOTIFICATION_TYPE_INTERIM) ?
3907                            AVRC_RSP_INTERIM : AVRC_RSP_CHANGED,
3908                        data_start, p_msg->len, 0);
3909        status = BT_STATUS_SUCCESS;
3910    } else {
3911        BTIF_TRACE_ERROR("%s: failed to build command. status: 0x%02x",
3912                         __func__, status);
3913    }
3914    osi_free(p_msg);
3915
3916#else
3917    BTIF_TRACE_DEBUG("%s: feature not enabled", __func__);
3918#endif
3919    return status;
3920}
3921
3922/***************************************************************************
3923**
3924** Function         send_groupnavigation_cmd
3925**
3926** Description      Send Pass-Through command
3927**
3928** Returns          void
3929**
3930***************************************************************************/
3931static bt_status_t send_groupnavigation_cmd(bt_bdaddr_t *bd_addr, uint8_t key_code,
3932                                            uint8_t key_state)
3933{
3934    tAVRC_STS status = BT_STATUS_UNSUPPORTED;
3935#if (AVRC_CTLR_INCLUDED == TRUE)
3936    rc_transaction_t *p_transaction=NULL;
3937    BTIF_TRACE_DEBUG("%s: key-code: %d, key-state: %d", __FUNCTION__,
3938                                                    key_code, key_state);
3939    CHECK_RC_CONNECTED
3940    if (btif_rc_cb.rc_features & BTA_AV_FEAT_RCTG)
3941    {
3942        bt_status_t tran_status = get_transaction(&p_transaction);
3943        if ((BT_STATUS_SUCCESS == tran_status) && (NULL != p_transaction)) {
3944             UINT8 buffer[AVRC_PASS_THRU_GROUP_LEN] = {0};
3945             UINT8* start = buffer;
3946             UINT24_TO_BE_STREAM(start, AVRC_CO_METADATA);
3947             *(start)++ = 0;
3948             UINT8_TO_BE_STREAM(start, key_code);
3949             BTA_AvRemoteVendorUniqueCmd(btif_rc_cb.rc_handle,
3950                                         p_transaction->lbl,
3951                                         (tBTA_AV_STATE)key_state, buffer,
3952                                         AVRC_PASS_THRU_GROUP_LEN);
3953             status =  BT_STATUS_SUCCESS;
3954             BTIF_TRACE_DEBUG("%s: succesfully sent group_navigation command to BTA",
3955                              __FUNCTION__);
3956        }
3957        else
3958        {
3959            status =  BT_STATUS_FAIL;
3960            BTIF_TRACE_DEBUG("%s: error in fetching transaction", __FUNCTION__);
3961        }
3962    }
3963    else
3964    {
3965        status =  BT_STATUS_FAIL;
3966        BTIF_TRACE_DEBUG("%s: feature not supported", __FUNCTION__);
3967    }
3968#else
3969    BTIF_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__);
3970#endif
3971    return status;
3972}
3973
3974/***************************************************************************
3975**
3976** Function         send_passthrough_cmd
3977**
3978** Description      Send Pass-Through command
3979**
3980** Returns          void
3981**
3982***************************************************************************/
3983static bt_status_t send_passthrough_cmd(bt_bdaddr_t *bd_addr, uint8_t key_code, uint8_t key_state)
3984{
3985    tAVRC_STS status = BT_STATUS_UNSUPPORTED;
3986#if (AVRC_CTLR_INCLUDED == TRUE)
3987    CHECK_RC_CONNECTED
3988    rc_transaction_t *p_transaction=NULL;
3989    BTIF_TRACE_DEBUG("%s: key-code: %d, key-state: %d", __FUNCTION__,
3990                                                    key_code, key_state);
3991    if (btif_rc_cb.rc_features & BTA_AV_FEAT_RCTG)
3992    {
3993        bt_status_t tran_status = get_transaction(&p_transaction);
3994        if (BT_STATUS_SUCCESS == tran_status && NULL != p_transaction)
3995        {
3996            BTA_AvRemoteCmd(btif_rc_cb.rc_handle, p_transaction->lbl,
3997                (tBTA_AV_RC)key_code, (tBTA_AV_STATE)key_state);
3998            status =  BT_STATUS_SUCCESS;
3999            BTIF_TRACE_DEBUG("%s: succesfully sent passthrough command to BTA", __FUNCTION__);
4000        }
4001        else
4002        {
4003            status =  BT_STATUS_FAIL;
4004            BTIF_TRACE_DEBUG("%s: error in fetching transaction", __FUNCTION__);
4005        }
4006    }
4007    else
4008    {
4009        status =  BT_STATUS_FAIL;
4010        BTIF_TRACE_DEBUG("%s: feature not supported", __FUNCTION__);
4011    }
4012#else
4013    BTIF_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__);
4014#endif
4015    return status;
4016}
4017
4018static const btrc_interface_t bt_rc_interface = {
4019    sizeof(bt_rc_interface),
4020    init,
4021    get_play_status_rsp,
4022    NULL, /* list_player_app_attr_rsp */
4023    NULL, /* list_player_app_value_rsp */
4024    NULL, /* get_player_app_value_rsp */
4025    NULL, /* get_player_app_attr_text_rsp */
4026    NULL, /* get_player_app_value_text_rsp */
4027    get_element_attr_rsp,
4028    NULL, /* set_player_app_value_rsp */
4029    register_notification_rsp,
4030    set_volume,
4031    cleanup,
4032};
4033
4034static const btrc_ctrl_interface_t bt_rc_ctrl_interface = {
4035    sizeof(bt_rc_ctrl_interface),
4036    init_ctrl,
4037    send_passthrough_cmd,
4038    send_groupnavigation_cmd,
4039    change_player_app_setting,
4040    set_volume_rsp,
4041    volume_change_notification_rsp,
4042    cleanup_ctrl,
4043};
4044
4045/*******************************************************************************
4046**
4047** Function         btif_rc_get_interface
4048**
4049** Description      Get the AVRCP Target callback interface
4050**
4051** Returns          btav_interface_t
4052**
4053*******************************************************************************/
4054const btrc_interface_t *btif_rc_get_interface(void)
4055{
4056    BTIF_TRACE_EVENT("%s", __FUNCTION__);
4057    return &bt_rc_interface;
4058}
4059
4060/*******************************************************************************
4061**
4062** Function         btif_rc_ctrl_get_interface
4063**
4064** Description      Get the AVRCP Controller callback interface
4065**
4066** Returns          btav_interface_t
4067**
4068*******************************************************************************/
4069const btrc_ctrl_interface_t *btif_rc_ctrl_get_interface(void)
4070{
4071    BTIF_TRACE_EVENT("%s", __FUNCTION__);
4072    return &bt_rc_ctrl_interface;
4073}
4074
4075/*******************************************************************************
4076**      Function         initialize_transaction
4077**
4078**      Description    Initializes fields of the transaction structure
4079**
4080**      Returns          void
4081*******************************************************************************/
4082static void initialize_transaction(int lbl)
4083{
4084    pthread_mutex_lock(&device.lbllock);
4085    if (lbl < MAX_TRANSACTIONS_PER_SESSION) {
4086        if (alarm_is_scheduled(device.transaction[lbl].txn_timer)) {
4087            clear_cmd_timeout(lbl);
4088        }
4089        device.transaction[lbl].lbl = lbl;
4090        device.transaction[lbl].in_use=FALSE;
4091        device.transaction[lbl].handle=0;
4092    }
4093    pthread_mutex_unlock(&device.lbllock);
4094}
4095
4096/*******************************************************************************
4097**      Function         lbl_init
4098**
4099**      Description    Initializes label structures and mutexes.
4100**
4101**      Returns         void
4102*******************************************************************************/
4103void lbl_init()
4104{
4105    memset(&device,0,sizeof(rc_device_t));
4106    pthread_mutexattr_t attr;
4107    pthread_mutexattr_init(&attr);
4108    pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
4109    pthread_mutex_init(&(device.lbllock), &attr);
4110    pthread_mutexattr_destroy(&attr);
4111    init_all_transactions();
4112}
4113
4114/*******************************************************************************
4115**
4116** Function         init_all_transactions
4117**
4118** Description    Initializes all transactions
4119**
4120** Returns          void
4121*******************************************************************************/
4122void init_all_transactions()
4123{
4124    UINT8 txn_indx=0;
4125    for(txn_indx=0; txn_indx < MAX_TRANSACTIONS_PER_SESSION; txn_indx++)
4126    {
4127        initialize_transaction(txn_indx);
4128    }
4129}
4130
4131/*******************************************************************************
4132**
4133** Function         get_transaction_by_lbl
4134**
4135** Description    Will return a transaction based on the label. If not inuse
4136**                     will return an error.
4137**
4138** Returns          bt_status_t
4139*******************************************************************************/
4140rc_transaction_t *get_transaction_by_lbl(UINT8 lbl)
4141{
4142    rc_transaction_t *transaction = NULL;
4143    pthread_mutex_lock(&device.lbllock);
4144
4145    /* Determine if this is a valid label */
4146    if (lbl < MAX_TRANSACTIONS_PER_SESSION)
4147    {
4148        if (FALSE==device.transaction[lbl].in_use)
4149        {
4150            transaction = NULL;
4151        }
4152        else
4153        {
4154            transaction = &(device.transaction[lbl]);
4155            BTIF_TRACE_DEBUG("%s: Got transaction.label: %d",__FUNCTION__,lbl);
4156        }
4157    }
4158
4159    pthread_mutex_unlock(&device.lbllock);
4160    return transaction;
4161}
4162
4163/*******************************************************************************
4164**
4165** Function         get_transaction
4166**
4167** Description    Obtains the transaction details.
4168**
4169** Returns          bt_status_t
4170*******************************************************************************/
4171
4172bt_status_t  get_transaction(rc_transaction_t **ptransaction)
4173{
4174    bt_status_t result = BT_STATUS_NOMEM;
4175    UINT8 i=0;
4176    pthread_mutex_lock(&device.lbllock);
4177
4178    // Check for unused transactions
4179    for (i=0; i<MAX_TRANSACTIONS_PER_SESSION; i++)
4180    {
4181        if (FALSE==device.transaction[i].in_use)
4182        {
4183            BTIF_TRACE_DEBUG("%s:Got transaction.label: %d",__FUNCTION__,device.transaction[i].lbl);
4184            device.transaction[i].in_use = TRUE;
4185            *ptransaction = &(device.transaction[i]);
4186            result = BT_STATUS_SUCCESS;
4187            break;
4188        }
4189    }
4190
4191    pthread_mutex_unlock(&device.lbllock);
4192    return result;
4193}
4194
4195/*******************************************************************************
4196**
4197** Function         release_transaction
4198**
4199** Description    Will release a transaction for reuse
4200**
4201** Returns          bt_status_t
4202*******************************************************************************/
4203void release_transaction(UINT8 lbl)
4204{
4205    rc_transaction_t *transaction = get_transaction_by_lbl(lbl);
4206
4207    /* If the transaction is in use... */
4208    if (transaction != NULL)
4209    {
4210        BTIF_TRACE_DEBUG("%s: lbl: %d", __FUNCTION__, lbl);
4211        initialize_transaction(lbl);
4212    }
4213}
4214
4215/*******************************************************************************
4216**
4217** Function         lbl_destroy
4218**
4219** Description    Cleanup of the mutex
4220**
4221** Returns          void
4222*******************************************************************************/
4223void lbl_destroy()
4224{
4225    pthread_mutex_destroy(&(device.lbllock));
4226}
4227
4228/*******************************************************************************
4229**      Function       sleep_ms
4230**
4231**      Description    Sleep the calling thread unconditionally for
4232**                     |timeout_ms| milliseconds.
4233**
4234**      Returns        void
4235*******************************************************************************/
4236static void sleep_ms(period_ms_t timeout_ms) {
4237    struct timespec delay;
4238    delay.tv_sec = timeout_ms / 1000;
4239    delay.tv_nsec = 1000 * 1000 * (timeout_ms % 1000);
4240
4241    OSI_NO_INTR(nanosleep(&delay, &delay));
4242}
4243
4244static bool absolute_volume_disabled() {
4245    char volume_disabled[PROPERTY_VALUE_MAX] = {0};
4246    osi_property_get("persist.bluetooth.disableabsvol", volume_disabled, "false");
4247    if (strncmp(volume_disabled, "true", 4) == 0) {
4248        BTIF_TRACE_WARNING("%s: Absolute volume disabled by property", __func__);
4249        return true;
4250    }
4251    return false;
4252}
4253