btif_rc.c revision afa6e1abbedaad8fe854b0f43999b8aeb801af91
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 "bta_api.h"
30#include "bta_av_api.h"
31#include "avrc_defs.h"
32#include "bd.h"
33#include "gki.h"
34
35#define LOG_TAG "BTIF_RC"
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);
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    int param_len;
678
679    BTIF_TRACE_EVENT("+ %s", __FUNCTION__);
680
681    if (pmeta_msg->p_msg->hdr.opcode != AVRC_OP_VENDOR)
682    {
683        BTIF_TRACE_WARNING("Invalid opcode: %x", pmeta_msg->p_msg->hdr.opcode);
684        return;
685    }
686    if (pmeta_msg->len < 3)
687    {
688        BTIF_TRACE_WARNING("Invalid length.Opcode: 0x%x, len: 0x%x", pmeta_msg->p_msg->hdr.opcode,
689            pmeta_msg->len);
690        return;
691    }
692
693    if (pmeta_msg->code >= AVRC_RSP_NOT_IMPL)
694    {
695#if (AVRC_ADV_CTRL_INCLUDED == TRUE)
696{
697     rc_transaction_t *transaction=NULL;
698     transaction=get_transaction_by_lbl(pmeta_msg->label);
699     if(NULL!=transaction)
700     {
701        handle_rc_metamsg_rsp(pmeta_msg);
702     }
703     else
704     {
705         BTIF_TRACE_DEBUG("%s:Discard vendor dependent rsp. code: %d label:%d.",
706             __FUNCTION__, pmeta_msg->code, pmeta_msg->label);
707     }
708     return;
709}
710#else
711{
712        BTIF_TRACE_DEBUG("%s:Received vendor dependent rsp. code: %d len: %d. Not processing it.",
713            __FUNCTION__, pmeta_msg->code, pmeta_msg->len);
714        return;
715}
716#endif
717      }
718
719    status=AVRC_ParsCommand(pmeta_msg->p_msg, &avrc_command, scratch_buf, sizeof(scratch_buf));
720    BTIF_TRACE_DEBUG("Received vendor command.code,PDU and label: %d, %d,%d",pmeta_msg->code,
721                       avrc_command.cmd.pdu, pmeta_msg->label);
722
723    if (status != AVRC_STS_NO_ERROR)
724    {
725        /* return error */
726        BTIF_TRACE_WARNING("%s: Error in parsing received metamsg command. status: 0x%02x",
727            __FUNCTION__, status);
728        send_reject_response(pmeta_msg->rc_handle, pmeta_msg->label, avrc_command.pdu, status);
729    }
730    else
731    {
732        /* if RegisterNotification, add it to our registered queue */
733
734        if (avrc_command.cmd.pdu == AVRC_PDU_REGISTER_NOTIFICATION)
735        {
736            UINT8 event_id = avrc_command.reg_notif.event_id;
737            param_len = sizeof(tAVRC_REG_NOTIF_CMD);
738            BTIF_TRACE_EVENT("%s:New register notification received.event_id:%s,label:0x%x,code:%x",
739            __FUNCTION__,dump_rc_notification_event_id(event_id), pmeta_msg->label,pmeta_msg->code);
740            btif_rc_cb.rc_notif[event_id-1].bNotify = TRUE;
741            btif_rc_cb.rc_notif[event_id-1].label = pmeta_msg->label;
742
743            if(event_id == AVRC_EVT_UIDS_CHANGE)
744            {
745                handle_uid_changed_notification(pmeta_msg, &avrc_command);
746                return;
747            }
748
749        }
750
751        BTIF_TRACE_EVENT("%s: Passing received metamsg command to app. pdu: %s",
752            __FUNCTION__, dump_rc_pdu(avrc_command.cmd.pdu));
753
754        /* Since handle_rc_metamsg_cmd() itself is called from
755            *btif context, no context switching is required. Invoke
756            * btif_rc_upstreams_evt directly from here. */
757        btif_rc_upstreams_evt((uint16_t)avrc_command.cmd.pdu, &avrc_command, pmeta_msg->code,
758                               pmeta_msg->label);
759    }
760}
761
762/***************************************************************************
763 **
764 ** Function       btif_rc_handler
765 **
766 ** Description    RC event handler
767 **
768 ***************************************************************************/
769void btif_rc_handler(tBTA_AV_EVT event, tBTA_AV *p_data)
770{
771    BTIF_TRACE_DEBUG ("%s event:%s", __FUNCTION__, dump_rc_event(event));
772    switch (event)
773    {
774        case BTA_AV_RC_OPEN_EVT:
775        {
776            BTIF_TRACE_DEBUG("Peer_features:%x", p_data->rc_open.peer_features);
777            handle_rc_connect( &(p_data->rc_open) );
778        }break;
779
780        case BTA_AV_RC_CLOSE_EVT:
781        {
782            handle_rc_disconnect( &(p_data->rc_close) );
783        }break;
784
785        case BTA_AV_REMOTE_CMD_EVT:
786        {
787            BTIF_TRACE_DEBUG("rc_id:0x%x key_state:%d", p_data->remote_cmd.rc_id,
788                               p_data->remote_cmd.key_state);
789            handle_rc_passthrough_cmd( (&p_data->remote_cmd) );
790        }
791        break;
792#if (AVRC_CTLR_INCLUDED == TRUE)
793        case BTA_AV_REMOTE_RSP_EVT:
794        {
795            BTIF_TRACE_DEBUG("RSP: rc_id:0x%x key_state:%d", p_data->remote_rsp.rc_id,
796                               p_data->remote_rsp.key_state);
797            handle_rc_passthrough_rsp( (&p_data->remote_rsp) );
798        }
799        break;
800#endif
801        case BTA_AV_RC_FEAT_EVT:
802        {
803            BTIF_TRACE_DEBUG("Peer_features:%x", p_data->rc_feat.peer_features);
804            btif_rc_cb.rc_features = p_data->rc_feat.peer_features;
805            handle_rc_features();
806        }
807        break;
808        case BTA_AV_META_MSG_EVT:
809        {
810            BTIF_TRACE_DEBUG("BTA_AV_META_MSG_EVT  code:%d label:%d", p_data->meta_msg.code,
811                p_data->meta_msg.label);
812            BTIF_TRACE_DEBUG("  company_id:0x%x len:%d handle:%d", p_data->meta_msg.company_id,
813                p_data->meta_msg.len, p_data->meta_msg.rc_handle);
814            /* handle the metamsg command */
815            handle_rc_metamsg_cmd(&(p_data->meta_msg));
816        }
817        break;
818        default:
819            BTIF_TRACE_DEBUG("Unhandled RC event : 0x%x", event);
820    }
821}
822
823/***************************************************************************
824 **
825 ** Function       btif_rc_get_connected_peer
826 **
827 ** Description    Fetches the connected headset's BD_ADDR if any
828 **
829 ***************************************************************************/
830BOOLEAN btif_rc_get_connected_peer(BD_ADDR peer_addr)
831{
832    if (btif_rc_cb.rc_connected == TRUE) {
833        bdcpy(peer_addr, btif_rc_cb.rc_addr);
834        return TRUE;
835    }
836    return FALSE;
837}
838
839/***************************************************************************
840 **
841 ** Function       btif_rc_check_handle_pending_play
842 **
843 ** Description    Clears the queued PLAY command. if bSend is TRUE, forwards to app
844 **
845 ***************************************************************************/
846
847/* clear the queued PLAY command. if bSend is TRUE, forward to app */
848void btif_rc_check_handle_pending_play (BD_ADDR peer_addr, BOOLEAN bSendToApp)
849{
850    UNUSED(peer_addr);
851
852    BTIF_TRACE_DEBUG("%s: bSendToApp=%d", __FUNCTION__, bSendToApp);
853    if (btif_rc_cb.rc_pending_play)
854    {
855        if (bSendToApp)
856        {
857            tBTA_AV_REMOTE_CMD remote_cmd;
858            APPL_TRACE_DEBUG("%s: Sending queued PLAYED event to app", __FUNCTION__);
859
860            memset (&remote_cmd, 0, sizeof(tBTA_AV_REMOTE_CMD));
861            remote_cmd.rc_handle  = btif_rc_cb.rc_handle;
862            remote_cmd.rc_id      = AVRC_ID_PLAY;
863            remote_cmd.hdr.ctype  = AVRC_CMD_CTRL;
864            remote_cmd.hdr.opcode = AVRC_OP_PASS_THRU;
865
866            /* delay sending to app, else there is a timing issue in the framework,
867             ** which causes the audio to be on th device's speaker. Delay between
868             ** OPEN & RC_PLAYs
869            */
870            GKI_delay (200);
871            /* send to app - both PRESSED & RELEASED */
872            remote_cmd.key_state  = AVRC_STATE_PRESS;
873            handle_rc_passthrough_cmd( &remote_cmd );
874
875            GKI_delay (100);
876
877            remote_cmd.key_state  = AVRC_STATE_RELEASE;
878            handle_rc_passthrough_cmd( &remote_cmd );
879        }
880        btif_rc_cb.rc_pending_play = FALSE;
881    }
882}
883
884/* Generic reject response */
885static void send_reject_response (UINT8 rc_handle, UINT8 label, UINT8 pdu, UINT8 status)
886{
887    UINT8 ctype = AVRC_RSP_REJ;
888    tAVRC_RESPONSE avrc_rsp;
889    BT_HDR *p_msg = NULL;
890    memset (&avrc_rsp, 0, sizeof(tAVRC_RESPONSE));
891
892    avrc_rsp.rsp.opcode = opcode_from_pdu(pdu);
893    avrc_rsp.rsp.pdu    = pdu;
894    avrc_rsp.rsp.status = status;
895
896    if (AVRC_STS_NO_ERROR == (status = AVRC_BldResponse(rc_handle, &avrc_rsp, &p_msg)) )
897    {
898        BTIF_TRACE_DEBUG("%s:Sending error notification to handle:%d. pdu:%s,status:0x%02x",
899            __FUNCTION__, rc_handle, dump_rc_pdu(pdu), status);
900        BTA_AvMetaRsp(rc_handle, label, ctype, p_msg);
901    }
902}
903
904/***************************************************************************
905 *  Function       send_metamsg_rsp
906 *
907 *  - Argument:
908 *                  rc_handle     RC handle corresponding to the connected RC
909 *                  label            Label of the RC response
910 *                  code            Response type
911 *                  pmetamsg_resp    Vendor response
912 *
913 *  - Description: Remote control metamsg response handler (AVRCP 1.3)
914 *
915 ***************************************************************************/
916static void send_metamsg_rsp (UINT8 rc_handle, UINT8 label, tBTA_AV_CODE code,
917    tAVRC_RESPONSE *pmetamsg_resp)
918{
919    UINT8 ctype;
920    tAVRC_STS status;
921
922    if (!pmetamsg_resp)
923    {
924        BTIF_TRACE_WARNING("%s: Invalid response received from application", __FUNCTION__);
925        return;
926    }
927
928    BTIF_TRACE_EVENT("+%s: rc_handle: %d, label: %d, code: 0x%02x, pdu: %s", __FUNCTION__,
929        rc_handle, label, code, dump_rc_pdu(pmetamsg_resp->rsp.pdu));
930
931    if (pmetamsg_resp->rsp.status != AVRC_STS_NO_ERROR)
932    {
933        ctype = AVRC_RSP_REJ;
934    }
935    else
936    {
937        if ( code < AVRC_RSP_NOT_IMPL)
938        {
939            if (code == AVRC_CMD_NOTIF)
940            {
941               ctype = AVRC_RSP_INTERIM;
942            }
943            else if (code == AVRC_CMD_STATUS)
944            {
945               ctype = AVRC_RSP_IMPL_STBL;
946            }
947            else
948            {
949               ctype = AVRC_RSP_ACCEPT;
950            }
951        }
952        else
953        {
954            ctype = code;
955        }
956    }
957    /* if response is for register_notification, make sure the rc has
958    actually registered for this */
959    if((pmetamsg_resp->rsp.pdu == AVRC_PDU_REGISTER_NOTIFICATION) && (code == AVRC_RSP_CHANGED))
960    {
961        BOOLEAN bSent = FALSE;
962        UINT8   event_id = pmetamsg_resp->reg_notif.event_id;
963        BOOLEAN bNotify = (btif_rc_cb.rc_connected) && (btif_rc_cb.rc_notif[event_id-1].bNotify);
964
965        /* de-register this notification for a CHANGED response */
966        btif_rc_cb.rc_notif[event_id-1].bNotify = FALSE;
967        BTIF_TRACE_DEBUG("%s rc_handle: %d. event_id: 0x%02d bNotify:%u", __FUNCTION__,
968             btif_rc_cb.rc_handle, event_id, bNotify);
969        if (bNotify)
970        {
971            BT_HDR *p_msg = NULL;
972            tAVRC_STS status;
973
974            if (AVRC_STS_NO_ERROR == (status = AVRC_BldResponse(btif_rc_cb.rc_handle,
975                pmetamsg_resp, &p_msg)) )
976            {
977                BTIF_TRACE_DEBUG("%s Sending notification to rc_handle: %d. event_id: 0x%02d",
978                     __FUNCTION__, btif_rc_cb.rc_handle, event_id);
979                bSent = TRUE;
980                BTA_AvMetaRsp(btif_rc_cb.rc_handle, btif_rc_cb.rc_notif[event_id-1].label,
981                    ctype, p_msg);
982            }
983            else
984            {
985                BTIF_TRACE_WARNING("%s failed to build metamsg response. status: 0x%02x",
986                    __FUNCTION__, status);
987            }
988
989        }
990
991        if (!bSent)
992        {
993            BTIF_TRACE_DEBUG("%s: Notification not sent, as there are no RC connections or the \
994                CT has not subscribed for event_id: %s", __FUNCTION__, dump_rc_notification_event_id(event_id));
995        }
996    }
997    else
998    {
999        /* All other commands go here */
1000
1001        BT_HDR *p_msg = NULL;
1002        tAVRC_STS status;
1003
1004        status = AVRC_BldResponse(rc_handle, pmetamsg_resp, &p_msg);
1005
1006        if (status == AVRC_STS_NO_ERROR)
1007        {
1008            BTA_AvMetaRsp(rc_handle, label, ctype, p_msg);
1009        }
1010        else
1011        {
1012            BTIF_TRACE_ERROR("%s: failed to build metamsg response. status: 0x%02x",
1013                __FUNCTION__, status);
1014        }
1015    }
1016}
1017
1018static UINT8 opcode_from_pdu(UINT8 pdu)
1019{
1020    UINT8 opcode = 0;
1021
1022    switch (pdu)
1023    {
1024    case AVRC_PDU_NEXT_GROUP:
1025    case AVRC_PDU_PREV_GROUP: /* pass thru */
1026        opcode  = AVRC_OP_PASS_THRU;
1027        break;
1028
1029    default: /* vendor */
1030        opcode  = AVRC_OP_VENDOR;
1031        break;
1032    }
1033
1034    return opcode;
1035}
1036
1037/*******************************************************************************
1038**
1039** Function         btif_rc_upstreams_evt
1040**
1041** Description      Executes AVRC UPSTREAMS events in btif context.
1042**
1043** Returns          void
1044**
1045*******************************************************************************/
1046static void btif_rc_upstreams_evt(UINT16 event, tAVRC_COMMAND *pavrc_cmd, UINT8 ctype, UINT8 label)
1047{
1048    BTIF_TRACE_EVENT("%s pdu: %s handle: 0x%x ctype:%x label:%x", __FUNCTION__,
1049        dump_rc_pdu(pavrc_cmd->pdu), btif_rc_cb.rc_handle, ctype, label);
1050
1051    switch (event)
1052    {
1053        case AVRC_PDU_GET_PLAY_STATUS:
1054        {
1055            FILL_PDU_QUEUE(IDX_GET_PLAY_STATUS_RSP, ctype, label, TRUE)
1056            HAL_CBACK(bt_rc_callbacks, get_play_status_cb);
1057        }
1058        break;
1059        case AVRC_PDU_LIST_PLAYER_APP_ATTR:
1060        case AVRC_PDU_LIST_PLAYER_APP_VALUES:
1061        case AVRC_PDU_GET_CUR_PLAYER_APP_VALUE:
1062        case AVRC_PDU_SET_PLAYER_APP_VALUE:
1063        case AVRC_PDU_GET_PLAYER_APP_ATTR_TEXT:
1064        case AVRC_PDU_GET_PLAYER_APP_VALUE_TEXT:
1065        {
1066            /* TODO: Add support for Application Settings */
1067            send_reject_response (btif_rc_cb.rc_handle, label, pavrc_cmd->pdu, AVRC_STS_BAD_CMD);
1068        }
1069        break;
1070        case AVRC_PDU_GET_ELEMENT_ATTR:
1071        {
1072            btrc_media_attr_t element_attrs[BTRC_MAX_ELEM_ATTR_SIZE];
1073            UINT8 num_attr;
1074             memset(&element_attrs, 0, sizeof(element_attrs));
1075            if (pavrc_cmd->get_elem_attrs.num_attr == 0)
1076            {
1077                /* CT requests for all attributes */
1078                int attr_cnt;
1079                num_attr = BTRC_MAX_ELEM_ATTR_SIZE;
1080                for (attr_cnt = 0; attr_cnt < BTRC_MAX_ELEM_ATTR_SIZE; attr_cnt++)
1081                {
1082                    element_attrs[attr_cnt] = attr_cnt + 1;
1083                }
1084            }
1085            else if (pavrc_cmd->get_elem_attrs.num_attr == 0xFF)
1086            {
1087                /* 0xff indicates, no attributes requested - reject */
1088                send_reject_response (btif_rc_cb.rc_handle, label, pavrc_cmd->pdu,
1089                    AVRC_STS_BAD_PARAM);
1090                return;
1091            }
1092            else
1093            {
1094                num_attr = pavrc_cmd->get_elem_attrs.num_attr;
1095                memcpy(element_attrs, pavrc_cmd->get_elem_attrs.attrs, sizeof(UINT32)
1096                    *pavrc_cmd->get_elem_attrs.num_attr);
1097            }
1098            FILL_PDU_QUEUE(IDX_GET_ELEMENT_ATTR_RSP, ctype, label, TRUE);
1099            HAL_CBACK(bt_rc_callbacks, get_element_attr_cb, num_attr, element_attrs);
1100        }
1101        break;
1102        case AVRC_PDU_REGISTER_NOTIFICATION:
1103        {
1104            if(pavrc_cmd->reg_notif.event_id == BTRC_EVT_PLAY_POS_CHANGED &&
1105                pavrc_cmd->reg_notif.param == 0)
1106            {
1107                BTIF_TRACE_WARNING("%s Device registering position changed with illegal param 0.",
1108                    __FUNCTION__);
1109                send_reject_response (btif_rc_cb.rc_handle, label, pavrc_cmd->pdu, AVRC_STS_BAD_PARAM);
1110                /* de-register this notification for a rejected response */
1111                btif_rc_cb.rc_notif[BTRC_EVT_PLAY_POS_CHANGED - 1].bNotify = FALSE;
1112                return;
1113            }
1114            HAL_CBACK(bt_rc_callbacks, register_notification_cb, pavrc_cmd->reg_notif.event_id,
1115                pavrc_cmd->reg_notif.param);
1116        }
1117        break;
1118        case AVRC_PDU_INFORM_DISPLAY_CHARSET:
1119        {
1120            tAVRC_RESPONSE avrc_rsp;
1121            BTIF_TRACE_EVENT("%s() AVRC_PDU_INFORM_DISPLAY_CHARSET", __FUNCTION__);
1122            if(btif_rc_cb.rc_connected == TRUE)
1123            {
1124                memset(&(avrc_rsp.inform_charset), 0, sizeof(tAVRC_RSP));
1125                avrc_rsp.inform_charset.opcode=opcode_from_pdu(AVRC_PDU_INFORM_DISPLAY_CHARSET);
1126                avrc_rsp.inform_charset.pdu=AVRC_PDU_INFORM_DISPLAY_CHARSET;
1127                avrc_rsp.inform_charset.status=AVRC_STS_NO_ERROR;
1128                send_metamsg_rsp(btif_rc_cb.rc_handle, label, ctype, &avrc_rsp);
1129            }
1130        }
1131        break;
1132        default:
1133        {
1134        send_reject_response (btif_rc_cb.rc_handle, label, pavrc_cmd->pdu,
1135            (pavrc_cmd->pdu == AVRC_PDU_SEARCH)?AVRC_STS_SEARCH_NOT_SUP:AVRC_STS_BAD_CMD);
1136        return;
1137        }
1138        break;
1139    }
1140
1141}
1142
1143
1144/*******************************************************************************
1145**
1146** Function         btif_rc_upstreams_rsp_evt
1147**
1148** Description      Executes AVRC UPSTREAMS response events in btif context.
1149**
1150** Returns          void
1151**
1152*******************************************************************************/
1153static void btif_rc_upstreams_rsp_evt(UINT16 event, tAVRC_RESPONSE *pavrc_resp, UINT8 ctype, UINT8 label)
1154{
1155    BTIF_TRACE_EVENT("%s pdu: %s handle: 0x%x ctype:%x label:%x", __FUNCTION__,
1156        dump_rc_pdu(pavrc_resp->pdu), btif_rc_cb.rc_handle, ctype, label);
1157
1158#if (AVRC_ADV_CTRL_INCLUDED == TRUE)
1159    switch (event)
1160    {
1161        case AVRC_PDU_REGISTER_NOTIFICATION:
1162        {
1163             if(AVRC_RSP_CHANGED==ctype)
1164                 btif_rc_cb.rc_volume=pavrc_resp->reg_notif.param.volume;
1165             HAL_CBACK(bt_rc_callbacks, volume_change_cb, pavrc_resp->reg_notif.param.volume,ctype)
1166        }
1167        break;
1168
1169        case AVRC_PDU_SET_ABSOLUTE_VOLUME:
1170        {
1171            BTIF_TRACE_DEBUG("Set absolute volume change event received: volume %d,ctype %d",
1172                pavrc_resp->volume.volume,ctype);
1173            if(AVRC_RSP_ACCEPT==ctype)
1174                btif_rc_cb.rc_volume=pavrc_resp->volume.volume;
1175            HAL_CBACK(bt_rc_callbacks,volume_change_cb,pavrc_resp->volume.volume,ctype)
1176        }
1177        break;
1178
1179        default:
1180            return;
1181    }
1182#endif
1183}
1184
1185/************************************************************************************
1186**  AVRCP API Functions
1187************************************************************************************/
1188
1189/*******************************************************************************
1190**
1191** Function         init
1192**
1193** Description      Initializes the AVRC interface
1194**
1195** Returns          bt_status_t
1196**
1197*******************************************************************************/
1198static bt_status_t init(btrc_callbacks_t* callbacks )
1199{
1200    BTIF_TRACE_EVENT("## %s ##", __FUNCTION__);
1201    bt_status_t result = BT_STATUS_SUCCESS;
1202
1203    if (bt_rc_callbacks)
1204        return BT_STATUS_DONE;
1205
1206    bt_rc_callbacks = callbacks;
1207    memset (&btif_rc_cb, 0, sizeof(btif_rc_cb));
1208    btif_rc_cb.rc_vol_label=MAX_LABEL;
1209    btif_rc_cb.rc_volume=MAX_VOLUME;
1210    lbl_init();
1211
1212    return result;
1213}
1214
1215/*******************************************************************************
1216**
1217** Function         init_ctrl
1218**
1219** Description      Initializes the AVRC interface
1220**
1221** Returns          bt_status_t
1222**
1223*******************************************************************************/
1224static bt_status_t init_ctrl(btrc_ctrl_callbacks_t* callbacks )
1225{
1226    BTIF_TRACE_EVENT("## %s ##", __FUNCTION__);
1227    bt_status_t result = BT_STATUS_SUCCESS;
1228
1229    if (bt_rc_ctrl_callbacks)
1230        return BT_STATUS_DONE;
1231
1232    bt_rc_ctrl_callbacks = callbacks;
1233    memset (&btif_rc_cb, 0, sizeof(btif_rc_cb));
1234    btif_rc_cb.rc_vol_label=MAX_LABEL;
1235    btif_rc_cb.rc_volume=MAX_VOLUME;
1236    lbl_init();
1237
1238    return result;
1239}
1240
1241/***************************************************************************
1242**
1243** Function         get_play_status_rsp
1244**
1245** Description      Returns the current play status.
1246**                      This method is called in response to
1247**                      GetPlayStatus request.
1248**
1249** Returns          bt_status_t
1250**
1251***************************************************************************/
1252static bt_status_t get_play_status_rsp(btrc_play_status_t play_status, uint32_t song_len,
1253    uint32_t song_pos)
1254{
1255    tAVRC_RESPONSE avrc_rsp;
1256    UINT32 i;
1257    CHECK_RC_CONNECTED
1258    memset(&(avrc_rsp.get_play_status), 0, sizeof(tAVRC_GET_PLAY_STATUS_RSP));
1259    avrc_rsp.get_play_status.song_len = song_len;
1260    avrc_rsp.get_play_status.song_pos = song_pos;
1261    avrc_rsp.get_play_status.play_status = play_status;
1262
1263    avrc_rsp.get_play_status.pdu = AVRC_PDU_GET_PLAY_STATUS;
1264    avrc_rsp.get_play_status.opcode = opcode_from_pdu(AVRC_PDU_GET_PLAY_STATUS);
1265    avrc_rsp.get_play_status.status = AVRC_STS_NO_ERROR;
1266    /* Send the response */
1267    SEND_METAMSG_RSP(IDX_GET_PLAY_STATUS_RSP, &avrc_rsp);
1268    return BT_STATUS_SUCCESS;
1269}
1270
1271/***************************************************************************
1272**
1273** Function         get_element_attr_rsp
1274**
1275** Description      Returns the current songs' element attributes
1276**                      in text.
1277**
1278** Returns          bt_status_t
1279**
1280***************************************************************************/
1281static bt_status_t get_element_attr_rsp(uint8_t num_attr, btrc_element_attr_val_t *p_attrs)
1282{
1283    tAVRC_RESPONSE avrc_rsp;
1284    UINT32 i;
1285    uint8_t j;
1286    tAVRC_ATTR_ENTRY element_attrs[BTRC_MAX_ELEM_ATTR_SIZE];
1287    CHECK_RC_CONNECTED
1288    memset(element_attrs, 0, sizeof(tAVRC_ATTR_ENTRY) * num_attr);
1289
1290    if (num_attr == 0)
1291    {
1292        avrc_rsp.get_play_status.status = AVRC_STS_BAD_PARAM;
1293    }
1294    else
1295    {
1296        for (i=0; i<num_attr; i++) {
1297            element_attrs[i].attr_id = p_attrs[i].attr_id;
1298            element_attrs[i].name.charset_id = AVRC_CHARSET_ID_UTF8;
1299            element_attrs[i].name.str_len = (UINT16)strlen((char *)p_attrs[i].text);
1300            element_attrs[i].name.p_str = p_attrs[i].text;
1301            BTIF_TRACE_DEBUG("%s attr_id:0x%x, charset_id:0x%x, str_len:%d, str:%s",
1302                __FUNCTION__, (unsigned int)element_attrs[i].attr_id,
1303                element_attrs[i].name.charset_id, element_attrs[i].name.str_len,
1304                element_attrs[i].name.p_str);
1305        }
1306        avrc_rsp.get_play_status.status = AVRC_STS_NO_ERROR;
1307    }
1308    avrc_rsp.get_elem_attrs.num_attr = num_attr;
1309    avrc_rsp.get_elem_attrs.p_attrs = element_attrs;
1310    avrc_rsp.get_elem_attrs.pdu = AVRC_PDU_GET_ELEMENT_ATTR;
1311    avrc_rsp.get_elem_attrs.opcode = opcode_from_pdu(AVRC_PDU_GET_ELEMENT_ATTR);
1312    /* Send the response */
1313    SEND_METAMSG_RSP(IDX_GET_ELEMENT_ATTR_RSP, &avrc_rsp);
1314    return BT_STATUS_SUCCESS;
1315}
1316
1317/***************************************************************************
1318**
1319** Function         register_notification_rsp
1320**
1321** Description      Response to the register notification request.
1322**                      in text.
1323**
1324** Returns          bt_status_t
1325**
1326***************************************************************************/
1327static bt_status_t register_notification_rsp(btrc_event_id_t event_id,
1328    btrc_notification_type_t type, btrc_register_notification_t *p_param)
1329{
1330    tAVRC_RESPONSE avrc_rsp;
1331    CHECK_RC_CONNECTED
1332    BTIF_TRACE_EVENT("## %s ## event_id:%s", __FUNCTION__, dump_rc_notification_event_id(event_id));
1333    if (btif_rc_cb.rc_notif[event_id-1].bNotify == FALSE)
1334    {
1335        BTIF_TRACE_ERROR("Avrcp Event id not registered: event_id = %x", event_id);
1336        return BT_STATUS_NOT_READY;
1337    }
1338    memset(&(avrc_rsp.reg_notif), 0, sizeof(tAVRC_REG_NOTIF_RSP));
1339    avrc_rsp.reg_notif.event_id = event_id;
1340
1341    switch(event_id)
1342    {
1343        case BTRC_EVT_PLAY_STATUS_CHANGED:
1344            avrc_rsp.reg_notif.param.play_status = p_param->play_status;
1345            break;
1346        case BTRC_EVT_TRACK_CHANGE:
1347            memcpy(&(avrc_rsp.reg_notif.param.track), &(p_param->track), sizeof(btrc_uid_t));
1348            break;
1349        case BTRC_EVT_PLAY_POS_CHANGED:
1350            avrc_rsp.reg_notif.param.play_pos = p_param->song_pos;
1351            break;
1352        default:
1353            BTIF_TRACE_WARNING("%s : Unhandled event ID : 0x%x", __FUNCTION__, event_id);
1354            return BT_STATUS_UNHANDLED;
1355    }
1356
1357    avrc_rsp.reg_notif.pdu = AVRC_PDU_REGISTER_NOTIFICATION;
1358    avrc_rsp.reg_notif.opcode = opcode_from_pdu(AVRC_PDU_REGISTER_NOTIFICATION);
1359    avrc_rsp.get_play_status.status = AVRC_STS_NO_ERROR;
1360
1361    /* Send the response. */
1362    send_metamsg_rsp(btif_rc_cb.rc_handle, btif_rc_cb.rc_notif[event_id-1].label,
1363        ((type == BTRC_NOTIFICATION_TYPE_INTERIM)?AVRC_CMD_NOTIF:AVRC_RSP_CHANGED), &avrc_rsp);
1364    return BT_STATUS_SUCCESS;
1365}
1366
1367/***************************************************************************
1368**
1369** Function         set_volume
1370**
1371** Description      Send current volume setting to remote side.
1372**                  Support limited to SetAbsoluteVolume
1373**                  This can be enhanced to support Relative Volume (AVRCP 1.0).
1374**                  With RelateVolume, we will send VOLUME_UP/VOLUME_DOWN
1375**                  as opposed to absolute volume level
1376** volume: Should be in the range 0-127. bit7 is reseved and cannot be set
1377**
1378** Returns          bt_status_t
1379**
1380***************************************************************************/
1381static bt_status_t set_volume(uint8_t volume)
1382{
1383    BTIF_TRACE_DEBUG("%s", __FUNCTION__);
1384    CHECK_RC_CONNECTED
1385    tAVRC_STS status = BT_STATUS_UNSUPPORTED;
1386    rc_transaction_t *p_transaction=NULL;
1387
1388    if(btif_rc_cb.rc_volume==volume)
1389    {
1390        status=BT_STATUS_DONE;
1391        BTIF_TRACE_ERROR("%s: volume value already set earlier: 0x%02x",__FUNCTION__, volume);
1392        return status;
1393    }
1394
1395    if ((btif_rc_cb.rc_features & BTA_AV_FEAT_RCTG) &&
1396        (btif_rc_cb.rc_features & BTA_AV_FEAT_ADV_CTRL))
1397    {
1398        tAVRC_COMMAND avrc_cmd = {0};
1399        BT_HDR *p_msg = NULL;
1400
1401        BTIF_TRACE_DEBUG("%s: Peer supports absolute volume. newVolume=%d", __FUNCTION__, volume);
1402        avrc_cmd.volume.opcode = AVRC_OP_VENDOR;
1403        avrc_cmd.volume.pdu = AVRC_PDU_SET_ABSOLUTE_VOLUME;
1404        avrc_cmd.volume.status = AVRC_STS_NO_ERROR;
1405        avrc_cmd.volume.volume = volume;
1406
1407        if (AVRC_BldCommand(&avrc_cmd, &p_msg) == AVRC_STS_NO_ERROR)
1408        {
1409            bt_status_t tran_status=get_transaction(&p_transaction);
1410            if(BT_STATUS_SUCCESS == tran_status && NULL!=p_transaction)
1411            {
1412                BTIF_TRACE_DEBUG("%s msgreq being sent out with label %d",
1413                                   __FUNCTION__,p_transaction->lbl);
1414                BTA_AvMetaCmd(btif_rc_cb.rc_handle,p_transaction->lbl, AVRC_CMD_CTRL, p_msg);
1415                status =  BT_STATUS_SUCCESS;
1416            }
1417            else
1418            {
1419                if(NULL!=p_msg)
1420                   GKI_freebuf(p_msg);
1421                BTIF_TRACE_ERROR("%s: failed to obtain transaction details. status: 0x%02x",
1422                                    __FUNCTION__, tran_status);
1423                status = BT_STATUS_FAIL;
1424            }
1425        }
1426        else
1427        {
1428            BTIF_TRACE_ERROR("%s: failed to build absolute volume command. status: 0x%02x",
1429                                __FUNCTION__, status);
1430            status = BT_STATUS_FAIL;
1431        }
1432    }
1433    else
1434        status=BT_STATUS_NOT_READY;
1435    return status;
1436}
1437
1438
1439/***************************************************************************
1440**
1441** Function         register_volumechange
1442**
1443** Description     Register for volume change notification from remote side.
1444**
1445** Returns          void
1446**
1447***************************************************************************/
1448
1449static void register_volumechange (UINT8 lbl)
1450{
1451    tAVRC_COMMAND avrc_cmd = {0};
1452    BT_HDR *p_msg = NULL;
1453    tAVRC_STS BldResp=AVRC_STS_BAD_CMD;
1454    UINT16 rv = 0;
1455    bt_status_t tran_status;
1456    rc_transaction_t *p_transaction=NULL;
1457
1458    BTIF_TRACE_DEBUG("%s called with label:%d",__FUNCTION__,lbl);
1459
1460    avrc_cmd.cmd.opcode=0x00;
1461    avrc_cmd.pdu = AVRC_PDU_REGISTER_NOTIFICATION;
1462    avrc_cmd.reg_notif.event_id = AVRC_EVT_VOLUME_CHANGE;
1463    avrc_cmd.reg_notif.status = AVRC_STS_NO_ERROR;
1464
1465    BldResp=AVRC_BldCommand(&avrc_cmd, &p_msg);
1466    if(AVRC_STS_NO_ERROR==BldResp && p_msg)
1467    {
1468         p_transaction=get_transaction_by_lbl(lbl);
1469         if(NULL!=p_transaction)
1470         {
1471             BTA_AvMetaCmd(btif_rc_cb.rc_handle,p_transaction->lbl, AVRC_CMD_NOTIF, p_msg);
1472             BTIF_TRACE_DEBUG("%s:BTA_AvMetaCmd called",__FUNCTION__);
1473         }
1474         else
1475         {
1476            if(NULL!=p_msg)
1477               GKI_freebuf(p_msg);
1478            BTIF_TRACE_ERROR("%s transaction not obtained with label: %d",__FUNCTION__,lbl);
1479         }
1480    }
1481    else
1482        BTIF_TRACE_ERROR("%s failed to build command:%d",__FUNCTION__,BldResp);
1483}
1484
1485
1486/***************************************************************************
1487**
1488** Function         handle_rc_metamsg_rsp
1489**
1490** Description      Handle RC metamessage response
1491**
1492** Returns          void
1493**
1494***************************************************************************/
1495static void handle_rc_metamsg_rsp(tBTA_AV_META_MSG *pmeta_msg)
1496{
1497    tAVRC_RESPONSE    avrc_response = {0};
1498    UINT8             scratch_buf[512] = {0};
1499    tAVRC_STS status = BT_STATUS_UNSUPPORTED;
1500
1501    if(AVRC_OP_VENDOR==pmeta_msg->p_msg->hdr.opcode &&(AVRC_RSP_CHANGED==pmeta_msg->code
1502      || AVRC_RSP_INTERIM==pmeta_msg->code || AVRC_RSP_ACCEPT==pmeta_msg->code
1503      || AVRC_RSP_REJ==pmeta_msg->code || AVRC_RSP_NOT_IMPL==pmeta_msg->code))
1504    {
1505        status=AVRC_ParsResponse(pmeta_msg->p_msg, &avrc_response, scratch_buf, sizeof(scratch_buf));
1506        BTIF_TRACE_DEBUG("%s: code %d,event ID %d,PDU %x,parsing status %d, label:%d",
1507          __FUNCTION__,pmeta_msg->code,avrc_response.reg_notif.event_id,avrc_response.reg_notif.pdu,
1508          status, pmeta_msg->label);
1509
1510        if (status != AVRC_STS_NO_ERROR)
1511        {
1512            if(AVRC_PDU_REGISTER_NOTIFICATION==avrc_response.rsp.pdu
1513                && AVRC_EVT_VOLUME_CHANGE==avrc_response.reg_notif.event_id
1514                && btif_rc_cb.rc_vol_label==pmeta_msg->label)
1515            {
1516                btif_rc_cb.rc_vol_label=MAX_LABEL;
1517                release_transaction(btif_rc_cb.rc_vol_label);
1518            }
1519            else if(AVRC_PDU_SET_ABSOLUTE_VOLUME==avrc_response.rsp.pdu)
1520            {
1521                release_transaction(pmeta_msg->label);
1522            }
1523            return;
1524        }
1525        else if(AVRC_PDU_REGISTER_NOTIFICATION==avrc_response.rsp.pdu
1526            && AVRC_EVT_VOLUME_CHANGE==avrc_response.reg_notif.event_id
1527            && btif_rc_cb.rc_vol_label!=pmeta_msg->label)
1528            {
1529                // Just discard the message, if the device sends back with an incorrect label
1530                BTIF_TRACE_DEBUG("%s:Discarding register notfn in rsp.code: %d and label %d",
1531                __FUNCTION__, pmeta_msg->code, pmeta_msg->label);
1532                return;
1533            }
1534    }
1535    else
1536    {
1537        BTIF_TRACE_DEBUG("%s:Received vendor dependent in adv ctrl rsp. code: %d len: %d. Not processing it.",
1538        __FUNCTION__, pmeta_msg->code, pmeta_msg->len);
1539        return;
1540    }
1541
1542    if(AVRC_PDU_REGISTER_NOTIFICATION==avrc_response.rsp.pdu
1543        && AVRC_EVT_VOLUME_CHANGE==avrc_response.reg_notif.event_id
1544        && AVRC_RSP_CHANGED==pmeta_msg->code)
1545     {
1546         /* re-register for volume change notification */
1547         // Do not re-register for rejected case, as it might get into endless loop
1548         register_volumechange(btif_rc_cb.rc_vol_label);
1549     }
1550     else if(AVRC_PDU_SET_ABSOLUTE_VOLUME==avrc_response.rsp.pdu)
1551     {
1552          /* free up the label here */
1553          release_transaction(pmeta_msg->label);
1554     }
1555
1556     BTIF_TRACE_EVENT("%s: Passing received metamsg response to app. pdu: %s",
1557             __FUNCTION__, dump_rc_pdu(avrc_response.pdu));
1558     btif_rc_upstreams_rsp_evt((uint16_t)avrc_response.rsp.pdu, &avrc_response, pmeta_msg->code,
1559                                pmeta_msg->label);
1560}
1561
1562
1563/***************************************************************************
1564**
1565** Function         cleanup
1566**
1567** Description      Closes the AVRC interface
1568**
1569** Returns          void
1570**
1571***************************************************************************/
1572static void cleanup()
1573{
1574    BTIF_TRACE_EVENT("## %s ##", __FUNCTION__);
1575    close_uinput();
1576    if (bt_rc_callbacks)
1577    {
1578        bt_rc_callbacks = NULL;
1579    }
1580    memset(&btif_rc_cb, 0, sizeof(btif_rc_cb_t));
1581    lbl_destroy();
1582}
1583
1584
1585static bt_status_t send_passthrough_cmd(bt_bdaddr_t *bd_addr, uint8_t key_code, uint8_t key_state)
1586{
1587    tAVRC_STS status = BT_STATUS_UNSUPPORTED;
1588#if (AVRC_CTLR_INCLUDED == TRUE)
1589    CHECK_RC_CONNECTED
1590    rc_transaction_t *p_transaction=NULL;
1591    BTIF_TRACE_DEBUG("%s: key-code: %d, key-state: %d", __FUNCTION__,
1592                                                    key_code, key_state);
1593    if (btif_rc_cb.rc_features & BTA_AV_FEAT_RCTG)
1594    {
1595        tAVRC_MSG_PASS avrc_cmd;
1596        bt_status_t tran_status = get_transaction(&p_transaction);
1597        if(BT_STATUS_SUCCESS == tran_status && NULL != p_transaction)
1598        {
1599            BTA_AvRemoteCmd(btif_rc_cb.rc_handle, p_transaction->lbl,
1600                (tBTA_AV_RC)key_code, (tBTA_AV_STATE)key_state);
1601            status =  BT_STATUS_SUCCESS;
1602            BTIF_TRACE_DEBUG("%s: succesfully sent passthrough command to BTA", __FUNCTION__);
1603        }
1604        else
1605        {
1606            status =  BT_STATUS_FAIL;
1607            BTIF_TRACE_DEBUG("%s: error in fetching transaction", __FUNCTION__);
1608        }
1609    }
1610    else
1611    {
1612        status =  BT_STATUS_FAIL;
1613        BTIF_TRACE_DEBUG("%s: feature not supported", __FUNCTION__);
1614    }
1615#else
1616    BTIF_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__);
1617#endif
1618    return status;
1619}
1620
1621static const btrc_interface_t bt_rc_interface = {
1622    sizeof(bt_rc_interface),
1623    init,
1624    get_play_status_rsp,
1625    NULL, /* list_player_app_attr_rsp */
1626    NULL, /* list_player_app_value_rsp */
1627    NULL, /* get_player_app_value_rsp */
1628    NULL, /* get_player_app_attr_text_rsp */
1629    NULL, /* get_player_app_value_text_rsp */
1630    get_element_attr_rsp,
1631    NULL, /* set_player_app_value_rsp */
1632    register_notification_rsp,
1633    set_volume,
1634    cleanup,
1635};
1636
1637static const btrc_ctrl_interface_t bt_rc_ctrl_interface = {
1638    sizeof(bt_rc_ctrl_interface),
1639    init_ctrl,
1640    send_passthrough_cmd,
1641    cleanup,
1642};
1643
1644/*******************************************************************************
1645**
1646** Function         btif_rc_get_interface
1647**
1648** Description      Get the AVRCP Target callback interface
1649**
1650** Returns          btav_interface_t
1651**
1652*******************************************************************************/
1653const btrc_interface_t *btif_rc_get_interface(void)
1654{
1655    BTIF_TRACE_EVENT("%s", __FUNCTION__);
1656    return &bt_rc_interface;
1657}
1658
1659/*******************************************************************************
1660**
1661** Function         btif_rc_ctrl_get_interface
1662**
1663** Description      Get the AVRCP Controller callback interface
1664**
1665** Returns          btav_interface_t
1666**
1667*******************************************************************************/
1668const btrc_ctrl_interface_t *btif_rc_ctrl_get_interface(void)
1669{
1670    BTIF_TRACE_EVENT("%s", __FUNCTION__);
1671    return &bt_rc_ctrl_interface;
1672}
1673
1674/*******************************************************************************
1675**      Function         initialize_transaction
1676**
1677**      Description    Initializes fields of the transaction structure
1678**
1679**      Returns          void
1680*******************************************************************************/
1681static void initialize_transaction(int lbl)
1682{
1683    pthread_mutex_lock(&device.lbllock);
1684    if(lbl < MAX_TRANSACTIONS_PER_SESSION)
1685    {
1686       device.transaction[lbl].lbl = lbl;
1687       device.transaction[lbl].in_use=FALSE;
1688       device.transaction[lbl].handle=0;
1689    }
1690    pthread_mutex_unlock(&device.lbllock);
1691}
1692
1693/*******************************************************************************
1694**      Function         lbl_init
1695**
1696**      Description    Initializes label structures and mutexes.
1697**
1698**      Returns         void
1699*******************************************************************************/
1700void lbl_init()
1701{
1702    memset(&device,0,sizeof(rc_device_t));
1703    pthread_mutexattr_t attr;
1704    pthread_mutexattr_init(&attr);
1705    pthread_mutex_init(&(device.lbllock), &attr);
1706    pthread_mutexattr_destroy(&attr);
1707    init_all_transactions();
1708}
1709
1710/*******************************************************************************
1711**
1712** Function         init_all_transactions
1713**
1714** Description    Initializes all transactions
1715**
1716** Returns          void
1717*******************************************************************************/
1718void init_all_transactions()
1719{
1720    UINT8 txn_indx=0;
1721    for(txn_indx=0; txn_indx < MAX_TRANSACTIONS_PER_SESSION; txn_indx++)
1722    {
1723        initialize_transaction(txn_indx);
1724    }
1725}
1726
1727/*******************************************************************************
1728**
1729** Function         get_transaction_by_lbl
1730**
1731** Description    Will return a transaction based on the label. If not inuse
1732**                     will return an error.
1733**
1734** Returns          bt_status_t
1735*******************************************************************************/
1736rc_transaction_t *get_transaction_by_lbl(UINT8 lbl)
1737{
1738    rc_transaction_t *transaction = NULL;
1739    pthread_mutex_lock(&device.lbllock);
1740
1741    /* Determine if this is a valid label */
1742    if (lbl < MAX_TRANSACTIONS_PER_SESSION)
1743    {
1744        if (FALSE==device.transaction[lbl].in_use)
1745        {
1746            transaction = NULL;
1747        }
1748        else
1749        {
1750            transaction = &(device.transaction[lbl]);
1751            BTIF_TRACE_DEBUG("%s: Got transaction.label: %d",__FUNCTION__,lbl);
1752        }
1753    }
1754
1755    pthread_mutex_unlock(&device.lbllock);
1756    return transaction;
1757}
1758
1759/*******************************************************************************
1760**
1761** Function         get_transaction
1762**
1763** Description    Obtains the transaction details.
1764**
1765** Returns          bt_status_t
1766*******************************************************************************/
1767
1768bt_status_t  get_transaction(rc_transaction_t **ptransaction)
1769{
1770    bt_status_t result = BT_STATUS_NOMEM;
1771    UINT8 i=0;
1772    pthread_mutex_lock(&device.lbllock);
1773
1774    // Check for unused transactions
1775    for (i=0; i<MAX_TRANSACTIONS_PER_SESSION; i++)
1776    {
1777        if (FALSE==device.transaction[i].in_use)
1778        {
1779            BTIF_TRACE_DEBUG("%s:Got transaction.label: %d",__FUNCTION__,device.transaction[i].lbl);
1780            device.transaction[i].in_use = TRUE;
1781            *ptransaction = &(device.transaction[i]);
1782            result = BT_STATUS_SUCCESS;
1783            break;
1784        }
1785    }
1786
1787    pthread_mutex_unlock(&device.lbllock);
1788    return result;
1789}
1790
1791
1792/*******************************************************************************
1793**
1794** Function         release_transaction
1795**
1796** Description    Will release a transaction for reuse
1797**
1798** Returns          bt_status_t
1799*******************************************************************************/
1800void release_transaction(UINT8 lbl)
1801{
1802    rc_transaction_t *transaction = get_transaction_by_lbl(lbl);
1803
1804    /* If the transaction is in use... */
1805    if (transaction != NULL)
1806    {
1807        BTIF_TRACE_DEBUG("%s: lbl: %d", __FUNCTION__, lbl);
1808        initialize_transaction(lbl);
1809    }
1810}
1811
1812/*******************************************************************************
1813**
1814** Function         lbl_destroy
1815**
1816** Description    Cleanup of the mutex
1817**
1818** Returns          void
1819*******************************************************************************/
1820void lbl_destroy()
1821{
1822    pthread_mutex_destroy(&(device.lbllock));
1823}
1824
1825/*******************************************************************************
1826**      Function       dev_blacklisted_for_absolute_volume
1827**
1828**      Description    Blacklist Devices that donot handle absolute volume well
1829**                     We are blacklisting all the devices that are not in whitelist
1830**
1831**      Returns        True if the device is in the list
1832*******************************************************************************/
1833static BOOLEAN dev_blacklisted_for_absolute_volume(BD_ADDR peer_dev)
1834{
1835    int i;
1836    char *dev_name_str = NULL;
1837    int whitelist_size = sizeof(rc_white_addr_prefix)/sizeof(rc_white_addr_prefix[0]);
1838
1839    for (i = 0; i < whitelist_size; i++) {
1840        if (rc_white_addr_prefix[i][0] == peer_dev[0] &&
1841            rc_white_addr_prefix[i][1] == peer_dev[1] &&
1842            rc_white_addr_prefix[i][2] == peer_dev[2]) {
1843            BTIF_TRACE_DEBUG("whitelist absolute volume for %02x:%02x:%02x",
1844                              peer_dev[0], peer_dev[1], peer_dev[2]);
1845            return FALSE;
1846        }
1847    }
1848
1849    dev_name_str = BTM_SecReadDevName(peer_dev);
1850    whitelist_size = sizeof(rc_white_name)/sizeof(char*);
1851    if (dev_name_str != NULL) {
1852        for (i = 0; i < whitelist_size; i++) {
1853            if (strcmp(dev_name_str, rc_white_name[i]) == 0) {
1854                BTIF_TRACE_DEBUG("whitelist absolute volume for %s", dev_name_str);
1855                return FALSE;
1856            }
1857        }
1858    }
1859
1860    BTIF_TRACE_WARNING("blacklist absolute volume for %02x:%02x:%02x, name = %s",
1861                        peer_dev[0], peer_dev[1], peer_dev[2], dev_name_str);
1862    return TRUE;
1863}
1864