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