blob: a29a42ceda4df388d8f7c92d9f11fc2e5a669ccd [file] [log] [blame]
The Android Open Source Project5738f832012-12-12 16:00:35 -08001/******************************************************************************
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>
Arman Ugurayd30195c2015-05-29 15:27:58 -070029#include <pthread.h>
Ian Coolidgec7503db2015-01-24 02:01:26 -080030#include <string.h>
Arman Ugurayd30195c2015-05-29 15:27:58 -070031#include <unistd.h>
32
The Android Open Source Project5738f832012-12-12 16:00:35 -080033#include "bta_api.h"
34#include "bta_av_api.h"
35#include "avrc_defs.h"
The Android Open Source Project5738f832012-12-12 16:00:35 -080036#include "gki.h"
37
Chris Mantonf8027002015-03-12 09:22:48 -070038#define LOG_TAG "bt_btif_avrc"
The Android Open Source Project5738f832012-12-12 16:00:35 -080039#include "btif_common.h"
Ravi Nagarajan9adddf42013-03-06 05:29:48 -080040#include "btif_util.h"
41#include "btif_av.h"
42#include "hardware/bt_rc.h"
43#include "uinput.h"
The Android Open Source Project5738f832012-12-12 16:00:35 -080044
45/*****************************************************************************
46** Constants & Macros
47******************************************************************************/
The Android Open Source Project5738f832012-12-12 16:00:35 -080048
49/* cod value for Headsets */
50#define COD_AV_HEADSETS 0x0404
Ravi Nagarajan9adddf42013-03-06 05:29:48 -080051/* for AVRC 1.4 need to change this */
52#define MAX_RC_NOTIFICATIONS AVRC_EVT_APP_SETTING_CHANGE
The Android Open Source Project5738f832012-12-12 16:00:35 -080053
Ravi Nagarajan9adddf42013-03-06 05:29:48 -080054#define IDX_GET_PLAY_STATUS_RSP 0
55#define IDX_LIST_APP_ATTR_RSP 1
56#define IDX_LIST_APP_VALUE_RSP 2
57#define IDX_GET_CURR_APP_VAL_RSP 3
58#define IDX_SET_APP_VAL_RSP 4
59#define IDX_GET_APP_ATTR_TXT_RSP 5
60#define IDX_GET_APP_VAL_TXT_RSP 6
61#define IDX_GET_ELEMENT_ATTR_RSP 7
Satya Calloji247c68f2013-08-01 02:14:43 -070062#define MAX_VOLUME 128
63#define MAX_LABEL 16
64#define MAX_TRANSACTIONS_PER_SESSION 16
Ravi Nagarajan9adddf42013-03-06 05:29:48 -080065#define MAX_CMD_QUEUE_LEN 8
66
67#define CHECK_RC_CONNECTED \
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -070068 BTIF_TRACE_DEBUG("## %s ##", __FUNCTION__); \
Ravi Nagarajan9adddf42013-03-06 05:29:48 -080069 if(btif_rc_cb.rc_connected == FALSE) \
70 { \
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -070071 BTIF_TRACE_WARNING("Function %s() called when RC is not connected", __FUNCTION__); \
Ravi Nagarajan9adddf42013-03-06 05:29:48 -080072 return BT_STATUS_NOT_READY; \
73 }
74
75#define FILL_PDU_QUEUE(index, ctype, label, pending) \
76{ \
77 btif_rc_cb.rc_pdu_info[index].ctype = ctype; \
78 btif_rc_cb.rc_pdu_info[index].label = label; \
79 btif_rc_cb.rc_pdu_info[index].is_rsp_pending = pending; \
80}
81
82#define SEND_METAMSG_RSP(index, avrc_rsp) \
83{ \
84 if(btif_rc_cb.rc_pdu_info[index].is_rsp_pending == FALSE) \
85 { \
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -070086 BTIF_TRACE_WARNING("%s Not sending response as no PDU was registered", __FUNCTION__); \
Ravi Nagarajan9adddf42013-03-06 05:29:48 -080087 return BT_STATUS_UNHANDLED; \
88 } \
89 send_metamsg_rsp(btif_rc_cb.rc_handle, btif_rc_cb.rc_pdu_info[index].label, \
90 btif_rc_cb.rc_pdu_info[index].ctype, avrc_rsp); \
91 btif_rc_cb.rc_pdu_info[index].ctype = 0; \
92 btif_rc_cb.rc_pdu_info[index].label = 0; \
93 btif_rc_cb.rc_pdu_info[index].is_rsp_pending = FALSE; \
94}
The Android Open Source Project5738f832012-12-12 16:00:35 -080095
96/*****************************************************************************
97** Local type definitions
98******************************************************************************/
99typedef struct {
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800100 UINT8 bNotify;
101 UINT8 label;
102} btif_rc_reg_notifications_t;
103
104typedef struct
105{
106 UINT8 label;
107 UINT8 ctype;
108 BOOLEAN is_rsp_pending;
109} btif_rc_cmd_ctxt_t;
110
111/* TODO : Merge btif_rc_reg_notifications_t and btif_rc_cmd_ctxt_t to a single struct */
112typedef struct {
The Android Open Source Project5738f832012-12-12 16:00:35 -0800113 BOOLEAN rc_connected;
114 UINT8 rc_handle;
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800115 tBTA_AV_FEAT rc_features;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800116 BD_ADDR rc_addr;
117 UINT16 rc_pending_play;
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800118 btif_rc_cmd_ctxt_t rc_pdu_info[MAX_CMD_QUEUE_LEN];
119 btif_rc_reg_notifications_t rc_notif[MAX_RC_NOTIFICATIONS];
Satya Calloji247c68f2013-08-01 02:14:43 -0700120 unsigned int rc_volume;
121 uint8_t rc_vol_label;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800122} btif_rc_cb_t;
123
Satya Calloji247c68f2013-08-01 02:14:43 -0700124typedef struct {
125 BOOLEAN in_use;
126 UINT8 lbl;
127 UINT8 handle;
128} rc_transaction_t;
129
130typedef struct
131{
132 pthread_mutex_t lbllock;
133 rc_transaction_t transaction[MAX_TRANSACTIONS_PER_SESSION];
134} rc_device_t;
135
136
137rc_device_t device;
138
The Android Open Source Project5738f832012-12-12 16:00:35 -0800139#define MAX_UINPUT_PATHS 3
140static const char* uinput_dev_path[] =
141 {"/dev/uinput", "/dev/input/uinput", "/dev/misc/uinput" };
142static int uinput_fd = -1;
143
144static int send_event (int fd, uint16_t type, uint16_t code, int32_t value);
145static void send_key (int fd, uint16_t key, int pressed);
146static int uinput_driver_check();
147static int uinput_create(char *name);
148static int init_uinput (void);
149static void close_uinput (void);
Matthew Xiea7ae4a12013-10-24 01:09:52 -0700150static BOOLEAN dev_blacklisted_for_absolute_volume(BD_ADDR peer_dev);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800151
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800152static const struct {
The Android Open Source Project5738f832012-12-12 16:00:35 -0800153 const char *name;
154 uint8_t avrcp;
155 uint16_t mapped_id;
156 uint8_t release_quirk;
157} key_map[] = {
158 { "PLAY", AVRC_ID_PLAY, KEY_PLAYCD, 1 },
159 { "STOP", AVRC_ID_STOP, KEY_STOPCD, 0 },
160 { "PAUSE", AVRC_ID_PAUSE, KEY_PAUSECD, 1 },
161 { "FORWARD", AVRC_ID_FORWARD, KEY_NEXTSONG, 0 },
162 { "BACKWARD", AVRC_ID_BACKWARD, KEY_PREVIOUSSONG, 0 },
163 { "REWIND", AVRC_ID_REWIND, KEY_REWIND, 0 },
John Du98497a52013-06-24 19:18:56 -0700164 { "FAST FORWARD", AVRC_ID_FAST_FOR, KEY_FAST_FORWARD, 0 },
The Android Open Source Project5738f832012-12-12 16:00:35 -0800165 { NULL, 0, 0, 0 }
166};
The Android Open Source Project5738f832012-12-12 16:00:35 -0800167
Matthew Xie7850a932013-11-05 17:19:39 -0800168/* the rc_black_addr_prefix and rc_white_addr_prefix are used to correct
169 * IOP issues of absolute volume feature
170 * We encoutered A2DP headsets/carkits advertising absolute volume but buggy.
171 * We would like to blacklist those devices.
172 * But we donot have a full list of the bad devices. So as a temp fix, we
173 * are blacklisting all the devices except the devices we have well tested,
174 * the ones in the whitelist.
175 *
176 * For now, only the rc_white_addr_prefix is used in the code while
177 * rc_black_addr_prefix is kept here for future long term solution.
178 */
Matthew Xie7850a932013-11-05 17:19:39 -0800179static const UINT8 rc_white_addr_prefix[][3] = {
180 {0x94, 0xCE, 0x2C}, // Sony SBH50
Thomas.TT_Linc9fbcde2014-04-07 16:13:06 +0800181 {0x30, 0x17, 0xC8} // Sony wm600
182};
183
184static const char* rc_white_name[] = {
185 "SBH50",
186 "MW600"
Matthew Xie7850a932013-11-05 17:19:39 -0800187};
188
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800189static void send_reject_response (UINT8 rc_handle, UINT8 label,
190 UINT8 pdu, UINT8 status);
191static UINT8 opcode_from_pdu(UINT8 pdu);
192static void send_metamsg_rsp (UINT8 rc_handle, UINT8 label,
193 tBTA_AV_CODE code, tAVRC_RESPONSE *pmetamsg_resp);
Satya Calloji247c68f2013-08-01 02:14:43 -0700194static void register_volumechange(UINT8 label);
195static void lbl_init();
196static void lbl_destroy();
197static void init_all_transactions();
198static bt_status_t get_transaction(rc_transaction_t **ptransaction);
199static void release_transaction(UINT8 label);
200static rc_transaction_t* get_transaction_by_lbl(UINT8 label);
201static void handle_rc_metamsg_rsp(tBTA_AV_META_MSG *pmeta_msg);
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800202static void btif_rc_upstreams_evt(UINT16 event, tAVRC_COMMAND* p_param, UINT8 ctype, UINT8 label);
Satya Calloji247c68f2013-08-01 02:14:43 -0700203static void btif_rc_upstreams_rsp_evt(UINT16 event, tAVRC_RESPONSE *pavrc_resp, UINT8 ctype, UINT8 label);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800204
205/*****************************************************************************
206** Static variables
207******************************************************************************/
208static btif_rc_cb_t btif_rc_cb;
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800209static btrc_callbacks_t *bt_rc_callbacks = NULL;
Mike Lockwood4ad470e2014-06-02 16:21:49 -0700210static btrc_ctrl_callbacks_t *bt_rc_ctrl_callbacks = NULL;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800211
212/*****************************************************************************
213** Static functions
214******************************************************************************/
215
216/*****************************************************************************
217** Externs
218******************************************************************************/
219extern BOOLEAN btif_hf_call_terminated_recently();
220extern BOOLEAN check_cod(const bt_bdaddr_t *remote_bdaddr, uint32_t cod);
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800221
The Android Open Source Project5738f832012-12-12 16:00:35 -0800222
223/*****************************************************************************
224** Functions
225******************************************************************************/
226
The Android Open Source Project5738f832012-12-12 16:00:35 -0800227/*****************************************************************************
228** Local uinput helper functions
229******************************************************************************/
230int send_event (int fd, uint16_t type, uint16_t code, int32_t value)
231{
232 struct uinput_event event;
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700233 BTIF_TRACE_DEBUG("%s type:%u code:%u value:%d", __FUNCTION__,
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800234 type, code, value);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800235 memset(&event, 0, sizeof(event));
236 event.type = type;
237 event.code = code;
238 event.value = value;
239
240 return write(fd, &event, sizeof(event));
241}
242
243void send_key (int fd, uint16_t key, int pressed)
244{
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700245 BTIF_TRACE_DEBUG("%s fd:%d key:%u pressed:%d", __FUNCTION__,
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800246 fd, key, pressed);
247
248 if (fd < 0)
249 {
The Android Open Source Project5738f832012-12-12 16:00:35 -0800250 return;
251 }
252
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700253 BTIF_TRACE_DEBUG("AVRCP: Send key %d (%d) fd=%d", key, pressed, fd);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800254 send_event(fd, EV_KEY, key, pressed);
255 send_event(fd, EV_SYN, SYN_REPORT, 0);
256}
257
258/************** uinput related functions **************/
259int uinput_driver_check()
260{
261 uint32_t i;
262 for (i=0; i < MAX_UINPUT_PATHS; i++)
263 {
264 if (access(uinput_dev_path[i], O_RDWR) == 0) {
265 return 0;
266 }
267 }
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700268 BTIF_TRACE_ERROR("%s ERROR: uinput device is not in the system", __FUNCTION__);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800269 return -1;
270}
271
272int uinput_create(char *name)
273{
274 struct uinput_dev dev;
Bernhard Rosenkränzer104e3f22014-11-12 21:53:08 +0100275 int fd, x = 0;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800276
277 for(x=0; x < MAX_UINPUT_PATHS; x++)
278 {
279 fd = open(uinput_dev_path[x], O_RDWR);
280 if (fd < 0)
281 continue;
282 break;
283 }
284 if (x == MAX_UINPUT_PATHS) {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700285 BTIF_TRACE_ERROR("%s ERROR: uinput device open failed", __FUNCTION__);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800286 return -1;
287 }
288 memset(&dev, 0, sizeof(dev));
289 if (name)
VenkatRaghavan VijayaRaghavan4540f592015-02-05 04:40:47 -0800290 strncpy(dev.name, name, UINPUT_MAX_NAME_SIZE-1);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800291
292 dev.id.bustype = BUS_BLUETOOTH;
293 dev.id.vendor = 0x0000;
294 dev.id.product = 0x0000;
295 dev.id.version = 0x0000;
296
297 if (write(fd, &dev, sizeof(dev)) < 0) {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700298 BTIF_TRACE_ERROR("%s Unable to write device information", __FUNCTION__);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800299 close(fd);
300 return -1;
301 }
302
303 ioctl(fd, UI_SET_EVBIT, EV_KEY);
304 ioctl(fd, UI_SET_EVBIT, EV_REL);
305 ioctl(fd, UI_SET_EVBIT, EV_SYN);
306
307 for (x = 0; key_map[x].name != NULL; x++)
308 ioctl(fd, UI_SET_KEYBIT, key_map[x].mapped_id);
309
310 for(x = 0; x < KEY_MAX; x++)
311 ioctl(fd, UI_SET_KEYBIT, x);
312
313 if (ioctl(fd, UI_DEV_CREATE, NULL) < 0) {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700314 BTIF_TRACE_ERROR("%s Unable to create uinput device", __FUNCTION__);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800315 close(fd);
316 return -1;
317 }
318 return fd;
319}
320
321int init_uinput (void)
322{
323 char *name = "AVRCP";
324
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700325 BTIF_TRACE_DEBUG("%s", __FUNCTION__);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800326 uinput_fd = uinput_create(name);
327 if (uinput_fd < 0) {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700328 BTIF_TRACE_ERROR("%s AVRCP: Failed to initialize uinput for %s (%d)",
The Android Open Source Project5738f832012-12-12 16:00:35 -0800329 __FUNCTION__, name, uinput_fd);
330 } else {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700331 BTIF_TRACE_DEBUG("%s AVRCP: Initialized uinput for %s (fd=%d)",
The Android Open Source Project5738f832012-12-12 16:00:35 -0800332 __FUNCTION__, name, uinput_fd);
333 }
334 return uinput_fd;
335}
336
337void close_uinput (void)
338{
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700339 BTIF_TRACE_DEBUG("%s", __FUNCTION__);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800340 if (uinput_fd > 0) {
341 ioctl(uinput_fd, UI_DEV_DESTROY);
342
343 close(uinput_fd);
344 uinput_fd = -1;
345 }
346}
The Android Open Source Project5738f832012-12-12 16:00:35 -0800347
Satya Calloji247c68f2013-08-01 02:14:43 -0700348void handle_rc_features()
349{
350 btrc_remote_features_t rc_features = BTRC_FEAT_NONE;
351 bt_bdaddr_t rc_addr;
352 bdcpy(rc_addr.address, btif_rc_cb.rc_addr);
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800353
Matthew Xiea7ae4a12013-10-24 01:09:52 -0700354 if (dev_blacklisted_for_absolute_volume(btif_rc_cb.rc_addr))
355 {
356 btif_rc_cb.rc_features &= ~BTA_AV_FEAT_ADV_CTRL;
357 }
358
Satya Calloji247c68f2013-08-01 02:14:43 -0700359 if (btif_rc_cb.rc_features & BTA_AV_FEAT_BROWSE)
360 {
361 rc_features |= BTRC_FEAT_BROWSE;
362 }
363 if ( (btif_rc_cb.rc_features & BTA_AV_FEAT_ADV_CTRL) &&
364 (btif_rc_cb.rc_features & BTA_AV_FEAT_RCTG))
365 {
366 rc_features |= BTRC_FEAT_ABSOLUTE_VOLUME;
367 }
368 if (btif_rc_cb.rc_features & BTA_AV_FEAT_METADATA)
369 {
370 rc_features |= BTRC_FEAT_METADATA;
371 }
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700372 BTIF_TRACE_DEBUG("%s: rc_features=0x%x", __FUNCTION__, rc_features);
Satya Calloji247c68f2013-08-01 02:14:43 -0700373 HAL_CBACK(bt_rc_callbacks, remote_features_cb, &rc_addr, rc_features)
374
375#if (AVRC_ADV_CTRL_INCLUDED == TRUE)
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700376 BTIF_TRACE_DEBUG("Checking for feature flags in btif_rc_handler with label %d",
Satya Calloji247c68f2013-08-01 02:14:43 -0700377 btif_rc_cb.rc_vol_label);
378 // Register for volume change on connect
379 if(btif_rc_cb.rc_features & BTA_AV_FEAT_ADV_CTRL &&
380 btif_rc_cb.rc_features & BTA_AV_FEAT_RCTG)
381 {
382 rc_transaction_t *p_transaction=NULL;
383 bt_status_t status = BT_STATUS_NOT_READY;
384 if(MAX_LABEL==btif_rc_cb.rc_vol_label)
385 {
386 status=get_transaction(&p_transaction);
387 }
388 else
389 {
390 p_transaction=get_transaction_by_lbl(btif_rc_cb.rc_vol_label);
391 if(NULL!=p_transaction)
392 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700393 BTIF_TRACE_DEBUG("register_volumechange already in progress for label %d",
Satya Calloji247c68f2013-08-01 02:14:43 -0700394 btif_rc_cb.rc_vol_label);
395 return;
396 }
397 else
398 status=get_transaction(&p_transaction);
399 }
400
401 if(BT_STATUS_SUCCESS == status && NULL!=p_transaction)
402 {
403 btif_rc_cb.rc_vol_label=p_transaction->lbl;
404 register_volumechange(btif_rc_cb.rc_vol_label);
405 }
406 }
407#endif
408}
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800409
The Android Open Source Project5738f832012-12-12 16:00:35 -0800410
411/***************************************************************************
412 * Function handle_rc_connect
413 *
John Du98497a52013-06-24 19:18:56 -0700414 * - Argument: tBTA_AV_RC_OPEN RC open data structure
The Android Open Source Project5738f832012-12-12 16:00:35 -0800415 *
416 * - Description: RC connection event handler
417 *
418 ***************************************************************************/
419void handle_rc_connect (tBTA_AV_RC_OPEN *p_rc_open)
420{
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700421 BTIF_TRACE_DEBUG("%s: rc_handle: %d", __FUNCTION__, p_rc_open->rc_handle);
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800422 bt_status_t result = BT_STATUS_SUCCESS;
Mike Lockwood93912472014-06-26 11:08:24 -0700423#if (AVRC_CTLR_INCLUDED == TRUE)
424 bt_bdaddr_t rc_addr;
425#endif
The Android Open Source Project5738f832012-12-12 16:00:35 -0800426
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800427 if(p_rc_open->status == BTA_AV_SUCCESS)
428 {
429 memcpy(btif_rc_cb.rc_addr, p_rc_open->peer_addr, sizeof(BD_ADDR));
430 btif_rc_cb.rc_features = p_rc_open->peer_features;
Satya Calloji247c68f2013-08-01 02:14:43 -0700431 btif_rc_cb.rc_vol_label=MAX_LABEL;
432 btif_rc_cb.rc_volume=MAX_VOLUME;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800433
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800434 btif_rc_cb.rc_connected = TRUE;
435 btif_rc_cb.rc_handle = p_rc_open->rc_handle;
436
Satya Calloji247c68f2013-08-01 02:14:43 -0700437 /* on locally initiated connection we will get remote features as part of connect */
438 if (btif_rc_cb.rc_features != 0)
439 handle_rc_features();
440
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800441 result = uinput_driver_check();
442 if(result == BT_STATUS_SUCCESS)
443 {
444 init_uinput();
445 }
Mike Lockwood4ad470e2014-06-02 16:21:49 -0700446#if (AVRC_CTLR_INCLUDED == TRUE)
447 bdcpy(rc_addr.address, btif_rc_cb.rc_addr);
448 /* report connection state if device is AVRCP target */
449 if (btif_rc_cb.rc_features & BTA_AV_FEAT_RCTG) {
450 HAL_CBACK(bt_rc_ctrl_callbacks, connection_state_cb, TRUE, &rc_addr);
451 }
452#endif
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800453 }
454 else
455 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700456 BTIF_TRACE_ERROR("%s Connect failed with error code: %d",
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800457 __FUNCTION__, p_rc_open->status);
458 btif_rc_cb.rc_connected = FALSE;
459 }
The Android Open Source Project5738f832012-12-12 16:00:35 -0800460}
461
462/***************************************************************************
463 * Function handle_rc_disconnect
464 *
John Du98497a52013-06-24 19:18:56 -0700465 * - Argument: tBTA_AV_RC_CLOSE RC close data structure
The Android Open Source Project5738f832012-12-12 16:00:35 -0800466 *
467 * - Description: RC disconnection event handler
468 *
469 ***************************************************************************/
470void handle_rc_disconnect (tBTA_AV_RC_CLOSE *p_rc_close)
471{
Mike Lockwood4ad470e2014-06-02 16:21:49 -0700472#if (AVRC_CTLR_INCLUDED == TRUE)
473 bt_bdaddr_t rc_addr;
474 tBTA_AV_FEAT features;
475#endif
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700476 BTIF_TRACE_DEBUG("%s: rc_handle: %d", __FUNCTION__, p_rc_close->rc_handle);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800477
478 btif_rc_cb.rc_handle = 0;
479 btif_rc_cb.rc_connected = FALSE;
480 memset(btif_rc_cb.rc_addr, 0, sizeof(BD_ADDR));
Nitin Srivastava68c53de2014-02-13 19:31:40 +0530481 memset(btif_rc_cb.rc_notif, 0, sizeof(btif_rc_cb.rc_notif));
Mike Lockwood4ad470e2014-06-02 16:21:49 -0700482#if (AVRC_CTLR_INCLUDED == TRUE)
483 features = btif_rc_cb.rc_features;
484#endif
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800485 btif_rc_cb.rc_features = 0;
Satya Calloji247c68f2013-08-01 02:14:43 -0700486 btif_rc_cb.rc_vol_label=MAX_LABEL;
487 btif_rc_cb.rc_volume=MAX_VOLUME;
488 init_all_transactions();
The Android Open Source Project5738f832012-12-12 16:00:35 -0800489 close_uinput();
Mike Lockwood4ad470e2014-06-02 16:21:49 -0700490#if (AVRC_CTLR_INCLUDED == TRUE)
491 bdcpy(rc_addr.address, btif_rc_cb.rc_addr);
492#endif
493 memset(btif_rc_cb.rc_addr, 0, sizeof(BD_ADDR));
494#if (AVRC_CTLR_INCLUDED == TRUE)
495 /* report connection state if device is AVRCP target */
496 if (features & BTA_AV_FEAT_RCTG) {
497 HAL_CBACK(bt_rc_ctrl_callbacks, connection_state_cb, FALSE, &rc_addr);
498 }
499#endif
The Android Open Source Project5738f832012-12-12 16:00:35 -0800500}
501
502/***************************************************************************
503 * Function handle_rc_passthrough_cmd
504 *
505 * - Argument: tBTA_AV_RC rc_id remote control command ID
506 * tBTA_AV_STATE key_state status of key press
507 *
508 * - Description: Remote control command handler
509 *
510 ***************************************************************************/
511void handle_rc_passthrough_cmd ( tBTA_AV_REMOTE_CMD *p_remote_cmd)
512{
513 const char *status;
514 int pressed, i;
515
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700516 BTIF_TRACE_DEBUG("%s: p_remote_cmd->rc_id=%d", __FUNCTION__, p_remote_cmd->rc_id);
John Du98497a52013-06-24 19:18:56 -0700517
The Android Open Source Project5738f832012-12-12 16:00:35 -0800518 /* If AVRC is open and peer sends PLAY but there is no AVDT, then we queue-up this PLAY */
519 if (p_remote_cmd)
520 {
521 /* queue AVRC PLAY if GAVDTP Open notification to app is pending (2 second timer) */
522 if ((p_remote_cmd->rc_id == BTA_AV_RC_PLAY) && (!btif_av_is_connected()))
523 {
524 if (p_remote_cmd->key_state == AVRC_STATE_PRESS)
525 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700526 APPL_TRACE_WARNING("%s: AVDT not open, queuing the PLAY command", __FUNCTION__);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800527 btif_rc_cb.rc_pending_play = TRUE;
528 }
529 return;
530 }
531
532 if ((p_remote_cmd->rc_id == BTA_AV_RC_PAUSE) && (btif_rc_cb.rc_pending_play))
533 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700534 APPL_TRACE_WARNING("%s: Clear the pending PLAY on PAUSE received", __FUNCTION__);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800535 btif_rc_cb.rc_pending_play = FALSE;
536 return;
537 }
538 }
539 if (p_remote_cmd->key_state == AVRC_STATE_RELEASE) {
540 status = "released";
541 pressed = 0;
542 } else {
543 status = "pressed";
544 pressed = 1;
545 }
546
547 /* If this is Play/Pause command (press or release) before processing, check the following
548 * a voice call has ended recently
549 * the remote device is not of type headset
550 * If the above conditions meet, drop the Play/Pause command
551 * This fix is to interop with certain carkits which sends an automatic PLAY or PAUSE
552 * commands right after call ends
553 */
554 if((p_remote_cmd->rc_id == BTA_AV_RC_PLAY || p_remote_cmd->rc_id == BTA_AV_RC_PAUSE)&&
555 (btif_hf_call_terminated_recently() == TRUE) &&
556 (check_cod( (const bt_bdaddr_t*)&(btif_rc_cb.rc_addr), COD_AV_HEADSETS) != TRUE))
557 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700558 BTIF_TRACE_DEBUG("%s:Dropping the play/Pause command received right after call end cmd:%d",
The Android Open Source Project5738f832012-12-12 16:00:35 -0800559 __FUNCTION__,p_remote_cmd->rc_id);
560 return;
561 }
562
John Du98497a52013-06-24 19:18:56 -0700563 if (p_remote_cmd->rc_id == BTA_AV_RC_FAST_FOR || p_remote_cmd->rc_id == BTA_AV_RC_REWIND) {
564 HAL_CBACK(bt_rc_callbacks, passthrough_cmd_cb, p_remote_cmd->rc_id, pressed);
565 return;
566 }
567
The Android Open Source Project5738f832012-12-12 16:00:35 -0800568 for (i = 0; key_map[i].name != NULL; i++) {
569 if (p_remote_cmd->rc_id == key_map[i].avrcp) {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700570 BTIF_TRACE_DEBUG("%s: %s %s", __FUNCTION__, key_map[i].name, status);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800571
572 /* MusicPlayer uses a long_press_timeout of 1 second for PLAYPAUSE button
573 * and maps that to autoshuffle. So if for some reason release for PLAY/PAUSE
574 * comes 1 second after the press, the MediaPlayer UI goes into a bad state.
575 * The reason for the delay could be sniff mode exit or some AVDTP procedure etc.
576 * The fix is to generate a release right after the press and drown the 'actual'
577 * release.
578 */
579 if ((key_map[i].release_quirk == 1) && (pressed == 0))
580 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700581 BTIF_TRACE_DEBUG("%s: AVRC %s Release Faked earlier, drowned now",
The Android Open Source Project5738f832012-12-12 16:00:35 -0800582 __FUNCTION__, key_map[i].name);
583 return;
584 }
The Android Open Source Project5738f832012-12-12 16:00:35 -0800585 send_key(uinput_fd, key_map[i].mapped_id, pressed);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800586 if ((key_map[i].release_quirk == 1) && (pressed == 1))
587 {
588 GKI_delay(30); // 30ms
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700589 BTIF_TRACE_DEBUG("%s: AVRC %s Release quirk enabled, send release now",
The Android Open Source Project5738f832012-12-12 16:00:35 -0800590 __FUNCTION__, key_map[i].name);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800591 send_key(uinput_fd, key_map[i].mapped_id, 0);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800592 }
593 break;
594 }
595 }
596
597 if (key_map[i].name == NULL)
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700598 BTIF_TRACE_ERROR("%s AVRCP: unknown button 0x%02X %s", __FUNCTION__,
The Android Open Source Project5738f832012-12-12 16:00:35 -0800599 p_remote_cmd->rc_id, status);
600}
601
Mike Lockwood4ad470e2014-06-02 16:21:49 -0700602/***************************************************************************
603 * Function handle_rc_passthrough_rsp
604 *
605 * - Argument: tBTA_AV_REMOTE_RSP passthrough command response
606 *
607 * - Description: Remote control passthrough response handler
608 *
609 ***************************************************************************/
610void handle_rc_passthrough_rsp ( tBTA_AV_REMOTE_RSP *p_remote_rsp)
611{
612#if (AVRC_CTLR_INCLUDED == TRUE)
613 const char *status;
614 if (btif_rc_cb.rc_features & BTA_AV_FEAT_RCTG)
615 {
616 int key_state;
617 if (p_remote_rsp->key_state == AVRC_STATE_RELEASE)
618 {
619 status = "released";
620 key_state = 1;
621 }
622 else
623 {
624 status = "pressed";
625 key_state = 0;
626 }
627
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700628 BTIF_TRACE_DEBUG("%s: rc_id=%d status=%s", __FUNCTION__, p_remote_rsp->rc_id, status);
Mike Lockwood4ad470e2014-06-02 16:21:49 -0700629
630 release_transaction(p_remote_rsp->label);
631 HAL_CBACK(bt_rc_ctrl_callbacks, passthrough_rsp_cb, p_remote_rsp->rc_id, key_state);
632 }
633 else
634 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700635 BTIF_TRACE_ERROR("%s DUT does not support AVRCP controller role", __FUNCTION__);
Mike Lockwood4ad470e2014-06-02 16:21:49 -0700636 }
637#else
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700638 BTIF_TRACE_ERROR("%s AVRCP controller role is not enabled", __FUNCTION__);
Mike Lockwood4ad470e2014-06-02 16:21:49 -0700639#endif
640}
641
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800642void handle_uid_changed_notification(tBTA_AV_META_MSG *pmeta_msg, tAVRC_COMMAND *pavrc_command)
The Android Open Source Project5738f832012-12-12 16:00:35 -0800643{
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800644 tAVRC_RESPONSE avrc_rsp = {0};
645 avrc_rsp.rsp.pdu = pavrc_command->pdu;
646 avrc_rsp.rsp.status = AVRC_STS_NO_ERROR;
647 avrc_rsp.rsp.opcode = pavrc_command->cmd.opcode;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800648
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800649 avrc_rsp.reg_notif.event_id = pavrc_command->reg_notif.event_id;
650 avrc_rsp.reg_notif.param.uid_counter = 0;
651
652 send_metamsg_rsp(pmeta_msg->rc_handle, pmeta_msg->label, AVRC_RSP_INTERIM, &avrc_rsp);
653 send_metamsg_rsp(pmeta_msg->rc_handle, pmeta_msg->label, AVRC_RSP_CHANGED, &avrc_rsp);
654
655}
656
657
658/***************************************************************************
659 * Function handle_rc_metamsg_cmd
660 *
661 * - Argument: tBTA_AV_VENDOR Structure containing the received
662 * metamsg command
663 *
664 * - Description: Remote control metamsg command handler (AVRCP 1.3)
665 *
666 ***************************************************************************/
667void handle_rc_metamsg_cmd (tBTA_AV_META_MSG *pmeta_msg)
668{
669 /* Parse the metamsg command and pass it on to BTL-IFS */
670 UINT8 scratch_buf[512] = {0};
671 tAVRC_COMMAND avrc_command = {0};
672 tAVRC_STS status;
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800673
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700674 BTIF_TRACE_EVENT("+ %s", __FUNCTION__);
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800675
676 if (pmeta_msg->p_msg->hdr.opcode != AVRC_OP_VENDOR)
677 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700678 BTIF_TRACE_WARNING("Invalid opcode: %x", pmeta_msg->p_msg->hdr.opcode);
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800679 return;
680 }
681 if (pmeta_msg->len < 3)
682 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700683 BTIF_TRACE_WARNING("Invalid length.Opcode: 0x%x, len: 0x%x", pmeta_msg->p_msg->hdr.opcode,
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800684 pmeta_msg->len);
685 return;
686 }
687
688 if (pmeta_msg->code >= AVRC_RSP_NOT_IMPL)
689 {
Satya Calloji247c68f2013-08-01 02:14:43 -0700690#if (AVRC_ADV_CTRL_INCLUDED == TRUE)
691{
692 rc_transaction_t *transaction=NULL;
693 transaction=get_transaction_by_lbl(pmeta_msg->label);
694 if(NULL!=transaction)
695 {
696 handle_rc_metamsg_rsp(pmeta_msg);
697 }
698 else
699 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700700 BTIF_TRACE_DEBUG("%s:Discard vendor dependent rsp. code: %d label:%d.",
Satya Calloji247c68f2013-08-01 02:14:43 -0700701 __FUNCTION__, pmeta_msg->code, pmeta_msg->label);
702 }
703 return;
704}
705#else
706{
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700707 BTIF_TRACE_DEBUG("%s:Received vendor dependent rsp. code: %d len: %d. Not processing it.",
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800708 __FUNCTION__, pmeta_msg->code, pmeta_msg->len);
709 return;
Satya Calloji247c68f2013-08-01 02:14:43 -0700710}
711#endif
712 }
713
714 status=AVRC_ParsCommand(pmeta_msg->p_msg, &avrc_command, scratch_buf, sizeof(scratch_buf));
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700715 BTIF_TRACE_DEBUG("Received vendor command.code,PDU and label: %d, %d,%d",pmeta_msg->code,
Satya Calloji247c68f2013-08-01 02:14:43 -0700716 avrc_command.cmd.pdu, pmeta_msg->label);
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800717
718 if (status != AVRC_STS_NO_ERROR)
719 {
720 /* return error */
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700721 BTIF_TRACE_WARNING("%s: Error in parsing received metamsg command. status: 0x%02x",
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800722 __FUNCTION__, status);
723 send_reject_response(pmeta_msg->rc_handle, pmeta_msg->label, avrc_command.pdu, status);
724 }
725 else
726 {
727 /* if RegisterNotification, add it to our registered queue */
728
729 if (avrc_command.cmd.pdu == AVRC_PDU_REGISTER_NOTIFICATION)
730 {
731 UINT8 event_id = avrc_command.reg_notif.event_id;
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700732 BTIF_TRACE_EVENT("%s:New register notification received.event_id:%s,label:0x%x,code:%x",
Satya Calloji247c68f2013-08-01 02:14:43 -0700733 __FUNCTION__,dump_rc_notification_event_id(event_id), pmeta_msg->label,pmeta_msg->code);
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800734 btif_rc_cb.rc_notif[event_id-1].bNotify = TRUE;
735 btif_rc_cb.rc_notif[event_id-1].label = pmeta_msg->label;
736
737 if(event_id == AVRC_EVT_UIDS_CHANGE)
738 {
739 handle_uid_changed_notification(pmeta_msg, &avrc_command);
740 return;
741 }
742
743 }
744
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700745 BTIF_TRACE_EVENT("%s: Passing received metamsg command to app. pdu: %s",
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800746 __FUNCTION__, dump_rc_pdu(avrc_command.cmd.pdu));
747
748 /* Since handle_rc_metamsg_cmd() itself is called from
749 *btif context, no context switching is required. Invoke
750 * btif_rc_upstreams_evt directly from here. */
751 btif_rc_upstreams_evt((uint16_t)avrc_command.cmd.pdu, &avrc_command, pmeta_msg->code,
Satya Calloji247c68f2013-08-01 02:14:43 -0700752 pmeta_msg->label);
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800753 }
The Android Open Source Project5738f832012-12-12 16:00:35 -0800754}
755
756/***************************************************************************
757 **
758 ** Function btif_rc_handler
759 **
760 ** Description RC event handler
761 **
762 ***************************************************************************/
763void btif_rc_handler(tBTA_AV_EVT event, tBTA_AV *p_data)
764{
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700765 BTIF_TRACE_DEBUG ("%s event:%s", __FUNCTION__, dump_rc_event(event));
The Android Open Source Project5738f832012-12-12 16:00:35 -0800766 switch (event)
767 {
768 case BTA_AV_RC_OPEN_EVT:
769 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700770 BTIF_TRACE_DEBUG("Peer_features:%x", p_data->rc_open.peer_features);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800771 handle_rc_connect( &(p_data->rc_open) );
772 }break;
773
774 case BTA_AV_RC_CLOSE_EVT:
775 {
776 handle_rc_disconnect( &(p_data->rc_close) );
777 }break;
778
779 case BTA_AV_REMOTE_CMD_EVT:
780 {
Matthew Xieafa6e1a2014-06-28 11:35:29 -0700781 BTIF_TRACE_DEBUG("rc_id:0x%x key_state:%d", p_data->remote_cmd.rc_id,
The Android Open Source Project5738f832012-12-12 16:00:35 -0800782 p_data->remote_cmd.key_state);
783 handle_rc_passthrough_cmd( (&p_data->remote_cmd) );
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800784 }
785 break;
Mike Lockwood93912472014-06-26 11:08:24 -0700786#if (AVRC_CTLR_INCLUDED == TRUE)
787 case BTA_AV_REMOTE_RSP_EVT:
788 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700789 BTIF_TRACE_DEBUG("RSP: rc_id:0x%x key_state:%d", p_data->remote_rsp.rc_id,
Mike Lockwood93912472014-06-26 11:08:24 -0700790 p_data->remote_rsp.key_state);
791 handle_rc_passthrough_rsp( (&p_data->remote_rsp) );
792 }
793 break;
794#endif
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800795 case BTA_AV_RC_FEAT_EVT:
796 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700797 BTIF_TRACE_DEBUG("Peer_features:%x", p_data->rc_feat.peer_features);
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800798 btif_rc_cb.rc_features = p_data->rc_feat.peer_features;
Satya Calloji247c68f2013-08-01 02:14:43 -0700799 handle_rc_features();
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800800 }
801 break;
802 case BTA_AV_META_MSG_EVT:
803 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700804 BTIF_TRACE_DEBUG("BTA_AV_META_MSG_EVT code:%d label:%d", p_data->meta_msg.code,
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800805 p_data->meta_msg.label);
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700806 BTIF_TRACE_DEBUG(" company_id:0x%x len:%d handle:%d", p_data->meta_msg.company_id,
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800807 p_data->meta_msg.len, p_data->meta_msg.rc_handle);
808 /* handle the metamsg command */
809 handle_rc_metamsg_cmd(&(p_data->meta_msg));
810 }
811 break;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800812 default:
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700813 BTIF_TRACE_DEBUG("Unhandled RC event : 0x%x", event);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800814 }
815}
816
817/***************************************************************************
818 **
819 ** Function btif_rc_get_connected_peer
820 **
821 ** Description Fetches the connected headset's BD_ADDR if any
822 **
823 ***************************************************************************/
824BOOLEAN btif_rc_get_connected_peer(BD_ADDR peer_addr)
825{
826 if (btif_rc_cb.rc_connected == TRUE) {
827 bdcpy(peer_addr, btif_rc_cb.rc_addr);
828 return TRUE;
829 }
830 return FALSE;
831}
832
833/***************************************************************************
834 **
835 ** Function btif_rc_check_handle_pending_play
836 **
837 ** Description Clears the queued PLAY command. if bSend is TRUE, forwards to app
838 **
839 ***************************************************************************/
840
841/* clear the queued PLAY command. if bSend is TRUE, forward to app */
842void btif_rc_check_handle_pending_play (BD_ADDR peer_addr, BOOLEAN bSendToApp)
843{
Mike J. Chen5cd8bff2014-01-31 18:16:59 -0800844 UNUSED(peer_addr);
845
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700846 BTIF_TRACE_DEBUG("%s: bSendToApp=%d", __FUNCTION__, bSendToApp);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800847 if (btif_rc_cb.rc_pending_play)
848 {
849 if (bSendToApp)
850 {
851 tBTA_AV_REMOTE_CMD remote_cmd;
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700852 APPL_TRACE_DEBUG("%s: Sending queued PLAYED event to app", __FUNCTION__);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800853
854 memset (&remote_cmd, 0, sizeof(tBTA_AV_REMOTE_CMD));
855 remote_cmd.rc_handle = btif_rc_cb.rc_handle;
856 remote_cmd.rc_id = AVRC_ID_PLAY;
857 remote_cmd.hdr.ctype = AVRC_CMD_CTRL;
858 remote_cmd.hdr.opcode = AVRC_OP_PASS_THRU;
859
860 /* delay sending to app, else there is a timing issue in the framework,
861 ** which causes the audio to be on th device's speaker. Delay between
862 ** OPEN & RC_PLAYs
863 */
864 GKI_delay (200);
865 /* send to app - both PRESSED & RELEASED */
866 remote_cmd.key_state = AVRC_STATE_PRESS;
867 handle_rc_passthrough_cmd( &remote_cmd );
868
869 GKI_delay (100);
870
871 remote_cmd.key_state = AVRC_STATE_RELEASE;
872 handle_rc_passthrough_cmd( &remote_cmd );
873 }
874 btif_rc_cb.rc_pending_play = FALSE;
875 }
876}
877
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800878/* Generic reject response */
879static void send_reject_response (UINT8 rc_handle, UINT8 label, UINT8 pdu, UINT8 status)
880{
881 UINT8 ctype = AVRC_RSP_REJ;
882 tAVRC_RESPONSE avrc_rsp;
883 BT_HDR *p_msg = NULL;
884 memset (&avrc_rsp, 0, sizeof(tAVRC_RESPONSE));
885
886 avrc_rsp.rsp.opcode = opcode_from_pdu(pdu);
887 avrc_rsp.rsp.pdu = pdu;
888 avrc_rsp.rsp.status = status;
889
890 if (AVRC_STS_NO_ERROR == (status = AVRC_BldResponse(rc_handle, &avrc_rsp, &p_msg)) )
891 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700892 BTIF_TRACE_DEBUG("%s:Sending error notification to handle:%d. pdu:%s,status:0x%02x",
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800893 __FUNCTION__, rc_handle, dump_rc_pdu(pdu), status);
894 BTA_AvMetaRsp(rc_handle, label, ctype, p_msg);
895 }
896}
897
898/***************************************************************************
899 * Function send_metamsg_rsp
900 *
901 * - Argument:
902 * rc_handle RC handle corresponding to the connected RC
903 * label Label of the RC response
904 * code Response type
905 * pmetamsg_resp Vendor response
906 *
907 * - Description: Remote control metamsg response handler (AVRCP 1.3)
908 *
909 ***************************************************************************/
910static void send_metamsg_rsp (UINT8 rc_handle, UINT8 label, tBTA_AV_CODE code,
911 tAVRC_RESPONSE *pmetamsg_resp)
912{
913 UINT8 ctype;
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800914
915 if (!pmetamsg_resp)
916 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700917 BTIF_TRACE_WARNING("%s: Invalid response received from application", __FUNCTION__);
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800918 return;
919 }
920
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700921 BTIF_TRACE_EVENT("+%s: rc_handle: %d, label: %d, code: 0x%02x, pdu: %s", __FUNCTION__,
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800922 rc_handle, label, code, dump_rc_pdu(pmetamsg_resp->rsp.pdu));
923
924 if (pmetamsg_resp->rsp.status != AVRC_STS_NO_ERROR)
925 {
926 ctype = AVRC_RSP_REJ;
927 }
928 else
929 {
930 if ( code < AVRC_RSP_NOT_IMPL)
931 {
932 if (code == AVRC_CMD_NOTIF)
933 {
934 ctype = AVRC_RSP_INTERIM;
935 }
936 else if (code == AVRC_CMD_STATUS)
937 {
938 ctype = AVRC_RSP_IMPL_STBL;
939 }
940 else
941 {
942 ctype = AVRC_RSP_ACCEPT;
943 }
944 }
945 else
946 {
947 ctype = code;
948 }
949 }
950 /* if response is for register_notification, make sure the rc has
951 actually registered for this */
952 if((pmetamsg_resp->rsp.pdu == AVRC_PDU_REGISTER_NOTIFICATION) && (code == AVRC_RSP_CHANGED))
953 {
954 BOOLEAN bSent = FALSE;
955 UINT8 event_id = pmetamsg_resp->reg_notif.event_id;
956 BOOLEAN bNotify = (btif_rc_cb.rc_connected) && (btif_rc_cb.rc_notif[event_id-1].bNotify);
957
958 /* de-register this notification for a CHANGED response */
959 btif_rc_cb.rc_notif[event_id-1].bNotify = FALSE;
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700960 BTIF_TRACE_DEBUG("%s rc_handle: %d. event_id: 0x%02d bNotify:%u", __FUNCTION__,
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800961 btif_rc_cb.rc_handle, event_id, bNotify);
962 if (bNotify)
963 {
964 BT_HDR *p_msg = NULL;
965 tAVRC_STS status;
966
967 if (AVRC_STS_NO_ERROR == (status = AVRC_BldResponse(btif_rc_cb.rc_handle,
968 pmetamsg_resp, &p_msg)) )
969 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700970 BTIF_TRACE_DEBUG("%s Sending notification to rc_handle: %d. event_id: 0x%02d",
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800971 __FUNCTION__, btif_rc_cb.rc_handle, event_id);
972 bSent = TRUE;
973 BTA_AvMetaRsp(btif_rc_cb.rc_handle, btif_rc_cb.rc_notif[event_id-1].label,
974 ctype, p_msg);
975 }
976 else
977 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700978 BTIF_TRACE_WARNING("%s failed to build metamsg response. status: 0x%02x",
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800979 __FUNCTION__, status);
980 }
981
982 }
983
984 if (!bSent)
985 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700986 BTIF_TRACE_DEBUG("%s: Notification not sent, as there are no RC connections or the \
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800987 CT has not subscribed for event_id: %s", __FUNCTION__, dump_rc_notification_event_id(event_id));
988 }
989 }
990 else
991 {
992 /* All other commands go here */
993
994 BT_HDR *p_msg = NULL;
995 tAVRC_STS status;
996
997 status = AVRC_BldResponse(rc_handle, pmetamsg_resp, &p_msg);
998
999 if (status == AVRC_STS_NO_ERROR)
1000 {
1001 BTA_AvMetaRsp(rc_handle, label, ctype, p_msg);
1002 }
1003 else
1004 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001005 BTIF_TRACE_ERROR("%s: failed to build metamsg response. status: 0x%02x",
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08001006 __FUNCTION__, status);
1007 }
1008 }
1009}
1010
1011static UINT8 opcode_from_pdu(UINT8 pdu)
1012{
1013 UINT8 opcode = 0;
1014
1015 switch (pdu)
1016 {
1017 case AVRC_PDU_NEXT_GROUP:
1018 case AVRC_PDU_PREV_GROUP: /* pass thru */
1019 opcode = AVRC_OP_PASS_THRU;
1020 break;
1021
1022 default: /* vendor */
1023 opcode = AVRC_OP_VENDOR;
1024 break;
1025 }
1026
1027 return opcode;
1028}
1029
1030/*******************************************************************************
1031**
1032** Function btif_rc_upstreams_evt
1033**
1034** Description Executes AVRC UPSTREAMS events in btif context.
1035**
1036** Returns void
1037**
1038*******************************************************************************/
1039static void btif_rc_upstreams_evt(UINT16 event, tAVRC_COMMAND *pavrc_cmd, UINT8 ctype, UINT8 label)
1040{
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001041 BTIF_TRACE_EVENT("%s pdu: %s handle: 0x%x ctype:%x label:%x", __FUNCTION__,
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08001042 dump_rc_pdu(pavrc_cmd->pdu), btif_rc_cb.rc_handle, ctype, label);
1043
1044 switch (event)
1045 {
1046 case AVRC_PDU_GET_PLAY_STATUS:
1047 {
1048 FILL_PDU_QUEUE(IDX_GET_PLAY_STATUS_RSP, ctype, label, TRUE)
1049 HAL_CBACK(bt_rc_callbacks, get_play_status_cb);
1050 }
1051 break;
1052 case AVRC_PDU_LIST_PLAYER_APP_ATTR:
1053 case AVRC_PDU_LIST_PLAYER_APP_VALUES:
1054 case AVRC_PDU_GET_CUR_PLAYER_APP_VALUE:
1055 case AVRC_PDU_SET_PLAYER_APP_VALUE:
1056 case AVRC_PDU_GET_PLAYER_APP_ATTR_TEXT:
1057 case AVRC_PDU_GET_PLAYER_APP_VALUE_TEXT:
1058 {
1059 /* TODO: Add support for Application Settings */
Zhihai Xu081d6e52013-03-29 17:27:01 -07001060 send_reject_response (btif_rc_cb.rc_handle, label, pavrc_cmd->pdu, AVRC_STS_BAD_CMD);
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08001061 }
1062 break;
1063 case AVRC_PDU_GET_ELEMENT_ATTR:
1064 {
1065 btrc_media_attr_t element_attrs[BTRC_MAX_ELEM_ATTR_SIZE];
1066 UINT8 num_attr;
Ravi Nagarajan841e5b52013-03-22 04:16:57 -07001067 memset(&element_attrs, 0, sizeof(element_attrs));
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08001068 if (pavrc_cmd->get_elem_attrs.num_attr == 0)
1069 {
1070 /* CT requests for all attributes */
1071 int attr_cnt;
Ravi Nagarajan841e5b52013-03-22 04:16:57 -07001072 num_attr = BTRC_MAX_ELEM_ATTR_SIZE;
1073 for (attr_cnt = 0; attr_cnt < BTRC_MAX_ELEM_ATTR_SIZE; attr_cnt++)
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08001074 {
Ravi Nagarajan841e5b52013-03-22 04:16:57 -07001075 element_attrs[attr_cnt] = attr_cnt + 1;
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08001076 }
1077 }
1078 else if (pavrc_cmd->get_elem_attrs.num_attr == 0xFF)
1079 {
Ravi Nagarajan841e5b52013-03-22 04:16:57 -07001080 /* 0xff indicates, no attributes requested - reject */
1081 send_reject_response (btif_rc_cb.rc_handle, label, pavrc_cmd->pdu,
1082 AVRC_STS_BAD_PARAM);
1083 return;
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08001084 }
1085 else
1086 {
Mallikarjuna GB0d65d4c2013-11-10 13:30:25 +05301087 int attr_cnt, filled_attr_count;
1088
1089 num_attr = 0;
1090 /* Attribute IDs from 1 to AVRC_MAX_NUM_MEDIA_ATTR_ID are only valid,
1091 * hence HAL definition limits the attributes to AVRC_MAX_NUM_MEDIA_ATTR_ID.
1092 * Fill only valid entries.
1093 */
1094 for (attr_cnt = 0; (attr_cnt < pavrc_cmd->get_elem_attrs.num_attr) &&
1095 (num_attr < AVRC_MAX_NUM_MEDIA_ATTR_ID); attr_cnt++)
1096 {
1097 if ((pavrc_cmd->get_elem_attrs.attrs[attr_cnt] > 0) &&
1098 (pavrc_cmd->get_elem_attrs.attrs[attr_cnt] <= AVRC_MAX_NUM_MEDIA_ATTR_ID))
1099 {
1100 /* Skip the duplicate entries : PTS sends duplicate entries for Fragment cases
1101 */
1102 for (filled_attr_count = 0; filled_attr_count < num_attr; filled_attr_count++)
1103 {
1104 if (element_attrs[filled_attr_count] == pavrc_cmd->get_elem_attrs.attrs[attr_cnt])
1105 break;
1106 }
1107 if (filled_attr_count == num_attr)
1108 {
1109 element_attrs[num_attr] = pavrc_cmd->get_elem_attrs.attrs[attr_cnt];
1110 num_attr++;
1111 }
1112 }
1113 }
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08001114 }
1115 FILL_PDU_QUEUE(IDX_GET_ELEMENT_ATTR_RSP, ctype, label, TRUE);
1116 HAL_CBACK(bt_rc_callbacks, get_element_attr_cb, num_attr, element_attrs);
1117 }
1118 break;
1119 case AVRC_PDU_REGISTER_NOTIFICATION:
1120 {
1121 if(pavrc_cmd->reg_notif.event_id == BTRC_EVT_PLAY_POS_CHANGED &&
1122 pavrc_cmd->reg_notif.param == 0)
1123 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001124 BTIF_TRACE_WARNING("%s Device registering position changed with illegal param 0.",
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08001125 __FUNCTION__);
1126 send_reject_response (btif_rc_cb.rc_handle, label, pavrc_cmd->pdu, AVRC_STS_BAD_PARAM);
1127 /* de-register this notification for a rejected response */
1128 btif_rc_cb.rc_notif[BTRC_EVT_PLAY_POS_CHANGED - 1].bNotify = FALSE;
1129 return;
1130 }
1131 HAL_CBACK(bt_rc_callbacks, register_notification_cb, pavrc_cmd->reg_notif.event_id,
1132 pavrc_cmd->reg_notif.param);
1133 }
1134 break;
1135 case AVRC_PDU_INFORM_DISPLAY_CHARSET:
1136 {
1137 tAVRC_RESPONSE avrc_rsp;
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001138 BTIF_TRACE_EVENT("%s() AVRC_PDU_INFORM_DISPLAY_CHARSET", __FUNCTION__);
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08001139 if(btif_rc_cb.rc_connected == TRUE)
1140 {
1141 memset(&(avrc_rsp.inform_charset), 0, sizeof(tAVRC_RSP));
1142 avrc_rsp.inform_charset.opcode=opcode_from_pdu(AVRC_PDU_INFORM_DISPLAY_CHARSET);
1143 avrc_rsp.inform_charset.pdu=AVRC_PDU_INFORM_DISPLAY_CHARSET;
1144 avrc_rsp.inform_charset.status=AVRC_STS_NO_ERROR;
1145 send_metamsg_rsp(btif_rc_cb.rc_handle, label, ctype, &avrc_rsp);
1146 }
1147 }
1148 break;
1149 default:
1150 {
1151 send_reject_response (btif_rc_cb.rc_handle, label, pavrc_cmd->pdu,
1152 (pavrc_cmd->pdu == AVRC_PDU_SEARCH)?AVRC_STS_SEARCH_NOT_SUP:AVRC_STS_BAD_CMD);
1153 return;
1154 }
1155 break;
1156 }
1157
1158}
1159
Satya Calloji247c68f2013-08-01 02:14:43 -07001160
1161/*******************************************************************************
1162**
1163** Function btif_rc_upstreams_rsp_evt
1164**
1165** Description Executes AVRC UPSTREAMS response events in btif context.
1166**
1167** Returns void
1168**
1169*******************************************************************************/
1170static void btif_rc_upstreams_rsp_evt(UINT16 event, tAVRC_RESPONSE *pavrc_resp, UINT8 ctype, UINT8 label)
1171{
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001172 BTIF_TRACE_EVENT("%s pdu: %s handle: 0x%x ctype:%x label:%x", __FUNCTION__,
Satya Calloji247c68f2013-08-01 02:14:43 -07001173 dump_rc_pdu(pavrc_resp->pdu), btif_rc_cb.rc_handle, ctype, label);
1174
1175#if (AVRC_ADV_CTRL_INCLUDED == TRUE)
1176 switch (event)
1177 {
1178 case AVRC_PDU_REGISTER_NOTIFICATION:
1179 {
1180 if(AVRC_RSP_CHANGED==ctype)
1181 btif_rc_cb.rc_volume=pavrc_resp->reg_notif.param.volume;
1182 HAL_CBACK(bt_rc_callbacks, volume_change_cb, pavrc_resp->reg_notif.param.volume,ctype)
1183 }
1184 break;
1185
1186 case AVRC_PDU_SET_ABSOLUTE_VOLUME:
1187 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001188 BTIF_TRACE_DEBUG("Set absolute volume change event received: volume %d,ctype %d",
Satya Calloji247c68f2013-08-01 02:14:43 -07001189 pavrc_resp->volume.volume,ctype);
1190 if(AVRC_RSP_ACCEPT==ctype)
1191 btif_rc_cb.rc_volume=pavrc_resp->volume.volume;
1192 HAL_CBACK(bt_rc_callbacks,volume_change_cb,pavrc_resp->volume.volume,ctype)
1193 }
1194 break;
1195
1196 default:
1197 return;
1198 }
1199#endif
1200}
1201
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08001202/************************************************************************************
1203** AVRCP API Functions
1204************************************************************************************/
1205
1206/*******************************************************************************
1207**
1208** Function init
1209**
1210** Description Initializes the AVRC interface
1211**
1212** Returns bt_status_t
1213**
1214*******************************************************************************/
1215static bt_status_t init(btrc_callbacks_t* callbacks )
1216{
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001217 BTIF_TRACE_EVENT("## %s ##", __FUNCTION__);
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08001218 bt_status_t result = BT_STATUS_SUCCESS;
1219
1220 if (bt_rc_callbacks)
1221 return BT_STATUS_DONE;
1222
1223 bt_rc_callbacks = callbacks;
1224 memset (&btif_rc_cb, 0, sizeof(btif_rc_cb));
Satya Calloji247c68f2013-08-01 02:14:43 -07001225 btif_rc_cb.rc_vol_label=MAX_LABEL;
1226 btif_rc_cb.rc_volume=MAX_VOLUME;
1227 lbl_init();
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08001228
1229 return result;
1230}
1231
Mike Lockwood4ad470e2014-06-02 16:21:49 -07001232/*******************************************************************************
1233**
1234** Function init_ctrl
1235**
1236** Description Initializes the AVRC interface
1237**
1238** Returns bt_status_t
1239**
1240*******************************************************************************/
1241static bt_status_t init_ctrl(btrc_ctrl_callbacks_t* callbacks )
1242{
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001243 BTIF_TRACE_EVENT("## %s ##", __FUNCTION__);
Mike Lockwood4ad470e2014-06-02 16:21:49 -07001244 bt_status_t result = BT_STATUS_SUCCESS;
1245
1246 if (bt_rc_ctrl_callbacks)
1247 return BT_STATUS_DONE;
1248
1249 bt_rc_ctrl_callbacks = callbacks;
1250 memset (&btif_rc_cb, 0, sizeof(btif_rc_cb));
1251 btif_rc_cb.rc_vol_label=MAX_LABEL;
1252 btif_rc_cb.rc_volume=MAX_VOLUME;
1253 lbl_init();
1254
1255 return result;
1256}
1257
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08001258/***************************************************************************
1259**
1260** Function get_play_status_rsp
1261**
1262** Description Returns the current play status.
1263** This method is called in response to
1264** GetPlayStatus request.
1265**
1266** Returns bt_status_t
1267**
1268***************************************************************************/
1269static bt_status_t get_play_status_rsp(btrc_play_status_t play_status, uint32_t song_len,
1270 uint32_t song_pos)
1271{
1272 tAVRC_RESPONSE avrc_rsp;
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08001273 CHECK_RC_CONNECTED
1274 memset(&(avrc_rsp.get_play_status), 0, sizeof(tAVRC_GET_PLAY_STATUS_RSP));
1275 avrc_rsp.get_play_status.song_len = song_len;
1276 avrc_rsp.get_play_status.song_pos = song_pos;
1277 avrc_rsp.get_play_status.play_status = play_status;
1278
1279 avrc_rsp.get_play_status.pdu = AVRC_PDU_GET_PLAY_STATUS;
1280 avrc_rsp.get_play_status.opcode = opcode_from_pdu(AVRC_PDU_GET_PLAY_STATUS);
Ravi Nagarajanb88fc6c2013-04-02 07:11:14 -07001281 avrc_rsp.get_play_status.status = AVRC_STS_NO_ERROR;
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08001282 /* Send the response */
1283 SEND_METAMSG_RSP(IDX_GET_PLAY_STATUS_RSP, &avrc_rsp);
1284 return BT_STATUS_SUCCESS;
1285}
1286
1287/***************************************************************************
1288**
1289** Function get_element_attr_rsp
1290**
1291** Description Returns the current songs' element attributes
1292** in text.
1293**
1294** Returns bt_status_t
1295**
1296***************************************************************************/
1297static bt_status_t get_element_attr_rsp(uint8_t num_attr, btrc_element_attr_val_t *p_attrs)
1298{
1299 tAVRC_RESPONSE avrc_rsp;
1300 UINT32 i;
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08001301 tAVRC_ATTR_ENTRY element_attrs[BTRC_MAX_ELEM_ATTR_SIZE];
1302 CHECK_RC_CONNECTED
1303 memset(element_attrs, 0, sizeof(tAVRC_ATTR_ENTRY) * num_attr);
1304
1305 if (num_attr == 0)
1306 {
1307 avrc_rsp.get_play_status.status = AVRC_STS_BAD_PARAM;
1308 }
1309 else
1310 {
1311 for (i=0; i<num_attr; i++) {
1312 element_attrs[i].attr_id = p_attrs[i].attr_id;
1313 element_attrs[i].name.charset_id = AVRC_CHARSET_ID_UTF8;
1314 element_attrs[i].name.str_len = (UINT16)strlen((char *)p_attrs[i].text);
1315 element_attrs[i].name.p_str = p_attrs[i].text;
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001316 BTIF_TRACE_DEBUG("%s attr_id:0x%x, charset_id:0x%x, str_len:%d, str:%s",
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08001317 __FUNCTION__, (unsigned int)element_attrs[i].attr_id,
1318 element_attrs[i].name.charset_id, element_attrs[i].name.str_len,
1319 element_attrs[i].name.p_str);
1320 }
1321 avrc_rsp.get_play_status.status = AVRC_STS_NO_ERROR;
1322 }
1323 avrc_rsp.get_elem_attrs.num_attr = num_attr;
1324 avrc_rsp.get_elem_attrs.p_attrs = element_attrs;
1325 avrc_rsp.get_elem_attrs.pdu = AVRC_PDU_GET_ELEMENT_ATTR;
1326 avrc_rsp.get_elem_attrs.opcode = opcode_from_pdu(AVRC_PDU_GET_ELEMENT_ATTR);
1327 /* Send the response */
1328 SEND_METAMSG_RSP(IDX_GET_ELEMENT_ATTR_RSP, &avrc_rsp);
1329 return BT_STATUS_SUCCESS;
1330}
1331
1332/***************************************************************************
1333**
1334** Function register_notification_rsp
1335**
1336** Description Response to the register notification request.
1337** in text.
1338**
1339** Returns bt_status_t
1340**
1341***************************************************************************/
1342static bt_status_t register_notification_rsp(btrc_event_id_t event_id,
1343 btrc_notification_type_t type, btrc_register_notification_t *p_param)
1344{
1345 tAVRC_RESPONSE avrc_rsp;
1346 CHECK_RC_CONNECTED
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001347 BTIF_TRACE_EVENT("## %s ## event_id:%s", __FUNCTION__, dump_rc_notification_event_id(event_id));
Nitin Srivastava68c53de2014-02-13 19:31:40 +05301348 if (btif_rc_cb.rc_notif[event_id-1].bNotify == FALSE)
1349 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001350 BTIF_TRACE_ERROR("Avrcp Event id not registered: event_id = %x", event_id);
Nitin Srivastava68c53de2014-02-13 19:31:40 +05301351 return BT_STATUS_NOT_READY;
1352 }
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08001353 memset(&(avrc_rsp.reg_notif), 0, sizeof(tAVRC_REG_NOTIF_RSP));
1354 avrc_rsp.reg_notif.event_id = event_id;
1355
1356 switch(event_id)
1357 {
1358 case BTRC_EVT_PLAY_STATUS_CHANGED:
1359 avrc_rsp.reg_notif.param.play_status = p_param->play_status;
1360 break;
1361 case BTRC_EVT_TRACK_CHANGE:
1362 memcpy(&(avrc_rsp.reg_notif.param.track), &(p_param->track), sizeof(btrc_uid_t));
1363 break;
Ravi Nagarajanb88fc6c2013-04-02 07:11:14 -07001364 case BTRC_EVT_PLAY_POS_CHANGED:
1365 avrc_rsp.reg_notif.param.play_pos = p_param->song_pos;
1366 break;
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08001367 default:
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001368 BTIF_TRACE_WARNING("%s : Unhandled event ID : 0x%x", __FUNCTION__, event_id);
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08001369 return BT_STATUS_UNHANDLED;
1370 }
1371
1372 avrc_rsp.reg_notif.pdu = AVRC_PDU_REGISTER_NOTIFICATION;
1373 avrc_rsp.reg_notif.opcode = opcode_from_pdu(AVRC_PDU_REGISTER_NOTIFICATION);
1374 avrc_rsp.get_play_status.status = AVRC_STS_NO_ERROR;
1375
1376 /* Send the response. */
1377 send_metamsg_rsp(btif_rc_cb.rc_handle, btif_rc_cb.rc_notif[event_id-1].label,
1378 ((type == BTRC_NOTIFICATION_TYPE_INTERIM)?AVRC_CMD_NOTIF:AVRC_RSP_CHANGED), &avrc_rsp);
1379 return BT_STATUS_SUCCESS;
1380}
1381
1382/***************************************************************************
1383**
Satya Calloji247c68f2013-08-01 02:14:43 -07001384** Function set_volume
1385**
1386** Description Send current volume setting to remote side.
1387** Support limited to SetAbsoluteVolume
1388** This can be enhanced to support Relative Volume (AVRCP 1.0).
1389** With RelateVolume, we will send VOLUME_UP/VOLUME_DOWN
1390** as opposed to absolute volume level
1391** volume: Should be in the range 0-127. bit7 is reseved and cannot be set
1392**
1393** Returns bt_status_t
1394**
1395***************************************************************************/
1396static bt_status_t set_volume(uint8_t volume)
1397{
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001398 BTIF_TRACE_DEBUG("%s", __FUNCTION__);
Satya Calloji247c68f2013-08-01 02:14:43 -07001399 CHECK_RC_CONNECTED
1400 tAVRC_STS status = BT_STATUS_UNSUPPORTED;
1401 rc_transaction_t *p_transaction=NULL;
1402
1403 if(btif_rc_cb.rc_volume==volume)
1404 {
1405 status=BT_STATUS_DONE;
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001406 BTIF_TRACE_ERROR("%s: volume value already set earlier: 0x%02x",__FUNCTION__, volume);
Satya Calloji247c68f2013-08-01 02:14:43 -07001407 return status;
1408 }
1409
1410 if ((btif_rc_cb.rc_features & BTA_AV_FEAT_RCTG) &&
1411 (btif_rc_cb.rc_features & BTA_AV_FEAT_ADV_CTRL))
1412 {
1413 tAVRC_COMMAND avrc_cmd = {0};
1414 BT_HDR *p_msg = NULL;
1415
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001416 BTIF_TRACE_DEBUG("%s: Peer supports absolute volume. newVolume=%d", __FUNCTION__, volume);
Satya Calloji247c68f2013-08-01 02:14:43 -07001417 avrc_cmd.volume.opcode = AVRC_OP_VENDOR;
1418 avrc_cmd.volume.pdu = AVRC_PDU_SET_ABSOLUTE_VOLUME;
1419 avrc_cmd.volume.status = AVRC_STS_NO_ERROR;
1420 avrc_cmd.volume.volume = volume;
1421
1422 if (AVRC_BldCommand(&avrc_cmd, &p_msg) == AVRC_STS_NO_ERROR)
1423 {
1424 bt_status_t tran_status=get_transaction(&p_transaction);
1425 if(BT_STATUS_SUCCESS == tran_status && NULL!=p_transaction)
1426 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001427 BTIF_TRACE_DEBUG("%s msgreq being sent out with label %d",
Satya Calloji247c68f2013-08-01 02:14:43 -07001428 __FUNCTION__,p_transaction->lbl);
1429 BTA_AvMetaCmd(btif_rc_cb.rc_handle,p_transaction->lbl, AVRC_CMD_CTRL, p_msg);
1430 status = BT_STATUS_SUCCESS;
1431 }
1432 else
1433 {
1434 if(NULL!=p_msg)
1435 GKI_freebuf(p_msg);
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001436 BTIF_TRACE_ERROR("%s: failed to obtain transaction details. status: 0x%02x",
Satya Calloji247c68f2013-08-01 02:14:43 -07001437 __FUNCTION__, tran_status);
1438 status = BT_STATUS_FAIL;
1439 }
1440 }
1441 else
1442 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001443 BTIF_TRACE_ERROR("%s: failed to build absolute volume command. status: 0x%02x",
Satya Calloji247c68f2013-08-01 02:14:43 -07001444 __FUNCTION__, status);
1445 status = BT_STATUS_FAIL;
1446 }
1447 }
1448 else
1449 status=BT_STATUS_NOT_READY;
1450 return status;
1451}
1452
1453
1454/***************************************************************************
1455**
1456** Function register_volumechange
1457**
1458** Description Register for volume change notification from remote side.
1459**
1460** Returns void
1461**
1462***************************************************************************/
1463
1464static void register_volumechange (UINT8 lbl)
1465{
1466 tAVRC_COMMAND avrc_cmd = {0};
1467 BT_HDR *p_msg = NULL;
1468 tAVRC_STS BldResp=AVRC_STS_BAD_CMD;
Satya Calloji247c68f2013-08-01 02:14:43 -07001469 rc_transaction_t *p_transaction=NULL;
1470
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001471 BTIF_TRACE_DEBUG("%s called with label:%d",__FUNCTION__,lbl);
Satya Calloji247c68f2013-08-01 02:14:43 -07001472
1473 avrc_cmd.cmd.opcode=0x00;
1474 avrc_cmd.pdu = AVRC_PDU_REGISTER_NOTIFICATION;
1475 avrc_cmd.reg_notif.event_id = AVRC_EVT_VOLUME_CHANGE;
1476 avrc_cmd.reg_notif.status = AVRC_STS_NO_ERROR;
1477
1478 BldResp=AVRC_BldCommand(&avrc_cmd, &p_msg);
1479 if(AVRC_STS_NO_ERROR==BldResp && p_msg)
1480 {
1481 p_transaction=get_transaction_by_lbl(lbl);
1482 if(NULL!=p_transaction)
1483 {
1484 BTA_AvMetaCmd(btif_rc_cb.rc_handle,p_transaction->lbl, AVRC_CMD_NOTIF, p_msg);
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001485 BTIF_TRACE_DEBUG("%s:BTA_AvMetaCmd called",__FUNCTION__);
Satya Calloji247c68f2013-08-01 02:14:43 -07001486 }
1487 else
1488 {
1489 if(NULL!=p_msg)
1490 GKI_freebuf(p_msg);
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001491 BTIF_TRACE_ERROR("%s transaction not obtained with label: %d",__FUNCTION__,lbl);
Satya Calloji247c68f2013-08-01 02:14:43 -07001492 }
1493 }
1494 else
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001495 BTIF_TRACE_ERROR("%s failed to build command:%d",__FUNCTION__,BldResp);
Satya Calloji247c68f2013-08-01 02:14:43 -07001496}
1497
1498
1499/***************************************************************************
1500**
1501** Function handle_rc_metamsg_rsp
1502**
1503** Description Handle RC metamessage response
1504**
1505** Returns void
1506**
1507***************************************************************************/
1508static void handle_rc_metamsg_rsp(tBTA_AV_META_MSG *pmeta_msg)
1509{
1510 tAVRC_RESPONSE avrc_response = {0};
1511 UINT8 scratch_buf[512] = {0};
1512 tAVRC_STS status = BT_STATUS_UNSUPPORTED;
1513
1514 if(AVRC_OP_VENDOR==pmeta_msg->p_msg->hdr.opcode &&(AVRC_RSP_CHANGED==pmeta_msg->code
1515 || AVRC_RSP_INTERIM==pmeta_msg->code || AVRC_RSP_ACCEPT==pmeta_msg->code
1516 || AVRC_RSP_REJ==pmeta_msg->code || AVRC_RSP_NOT_IMPL==pmeta_msg->code))
1517 {
1518 status=AVRC_ParsResponse(pmeta_msg->p_msg, &avrc_response, scratch_buf, sizeof(scratch_buf));
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001519 BTIF_TRACE_DEBUG("%s: code %d,event ID %d,PDU %x,parsing status %d, label:%d",
Satya Calloji247c68f2013-08-01 02:14:43 -07001520 __FUNCTION__,pmeta_msg->code,avrc_response.reg_notif.event_id,avrc_response.reg_notif.pdu,
1521 status, pmeta_msg->label);
1522
1523 if (status != AVRC_STS_NO_ERROR)
1524 {
1525 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 btif_rc_cb.rc_vol_label=MAX_LABEL;
1530 release_transaction(btif_rc_cb.rc_vol_label);
1531 }
1532 else if(AVRC_PDU_SET_ABSOLUTE_VOLUME==avrc_response.rsp.pdu)
1533 {
1534 release_transaction(pmeta_msg->label);
1535 }
1536 return;
1537 }
1538 else if(AVRC_PDU_REGISTER_NOTIFICATION==avrc_response.rsp.pdu
1539 && AVRC_EVT_VOLUME_CHANGE==avrc_response.reg_notif.event_id
1540 && btif_rc_cb.rc_vol_label!=pmeta_msg->label)
1541 {
1542 // Just discard the message, if the device sends back with an incorrect label
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001543 BTIF_TRACE_DEBUG("%s:Discarding register notfn in rsp.code: %d and label %d",
Satya Calloji247c68f2013-08-01 02:14:43 -07001544 __FUNCTION__, pmeta_msg->code, pmeta_msg->label);
1545 return;
1546 }
1547 }
1548 else
1549 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001550 BTIF_TRACE_DEBUG("%s:Received vendor dependent in adv ctrl rsp. code: %d len: %d. Not processing it.",
Satya Calloji247c68f2013-08-01 02:14:43 -07001551 __FUNCTION__, pmeta_msg->code, pmeta_msg->len);
1552 return;
1553 }
1554
1555 if(AVRC_PDU_REGISTER_NOTIFICATION==avrc_response.rsp.pdu
1556 && AVRC_EVT_VOLUME_CHANGE==avrc_response.reg_notif.event_id
1557 && AVRC_RSP_CHANGED==pmeta_msg->code)
1558 {
1559 /* re-register for volume change notification */
1560 // Do not re-register for rejected case, as it might get into endless loop
1561 register_volumechange(btif_rc_cb.rc_vol_label);
1562 }
1563 else if(AVRC_PDU_SET_ABSOLUTE_VOLUME==avrc_response.rsp.pdu)
1564 {
1565 /* free up the label here */
1566 release_transaction(pmeta_msg->label);
1567 }
1568
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001569 BTIF_TRACE_EVENT("%s: Passing received metamsg response to app. pdu: %s",
Satya Calloji247c68f2013-08-01 02:14:43 -07001570 __FUNCTION__, dump_rc_pdu(avrc_response.pdu));
1571 btif_rc_upstreams_rsp_evt((uint16_t)avrc_response.rsp.pdu, &avrc_response, pmeta_msg->code,
1572 pmeta_msg->label);
1573}
1574
1575
1576/***************************************************************************
1577**
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08001578** Function cleanup
1579**
1580** Description Closes the AVRC interface
1581**
1582** Returns void
1583**
1584***************************************************************************/
1585static void cleanup()
1586{
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001587 BTIF_TRACE_EVENT("## %s ##", __FUNCTION__);
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08001588 close_uinput();
1589 if (bt_rc_callbacks)
1590 {
1591 bt_rc_callbacks = NULL;
1592 }
1593 memset(&btif_rc_cb, 0, sizeof(btif_rc_cb_t));
Satya Calloji247c68f2013-08-01 02:14:43 -07001594 lbl_destroy();
Anubhav Guptadaddea92014-09-08 16:00:22 +05301595 BTIF_TRACE_EVENT("## %s ## completed", __FUNCTION__);
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08001596}
1597
Anubhav Guptadaddea92014-09-08 16:00:22 +05301598/***************************************************************************
1599**
1600** Function cleanup_ctrl
1601**
1602** Description Closes the AVRC Controller interface
1603**
1604** Returns void
1605**
1606***************************************************************************/
1607static void cleanup_ctrl()
1608{
1609 BTIF_TRACE_EVENT("## %s ##", __FUNCTION__);
1610
1611 if (bt_rc_ctrl_callbacks)
1612 {
1613 bt_rc_ctrl_callbacks = NULL;
1614 }
1615 memset(&btif_rc_cb, 0, sizeof(btif_rc_cb_t));
1616 lbl_destroy();
1617 BTIF_TRACE_EVENT("## %s ## completed", __FUNCTION__);
1618}
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08001619
Mike Lockwood4ad470e2014-06-02 16:21:49 -07001620static bt_status_t send_passthrough_cmd(bt_bdaddr_t *bd_addr, uint8_t key_code, uint8_t key_state)
1621{
1622 tAVRC_STS status = BT_STATUS_UNSUPPORTED;
1623#if (AVRC_CTLR_INCLUDED == TRUE)
1624 CHECK_RC_CONNECTED
1625 rc_transaction_t *p_transaction=NULL;
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001626 BTIF_TRACE_DEBUG("%s: key-code: %d, key-state: %d", __FUNCTION__,
Mike Lockwood4ad470e2014-06-02 16:21:49 -07001627 key_code, key_state);
1628 if (btif_rc_cb.rc_features & BTA_AV_FEAT_RCTG)
1629 {
Mike Lockwood4ad470e2014-06-02 16:21:49 -07001630 bt_status_t tran_status = get_transaction(&p_transaction);
1631 if(BT_STATUS_SUCCESS == tran_status && NULL != p_transaction)
1632 {
1633 BTA_AvRemoteCmd(btif_rc_cb.rc_handle, p_transaction->lbl,
1634 (tBTA_AV_RC)key_code, (tBTA_AV_STATE)key_state);
1635 status = BT_STATUS_SUCCESS;
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001636 BTIF_TRACE_DEBUG("%s: succesfully sent passthrough command to BTA", __FUNCTION__);
Mike Lockwood4ad470e2014-06-02 16:21:49 -07001637 }
1638 else
1639 {
1640 status = BT_STATUS_FAIL;
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001641 BTIF_TRACE_DEBUG("%s: error in fetching transaction", __FUNCTION__);
Mike Lockwood4ad470e2014-06-02 16:21:49 -07001642 }
1643 }
1644 else
1645 {
1646 status = BT_STATUS_FAIL;
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001647 BTIF_TRACE_DEBUG("%s: feature not supported", __FUNCTION__);
Mike Lockwood4ad470e2014-06-02 16:21:49 -07001648 }
1649#else
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001650 BTIF_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__);
Mike Lockwood4ad470e2014-06-02 16:21:49 -07001651#endif
1652 return status;
1653}
1654
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08001655static const btrc_interface_t bt_rc_interface = {
1656 sizeof(bt_rc_interface),
1657 init,
1658 get_play_status_rsp,
1659 NULL, /* list_player_app_attr_rsp */
1660 NULL, /* list_player_app_value_rsp */
1661 NULL, /* get_player_app_value_rsp */
1662 NULL, /* get_player_app_attr_text_rsp */
1663 NULL, /* get_player_app_value_text_rsp */
1664 get_element_attr_rsp,
1665 NULL, /* set_player_app_value_rsp */
1666 register_notification_rsp,
Satya Calloji247c68f2013-08-01 02:14:43 -07001667 set_volume,
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08001668 cleanup,
1669};
1670
Mike Lockwood4ad470e2014-06-02 16:21:49 -07001671static const btrc_ctrl_interface_t bt_rc_ctrl_interface = {
1672 sizeof(bt_rc_ctrl_interface),
1673 init_ctrl,
1674 send_passthrough_cmd,
Anubhav Guptadaddea92014-09-08 16:00:22 +05301675 cleanup_ctrl,
Mike Lockwood4ad470e2014-06-02 16:21:49 -07001676};
1677
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08001678/*******************************************************************************
1679**
1680** Function btif_rc_get_interface
1681**
Mike Lockwood4ad470e2014-06-02 16:21:49 -07001682** Description Get the AVRCP Target callback interface
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08001683**
1684** Returns btav_interface_t
1685**
1686*******************************************************************************/
1687const btrc_interface_t *btif_rc_get_interface(void)
1688{
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001689 BTIF_TRACE_EVENT("%s", __FUNCTION__);
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08001690 return &bt_rc_interface;
Satya Calloji247c68f2013-08-01 02:14:43 -07001691}
1692
1693/*******************************************************************************
Mike Lockwood4ad470e2014-06-02 16:21:49 -07001694**
1695** Function btif_rc_ctrl_get_interface
1696**
1697** Description Get the AVRCP Controller callback interface
1698**
1699** Returns btav_interface_t
1700**
1701*******************************************************************************/
1702const btrc_ctrl_interface_t *btif_rc_ctrl_get_interface(void)
1703{
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001704 BTIF_TRACE_EVENT("%s", __FUNCTION__);
Mike Lockwood4ad470e2014-06-02 16:21:49 -07001705 return &bt_rc_ctrl_interface;
1706}
1707
1708/*******************************************************************************
Satya Calloji247c68f2013-08-01 02:14:43 -07001709** Function initialize_transaction
1710**
1711** Description Initializes fields of the transaction structure
1712**
1713** Returns void
1714*******************************************************************************/
1715static void initialize_transaction(int lbl)
1716{
1717 pthread_mutex_lock(&device.lbllock);
1718 if(lbl < MAX_TRANSACTIONS_PER_SESSION)
1719 {
1720 device.transaction[lbl].lbl = lbl;
1721 device.transaction[lbl].in_use=FALSE;
1722 device.transaction[lbl].handle=0;
1723 }
1724 pthread_mutex_unlock(&device.lbllock);
1725}
1726
1727/*******************************************************************************
1728** Function lbl_init
1729**
1730** Description Initializes label structures and mutexes.
1731**
1732** Returns void
1733*******************************************************************************/
1734void lbl_init()
1735{
1736 memset(&device,0,sizeof(rc_device_t));
1737 pthread_mutexattr_t attr;
1738 pthread_mutexattr_init(&attr);
1739 pthread_mutex_init(&(device.lbllock), &attr);
1740 pthread_mutexattr_destroy(&attr);
1741 init_all_transactions();
1742}
1743
1744/*******************************************************************************
1745**
1746** Function init_all_transactions
1747**
1748** Description Initializes all transactions
1749**
1750** Returns void
1751*******************************************************************************/
1752void init_all_transactions()
1753{
1754 UINT8 txn_indx=0;
1755 for(txn_indx=0; txn_indx < MAX_TRANSACTIONS_PER_SESSION; txn_indx++)
1756 {
1757 initialize_transaction(txn_indx);
1758 }
1759}
1760
1761/*******************************************************************************
1762**
1763** Function get_transaction_by_lbl
1764**
1765** Description Will return a transaction based on the label. If not inuse
1766** will return an error.
1767**
1768** Returns bt_status_t
1769*******************************************************************************/
1770rc_transaction_t *get_transaction_by_lbl(UINT8 lbl)
1771{
1772 rc_transaction_t *transaction = NULL;
1773 pthread_mutex_lock(&device.lbllock);
1774
1775 /* Determine if this is a valid label */
1776 if (lbl < MAX_TRANSACTIONS_PER_SESSION)
1777 {
1778 if (FALSE==device.transaction[lbl].in_use)
1779 {
1780 transaction = NULL;
1781 }
1782 else
1783 {
1784 transaction = &(device.transaction[lbl]);
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001785 BTIF_TRACE_DEBUG("%s: Got transaction.label: %d",__FUNCTION__,lbl);
Satya Calloji247c68f2013-08-01 02:14:43 -07001786 }
1787 }
1788
1789 pthread_mutex_unlock(&device.lbllock);
1790 return transaction;
1791}
1792
1793/*******************************************************************************
1794**
1795** Function get_transaction
1796**
1797** Description Obtains the transaction details.
1798**
1799** Returns bt_status_t
1800*******************************************************************************/
1801
1802bt_status_t get_transaction(rc_transaction_t **ptransaction)
1803{
1804 bt_status_t result = BT_STATUS_NOMEM;
1805 UINT8 i=0;
1806 pthread_mutex_lock(&device.lbllock);
1807
1808 // Check for unused transactions
1809 for (i=0; i<MAX_TRANSACTIONS_PER_SESSION; i++)
1810 {
1811 if (FALSE==device.transaction[i].in_use)
1812 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001813 BTIF_TRACE_DEBUG("%s:Got transaction.label: %d",__FUNCTION__,device.transaction[i].lbl);
Satya Calloji247c68f2013-08-01 02:14:43 -07001814 device.transaction[i].in_use = TRUE;
1815 *ptransaction = &(device.transaction[i]);
1816 result = BT_STATUS_SUCCESS;
1817 break;
1818 }
1819 }
1820
1821 pthread_mutex_unlock(&device.lbllock);
1822 return result;
1823}
1824
1825
1826/*******************************************************************************
1827**
1828** Function release_transaction
1829**
1830** Description Will release a transaction for reuse
1831**
1832** Returns bt_status_t
1833*******************************************************************************/
1834void release_transaction(UINT8 lbl)
1835{
1836 rc_transaction_t *transaction = get_transaction_by_lbl(lbl);
1837
1838 /* If the transaction is in use... */
1839 if (transaction != NULL)
1840 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001841 BTIF_TRACE_DEBUG("%s: lbl: %d", __FUNCTION__, lbl);
Satya Calloji247c68f2013-08-01 02:14:43 -07001842 initialize_transaction(lbl);
1843 }
1844}
1845
1846/*******************************************************************************
1847**
1848** Function lbl_destroy
1849**
1850** Description Cleanup of the mutex
1851**
1852** Returns void
1853*******************************************************************************/
1854void lbl_destroy()
1855{
1856 pthread_mutex_destroy(&(device.lbllock));
1857}
Matthew Xiea7ae4a12013-10-24 01:09:52 -07001858
1859/*******************************************************************************
1860** Function dev_blacklisted_for_absolute_volume
1861**
1862** Description Blacklist Devices that donot handle absolute volume well
Matthew Xie7850a932013-11-05 17:19:39 -08001863** We are blacklisting all the devices that are not in whitelist
Matthew Xiea7ae4a12013-10-24 01:09:52 -07001864**
1865** Returns True if the device is in the list
1866*******************************************************************************/
1867static BOOLEAN dev_blacklisted_for_absolute_volume(BD_ADDR peer_dev)
1868{
1869 int i;
Thomas.TT_Linc9fbcde2014-04-07 16:13:06 +08001870 char *dev_name_str = NULL;
Matthew Xie7850a932013-11-05 17:19:39 -08001871 int whitelist_size = sizeof(rc_white_addr_prefix)/sizeof(rc_white_addr_prefix[0]);
Thomas.TT_Linc9fbcde2014-04-07 16:13:06 +08001872
Matthew Xie7850a932013-11-05 17:19:39 -08001873 for (i = 0; i < whitelist_size; i++) {
1874 if (rc_white_addr_prefix[i][0] == peer_dev[0] &&
1875 rc_white_addr_prefix[i][1] == peer_dev[1] &&
1876 rc_white_addr_prefix[i][2] == peer_dev[2]) {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001877 BTIF_TRACE_DEBUG("whitelist absolute volume for %02x:%02x:%02x",
Thomas.TT_Linc9fbcde2014-04-07 16:13:06 +08001878 peer_dev[0], peer_dev[1], peer_dev[2]);
Matthew Xie7850a932013-11-05 17:19:39 -08001879 return FALSE;
Matthew Xiea7ae4a12013-10-24 01:09:52 -07001880 }
1881 }
Thomas.TT_Linc9fbcde2014-04-07 16:13:06 +08001882
1883 dev_name_str = BTM_SecReadDevName(peer_dev);
1884 whitelist_size = sizeof(rc_white_name)/sizeof(char*);
1885 if (dev_name_str != NULL) {
1886 for (i = 0; i < whitelist_size; i++) {
1887 if (strcmp(dev_name_str, rc_white_name[i]) == 0) {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001888 BTIF_TRACE_DEBUG("whitelist absolute volume for %s", dev_name_str);
Thomas.TT_Linc9fbcde2014-04-07 16:13:06 +08001889 return FALSE;
1890 }
1891 }
1892 }
1893
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001894 BTIF_TRACE_WARNING("blacklist absolute volume for %02x:%02x:%02x, name = %s",
Thomas.TT_Linc9fbcde2014-04-07 16:13:06 +08001895 peer_dev[0], peer_dev[1], peer_dev[2], dev_name_str);
Matthew Xie7850a932013-11-05 17:19:39 -08001896 return TRUE;
Matthew Xiea7ae4a12013-10-24 01:09:52 -07001897}