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