blob: 46a54a8219c987fa49f8058dc9aaf97b26c6aea8 [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>
29#include "bta_api.h"
30#include "bta_av_api.h"
31#include "avrc_defs.h"
32#include "bd.h"
33#include "gki.h"
34
35#define LOG_TAG "BTIF_RC"
36#include "btif_common.h"
Ravi Nagarajan9adddf42013-03-06 05:29:48 -080037#include "btif_util.h"
38#include "btif_av.h"
39#include "hardware/bt_rc.h"
40#include "uinput.h"
The Android Open Source Project5738f832012-12-12 16:00:35 -080041
42/*****************************************************************************
43** Constants & Macros
44******************************************************************************/
The Android Open Source Project5738f832012-12-12 16:00:35 -080045
46/* cod value for Headsets */
47#define COD_AV_HEADSETS 0x0404
Ravi Nagarajan9adddf42013-03-06 05:29:48 -080048/* for AVRC 1.4 need to change this */
Ayan Ghoshd74324f2014-07-25 17:51:32 +053049#define MAX_RC_NOTIFICATIONS AVRC_EVT_VOLUME_CHANGE
50//#define TEST_BROWSE_RESPONSE
51#define MAX_FOLDER_RSP_SUPPORT 3
The Android Open Source Project5738f832012-12-12 16:00:35 -080052
Ayan Ghoshd74324f2014-07-25 17:51:32 +053053#define IDX_GET_PLAY_STATUS_RSP 0
54#define IDX_LIST_APP_ATTR_RSP 1
55#define IDX_LIST_APP_VALUE_RSP 2
56#define IDX_GET_CURR_APP_VAL_RSP 3
57#define IDX_SET_APP_VAL_RSP 4
58#define IDX_GET_APP_ATTR_TXT_RSP 5
59#define IDX_GET_APP_VAL_TXT_RSP 6
60#define IDX_GET_ELEMENT_ATTR_RSP 7
61#define IDX_GET_FOLDER_ITEMS_RSP 8
62#define IDX_SET_FOLDER_ITEM_RSP 9
63#define IDX_SET_ADDRESS_PLAYER_RSP 10
64#define IDX_SET_BROWSE_PLAYER_RSP 11
65#define IDX_CHANGE_PATH_RSP 12
66#define IDX_PLAY_ITEM_RSP 13
67#define IDX_GET_ITEM_ATTR_RSP 14
Satya Calloji247c68f2013-08-01 02:14:43 -070068#define MAX_VOLUME 128
69#define MAX_LABEL 16
70#define MAX_TRANSACTIONS_PER_SESSION 16
Rohit Singha9fb00a2013-07-27 14:46:29 +053071#define PLAY_STATUS_PLAYING 1
Ayan Ghoshd74324f2014-07-25 17:51:32 +053072#define MAX_CMD_QUEUE_LEN 15
73#define ERR_PLAYER_NOT_ADDRESED 0x13
Ravi Nagarajan9adddf42013-03-06 05:29:48 -080074
75#define CHECK_RC_CONNECTED \
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -070076 BTIF_TRACE_DEBUG("## %s ##", __FUNCTION__); \
Ravi Nagarajan9adddf42013-03-06 05:29:48 -080077 if(btif_rc_cb.rc_connected == FALSE) \
78 { \
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -070079 BTIF_TRACE_WARNING("Function %s() called when RC is not connected", __FUNCTION__); \
Ravi Nagarajan9adddf42013-03-06 05:29:48 -080080 return BT_STATUS_NOT_READY; \
81 }
82
83#define FILL_PDU_QUEUE(index, ctype, label, pending) \
84{ \
85 btif_rc_cb.rc_pdu_info[index].ctype = ctype; \
86 btif_rc_cb.rc_pdu_info[index].label = label; \
87 btif_rc_cb.rc_pdu_info[index].is_rsp_pending = pending; \
88}
89
90#define SEND_METAMSG_RSP(index, avrc_rsp) \
91{ \
92 if(btif_rc_cb.rc_pdu_info[index].is_rsp_pending == FALSE) \
93 { \
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -070094 BTIF_TRACE_WARNING("%s Not sending response as no PDU was registered", __FUNCTION__); \
Ravi Nagarajan9adddf42013-03-06 05:29:48 -080095 return BT_STATUS_UNHANDLED; \
96 } \
97 send_metamsg_rsp(btif_rc_cb.rc_handle, btif_rc_cb.rc_pdu_info[index].label, \
98 btif_rc_cb.rc_pdu_info[index].ctype, avrc_rsp); \
99 btif_rc_cb.rc_pdu_info[index].ctype = 0; \
100 btif_rc_cb.rc_pdu_info[index].label = 0; \
101 btif_rc_cb.rc_pdu_info[index].is_rsp_pending = FALSE; \
102}
The Android Open Source Project5738f832012-12-12 16:00:35 -0800103
Ayan Ghoshd74324f2014-07-25 17:51:32 +0530104
105#define SEND_BROWSEMSG_RSP(index , avrc_rsp) \
106{ \
107 if(btif_rc_cb.rc_pdu_info[index].is_rsp_pending == FALSE) \
108 { \
109 BTIF_TRACE_WARNING("%s Not sending response as no PDU was registered", __FUNCTION__); \
110 return BT_STATUS_UNHANDLED; \
111 } \
112 send_browsemsg_rsp(btif_rc_cb.rc_handle, btif_rc_cb.rc_pdu_info[index].label, \
113 btif_rc_cb.rc_pdu_info[index].ctype, avrc_rsp); \
114 btif_rc_cb.rc_pdu_info[index].ctype = 0; \
115 btif_rc_cb.rc_pdu_info[index].label = 0; \
116 btif_rc_cb.rc_pdu_info[index].is_rsp_pending = FALSE; \
117}
118
The Android Open Source Project5738f832012-12-12 16:00:35 -0800119/*****************************************************************************
120** Local type definitions
121******************************************************************************/
122typedef struct {
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800123 UINT8 bNotify;
124 UINT8 label;
125} btif_rc_reg_notifications_t;
126
127typedef struct
128{
129 UINT8 label;
130 UINT8 ctype;
131 BOOLEAN is_rsp_pending;
132} btif_rc_cmd_ctxt_t;
133
134/* TODO : Merge btif_rc_reg_notifications_t and btif_rc_cmd_ctxt_t to a single struct */
135typedef struct {
The Android Open Source Project5738f832012-12-12 16:00:35 -0800136 BOOLEAN rc_connected;
137 UINT8 rc_handle;
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800138 tBTA_AV_FEAT rc_features;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800139 BD_ADDR rc_addr;
140 UINT16 rc_pending_play;
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800141 btif_rc_cmd_ctxt_t rc_pdu_info[MAX_CMD_QUEUE_LEN];
142 btif_rc_reg_notifications_t rc_notif[MAX_RC_NOTIFICATIONS];
Satya Calloji247c68f2013-08-01 02:14:43 -0700143 unsigned int rc_volume;
144 uint8_t rc_vol_label;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800145} btif_rc_cb_t;
146
Satya Calloji247c68f2013-08-01 02:14:43 -0700147typedef struct {
148 BOOLEAN in_use;
149 UINT8 lbl;
150 UINT8 handle;
151} rc_transaction_t;
152
153typedef struct
154{
155 pthread_mutex_t lbllock;
156 rc_transaction_t transaction[MAX_TRANSACTIONS_PER_SESSION];
157} rc_device_t;
158
159
160rc_device_t device;
161
The Android Open Source Project5738f832012-12-12 16:00:35 -0800162#define MAX_UINPUT_PATHS 3
163static const char* uinput_dev_path[] =
164 {"/dev/uinput", "/dev/input/uinput", "/dev/misc/uinput" };
165static int uinput_fd = -1;
166
167static int send_event (int fd, uint16_t type, uint16_t code, int32_t value);
168static void send_key (int fd, uint16_t key, int pressed);
169static int uinput_driver_check();
170static int uinput_create(char *name);
171static int init_uinput (void);
172static void close_uinput (void);
Matthew Xiea7ae4a12013-10-24 01:09:52 -0700173static BOOLEAN dev_blacklisted_for_absolute_volume(BD_ADDR peer_dev);
pramod kotreshappa6fa16452014-09-10 20:04:20 -0700174#if (AVRC_CTLR_INCLUDED == TRUE)
175static BOOLEAN conn_status = FALSE;
176#endif
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800177static const struct {
The Android Open Source Project5738f832012-12-12 16:00:35 -0800178 const char *name;
179 uint8_t avrcp;
180 uint16_t mapped_id;
181 uint8_t release_quirk;
182} key_map[] = {
183 { "PLAY", AVRC_ID_PLAY, KEY_PLAYCD, 1 },
184 { "STOP", AVRC_ID_STOP, KEY_STOPCD, 0 },
185 { "PAUSE", AVRC_ID_PAUSE, KEY_PAUSECD, 1 },
186 { "FORWARD", AVRC_ID_FORWARD, KEY_NEXTSONG, 0 },
187 { "BACKWARD", AVRC_ID_BACKWARD, KEY_PREVIOUSSONG, 0 },
188 { "REWIND", AVRC_ID_REWIND, KEY_REWIND, 0 },
John Du98497a52013-06-24 19:18:56 -0700189 { "FAST FORWARD", AVRC_ID_FAST_FOR, KEY_FAST_FORWARD, 0 },
The Android Open Source Project5738f832012-12-12 16:00:35 -0800190 { NULL, 0, 0, 0 }
191};
The Android Open Source Project5738f832012-12-12 16:00:35 -0800192
Matthew Xie7850a932013-11-05 17:19:39 -0800193/* the rc_black_addr_prefix and rc_white_addr_prefix are used to correct
194 * IOP issues of absolute volume feature
195 * We encoutered A2DP headsets/carkits advertising absolute volume but buggy.
196 * We would like to blacklist those devices.
197 * But we donot have a full list of the bad devices. So as a temp fix, we
198 * are blacklisting all the devices except the devices we have well tested,
199 * the ones in the whitelist.
200 *
201 * For now, only the rc_white_addr_prefix is used in the code while
202 * rc_black_addr_prefix is kept here for future long term solution.
203 */
Matthew Xiea7ae4a12013-10-24 01:09:52 -0700204static const UINT8 rc_black_addr_prefix[][3] = {
Matthew Xie7850a932013-11-05 17:19:39 -0800205 {0x0, 0x18, 0x6B}, // LG HBS-730
Matthew Xiea7ae4a12013-10-24 01:09:52 -0700206 {0x0, 0x26, 0x7E} // VW Passat
207};
208
Matthew Xie7850a932013-11-05 17:19:39 -0800209static const UINT8 rc_white_addr_prefix[][3] = {
210 {0x94, 0xCE, 0x2C}, // Sony SBH50
Ayan Ghosh562fb682014-08-12 13:04:46 +0530211 {0x30, 0x17, 0xC8}, // Sony wm600
212 {0x00, 0x15, 0x83}, // BlueSoleil dongle
213 {0x00, 0x80, 0x98}, // PTS dongle
214 {0x48, 0xC1, 0xAC}, // Plantronics Backbeat Go
Ayan Ghosh06917da2014-11-10 22:02:07 +0530215 {0x00, 0x1B, 0xDC}, // PTS dongle 2
216 {0x00, 0x19, 0x8E}, // Demant
217 {0x04, 0x88, 0xE2}, // Apple
pramod kotreshappab1c3b3d2015-02-05 11:49:34 -0800218 {0x00, 0x0C, 0x8A}, // Bose
219 {0x1C, 0x48, 0xF9} // Jabra Pulse
Thomas.TT_Linc9fbcde2014-04-07 16:13:06 +0800220};
221
222static const char* rc_white_name[] = {
223 "SBH50",
224 "MW600"
Matthew Xie7850a932013-11-05 17:19:39 -0800225};
226
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800227static void send_reject_response (UINT8 rc_handle, UINT8 label,
228 UINT8 pdu, UINT8 status);
229static UINT8 opcode_from_pdu(UINT8 pdu);
230static void send_metamsg_rsp (UINT8 rc_handle, UINT8 label,
231 tBTA_AV_CODE code, tAVRC_RESPONSE *pmetamsg_resp);
Satya Calloji247c68f2013-08-01 02:14:43 -0700232static void register_volumechange(UINT8 label);
233static void lbl_init();
234static void lbl_destroy();
235static void init_all_transactions();
236static bt_status_t get_transaction(rc_transaction_t **ptransaction);
237static void release_transaction(UINT8 label);
238static rc_transaction_t* get_transaction_by_lbl(UINT8 label);
239static void handle_rc_metamsg_rsp(tBTA_AV_META_MSG *pmeta_msg);
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800240static void btif_rc_upstreams_evt(UINT16 event, tAVRC_COMMAND* p_param, UINT8 ctype, UINT8 label);
Satya Calloji247c68f2013-08-01 02:14:43 -0700241static void btif_rc_upstreams_rsp_evt(UINT16 event, tAVRC_RESPONSE *pavrc_resp, UINT8 ctype, UINT8 label);
Ayan Ghoshd74324f2014-07-25 17:51:32 +0530242static bt_status_t set_addrplayer_rsp(btrc_status_t status_code);
243
244/*Added for Browsing Message Response */
245static void send_browsemsg_rsp (UINT8 rc_handle, UINT8 label,
246 tBTA_AV_CODE code, tAVRC_RESPONSE *pmetamsg_resp);
247
The Android Open Source Project5738f832012-12-12 16:00:35 -0800248
249/*****************************************************************************
250** Static variables
251******************************************************************************/
252static btif_rc_cb_t btif_rc_cb;
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800253static btrc_callbacks_t *bt_rc_callbacks = NULL;
Mike Lockwood4ad470e2014-06-02 16:21:49 -0700254static btrc_ctrl_callbacks_t *bt_rc_ctrl_callbacks = NULL;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800255
256/*****************************************************************************
257** Static functions
258******************************************************************************/
259
260/*****************************************************************************
261** Externs
262******************************************************************************/
263extern BOOLEAN btif_hf_call_terminated_recently();
264extern BOOLEAN check_cod(const bt_bdaddr_t *remote_bdaddr, uint32_t cod);
Ayan Ghoshd74324f2014-07-25 17:51:32 +0530265extern BOOLEAN btif_hf_is_call_idle();
The Android Open Source Project5738f832012-12-12 16:00:35 -0800266
267/*****************************************************************************
268** Functions
269******************************************************************************/
270
The Android Open Source Project5738f832012-12-12 16:00:35 -0800271/*****************************************************************************
272** Local uinput helper functions
273******************************************************************************/
274int send_event (int fd, uint16_t type, uint16_t code, int32_t value)
275{
276 struct uinput_event event;
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700277 BTIF_TRACE_DEBUG("%s type:%u code:%u value:%d", __FUNCTION__,
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800278 type, code, value);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800279 memset(&event, 0, sizeof(event));
280 event.type = type;
281 event.code = code;
282 event.value = value;
283
Sharvil Nanavati405b5c92016-06-17 14:15:46 -0700284 return TEMP_FAILURE_RETRY(write(fd, &event, sizeof(event)));
The Android Open Source Project5738f832012-12-12 16:00:35 -0800285}
286
287void send_key (int fd, uint16_t key, int pressed)
288{
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700289 BTIF_TRACE_DEBUG("%s fd:%d key:%u pressed:%d", __FUNCTION__,
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800290 fd, key, pressed);
291
292 if (fd < 0)
293 {
The Android Open Source Project5738f832012-12-12 16:00:35 -0800294 return;
295 }
296
rakesh reddy03b63652014-08-14 11:58:45 +0530297 BTIF_TRACE_IMP("AVRCP: Send key %d (%d) fd=%d", key, pressed, fd);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800298 send_event(fd, EV_KEY, key, pressed);
299 send_event(fd, EV_SYN, SYN_REPORT, 0);
300}
301
302/************** uinput related functions **************/
303int uinput_driver_check()
304{
305 uint32_t i;
306 for (i=0; i < MAX_UINPUT_PATHS; i++)
307 {
308 if (access(uinput_dev_path[i], O_RDWR) == 0) {
309 return 0;
310 }
311 }
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700312 BTIF_TRACE_ERROR("%s ERROR: uinput device is not in the system", __FUNCTION__);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800313 return -1;
314}
315
316int uinput_create(char *name)
317{
318 struct uinput_dev dev;
319 int fd, err, x = 0;
320
321 for(x=0; x < MAX_UINPUT_PATHS; x++)
322 {
Sharvil Nanavati405b5c92016-06-17 14:15:46 -0700323 fd = TEMP_FAILURE_RETRY(open(uinput_dev_path[x], O_RDWR));
The Android Open Source Project5738f832012-12-12 16:00:35 -0800324 if (fd < 0)
325 continue;
326 break;
327 }
328 if (x == MAX_UINPUT_PATHS) {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700329 BTIF_TRACE_ERROR("%s ERROR: uinput device open failed", __FUNCTION__);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800330 return -1;
331 }
332 memset(&dev, 0, sizeof(dev));
333 if (name)
334 strncpy(dev.name, name, UINPUT_MAX_NAME_SIZE);
335
336 dev.id.bustype = BUS_BLUETOOTH;
337 dev.id.vendor = 0x0000;
338 dev.id.product = 0x0000;
339 dev.id.version = 0x0000;
340
Sharvil Nanavati405b5c92016-06-17 14:15:46 -0700341 if (TEMP_FAILURE_RETRY(write(fd, &dev, sizeof(dev))) < 0) {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700342 BTIF_TRACE_ERROR("%s Unable to write device information", __FUNCTION__);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800343 close(fd);
344 return -1;
345 }
346
Sharvil Nanavati405b5c92016-06-17 14:15:46 -0700347 TEMP_FAILURE_RETRY(ioctl(fd, UI_SET_EVBIT, EV_KEY));
348 TEMP_FAILURE_RETRY(ioctl(fd, UI_SET_EVBIT, EV_REL));
349 TEMP_FAILURE_RETRY(ioctl(fd, UI_SET_EVBIT, EV_SYN));
The Android Open Source Project5738f832012-12-12 16:00:35 -0800350
351 for (x = 0; key_map[x].name != NULL; x++)
Sharvil Nanavati405b5c92016-06-17 14:15:46 -0700352 TEMP_FAILURE_RETRY(ioctl(fd, UI_SET_KEYBIT, key_map[x].mapped_id));
The Android Open Source Project5738f832012-12-12 16:00:35 -0800353
354 for(x = 0; x < KEY_MAX; x++)
Sharvil Nanavati405b5c92016-06-17 14:15:46 -0700355 TEMP_FAILURE_RETRY(ioctl(fd, UI_SET_KEYBIT, x));
The Android Open Source Project5738f832012-12-12 16:00:35 -0800356
Sharvil Nanavati405b5c92016-06-17 14:15:46 -0700357 if (TEMP_FAILURE_RETRY(ioctl(fd, UI_DEV_CREATE, NULL)) < 0) {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700358 BTIF_TRACE_ERROR("%s Unable to create uinput device", __FUNCTION__);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800359 close(fd);
360 return -1;
361 }
362 return fd;
363}
364
365int init_uinput (void)
366{
367 char *name = "AVRCP";
368
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700369 BTIF_TRACE_DEBUG("%s", __FUNCTION__);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800370 uinput_fd = uinput_create(name);
371 if (uinput_fd < 0) {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700372 BTIF_TRACE_ERROR("%s AVRCP: Failed to initialize uinput for %s (%d)",
The Android Open Source Project5738f832012-12-12 16:00:35 -0800373 __FUNCTION__, name, uinput_fd);
374 } else {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700375 BTIF_TRACE_DEBUG("%s AVRCP: Initialized uinput for %s (fd=%d)",
The Android Open Source Project5738f832012-12-12 16:00:35 -0800376 __FUNCTION__, name, uinput_fd);
377 }
378 return uinput_fd;
379}
380
381void close_uinput (void)
382{
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700383 BTIF_TRACE_DEBUG("%s", __FUNCTION__);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800384 if (uinput_fd > 0) {
Sharvil Nanavati405b5c92016-06-17 14:15:46 -0700385 TEMP_FAILURE_RETRY(ioctl(uinput_fd, UI_DEV_DESTROY));
The Android Open Source Project5738f832012-12-12 16:00:35 -0800386
387 close(uinput_fd);
388 uinput_fd = -1;
389 }
390}
The Android Open Source Project5738f832012-12-12 16:00:35 -0800391
Satya Calloji247c68f2013-08-01 02:14:43 -0700392void handle_rc_features()
393{
Ayan Ghoshf2a653d2014-09-18 20:08:30 +0530394 if (bt_rc_callbacks != NULL)
Matthew Xiea7ae4a12013-10-24 01:09:52 -0700395 {
Ayan Ghoshf2a653d2014-09-18 20:08:30 +0530396 /*Enabling Absolute volume and other avrcp TG specific features only if A2dp Src and
397 Avrcp TG role is activated along with Avrcp CT. Check for bt_rc_callbacks not equal to
398 null assures that avrcp TG service is up
399 */
400 btrc_remote_features_t rc_features = BTRC_FEAT_NONE;
401 bt_bdaddr_t rc_addr;
402 bt_bdaddr_t avdtp_addr;
403 bdstr_t addr1, addr2;
Matthew Xiea7ae4a12013-10-24 01:09:52 -0700404
Ayan Ghoshf2a653d2014-09-18 20:08:30 +0530405 bdcpy(rc_addr.address, btif_rc_cb.rc_addr);
406 avdtp_addr = btif_av_get_addr();
407
408 BTIF_TRACE_DEBUG("AVDTP Address : %s AVCTP address: %s",
409 bd2str(&avdtp_addr, &addr1), bd2str(&rc_addr, &addr2));
410
411 if (dev_blacklisted_for_absolute_volume(btif_rc_cb.rc_addr) ||
412 bdcmp(avdtp_addr.address, rc_addr.address))
413 {
414 btif_rc_cb.rc_features &= ~BTA_AV_FEAT_ADV_CTRL;
415 }
416
417 if (btif_rc_cb.rc_features & BTA_AV_FEAT_BROWSE)
418 {
419 rc_features |= BTRC_FEAT_BROWSE;
420 }
421 if ( (btif_rc_cb.rc_features & BTA_AV_FEAT_ADV_CTRL) &&
422 (btif_rc_cb.rc_features & BTA_AV_FEAT_RCTG))
423 {
424 rc_features |= BTRC_FEAT_ABSOLUTE_VOLUME;
425 }
426 if (btif_rc_cb.rc_features & BTA_AV_FEAT_METADATA)
427 {
428 rc_features |= BTRC_FEAT_METADATA;
429 }
rakesh reddy03b63652014-08-14 11:58:45 +0530430 BTIF_TRACE_IMP("%s: rc_features=0x%x", __FUNCTION__, rc_features);
Ayan Ghoshf2a653d2014-09-18 20:08:30 +0530431
432 HAL_CBACK(bt_rc_callbacks, remote_features_cb, &rc_addr, rc_features)
Satya Calloji247c68f2013-08-01 02:14:43 -0700433
434#if (AVRC_ADV_CTRL_INCLUDED == TRUE)
Ayan Ghoshf2a653d2014-09-18 20:08:30 +0530435 BTIF_TRACE_DEBUG("Checking for feature flags in btif_rc_handler with label %d",
Satya Calloji247c68f2013-08-01 02:14:43 -0700436 btif_rc_cb.rc_vol_label);
Ayan Ghoshf2a653d2014-09-18 20:08:30 +0530437 // Register for volume change on connect
438 if(btif_rc_cb.rc_features & BTA_AV_FEAT_ADV_CTRL &&
Satya Calloji247c68f2013-08-01 02:14:43 -0700439 btif_rc_cb.rc_features & BTA_AV_FEAT_RCTG)
Ayan Ghoshf2a653d2014-09-18 20:08:30 +0530440 {
441 rc_transaction_t *p_transaction=NULL;
442 bt_status_t status = BT_STATUS_NOT_READY;
443 if(MAX_LABEL==btif_rc_cb.rc_vol_label)
Satya Calloji247c68f2013-08-01 02:14:43 -0700444 {
Ayan Ghoshf2a653d2014-09-18 20:08:30 +0530445 status=get_transaction(&p_transaction);
Satya Calloji247c68f2013-08-01 02:14:43 -0700446 }
447 else
Ayan Ghoshf2a653d2014-09-18 20:08:30 +0530448 {
449 p_transaction=get_transaction_by_lbl(btif_rc_cb.rc_vol_label);
450 if(NULL!=p_transaction)
451 {
452 BTIF_TRACE_DEBUG("register_volumechange already in progress for label %d",
453 btif_rc_cb.rc_vol_label);
454 return;
455 }
456 else
457 {
458 status=get_transaction(&p_transaction);
459 }
460 }
Satya Calloji247c68f2013-08-01 02:14:43 -0700461
Ayan Ghoshf2a653d2014-09-18 20:08:30 +0530462 if(BT_STATUS_SUCCESS == status && NULL!=p_transaction)
463 {
464 btif_rc_cb.rc_vol_label=p_transaction->lbl;
465 register_volumechange(btif_rc_cb.rc_vol_label);
466 }
467 }
Satya Calloji247c68f2013-08-01 02:14:43 -0700468#endif
Ayan Ghoshf2a653d2014-09-18 20:08:30 +0530469 }
470 else
471 {
472 /*Disable all TG related bits if AVRCP TG feature is not enabled*/
473 BTIF_TRACE_WARNING("Avrcp TG role not enabled, disabling TG specific featuremask");
474 btif_rc_cb.rc_features &= ~BTA_AV_FEAT_ADV_CTRL;
AnubhavGuptad17f8cb2014-11-01 18:09:01 +0530475 btif_rc_cb.rc_features &= ~BTA_AV_FEAT_BROWSE;
476 btif_rc_cb.rc_features &= ~BTA_AV_FEAT_METADATA;
Ayan Ghoshf2a653d2014-09-18 20:08:30 +0530477 }
Satya Calloji247c68f2013-08-01 02:14:43 -0700478}
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800479
The Android Open Source Project5738f832012-12-12 16:00:35 -0800480
481/***************************************************************************
482 * Function handle_rc_connect
483 *
John Du98497a52013-06-24 19:18:56 -0700484 * - Argument: tBTA_AV_RC_OPEN RC open data structure
The Android Open Source Project5738f832012-12-12 16:00:35 -0800485 *
486 * - Description: RC connection event handler
487 *
488 ***************************************************************************/
489void handle_rc_connect (tBTA_AV_RC_OPEN *p_rc_open)
490{
rakesh reddy03b63652014-08-14 11:58:45 +0530491 BTIF_TRACE_IMP("%s: rc_handle: %d", __FUNCTION__, p_rc_open->rc_handle);
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800492 bt_status_t result = BT_STATUS_SUCCESS;
493 int i;
494 char bd_str[18];
Mike Lockwood93912472014-06-26 11:08:24 -0700495#if (AVRC_CTLR_INCLUDED == TRUE)
496 bt_bdaddr_t rc_addr;
497#endif
The Android Open Source Project5738f832012-12-12 16:00:35 -0800498
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800499 if(p_rc_open->status == BTA_AV_SUCCESS)
500 {
Rohit Singha9fb00a2013-07-27 14:46:29 +0530501 //check if already some RC is connected
502 if (btif_rc_cb.rc_connected)
503 {
504 BTIF_TRACE_ERROR("Got RC OPEN in connected state, Connected RC: %d \
505 and Current RC: %d", btif_rc_cb.rc_handle,p_rc_open->rc_handle );
506 if ((btif_rc_cb.rc_handle != p_rc_open->rc_handle)
507 && (bdcmp(btif_rc_cb.rc_addr, p_rc_open->peer_addr)))
508 {
509 BTIF_TRACE_DEBUG("Got RC connected for some other handle");
510 BTA_AvCloseRc(p_rc_open->rc_handle);
511 return;
512 }
513 }
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800514 memcpy(btif_rc_cb.rc_addr, p_rc_open->peer_addr, sizeof(BD_ADDR));
515 btif_rc_cb.rc_features = p_rc_open->peer_features;
Satya Calloji247c68f2013-08-01 02:14:43 -0700516 btif_rc_cb.rc_vol_label=MAX_LABEL;
517 btif_rc_cb.rc_volume=MAX_VOLUME;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800518
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800519 btif_rc_cb.rc_connected = TRUE;
520 btif_rc_cb.rc_handle = p_rc_open->rc_handle;
521
Satya Calloji247c68f2013-08-01 02:14:43 -0700522 /* on locally initiated connection we will get remote features as part of connect */
523 if (btif_rc_cb.rc_features != 0)
524 handle_rc_features();
Ayan Ghoshf2a653d2014-09-18 20:08:30 +0530525 if (bt_rc_callbacks)
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800526 {
Ayan Ghoshf2a653d2014-09-18 20:08:30 +0530527 result = uinput_driver_check();
528 if(result == BT_STATUS_SUCCESS)
529 {
530 init_uinput();
531 }
532 }
533 else
534 {
535 BTIF_TRACE_WARNING("Avrcp TG role not enabled, not initializing UInput");
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800536 }
Mike Lockwood4ad470e2014-06-02 16:21:49 -0700537#if (AVRC_CTLR_INCLUDED == TRUE)
538 bdcpy(rc_addr.address, btif_rc_cb.rc_addr);
539 /* report connection state if device is AVRCP target */
pramod kotreshappa6fa16452014-09-10 20:04:20 -0700540 if (btif_rc_cb.rc_features & BTA_AV_FEAT_RCTG)
541 {
Mike Lockwood4ad470e2014-06-02 16:21:49 -0700542 HAL_CBACK(bt_rc_ctrl_callbacks, connection_state_cb, TRUE, &rc_addr);
pramod kotreshappa6fa16452014-09-10 20:04:20 -0700543 conn_status = TRUE;
544 }
545 else
546 {
547 BTIF_TRACE_ERROR("RC connection state not updated to upper layer");
548 conn_status = FALSE;
Mike Lockwood4ad470e2014-06-02 16:21:49 -0700549 }
550#endif
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800551 }
552 else
553 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700554 BTIF_TRACE_ERROR("%s Connect failed with error code: %d",
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800555 __FUNCTION__, p_rc_open->status);
556 btif_rc_cb.rc_connected = FALSE;
557 }
The Android Open Source Project5738f832012-12-12 16:00:35 -0800558}
559
560/***************************************************************************
561 * Function handle_rc_disconnect
562 *
John Du98497a52013-06-24 19:18:56 -0700563 * - Argument: tBTA_AV_RC_CLOSE RC close data structure
The Android Open Source Project5738f832012-12-12 16:00:35 -0800564 *
565 * - Description: RC disconnection event handler
566 *
567 ***************************************************************************/
568void handle_rc_disconnect (tBTA_AV_RC_CLOSE *p_rc_close)
569{
Mike Lockwood4ad470e2014-06-02 16:21:49 -0700570#if (AVRC_CTLR_INCLUDED == TRUE)
571 bt_bdaddr_t rc_addr;
572 tBTA_AV_FEAT features;
573#endif
rakesh reddy03b63652014-08-14 11:58:45 +0530574 BTIF_TRACE_IMP("%s: rc_handle: %d", __FUNCTION__, p_rc_close->rc_handle);
Rohit Singha9fb00a2013-07-27 14:46:29 +0530575 if ((p_rc_close->rc_handle != btif_rc_cb.rc_handle)
576 && (bdcmp(btif_rc_cb.rc_addr, p_rc_close->peer_addr)))
577 {
578 BTIF_TRACE_ERROR("Got disconnect of unknown device");
579 return;
580 }
The Android Open Source Project5738f832012-12-12 16:00:35 -0800581 btif_rc_cb.rc_handle = 0;
582 btif_rc_cb.rc_connected = FALSE;
583 memset(btif_rc_cb.rc_addr, 0, sizeof(BD_ADDR));
Nitin Srivastava68c53de2014-02-13 19:31:40 +0530584 memset(btif_rc_cb.rc_notif, 0, sizeof(btif_rc_cb.rc_notif));
Mike Lockwood4ad470e2014-06-02 16:21:49 -0700585#if (AVRC_CTLR_INCLUDED == TRUE)
586 features = btif_rc_cb.rc_features;
587#endif
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800588 btif_rc_cb.rc_features = 0;
Satya Calloji247c68f2013-08-01 02:14:43 -0700589 btif_rc_cb.rc_vol_label=MAX_LABEL;
590 btif_rc_cb.rc_volume=MAX_VOLUME;
591 init_all_transactions();
Ayan Ghoshf2a653d2014-09-18 20:08:30 +0530592 if (bt_rc_callbacks != NULL)
593 {
594 close_uinput();
595 }
596 else
597 {
598 BTIF_TRACE_WARNING("Avrcp TG role not enabled, not closing UInput");
599 }
Mike Lockwood4ad470e2014-06-02 16:21:49 -0700600#if (AVRC_CTLR_INCLUDED == TRUE)
601 bdcpy(rc_addr.address, btif_rc_cb.rc_addr);
602#endif
603 memset(btif_rc_cb.rc_addr, 0, sizeof(BD_ADDR));
604#if (AVRC_CTLR_INCLUDED == TRUE)
605 /* report connection state if device is AVRCP target */
pramod kotreshappa6fa16452014-09-10 20:04:20 -0700606 if (features & BTA_AV_FEAT_RCTG)
607 {
Mike Lockwood4ad470e2014-06-02 16:21:49 -0700608 HAL_CBACK(bt_rc_ctrl_callbacks, connection_state_cb, FALSE, &rc_addr);
pramod kotreshappa6fa16452014-09-10 20:04:20 -0700609 conn_status = FALSE;
Mike Lockwood4ad470e2014-06-02 16:21:49 -0700610 }
611#endif
The Android Open Source Project5738f832012-12-12 16:00:35 -0800612}
613
614/***************************************************************************
615 * Function handle_rc_passthrough_cmd
616 *
617 * - Argument: tBTA_AV_RC rc_id remote control command ID
618 * tBTA_AV_STATE key_state status of key press
619 *
620 * - Description: Remote control command handler
621 *
622 ***************************************************************************/
623void handle_rc_passthrough_cmd ( tBTA_AV_REMOTE_CMD *p_remote_cmd)
624{
625 const char *status;
626 int pressed, i;
627
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700628 BTIF_TRACE_DEBUG("%s: p_remote_cmd->rc_id=%d", __FUNCTION__, p_remote_cmd->rc_id);
Ajay Kumarc2dffa22014-06-11 22:09:20 +0530629 if (p_remote_cmd == NULL)
630 return;
John Du98497a52013-06-24 19:18:56 -0700631
The Android Open Source Project5738f832012-12-12 16:00:35 -0800632 /* If AVRC is open and peer sends PLAY but there is no AVDT, then we queue-up this PLAY */
633 if (p_remote_cmd)
634 {
635 /* queue AVRC PLAY if GAVDTP Open notification to app is pending (2 second timer) */
636 if ((p_remote_cmd->rc_id == BTA_AV_RC_PLAY) && (!btif_av_is_connected()))
637 {
638 if (p_remote_cmd->key_state == AVRC_STATE_PRESS)
639 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700640 APPL_TRACE_WARNING("%s: AVDT not open, queuing the PLAY command", __FUNCTION__);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800641 btif_rc_cb.rc_pending_play = TRUE;
642 }
643 return;
644 }
645
646 if ((p_remote_cmd->rc_id == BTA_AV_RC_PAUSE) && (btif_rc_cb.rc_pending_play))
647 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700648 APPL_TRACE_WARNING("%s: Clear the pending PLAY on PAUSE received", __FUNCTION__);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800649 btif_rc_cb.rc_pending_play = FALSE;
650 return;
651 }
652 }
Rohit Singha9fb00a2013-07-27 14:46:29 +0530653
654 if(!btif_av_is_connected())
655 {
656 APPL_TRACE_WARNING("%s: AVDT not open, discarding pass-through command: %d",
657 __FUNCTION__, p_remote_cmd->rc_id);
658 return;
659 }
660
pramod kotreshappa9c67b132014-11-16 17:02:45 -0800661 if ((p_remote_cmd->rc_id == BTA_AV_RC_STOP) && (!btif_av_stream_started_ready()))
662 {
663 APPL_TRACE_WARNING("%s: Stream suspended, ignore STOP cmd",__FUNCTION__);
664 return;
665 }
666
The Android Open Source Project5738f832012-12-12 16:00:35 -0800667 if (p_remote_cmd->key_state == AVRC_STATE_RELEASE) {
668 status = "released";
669 pressed = 0;
670 } else {
671 status = "pressed";
672 pressed = 1;
673 }
674
John Du98497a52013-06-24 19:18:56 -0700675 if (p_remote_cmd->rc_id == BTA_AV_RC_FAST_FOR || p_remote_cmd->rc_id == BTA_AV_RC_REWIND) {
676 HAL_CBACK(bt_rc_callbacks, passthrough_cmd_cb, p_remote_cmd->rc_id, pressed);
677 return;
678 }
679
The Android Open Source Project5738f832012-12-12 16:00:35 -0800680 for (i = 0; key_map[i].name != NULL; i++) {
681 if (p_remote_cmd->rc_id == key_map[i].avrcp) {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700682 BTIF_TRACE_DEBUG("%s: %s %s", __FUNCTION__, key_map[i].name, status);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800683
684 /* MusicPlayer uses a long_press_timeout of 1 second for PLAYPAUSE button
685 * and maps that to autoshuffle. So if for some reason release for PLAY/PAUSE
686 * comes 1 second after the press, the MediaPlayer UI goes into a bad state.
687 * The reason for the delay could be sniff mode exit or some AVDTP procedure etc.
688 * The fix is to generate a release right after the press and drown the 'actual'
689 * release.
690 */
691 if ((key_map[i].release_quirk == 1) && (pressed == 0))
692 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700693 BTIF_TRACE_DEBUG("%s: AVRC %s Release Faked earlier, drowned now",
The Android Open Source Project5738f832012-12-12 16:00:35 -0800694 __FUNCTION__, key_map[i].name);
695 return;
696 }
The Android Open Source Project5738f832012-12-12 16:00:35 -0800697 send_key(uinput_fd, key_map[i].mapped_id, pressed);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800698 if ((key_map[i].release_quirk == 1) && (pressed == 1))
699 {
700 GKI_delay(30); // 30ms
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700701 BTIF_TRACE_DEBUG("%s: AVRC %s Release quirk enabled, send release now",
The Android Open Source Project5738f832012-12-12 16:00:35 -0800702 __FUNCTION__, key_map[i].name);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800703 send_key(uinput_fd, key_map[i].mapped_id, 0);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800704 }
705 break;
706 }
707 }
708
709 if (key_map[i].name == NULL)
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700710 BTIF_TRACE_ERROR("%s AVRCP: unknown button 0x%02X %s", __FUNCTION__,
The Android Open Source Project5738f832012-12-12 16:00:35 -0800711 p_remote_cmd->rc_id, status);
712}
713
Mike Lockwood4ad470e2014-06-02 16:21:49 -0700714/***************************************************************************
715 * Function handle_rc_passthrough_rsp
716 *
717 * - Argument: tBTA_AV_REMOTE_RSP passthrough command response
718 *
719 * - Description: Remote control passthrough response handler
720 *
721 ***************************************************************************/
722void handle_rc_passthrough_rsp ( tBTA_AV_REMOTE_RSP *p_remote_rsp)
723{
724#if (AVRC_CTLR_INCLUDED == TRUE)
725 const char *status;
726 if (btif_rc_cb.rc_features & BTA_AV_FEAT_RCTG)
727 {
728 int key_state;
729 if (p_remote_rsp->key_state == AVRC_STATE_RELEASE)
730 {
731 status = "released";
732 key_state = 1;
733 }
734 else
735 {
736 status = "pressed";
737 key_state = 0;
738 }
739
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700740 BTIF_TRACE_DEBUG("%s: rc_id=%d status=%s", __FUNCTION__, p_remote_rsp->rc_id, status);
Mike Lockwood4ad470e2014-06-02 16:21:49 -0700741
742 release_transaction(p_remote_rsp->label);
743 HAL_CBACK(bt_rc_ctrl_callbacks, passthrough_rsp_cb, p_remote_rsp->rc_id, key_state);
744 }
745 else
746 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700747 BTIF_TRACE_ERROR("%s DUT does not support AVRCP controller role", __FUNCTION__);
Mike Lockwood4ad470e2014-06-02 16:21:49 -0700748 }
749#else
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700750 BTIF_TRACE_ERROR("%s AVRCP controller role is not enabled", __FUNCTION__);
Mike Lockwood4ad470e2014-06-02 16:21:49 -0700751#endif
752}
753
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800754void handle_uid_changed_notification(tBTA_AV_META_MSG *pmeta_msg, tAVRC_COMMAND *pavrc_command)
The Android Open Source Project5738f832012-12-12 16:00:35 -0800755{
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800756 tAVRC_RESPONSE avrc_rsp = {0};
757 avrc_rsp.rsp.pdu = pavrc_command->pdu;
758 avrc_rsp.rsp.status = AVRC_STS_NO_ERROR;
759 avrc_rsp.rsp.opcode = pavrc_command->cmd.opcode;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800760
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800761 avrc_rsp.reg_notif.event_id = pavrc_command->reg_notif.event_id;
762 avrc_rsp.reg_notif.param.uid_counter = 0;
763
764 send_metamsg_rsp(pmeta_msg->rc_handle, pmeta_msg->label, AVRC_RSP_INTERIM, &avrc_rsp);
765 send_metamsg_rsp(pmeta_msg->rc_handle, pmeta_msg->label, AVRC_RSP_CHANGED, &avrc_rsp);
766
767}
768
769
770/***************************************************************************
771 * Function handle_rc_metamsg_cmd
772 *
773 * - Argument: tBTA_AV_VENDOR Structure containing the received
774 * metamsg command
775 *
776 * - Description: Remote control metamsg command handler (AVRCP 1.3)
777 *
778 ***************************************************************************/
779void handle_rc_metamsg_cmd (tBTA_AV_META_MSG *pmeta_msg)
780{
781 /* Parse the metamsg command and pass it on to BTL-IFS */
782 UINT8 scratch_buf[512] = {0};
783 tAVRC_COMMAND avrc_command = {0};
784 tAVRC_STS status;
785 int param_len;
786
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700787 BTIF_TRACE_EVENT("+ %s", __FUNCTION__);
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800788
789 if (pmeta_msg->p_msg->hdr.opcode != AVRC_OP_VENDOR)
790 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700791 BTIF_TRACE_WARNING("Invalid opcode: %x", pmeta_msg->p_msg->hdr.opcode);
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800792 return;
793 }
794 if (pmeta_msg->len < 3)
795 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700796 BTIF_TRACE_WARNING("Invalid length.Opcode: 0x%x, len: 0x%x", pmeta_msg->p_msg->hdr.opcode,
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800797 pmeta_msg->len);
798 return;
799 }
800
801 if (pmeta_msg->code >= AVRC_RSP_NOT_IMPL)
802 {
Satya Calloji247c68f2013-08-01 02:14:43 -0700803#if (AVRC_ADV_CTRL_INCLUDED == TRUE)
804{
805 rc_transaction_t *transaction=NULL;
806 transaction=get_transaction_by_lbl(pmeta_msg->label);
807 if(NULL!=transaction)
808 {
809 handle_rc_metamsg_rsp(pmeta_msg);
810 }
811 else
812 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700813 BTIF_TRACE_DEBUG("%s:Discard vendor dependent rsp. code: %d label:%d.",
Satya Calloji247c68f2013-08-01 02:14:43 -0700814 __FUNCTION__, pmeta_msg->code, pmeta_msg->label);
815 }
816 return;
817}
818#else
819{
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700820 BTIF_TRACE_DEBUG("%s:Received vendor dependent rsp. code: %d len: %d. Not processing it.",
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800821 __FUNCTION__, pmeta_msg->code, pmeta_msg->len);
822 return;
Satya Calloji247c68f2013-08-01 02:14:43 -0700823}
824#endif
825 }
826
827 status=AVRC_ParsCommand(pmeta_msg->p_msg, &avrc_command, scratch_buf, sizeof(scratch_buf));
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700828 BTIF_TRACE_DEBUG("Received vendor command.code,PDU and label: %d, %d,%d",pmeta_msg->code,
Satya Calloji247c68f2013-08-01 02:14:43 -0700829 avrc_command.cmd.pdu, pmeta_msg->label);
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800830
831 if (status != AVRC_STS_NO_ERROR)
832 {
833 /* return error */
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700834 BTIF_TRACE_WARNING("%s: Error in parsing received metamsg command. status: 0x%02x",
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800835 __FUNCTION__, status);
836 send_reject_response(pmeta_msg->rc_handle, pmeta_msg->label, avrc_command.pdu, status);
837 }
838 else
839 {
840 /* if RegisterNotification, add it to our registered queue */
841
842 if (avrc_command.cmd.pdu == AVRC_PDU_REGISTER_NOTIFICATION)
843 {
844 UINT8 event_id = avrc_command.reg_notif.event_id;
845 param_len = sizeof(tAVRC_REG_NOTIF_CMD);
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700846 BTIF_TRACE_EVENT("%s:New register notification received.event_id:%s,label:0x%x,code:%x",
Satya Calloji247c68f2013-08-01 02:14:43 -0700847 __FUNCTION__,dump_rc_notification_event_id(event_id), pmeta_msg->label,pmeta_msg->code);
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800848 btif_rc_cb.rc_notif[event_id-1].bNotify = TRUE;
849 btif_rc_cb.rc_notif[event_id-1].label = pmeta_msg->label;
850
851 if(event_id == AVRC_EVT_UIDS_CHANGE)
852 {
853 handle_uid_changed_notification(pmeta_msg, &avrc_command);
854 return;
855 }
856
857 }
858
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700859 BTIF_TRACE_EVENT("%s: Passing received metamsg command to app. pdu: %s",
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800860 __FUNCTION__, dump_rc_pdu(avrc_command.cmd.pdu));
861
862 /* Since handle_rc_metamsg_cmd() itself is called from
863 *btif context, no context switching is required. Invoke
864 * btif_rc_upstreams_evt directly from here. */
865 btif_rc_upstreams_evt((uint16_t)avrc_command.cmd.pdu, &avrc_command, pmeta_msg->code,
Satya Calloji247c68f2013-08-01 02:14:43 -0700866 pmeta_msg->label);
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800867 }
The Android Open Source Project5738f832012-12-12 16:00:35 -0800868}
869
Ayan Ghoshd74324f2014-07-25 17:51:32 +0530870/************************************************************************************
871* Function handle_get_folder_item_mediaplyerlist_cmd
872*
873* - Argument: tBTA_AV_BROWSE_MSG structure containing the received
874* browse message
875* tAVRC_COMMAND structure containing the commands
876* to be updated
877* UINT8 event, variable having value of event.
878*
879* - Description: Handler for get media player list command
880*
881************************************************************************************/
882UINT8 handle_get_folder_item_mediaplyerlist_cmd (tBTA_AV_BROWSE_MSG *pbrowse_msg,
883 tAVRC_COMMAND *cmd, UINT8 *event)
884{
885 UINT8 *p_length, *start_item, *end_item;
886 UINT8 length, xx;
887 *event = pbrowse_msg->p_msg->browse.p_browse_data[0] ;
888 cmd->get_items.pdu = *event;
889 //Check length
890 p_length = &pbrowse_msg->p_msg->browse.p_browse_data[1];
891 BE_STREAM_TO_UINT16(length, p_length);
Ayan Ghosh68f692f2014-09-04 19:40:43 +0530892 if (length < 10)
Ayan Ghoshd74324f2014-07-25 17:51:32 +0530893 {
Ayan Ghosh68f692f2014-09-04 19:40:43 +0530894 BTIF_TRACE_ERROR("GET_FOLDER_ITEMS: length error: =%d", length);
Ayan Ghoshd74324f2014-07-25 17:51:32 +0530895 return TRUE;
896 }
897 else
898 {
899 start_item = &pbrowse_msg->p_msg->browse.p_browse_data[4];
900 BE_STREAM_TO_UINT32(cmd->get_items.start_item ,start_item);
901 BTIF_TRACE_EVENT("pbrowse_msg start_item :%x",cmd->get_items.start_item);
902 end_item = &pbrowse_msg->p_msg->browse.p_browse_data[8];
903 BE_STREAM_TO_UINT32(cmd->get_items.end_item,end_item);
904 BTIF_TRACE_EVENT("pbrowse_msg start_item :%x",cmd->get_items.end_item);
905 cmd->get_items.attr_count = 0xff; /* in MediaPlayerList we don't have attr_id */
906 //Update OPCODE
907 cmd->get_items.opcode = AVRC_OP_BROWSE;
908 cmd->get_items.scope = pbrowse_msg->p_msg->browse.p_browse_data[3] ;
909 cmd->get_items.status = AVRC_STS_NO_ERROR ;
910 for (xx = 0; xx < BTRC_MAX_ELEM_ATTR_SIZE ; xx++)
911 {
912 cmd->get_items.attrs[xx] = 0;
913 }
914 return FALSE;
915 }
916}
917
918/************************************************************************************
919* Function handle_get_folder_item_filesystem_cmd
920*
921* - Argument: tBTA_AV_BROWSE_MSG structure containing the received
922* browse message
923* tAVRC_COMMAND structure containing the commands
924* to be updated
925* UINT8 event, variable having value of event.
926*
927* - Description: Handler for get folder item command
928*
929************************************************************************************/
930UINT8 handle_get_folder_item_filesystem_cmd (tBTA_AV_BROWSE_MSG *pbrowse_msg, tAVRC_COMMAND *cmd,
931 UINT8 *event)
932{
933 UINT8 *p_length, *start_item, *end_item, *p_data;
934 UINT8 length, attr_count = 0, xx;
935 *event = pbrowse_msg->p_msg->browse.p_browse_data[0] ;
936 cmd->get_items.pdu = *event;
937 //Check length
938 p_length = &pbrowse_msg->p_msg->browse.p_browse_data[1];
939 BE_STREAM_TO_UINT16(length, p_length);
940 attr_count = pbrowse_msg->p_msg->browse.p_browse_data[12];
941 BTIF_TRACE_ERROR("GET_FOLDER_ITEMS: attr_count: =%d", attr_count);
942 switch (attr_count)
943 {
944 case 0xff:
945 if (length != 10)
946 {
947 BTIF_TRACE_ERROR("GET_FOLDER_ITEMS: length error: =%d", length);
948 return TRUE;
949 }
950 break;
951 default:
952 if (length != ((attr_count * 4) + 10))
953 {
954 BTIF_TRACE_ERROR("GET_FOLDER_ITEMS: length error: =%d", length);
955 return TRUE;
956 }
957 }
958
959 start_item = &pbrowse_msg->p_msg->browse.p_browse_data[4];
960 BE_STREAM_TO_UINT32(cmd->get_items.start_item ,start_item);
961 BTIF_TRACE_EVENT("pbrowse_msg start_item :%x",cmd->get_items.start_item);
962 end_item = &pbrowse_msg->p_msg->browse.p_browse_data[8];
963 BE_STREAM_TO_UINT32(cmd->get_items.end_item,end_item);
964 BTIF_TRACE_EVENT("pbrowse_msg start_item :%x",cmd->get_items.end_item);
965 cmd->get_items.attr_count = attr_count;
966 if (attr_count == 0)
967 {
968 for (xx = 0; xx < BTRC_MAX_ELEM_ATTR_SIZE; xx++)
969 {
970 cmd->get_items.attrs[xx] = xx + 1;
971 }
972 }
973 else if (attr_count == 0xff) /* no attribute requested */
974 {
975 BTIF_TRACE_DEBUG("No attribute requested");
976 }
Sai Aitharajud12d60e2015-02-06 09:20:32 +0530977 else if (attr_count <= AVRC_MAX_ELEM_ATTR_SIZE)
Ayan Ghoshd74324f2014-07-25 17:51:32 +0530978 {
979 p_data = &pbrowse_msg->p_msg->browse.p_browse_data[13];
980 for (xx = 0; xx < attr_count; xx++)
Amit Goel85a35032014-07-31 20:14:27 -0700981 {
982 if (xx < AVRC_MAX_ELEM_ATTR_SIZE)
983 BE_STREAM_TO_UINT32(cmd->get_items.attrs[xx], p_data)
984 }
Ayan Ghoshd74324f2014-07-25 17:51:32 +0530985 }
986 //Update OPCODE
987 cmd->get_items.opcode = AVRC_OP_BROWSE;
988 cmd->get_items.scope = pbrowse_msg->p_msg->browse.p_browse_data[3] ;
989 cmd->get_items.status = AVRC_STS_NO_ERROR ;
990 return FALSE;
991}
992
993/************************************************************************************
994* Function handle_rc_browsemsg_cmd
995*
996* - Argument: tBTA_AV_BROWSE_MSG structure containing the recieved
997* browse message
998*
999* - Description: Remote Control browse message handler
1000*
1001************************************************************************************/
1002void handle_rc_browsemsg_cmd (tBTA_AV_BROWSE_MSG *pbrowse_msg)
1003{
1004 UINT8 event;
1005 UINT16 length;
1006 tAVRC_COMMAND cmd;
1007 UINT8 *start_item, *p_length, *p_data;
1008 UINT8 *end_item;
1009 tAVRC_RESPONSE avrc_rsp;
1010 UINT8 dropmsg = TRUE;
1011
1012 BTIF_TRACE_EVENT("+ %s", __FUNCTION__);
1013 BTIF_TRACE_EVENT("pbrowse_msg PDU_ID :%x",pbrowse_msg->p_msg->browse.p_browse_data[0]);
1014 BTIF_TRACE_EVENT("pbrowse_msg length :%x",pbrowse_msg->p_msg->browse.browse_len);
1015 switch(pbrowse_msg->p_msg->browse.p_browse_data[0])
1016 {
1017 case AVRC_PDU_GET_FOLDER_ITEMS:
1018 {
1019 UINT8 scope = pbrowse_msg->p_msg->browse.p_browse_data[3];
1020 switch (scope)
1021 {
1022 case AVRC_SCOPE_PLAYER_LIST:
1023 dropmsg = handle_get_folder_item_mediaplyerlist_cmd(pbrowse_msg, &cmd, &event);
1024 break;
1025 case AVRC_SCOPE_FILE_SYSTEM:
1026 case AVRC_SCOPE_NOW_PLAYING:
1027 dropmsg = handle_get_folder_item_filesystem_cmd(pbrowse_msg, &cmd, &event);
1028 break;
1029 }
1030 if (dropmsg == FALSE)
1031 {
1032 btif_rc_upstreams_evt(event,&cmd,0,pbrowse_msg->label);
1033 }
1034 }
1035 break;
1036
1037 case AVRC_PDU_SET_BROWSED_PLAYER:
1038 event = pbrowse_msg->p_msg->browse.p_browse_data[0] ;
1039 cmd.br_player.pdu = event;
1040 //Check for length
1041 p_length = &pbrowse_msg->p_msg->browse.p_browse_data[1];
1042 BE_STREAM_TO_UINT16(length, p_length);
1043 if (length != 0x0002)
1044 {
1045 BTIF_TRACE_ERROR("SET_BROWSED_PLAYERlength error: = %d", length);
1046 }
1047 else
1048 {
1049 p_length = &pbrowse_msg->p_msg->browse.p_browse_data[3];
1050 BE_STREAM_TO_UINT16(cmd.br_player.player_id, p_length);
1051 cmd.br_player.opcode = AVRC_OP_BROWSE;
1052 btif_rc_upstreams_evt(event, &cmd, 0, pbrowse_msg->label);
1053 dropmsg = FALSE;
1054 }
1055 break;
1056
1057 case AVRC_PDU_CHANGE_PATH:
1058 event = pbrowse_msg->p_msg->browse.p_browse_data[0] ;
1059 cmd.chg_path.pdu = event;
1060 p_data = &pbrowse_msg->p_msg->browse.p_browse_data[1];
1061 BE_STREAM_TO_UINT16(length, p_data);
1062 if (length != 11)
1063 {
1064 BTIF_TRACE_ERROR("CHANGE_PATH length error: = %d",length);
1065 }
1066 else
1067 {
1068 p_data = &pbrowse_msg->p_msg->browse.p_browse_data[3];
1069 BE_STREAM_TO_UINT16(cmd.chg_path.uid_counter, p_data);
1070 cmd.chg_path.direction = pbrowse_msg->p_msg->browse.p_browse_data[5];
1071 cmd.chg_path.opcode = AVRC_OP_BROWSE;
1072 cmd.chg_path.status = AVRC_STS_NO_ERROR;
1073 p_data = &pbrowse_msg->p_msg->browse.p_browse_data[6];
1074 BE_STREAM_TO_UINT64(cmd.chg_path.folder_uid, p_data);
1075 btif_rc_upstreams_evt(event, &cmd, 0, pbrowse_msg->label);
1076 dropmsg = FALSE;
1077 }
1078 break;
1079
1080 case AVRC_PDU_GET_ITEM_ATTRIBUTES:
1081 {
1082 UINT16 packet_len;
1083 UINT8 num_attr, index;
1084 event = pbrowse_msg->p_msg->browse.p_browse_data[0] ;
1085 cmd.get_attrs.pdu = event;
1086 p_data = &pbrowse_msg->p_msg->browse.p_browse_data[1];
1087 BE_STREAM_TO_UINT16(packet_len, p_data);
1088 p_data = &pbrowse_msg->p_msg->browse.p_browse_data[14];
1089 BE_STREAM_TO_UINT8(num_attr, p_data);
1090 if (packet_len != ((num_attr * 4) + 12))
1091 {
1092 BTIF_TRACE_ERROR("Get Item Attributes length error: = %d",packet_len);
1093 }
1094 else
1095 {
1096 cmd.get_attrs.status = AVRC_STS_NO_ERROR;
1097 cmd.get_attrs.opcode = AVRC_OP_BROWSE;
1098 cmd.get_attrs.scope = pbrowse_msg->p_msg->browse.p_browse_data[3];
1099 p_data = &pbrowse_msg->p_msg->browse.p_browse_data[4];
1100 BE_STREAM_TO_UINT64(cmd.get_attrs.uid, p_data);
1101 p_data = &pbrowse_msg->p_msg->browse.p_browse_data[12];
1102 BE_STREAM_TO_UINT16(cmd.get_attrs.uid_counter, p_data);
1103 cmd.get_attrs.attr_count = num_attr;
1104 if (num_attr == 0)
1105 {
1106 /* remote requested all Attribute ID*/
1107 for (index = 0; index < BTRC_MAX_ELEM_ATTR_SIZE; index++)
1108 {
1109 cmd.get_attrs.attrs[index] = index + 1;
1110 }
1111 }
1112 else
1113 {
1114 p_data = &pbrowse_msg->p_msg->browse.p_browse_data[15];
1115 BTIF_TRACE_ERROR("GetItemAttr num_attr: = %d", cmd.get_attrs.attr_count);
1116 for (index = 0; index < num_attr ; index++)
1117 {
1118 BE_STREAM_TO_UINT32(cmd.get_attrs.attrs[index], p_data);
1119 BTIF_TRACE_ERROR("GetItemAttr attrid: = %d", cmd.get_attrs.attrs[index]);
1120 }
1121 }
1122 btif_rc_upstreams_evt(event, &cmd, 0, pbrowse_msg->label);
1123 dropmsg = FALSE;
1124 }
1125 }
1126 break;
1127
1128 default:
1129 BTIF_TRACE_ERROR("pbrowse_msg ERROR");
1130 break;
1131 }
1132 if (dropmsg == TRUE)
1133 {
1134 avrc_rsp.rsp.pdu = pbrowse_msg->p_msg->browse.p_browse_data[0];
1135 avrc_rsp.rsp.status = AVRC_STS_BAD_CMD;
1136 avrc_rsp.rsp.opcode = AVRC_OP_BROWSE;
1137 BTIF_TRACE_ERROR("handle_rc_browsemsg_cmd: pbrowse_msg ERROR: %x", avrc_rsp.rsp.pdu);
1138 send_browsemsg_rsp(btif_rc_cb.rc_handle, pbrowse_msg->label, 0, &avrc_rsp);
1139 }
1140
1141}
1142
1143
The Android Open Source Project5738f832012-12-12 16:00:35 -08001144/***************************************************************************
1145 **
1146 ** Function btif_rc_handler
1147 **
1148 ** Description RC event handler
1149 **
1150 ***************************************************************************/
1151void btif_rc_handler(tBTA_AV_EVT event, tBTA_AV *p_data)
1152{
rakesh reddy03b63652014-08-14 11:58:45 +05301153 BTIF_TRACE_IMP ("%s event:%s", __FUNCTION__, dump_rc_event(event));
The Android Open Source Project5738f832012-12-12 16:00:35 -08001154 switch (event)
1155 {
1156 case BTA_AV_RC_OPEN_EVT:
1157 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001158 BTIF_TRACE_DEBUG("Peer_features:%x", p_data->rc_open.peer_features);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001159 handle_rc_connect( &(p_data->rc_open) );
1160 }break;
1161
1162 case BTA_AV_RC_CLOSE_EVT:
1163 {
1164 handle_rc_disconnect( &(p_data->rc_close) );
1165 }break;
1166
1167 case BTA_AV_REMOTE_CMD_EVT:
1168 {
Ayan Ghoshf2a653d2014-09-18 20:08:30 +05301169 if (bt_rc_callbacks != NULL)
Rohit Singha9fb00a2013-07-27 14:46:29 +05301170 {
Ayan Ghoshf2a653d2014-09-18 20:08:30 +05301171 BTIF_TRACE_DEBUG("rc_id:0x%x key_state:%d",
1172 p_data->remote_cmd.rc_id, p_data->remote_cmd.key_state);
1173 /** In race conditions just after 2nd AVRCP is connected
1174 * remote might send pass through commands, so check for
1175 * Rc handle before processing pass through commands
1176 **/
1177 if (btif_rc_cb.rc_handle == p_data->remote_cmd.rc_handle)
1178 {
1179 handle_rc_passthrough_cmd( (&p_data->remote_cmd) );
1180 }
1181 else
1182 {
1183 BTIF_TRACE_DEBUG("Pass-through command for Invalid rc handle");
1184 }
Rohit Singha9fb00a2013-07-27 14:46:29 +05301185 }
1186 else
1187 {
Ayan Ghoshf2a653d2014-09-18 20:08:30 +05301188 BTIF_TRACE_ERROR("AVRCP TG role not up, drop passthrough commands");
Rohit Singha9fb00a2013-07-27 14:46:29 +05301189 }
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08001190 }
1191 break;
Mike Lockwood93912472014-06-26 11:08:24 -07001192#if (AVRC_CTLR_INCLUDED == TRUE)
1193 case BTA_AV_REMOTE_RSP_EVT:
1194 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001195 BTIF_TRACE_DEBUG("RSP: rc_id:0x%x key_state:%d", p_data->remote_rsp.rc_id,
Mike Lockwood93912472014-06-26 11:08:24 -07001196 p_data->remote_rsp.key_state);
1197 handle_rc_passthrough_rsp( (&p_data->remote_rsp) );
1198 }
1199 break;
1200#endif
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08001201 case BTA_AV_RC_FEAT_EVT:
1202 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001203 BTIF_TRACE_DEBUG("Peer_features:%x", p_data->rc_feat.peer_features);
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08001204 btif_rc_cb.rc_features = p_data->rc_feat.peer_features;
Satya Calloji247c68f2013-08-01 02:14:43 -07001205 handle_rc_features();
pramod kotreshappa6fa16452014-09-10 20:04:20 -07001206#if (AVRC_CTLR_INCLUDED == TRUE)
1207 bt_bdaddr_t rc_addr;
1208 bdcpy(rc_addr.address, btif_rc_cb.rc_addr);
1209 if (btif_rc_cb.rc_features & BTA_AV_FEAT_RCTG &&
1210 btif_rc_cb.rc_connected == TRUE && conn_status == FALSE)
1211 {
1212 BTIF_TRACE_DEBUG("Update RC Connection State");
1213 HAL_CBACK(bt_rc_ctrl_callbacks, connection_state_cb, TRUE, &rc_addr);
1214 conn_status = TRUE;
1215 }
1216#endif
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08001217 }
1218 break;
1219 case BTA_AV_META_MSG_EVT:
1220 {
Ayan Ghoshf2a653d2014-09-18 20:08:30 +05301221 if (bt_rc_callbacks != NULL)
1222 {
1223 BTIF_TRACE_DEBUG("BTA_AV_META_MSG_EVT code:%d label:%d",
1224 p_data->meta_msg.code,
1225 p_data->meta_msg.label);
1226 BTIF_TRACE_DEBUG(" company_id:0x%x len:%d handle:%d",
1227 p_data->meta_msg.company_id,
1228 p_data->meta_msg.len,
1229 p_data->meta_msg.rc_handle);
1230 /* handle the metamsg command */
1231 handle_rc_metamsg_cmd(&(p_data->meta_msg));
1232 /* Free the Memory allocated for tAVRC_MSG */
1233 }
1234 else
1235 {
1236 BTIF_TRACE_ERROR("AVRCP TG role not up, drop meta commands");
1237 }
Rohit Singha9fb00a2013-07-27 14:46:29 +05301238 GKI_freebuf(p_data->meta_msg.p_msg);
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08001239 }
1240 break;
Ayan Ghoshd74324f2014-07-25 17:51:32 +05301241 case BTA_AV_BROWSE_MSG_EVT:
1242 {
Ayan Ghoshf2a653d2014-09-18 20:08:30 +05301243 if (bt_rc_callbacks != NULL)
1244 {
1245 BTIF_TRACE_DEBUG("BTA_AV_BROWSE_MSG_EVT label:%d handle:%d",
1246 p_data->browse_msg.label,
1247 p_data->browse_msg.rc_handle);
1248 handle_rc_browsemsg_cmd(&(p_data->browse_msg));
1249 }
1250 else
1251 {
1252 BTIF_TRACE_ERROR("AVRCP TG role not up, drop browse commands");
1253 }
Ayan Ghoshd74324f2014-07-25 17:51:32 +05301254 GKI_freebuf(p_data->browse_msg.p_msg);
1255 }
1256 break;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001257 default:
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001258 BTIF_TRACE_DEBUG("Unhandled RC event : 0x%x", event);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001259 }
1260}
1261
1262/***************************************************************************
1263 **
1264 ** Function btif_rc_get_connected_peer
1265 **
1266 ** Description Fetches the connected headset's BD_ADDR if any
1267 **
1268 ***************************************************************************/
1269BOOLEAN btif_rc_get_connected_peer(BD_ADDR peer_addr)
1270{
1271 if (btif_rc_cb.rc_connected == TRUE) {
1272 bdcpy(peer_addr, btif_rc_cb.rc_addr);
1273 return TRUE;
1274 }
1275 return FALSE;
1276}
1277
1278/***************************************************************************
1279 **
1280 ** Function btif_rc_check_handle_pending_play
1281 **
1282 ** Description Clears the queued PLAY command. if bSend is TRUE, forwards to app
1283 **
1284 ***************************************************************************/
1285
1286/* clear the queued PLAY command. if bSend is TRUE, forward to app */
1287void btif_rc_check_handle_pending_play (BD_ADDR peer_addr, BOOLEAN bSendToApp)
1288{
Mike J. Chen5cd8bff2014-01-31 18:16:59 -08001289 UNUSED(peer_addr);
1290
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001291 BTIF_TRACE_DEBUG("%s: bSendToApp=%d", __FUNCTION__, bSendToApp);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001292 if (btif_rc_cb.rc_pending_play)
1293 {
1294 if (bSendToApp)
1295 {
1296 tBTA_AV_REMOTE_CMD remote_cmd;
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001297 APPL_TRACE_DEBUG("%s: Sending queued PLAYED event to app", __FUNCTION__);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001298
1299 memset (&remote_cmd, 0, sizeof(tBTA_AV_REMOTE_CMD));
1300 remote_cmd.rc_handle = btif_rc_cb.rc_handle;
1301 remote_cmd.rc_id = AVRC_ID_PLAY;
1302 remote_cmd.hdr.ctype = AVRC_CMD_CTRL;
1303 remote_cmd.hdr.opcode = AVRC_OP_PASS_THRU;
1304
1305 /* delay sending to app, else there is a timing issue in the framework,
1306 ** which causes the audio to be on th device's speaker. Delay between
1307 ** OPEN & RC_PLAYs
1308 */
1309 GKI_delay (200);
1310 /* send to app - both PRESSED & RELEASED */
1311 remote_cmd.key_state = AVRC_STATE_PRESS;
1312 handle_rc_passthrough_cmd( &remote_cmd );
1313
1314 GKI_delay (100);
1315
1316 remote_cmd.key_state = AVRC_STATE_RELEASE;
1317 handle_rc_passthrough_cmd( &remote_cmd );
1318 }
1319 btif_rc_cb.rc_pending_play = FALSE;
1320 }
1321}
1322
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08001323/* Generic reject response */
1324static void send_reject_response (UINT8 rc_handle, UINT8 label, UINT8 pdu, UINT8 status)
1325{
1326 UINT8 ctype = AVRC_RSP_REJ;
1327 tAVRC_RESPONSE avrc_rsp;
1328 BT_HDR *p_msg = NULL;
1329 memset (&avrc_rsp, 0, sizeof(tAVRC_RESPONSE));
1330
1331 avrc_rsp.rsp.opcode = opcode_from_pdu(pdu);
1332 avrc_rsp.rsp.pdu = pdu;
1333 avrc_rsp.rsp.status = status;
1334
1335 if (AVRC_STS_NO_ERROR == (status = AVRC_BldResponse(rc_handle, &avrc_rsp, &p_msg)) )
1336 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001337 BTIF_TRACE_DEBUG("%s:Sending error notification to handle:%d. pdu:%s,status:0x%02x",
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08001338 __FUNCTION__, rc_handle, dump_rc_pdu(pdu), status);
1339 BTA_AvMetaRsp(rc_handle, label, ctype, p_msg);
1340 }
1341}
1342
1343/***************************************************************************
1344 * Function send_metamsg_rsp
1345 *
1346 * - Argument:
1347 * rc_handle RC handle corresponding to the connected RC
1348 * label Label of the RC response
1349 * code Response type
1350 * pmetamsg_resp Vendor response
1351 *
1352 * - Description: Remote control metamsg response handler (AVRCP 1.3)
1353 *
1354 ***************************************************************************/
1355static void send_metamsg_rsp (UINT8 rc_handle, UINT8 label, tBTA_AV_CODE code,
1356 tAVRC_RESPONSE *pmetamsg_resp)
1357{
1358 UINT8 ctype;
1359 tAVRC_STS status;
1360
1361 if (!pmetamsg_resp)
1362 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001363 BTIF_TRACE_WARNING("%s: Invalid response received from application", __FUNCTION__);
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08001364 return;
1365 }
1366
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001367 BTIF_TRACE_EVENT("+%s: rc_handle: %d, label: %d, code: 0x%02x, pdu: %s", __FUNCTION__,
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08001368 rc_handle, label, code, dump_rc_pdu(pmetamsg_resp->rsp.pdu));
1369
1370 if (pmetamsg_resp->rsp.status != AVRC_STS_NO_ERROR)
1371 {
1372 ctype = AVRC_RSP_REJ;
1373 }
1374 else
1375 {
1376 if ( code < AVRC_RSP_NOT_IMPL)
1377 {
1378 if (code == AVRC_CMD_NOTIF)
1379 {
1380 ctype = AVRC_RSP_INTERIM;
1381 }
1382 else if (code == AVRC_CMD_STATUS)
1383 {
1384 ctype = AVRC_RSP_IMPL_STBL;
1385 }
1386 else
1387 {
1388 ctype = AVRC_RSP_ACCEPT;
1389 }
1390 }
1391 else
1392 {
1393 ctype = code;
1394 }
1395 }
1396 /* if response is for register_notification, make sure the rc has
1397 actually registered for this */
1398 if((pmetamsg_resp->rsp.pdu == AVRC_PDU_REGISTER_NOTIFICATION) && (code == AVRC_RSP_CHANGED))
1399 {
1400 BOOLEAN bSent = FALSE;
1401 UINT8 event_id = pmetamsg_resp->reg_notif.event_id;
1402 BOOLEAN bNotify = (btif_rc_cb.rc_connected) && (btif_rc_cb.rc_notif[event_id-1].bNotify);
1403
1404 /* de-register this notification for a CHANGED response */
1405 btif_rc_cb.rc_notif[event_id-1].bNotify = FALSE;
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001406 BTIF_TRACE_DEBUG("%s rc_handle: %d. event_id: 0x%02d bNotify:%u", __FUNCTION__,
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08001407 btif_rc_cb.rc_handle, event_id, bNotify);
1408 if (bNotify)
1409 {
1410 BT_HDR *p_msg = NULL;
1411 tAVRC_STS status;
1412
1413 if (AVRC_STS_NO_ERROR == (status = AVRC_BldResponse(btif_rc_cb.rc_handle,
1414 pmetamsg_resp, &p_msg)) )
1415 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001416 BTIF_TRACE_DEBUG("%s Sending notification to rc_handle: %d. event_id: 0x%02d",
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08001417 __FUNCTION__, btif_rc_cb.rc_handle, event_id);
1418 bSent = TRUE;
1419 BTA_AvMetaRsp(btif_rc_cb.rc_handle, btif_rc_cb.rc_notif[event_id-1].label,
1420 ctype, p_msg);
1421 }
1422 else
1423 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001424 BTIF_TRACE_WARNING("%s failed to build metamsg response. status: 0x%02x",
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08001425 __FUNCTION__, status);
1426 }
1427
1428 }
1429
1430 if (!bSent)
1431 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001432 BTIF_TRACE_DEBUG("%s: Notification not sent, as there are no RC connections or the \
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08001433 CT has not subscribed for event_id: %s", __FUNCTION__, dump_rc_notification_event_id(event_id));
1434 }
1435 }
1436 else
1437 {
1438 /* All other commands go here */
1439
1440 BT_HDR *p_msg = NULL;
1441 tAVRC_STS status;
1442
1443 status = AVRC_BldResponse(rc_handle, pmetamsg_resp, &p_msg);
1444
1445 if (status == AVRC_STS_NO_ERROR)
1446 {
1447 BTA_AvMetaRsp(rc_handle, label, ctype, p_msg);
1448 }
1449 else
1450 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001451 BTIF_TRACE_ERROR("%s: failed to build metamsg response. status: 0x%02x",
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08001452 __FUNCTION__, status);
1453 }
1454 }
1455}
1456
1457static UINT8 opcode_from_pdu(UINT8 pdu)
1458{
1459 UINT8 opcode = 0;
1460
1461 switch (pdu)
1462 {
1463 case AVRC_PDU_NEXT_GROUP:
1464 case AVRC_PDU_PREV_GROUP: /* pass thru */
1465 opcode = AVRC_OP_PASS_THRU;
1466 break;
1467
1468 default: /* vendor */
1469 opcode = AVRC_OP_VENDOR;
1470 break;
1471 }
1472
1473 return opcode;
1474}
1475
Ayan Ghoshd74324f2014-07-25 17:51:32 +05301476/****************************************************************************
1477* Function send_browsemsg_rsp
1478*
1479* Arguments - rc_handle RC handle corresponding to the connected RC
1480* label Label of the RC response
1481* code Response type---->Not needed for Browsing
1482* pmetamsg_resp Vendor response
1483*
1484* Description - Remote control browse Message Rsp
1485*
1486*******************************************************************************/
1487static void send_browsemsg_rsp (UINT8 rc_handle, UINT8 label, tBTA_AV_CODE code,
1488 tAVRC_RESPONSE *pbrowsemsg_resp)
1489{
1490 tAVRC_STS status;
1491 BT_HDR *p_msg = NULL;
1492
1493 if (!pbrowsemsg_resp)
1494 {
1495 BTIF_TRACE_WARNING("%s: Invalid response received from application", __FUNCTION__);
1496 return;
1497 }
1498
1499 BTIF_TRACE_EVENT("+%s:rc_handle: %d, label: %d, code: 0x%02x, pdu: %s", __FUNCTION__,\
1500 rc_handle, label, code, dump_rc_pdu(pbrowsemsg_resp->rsp.pdu));
1501 if (pbrowsemsg_resp->rsp.status != AVRC_STS_NO_ERROR)
1502 {
1503 BTIF_TRACE_ERROR("send_browsemsg_rsp **Error**");
1504 }
1505 /*Browse Command and Response structure are different
1506 *as comapared to Meta data response ,opcode and c-type
1507 *not part of browse response hence handling browse response
1508 *in seprate function
1509 */
1510 status = AVRC_BldBrowseResponse(rc_handle, pbrowsemsg_resp, &p_msg);
1511 if (status == AVRC_STS_NO_ERROR)
1512 {
1513 BTA_AvMetaRsp(rc_handle, label, 0, p_msg);
1514 }
1515 else
1516 {
1517 BTIF_TRACE_ERROR("%s: failed to build metamsg response. status: 0x%02x",
1518 __FUNCTION__, status);
1519 }
1520}
1521
1522/****************************************************************************
1523* Function app_sendbrowsemsg
1524*
1525* Arguments - index Of array stored while recieving command
1526* avrc_rsp Avrcp response from application
1527*
1528* Description - Send Browse message
1529*
1530*******************************************************************************/
1531int app_sendbrowsemsg(UINT8 index ,tAVRC_RESPONSE *avrc_rsp)
1532{
1533 SEND_BROWSEMSG_RSP(index ,avrc_rsp);
1534 return 0;
1535}
1536
1537
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08001538/*******************************************************************************
1539**
1540** Function btif_rc_upstreams_evt
1541**
1542** Description Executes AVRC UPSTREAMS events in btif context.
1543**
1544** Returns void
1545**
1546*******************************************************************************/
1547static void btif_rc_upstreams_evt(UINT16 event, tAVRC_COMMAND *pavrc_cmd, UINT8 ctype, UINT8 label)
1548{
rakesh reddy03b63652014-08-14 11:58:45 +05301549 BTIF_TRACE_IMP("%s pdu: %s handle: 0x%x ctype:%x label:%x", __FUNCTION__,
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08001550 dump_rc_pdu(pavrc_cmd->pdu), btif_rc_cb.rc_handle, ctype, label);
1551
1552 switch (event)
1553 {
1554 case AVRC_PDU_GET_PLAY_STATUS:
1555 {
Ayan Ghoshd74324f2014-07-25 17:51:32 +05301556 BTIF_TRACE_DEBUG("AVRC_PDU_GET_PLAY_STATUS ");
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08001557 FILL_PDU_QUEUE(IDX_GET_PLAY_STATUS_RSP, ctype, label, TRUE)
1558 HAL_CBACK(bt_rc_callbacks, get_play_status_cb);
1559 }
1560 break;
1561 case AVRC_PDU_LIST_PLAYER_APP_ATTR:
Ayan Ghoshd74324f2014-07-25 17:51:32 +05301562 {
1563 BTIF_TRACE_DEBUG("AVRC_PDU_LIST_PLAYER_APP_ATTR ");
1564 FILL_PDU_QUEUE(IDX_LIST_APP_ATTR_RSP, ctype, label, TRUE)
1565 HAL_CBACK(bt_rc_callbacks, list_player_app_attr_cb);
1566 }
1567 break;
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08001568 case AVRC_PDU_LIST_PLAYER_APP_VALUES:
Ayan Ghoshd74324f2014-07-25 17:51:32 +05301569 {
1570 BTIF_TRACE_DEBUG("AVRC_PDU_LIST_PLAYER_APP_VALUES =%d" ,pavrc_cmd->list_app_values.attr_id);
1571 if (pavrc_cmd->list_app_values.attr_id == 0)
1572 {
1573 send_reject_response (btif_rc_cb.rc_handle, label, pavrc_cmd->pdu, AVRC_STS_BAD_PARAM);
1574 break;
1575 }
1576 FILL_PDU_QUEUE(IDX_LIST_APP_VALUE_RSP, ctype, label, TRUE)
1577 HAL_CBACK(bt_rc_callbacks, list_player_app_values_cb ,pavrc_cmd->list_app_values.attr_id);
1578 }
1579 break;
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08001580 case AVRC_PDU_GET_CUR_PLAYER_APP_VALUE:
Ayan Ghoshd74324f2014-07-25 17:51:32 +05301581 {
1582 btrc_player_attr_t player_attr[BTRC_MAX_ELEM_ATTR_SIZE];
1583 UINT8 player_attr_num;
1584 BTIF_TRACE_DEBUG("PLAYER_APP_VALUE PDU 0x13 = %d",pavrc_cmd->get_cur_app_val.num_attr);
1585 if ((pavrc_cmd->get_cur_app_val.num_attr == 0) ||
1586 (pavrc_cmd->get_cur_app_val.num_attr > BTRC_MAX_ELEM_ATTR_SIZE))
1587 {
1588 send_reject_response (btif_rc_cb.rc_handle, label, pavrc_cmd->pdu, AVRC_STS_BAD_PARAM);
1589 break;
1590 }
1591 memset( player_attr, 0, sizeof(player_attr));
1592 for (player_attr_num = 0 ; player_attr_num < pavrc_cmd->get_cur_app_val.num_attr;
1593 ++player_attr_num)
1594 {
1595 player_attr[player_attr_num] = pavrc_cmd->get_cur_app_val.attrs[player_attr_num];
1596 }
1597 FILL_PDU_QUEUE(IDX_GET_CURR_APP_VAL_RSP, ctype, label, TRUE)
1598 HAL_CBACK(bt_rc_callbacks, get_player_app_value_cb ,
1599 pavrc_cmd->get_cur_app_val.num_attr, player_attr );
1600 }
1601 break;
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08001602 case AVRC_PDU_SET_PLAYER_APP_VALUE:
Ayan Ghoshd74324f2014-07-25 17:51:32 +05301603 {
1604 btrc_player_settings_t attr;
1605 UINT8 count;
1606 tAVRC_RESPONSE avrc_rsp;
1607 if ((pavrc_cmd->set_app_val.num_val== 0) ||
1608 (pavrc_cmd->set_app_val.num_val > BTRC_MAX_ELEM_ATTR_SIZE))
1609 {
1610 send_reject_response (btif_rc_cb.rc_handle, label,
1611 pavrc_cmd->pdu, AVRC_STS_BAD_PARAM);
1612 break;
1613 }
1614 else
1615 {
1616 for(count = 0; count < pavrc_cmd->set_app_val.num_val ; ++count)
1617 {
1618 attr.attr_ids[count] = pavrc_cmd->set_app_val.p_vals[count].attr_id ;
1619 attr.attr_values[count]= pavrc_cmd->set_app_val.p_vals[count].attr_val;
1620 }
1621 attr.num_attr = pavrc_cmd->set_app_val.num_val ;
1622 FILL_PDU_QUEUE(IDX_SET_APP_VAL_RSP, ctype, label, TRUE)
1623 HAL_CBACK(bt_rc_callbacks, set_player_app_value_cb, &attr );
1624 }
1625 }
1626 break;
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08001627 case AVRC_PDU_GET_PLAYER_APP_ATTR_TEXT:
Ayan Ghoshd74324f2014-07-25 17:51:32 +05301628 {
1629 btrc_player_attr_t player_attr_txt [BTRC_MAX_ELEM_ATTR_SIZE];
1630 UINT8 count_txt = 0 ;
1631 if ((pavrc_cmd->get_app_attr_txt.num_attr == 0) ||
1632 (pavrc_cmd->get_app_attr_txt.num_attr > BTRC_MAX_ELEM_ATTR_SIZE))
1633 {
1634 send_reject_response (btif_rc_cb.rc_handle, label, pavrc_cmd->pdu, AVRC_STS_BAD_PARAM);
1635 }
1636 else
1637 {
1638 for (count_txt = 0;count_txt < pavrc_cmd->get_app_attr_txt.num_attr ; ++count_txt)
1639 {
1640 player_attr_txt[count_txt] = pavrc_cmd->get_app_attr_txt.attrs[count_txt];
1641 }
1642 FILL_PDU_QUEUE(IDX_GET_APP_ATTR_TXT_RSP, ctype, label, TRUE)
1643 HAL_CBACK(bt_rc_callbacks, get_player_app_attrs_text_cb,
1644 pavrc_cmd->get_app_attr_txt.num_attr, player_attr_txt );
1645 }
1646 }
1647 break;
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08001648 case AVRC_PDU_GET_PLAYER_APP_VALUE_TEXT:
1649 {
Ayan Ghoshd74324f2014-07-25 17:51:32 +05301650 if (pavrc_cmd->get_app_val_txt.attr_id == 0 ||
1651 pavrc_cmd->get_app_val_txt.attr_id > AVRC_PLAYER_VAL_GROUP_REPEAT)
1652 {
1653 send_reject_response (btif_rc_cb.rc_handle, label, pavrc_cmd->pdu, AVRC_STS_BAD_PARAM);
1654 break;
1655 }
1656 if (pavrc_cmd->get_app_val_txt.num_val == 0)
1657 {
1658 send_reject_response (btif_rc_cb.rc_handle, label, pavrc_cmd->pdu, AVRC_STS_BAD_PARAM);
1659 }
1660 else
1661 {
1662 FILL_PDU_QUEUE(IDX_GET_APP_VAL_TXT_RSP, ctype, label, TRUE)
1663 HAL_CBACK(bt_rc_callbacks, get_player_app_values_text_cb,
1664 pavrc_cmd->get_app_val_txt.attr_id, pavrc_cmd->get_app_val_txt.num_val,
1665 pavrc_cmd->get_app_val_txt.vals);
1666 }
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08001667 }
1668 break;
1669 case AVRC_PDU_GET_ELEMENT_ATTR:
1670 {
1671 btrc_media_attr_t element_attrs[BTRC_MAX_ELEM_ATTR_SIZE];
1672 UINT8 num_attr;
Ravi Nagarajan841e5b52013-03-22 04:16:57 -07001673 memset(&element_attrs, 0, sizeof(element_attrs));
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08001674 if (pavrc_cmd->get_elem_attrs.num_attr == 0)
1675 {
1676 /* CT requests for all attributes */
1677 int attr_cnt;
Ravi Nagarajan841e5b52013-03-22 04:16:57 -07001678 num_attr = BTRC_MAX_ELEM_ATTR_SIZE;
1679 for (attr_cnt = 0; attr_cnt < BTRC_MAX_ELEM_ATTR_SIZE; attr_cnt++)
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08001680 {
Ravi Nagarajan841e5b52013-03-22 04:16:57 -07001681 element_attrs[attr_cnt] = attr_cnt + 1;
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08001682 }
1683 }
1684 else if (pavrc_cmd->get_elem_attrs.num_attr == 0xFF)
1685 {
Ravi Nagarajan841e5b52013-03-22 04:16:57 -07001686 /* 0xff indicates, no attributes requested - reject */
1687 send_reject_response (btif_rc_cb.rc_handle, label, pavrc_cmd->pdu,
1688 AVRC_STS_BAD_PARAM);
1689 return;
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08001690 }
1691 else
1692 {
Rohit Singha9fb00a2013-07-27 14:46:29 +05301693 int attr_cnt, filled_attr_count;
1694
1695 num_attr = 0;
1696 /* Attribute IDs from 1 to AVRC_MAX_NUM_MEDIA_ATTR_ID are only valid,
1697 * hence HAL definition limits the attributes to AVRC_MAX_NUM_MEDIA_ATTR_ID.
1698 * Fill only valid entries.
1699 */
1700 for (attr_cnt = 0; (attr_cnt < pavrc_cmd->get_elem_attrs.num_attr) &&
1701 (num_attr < AVRC_MAX_NUM_MEDIA_ATTR_ID); attr_cnt++)
1702 {
1703 if ((pavrc_cmd->get_elem_attrs.attrs[attr_cnt] > 0) &&
1704 (pavrc_cmd->get_elem_attrs.attrs[attr_cnt] <= AVRC_MAX_NUM_MEDIA_ATTR_ID))
1705 {
1706 /* Skip the duplicate entries : PTS sends duplicate entries for Fragment cases
1707 */
1708 for (filled_attr_count = 0; filled_attr_count < num_attr; filled_attr_count++)
1709 {
1710 if (element_attrs[filled_attr_count] == pavrc_cmd->get_elem_attrs.attrs[attr_cnt])
1711 break;
1712 }
1713 if (filled_attr_count == num_attr)
1714 {
1715 element_attrs[num_attr] = pavrc_cmd->get_elem_attrs.attrs[attr_cnt];
1716 num_attr++;
1717 }
1718 }
1719 }
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08001720 }
1721 FILL_PDU_QUEUE(IDX_GET_ELEMENT_ATTR_RSP, ctype, label, TRUE);
1722 HAL_CBACK(bt_rc_callbacks, get_element_attr_cb, num_attr, element_attrs);
1723 }
1724 break;
1725 case AVRC_PDU_REGISTER_NOTIFICATION:
1726 {
Ayan Ghoshd74324f2014-07-25 17:51:32 +05301727 if (pavrc_cmd->reg_notif.event_id == BTRC_EVT_PLAY_POS_CHANGED &&
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08001728 pavrc_cmd->reg_notif.param == 0)
1729 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001730 BTIF_TRACE_WARNING("%s Device registering position changed with illegal param 0.",
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08001731 __FUNCTION__);
1732 send_reject_response (btif_rc_cb.rc_handle, label, pavrc_cmd->pdu, AVRC_STS_BAD_PARAM);
1733 /* de-register this notification for a rejected response */
1734 btif_rc_cb.rc_notif[BTRC_EVT_PLAY_POS_CHANGED - 1].bNotify = FALSE;
1735 return;
1736 }
1737 HAL_CBACK(bt_rc_callbacks, register_notification_cb, pavrc_cmd->reg_notif.event_id,
1738 pavrc_cmd->reg_notif.param);
1739 }
1740 break;
1741 case AVRC_PDU_INFORM_DISPLAY_CHARSET:
1742 {
1743 tAVRC_RESPONSE avrc_rsp;
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001744 BTIF_TRACE_EVENT("%s() AVRC_PDU_INFORM_DISPLAY_CHARSET", __FUNCTION__);
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08001745 if(btif_rc_cb.rc_connected == TRUE)
1746 {
1747 memset(&(avrc_rsp.inform_charset), 0, sizeof(tAVRC_RSP));
1748 avrc_rsp.inform_charset.opcode=opcode_from_pdu(AVRC_PDU_INFORM_DISPLAY_CHARSET);
1749 avrc_rsp.inform_charset.pdu=AVRC_PDU_INFORM_DISPLAY_CHARSET;
1750 avrc_rsp.inform_charset.status=AVRC_STS_NO_ERROR;
1751 send_metamsg_rsp(btif_rc_cb.rc_handle, label, ctype, &avrc_rsp);
1752 }
1753 }
1754 break;
Ayan Ghoshd74324f2014-07-25 17:51:32 +05301755 case AVRC_PDU_SET_ADDRESSED_PLAYER:
1756 {
1757 btrc_status_t status_code = AVRC_STS_NO_ERROR;
1758 BTIF_TRACE_EVENT("%s() AVRC_PDU_SET_ADDRESSED_PLAYER", __FUNCTION__);
1759 if (!btif_hf_is_call_idle())
1760 {
1761 set_addrplayer_rsp(ERR_PLAYER_NOT_ADDRESED); // send reject if call is in progress
1762 return;
1763 }
1764 if (btif_rc_cb.rc_connected == TRUE)
1765 {
1766 FILL_PDU_QUEUE(IDX_SET_ADDRESS_PLAYER_RSP, ctype, label, TRUE);
1767 HAL_CBACK(bt_rc_callbacks, set_addrplayer_cb, pavrc_cmd->addr_player.player_id);
1768 }
1769 }
1770 break;
1771 case AVRC_PDU_GET_FOLDER_ITEMS:
1772 {
1773 tAVRC_RESPONSE avrc_rsp;
1774 btrc_getfolderitem_t getfolder;
1775 btrc_browse_folderitem_t scope;
1776 UINT8 player[] = "MusicPlayer1";
1777 tAVRC_ITEM tem[1];
1778 UINT8 index, numAttr;
1779 BTIF_TRACE_EVENT("%s()AVRC_PDU_GET_FOLDER_ITEMS", __FUNCTION__);
1780 FILL_PDU_QUEUE(IDX_GET_FOLDER_ITEMS_RSP,ctype, label, TRUE);
1781 BTIF_TRACE_EVENT("rc_connected: %d",btif_rc_cb.rc_connected);
1782 if (btif_rc_cb.rc_connected == TRUE)
1783 {
1784 getfolder.start_item = pavrc_cmd->get_items.start_item;
1785 getfolder.end_item = pavrc_cmd->get_items.end_item;
1786 getfolder.size = AVCT_GetBrowseMtu(btif_rc_cb.rc_handle);
1787 getfolder.attr_count = pavrc_cmd->get_items.attr_count;
1788 scope = (btrc_browse_folderitem_t)pavrc_cmd->get_items.scope;
1789 if (getfolder.attr_count == 255)
1790 {
1791 numAttr = 0;
1792 }
1793 else
1794 {
1795 if (getfolder.attr_count == 0)
1796 {
1797 numAttr = 7;
1798 for (index = 0; index < BTRC_MAX_ELEM_ATTR_SIZE; index++)
1799 {
1800 getfolder.attrs[index] = index + 1;
1801 }
1802 }
1803 else
1804 {
1805 numAttr = getfolder.attr_count;
1806 for (index = 0; index < numAttr; index++)
1807 {
1808 getfolder.attrs[index] = pavrc_cmd->get_items.attrs[index];
1809 BTIF_TRACE_ERROR("getfolder[%d] = %d", index, getfolder.\
1810 attrs[index]);
1811 BTIF_TRACE_ERROR("pavrc_cmd->get_items.attrs[%d] = %d",\
1812 index, pavrc_cmd->get_items.attrs[index]);
1813 }
1814 }
1815 }
1816 HAL_CBACK(bt_rc_callbacks, get_folderitems_cb, scope, &getfolder);
1817 }
1818 }
1819 break;
1820 case AVRC_PDU_SET_BROWSED_PLAYER:
1821 {
1822 BTIF_TRACE_EVENT("%s() AVRC_PDU_SET_BROWSED_PLAYER", __FUNCTION__);
1823 if (btif_rc_cb.rc_connected == TRUE)
1824 {
1825 FILL_PDU_QUEUE(IDX_SET_BROWSE_PLAYER_RSP, ctype, label, TRUE);
1826 HAL_CBACK(bt_rc_callbacks, set_browsed_player_cb, pavrc_cmd->br_player.player_id);
1827 }
1828 }
1829 break;
1830 case AVRC_PDU_CHANGE_PATH:
1831 {
1832 BTIF_TRACE_EVENT("%s() AVRC_PDU_CHANGE_PATH", __FUNCTION__);
1833 if (btif_rc_cb.rc_connected == TRUE)
1834 {
1835 FILL_PDU_QUEUE(IDX_CHANGE_PATH_RSP, ctype, label, TRUE);
1836 HAL_CBACK(bt_rc_callbacks, change_path_cb, pavrc_cmd->chg_path.direction, \
1837 pavrc_cmd->chg_path.folder_uid);
1838 }
1839 }
1840 break;
1841 case AVRC_PDU_GET_ITEM_ATTRIBUTES:
1842 {
1843 UINT8 num_attr = pavrc_cmd->get_attrs.attr_count;
1844 UINT8 index, num_attr_requested = 0;
1845 BTIF_TRACE_EVENT("%s() AVRC_PDU_GET_ITEM_ATTRIBUTES", __FUNCTION__);
1846 btrc_media_attr_t element_attrs[BTRC_MAX_ELEM_ATTR_SIZE];
1847 memset(&element_attrs, 0, sizeof(element_attrs));
1848 if (num_attr == 0)
1849 {
1850 /* CT requests for all attributes */
1851 for (index = 0; index < BTRC_MAX_ELEM_ATTR_SIZE; index++)
1852 {
1853 element_attrs[index] = index + 1;
1854 }
1855 num_attr_requested = 7; /* get all seven */
1856 }
1857 else if (num_attr == 0xFF)
1858 {
1859 /* 0xff indicates, no attributes requested - reject */
1860 send_reject_response (btif_rc_cb.rc_handle, label, pavrc_cmd->pdu,
1861 AVRC_STS_BAD_PARAM);
1862 return;
1863 }
1864 else
1865 {
1866 /* Attribute IDs from 1 to BTRC_MAX_ELEM_ATTR_SIZE are only valid,
1867 * hence HAL definition limits the attributes to BTRC_MAX_ELEM_ATTR_SIZE.
1868 * Fill only valid entries.
1869 */
1870 for (index = 0; (index < num_attr) && (num_attr <= BTRC_MAX_ELEM_ATTR_SIZE); index++)
1871 {
1872 if ((pavrc_cmd->get_attrs.attrs[index] > 0) &&
1873 (pavrc_cmd->get_attrs.attrs[index] <= BTRC_MAX_ELEM_ATTR_SIZE))
1874 {
1875 element_attrs[index] = pavrc_cmd->get_attrs.attrs[index];
1876 BTIF_TRACE_ERROR("element_attrs[%d]: %d", index, element_attrs[index]);
1877 }
1878 }
1879 num_attr_requested = index;
1880 BTIF_TRACE_ERROR("num_attr_requested: %d", num_attr_requested);
1881 }
1882
1883 if (btif_rc_cb.rc_connected == TRUE)
1884 {
1885 FILL_PDU_QUEUE(IDX_GET_ITEM_ATTR_RSP, ctype, label, TRUE);
1886 HAL_CBACK(bt_rc_callbacks, get_item_attr_cb, pavrc_cmd->get_attrs.scope,
1887 pavrc_cmd->get_attrs.uid, num_attr_requested, element_attrs);
1888 }
1889 }
1890 break;
1891 case AVRC_PDU_PLAY_ITEM:
1892 {
1893 BTIF_TRACE_EVENT("%s() AVRC_PDU_PLAY_ITEM", __FUNCTION__);
1894 if (btif_rc_cb.rc_connected == TRUE)
1895 {
1896 FILL_PDU_QUEUE(IDX_PLAY_ITEM_RSP, ctype, label, TRUE);
1897 HAL_CBACK(bt_rc_callbacks, play_item_cb, pavrc_cmd->play_item.scope,
1898 pavrc_cmd->play_item.uid);
1899 }
1900 }
1901 break;
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08001902 default:
1903 {
Ayan Ghoshd74324f2014-07-25 17:51:32 +05301904 send_reject_response(btif_rc_cb.rc_handle, label, pavrc_cmd->pdu,
1905 (pavrc_cmd->pdu == AVRC_PDU_SEARCH)? AVRC_STS_SEARCH_NOT_SUP:
1906 AVRC_STS_BAD_CMD);
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08001907 }
1908 break;
1909 }
1910
1911}
1912
Satya Calloji247c68f2013-08-01 02:14:43 -07001913
1914/*******************************************************************************
1915**
1916** Function btif_rc_upstreams_rsp_evt
1917**
1918** Description Executes AVRC UPSTREAMS response events in btif context.
1919**
1920** Returns void
1921**
1922*******************************************************************************/
1923static void btif_rc_upstreams_rsp_evt(UINT16 event, tAVRC_RESPONSE *pavrc_resp, UINT8 ctype, UINT8 label)
1924{
rakesh reddy03b63652014-08-14 11:58:45 +05301925 BTIF_TRACE_IMP("%s pdu: %s handle: 0x%x ctype:%x label:%x", __FUNCTION__,
Satya Calloji247c68f2013-08-01 02:14:43 -07001926 dump_rc_pdu(pavrc_resp->pdu), btif_rc_cb.rc_handle, ctype, label);
1927
1928#if (AVRC_ADV_CTRL_INCLUDED == TRUE)
1929 switch (event)
1930 {
1931 case AVRC_PDU_REGISTER_NOTIFICATION:
1932 {
1933 if(AVRC_RSP_CHANGED==ctype)
1934 btif_rc_cb.rc_volume=pavrc_resp->reg_notif.param.volume;
1935 HAL_CBACK(bt_rc_callbacks, volume_change_cb, pavrc_resp->reg_notif.param.volume,ctype)
1936 }
1937 break;
1938
1939 case AVRC_PDU_SET_ABSOLUTE_VOLUME:
1940 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001941 BTIF_TRACE_DEBUG("Set absolute volume change event received: volume %d,ctype %d",
Satya Calloji247c68f2013-08-01 02:14:43 -07001942 pavrc_resp->volume.volume,ctype);
1943 if(AVRC_RSP_ACCEPT==ctype)
1944 btif_rc_cb.rc_volume=pavrc_resp->volume.volume;
1945 HAL_CBACK(bt_rc_callbacks,volume_change_cb,pavrc_resp->volume.volume,ctype)
1946 }
1947 break;
1948
1949 default:
1950 return;
1951 }
1952#endif
1953}
1954
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08001955/************************************************************************************
1956** AVRCP API Functions
1957************************************************************************************/
1958
1959/*******************************************************************************
1960**
1961** Function init
1962**
1963** Description Initializes the AVRC interface
1964**
1965** Returns bt_status_t
1966**
1967*******************************************************************************/
1968static bt_status_t init(btrc_callbacks_t* callbacks )
1969{
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001970 BTIF_TRACE_EVENT("## %s ##", __FUNCTION__);
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08001971 bt_status_t result = BT_STATUS_SUCCESS;
1972
1973 if (bt_rc_callbacks)
1974 return BT_STATUS_DONE;
1975
1976 bt_rc_callbacks = callbacks;
1977 memset (&btif_rc_cb, 0, sizeof(btif_rc_cb));
Satya Calloji247c68f2013-08-01 02:14:43 -07001978 btif_rc_cb.rc_vol_label=MAX_LABEL;
1979 btif_rc_cb.rc_volume=MAX_VOLUME;
1980 lbl_init();
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08001981
1982 return result;
1983}
1984
Mike Lockwood4ad470e2014-06-02 16:21:49 -07001985/*******************************************************************************
1986**
1987** Function init_ctrl
1988**
1989** Description Initializes the AVRC interface
1990**
1991** Returns bt_status_t
1992**
1993*******************************************************************************/
1994static bt_status_t init_ctrl(btrc_ctrl_callbacks_t* callbacks )
1995{
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001996 BTIF_TRACE_EVENT("## %s ##", __FUNCTION__);
Mike Lockwood4ad470e2014-06-02 16:21:49 -07001997 bt_status_t result = BT_STATUS_SUCCESS;
1998
1999 if (bt_rc_ctrl_callbacks)
2000 return BT_STATUS_DONE;
2001
2002 bt_rc_ctrl_callbacks = callbacks;
2003 memset (&btif_rc_cb, 0, sizeof(btif_rc_cb));
2004 btif_rc_cb.rc_vol_label=MAX_LABEL;
2005 btif_rc_cb.rc_volume=MAX_VOLUME;
2006 lbl_init();
2007
2008 return result;
2009}
2010
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08002011/***************************************************************************
2012**
2013** Function get_play_status_rsp
2014**
2015** Description Returns the current play status.
2016** This method is called in response to
2017** GetPlayStatus request.
2018**
2019** Returns bt_status_t
2020**
2021***************************************************************************/
2022static bt_status_t get_play_status_rsp(btrc_play_status_t play_status, uint32_t song_len,
2023 uint32_t song_pos)
2024{
2025 tAVRC_RESPONSE avrc_rsp;
2026 UINT32 i;
2027 CHECK_RC_CONNECTED
2028 memset(&(avrc_rsp.get_play_status), 0, sizeof(tAVRC_GET_PLAY_STATUS_RSP));
2029 avrc_rsp.get_play_status.song_len = song_len;
2030 avrc_rsp.get_play_status.song_pos = song_pos;
2031 avrc_rsp.get_play_status.play_status = play_status;
2032
2033 avrc_rsp.get_play_status.pdu = AVRC_PDU_GET_PLAY_STATUS;
2034 avrc_rsp.get_play_status.opcode = opcode_from_pdu(AVRC_PDU_GET_PLAY_STATUS);
Ravi Nagarajanb88fc6c2013-04-02 07:11:14 -07002035 avrc_rsp.get_play_status.status = AVRC_STS_NO_ERROR;
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08002036 /* Send the response */
2037 SEND_METAMSG_RSP(IDX_GET_PLAY_STATUS_RSP, &avrc_rsp);
2038 return BT_STATUS_SUCCESS;
2039}
2040
Ayan Ghoshd74324f2014-07-25 17:51:32 +05302041
2042/**************************************************************************
2043**
2044** Function list_player_app_attr_rsp
2045**
2046** Description ListPlayerApplicationSettingAttributes (PDU ID: 0x11)
2047** This method is callled in response to PDU 0x11
2048**
2049** Returns bt_status_t
2050**
2051****************************************************************************/
2052static bt_status_t list_player_app_attr_rsp( uint8_t num_attr, btrc_player_attr_t *p_attrs)
2053{
2054 tAVRC_RESPONSE avrc_rsp;
2055 UINT32 i;
2056
2057 CHECK_RC_CONNECTED
2058 memset(&(avrc_rsp.list_app_attr), 0, sizeof(tAVRC_LIST_APP_ATTR_RSP));
2059 if (num_attr == 0)
2060 {
2061 avrc_rsp.list_app_attr.status = AVRC_STS_BAD_PARAM;
2062 }
2063 else
2064 {
2065 avrc_rsp.list_app_attr.num_attr = num_attr;
2066 for (i = 0 ; i < num_attr ; ++i)
2067 {
2068 avrc_rsp.list_app_attr.attrs[i] = p_attrs[i];
2069 }
2070 avrc_rsp.list_app_attr.status = AVRC_STS_NO_ERROR;
2071 }
2072 avrc_rsp.list_app_attr.pdu = AVRC_PDU_LIST_PLAYER_APP_ATTR ;
2073 avrc_rsp.list_app_attr.opcode = opcode_from_pdu(AVRC_PDU_LIST_PLAYER_APP_ATTR);
2074 /* Send the response */
2075 SEND_METAMSG_RSP(IDX_LIST_APP_ATTR_RSP, &avrc_rsp);
2076 return BT_STATUS_SUCCESS;
2077}
2078
2079/**********************************************************************
2080**
2081** Function list_player_app_value_rsp
2082**
2083** Description ListPlayerApplicationSettingValues (PDU ID: 0x12)
2084 This method is called in response to PDU 0x12
2085************************************************************************/
2086static bt_status_t list_player_app_value_rsp( uint8_t num_val, uint8_t *value)
2087{
2088 tAVRC_RESPONSE avrc_rsp;
2089 UINT32 i;
2090
2091 CHECK_RC_CONNECTED
2092 memset(&(avrc_rsp.list_app_values), 0, sizeof(tAVRC_LIST_APP_VALUES_RSP));
2093 if ((num_val == 0) || (num_val > AVRC_MAX_APP_ATTR_SIZE))
2094 {
2095 avrc_rsp.list_app_values.status = AVRC_STS_BAD_PARAM;
2096 }
2097 else
2098 {
2099 avrc_rsp.list_app_values.num_val = num_val;
2100 for (i = 0; i < num_val; ++i)
2101 {
2102 avrc_rsp.list_app_values.vals[i] = value[i];
2103 }
2104 avrc_rsp.list_app_values.status = AVRC_STS_NO_ERROR;
2105 }
2106 avrc_rsp.list_app_values.pdu = AVRC_PDU_LIST_PLAYER_APP_VALUES;
2107 avrc_rsp.list_app_attr.opcode = opcode_from_pdu(AVRC_PDU_LIST_PLAYER_APP_VALUES);
2108 /* Send the response */
2109 SEND_METAMSG_RSP(IDX_LIST_APP_VALUE_RSP, &avrc_rsp);
2110 return BT_STATUS_SUCCESS;
2111}
2112
2113
2114/**********************************************************************
2115**
2116** Function get_player_app_value_rsp
2117**
2118** Description This methos is called in response to PDU ID 0x13
2119**
2120***********************************************************************/
2121static bt_status_t get_player_app_value_rsp(btrc_player_settings_t *p_vals)
2122{
2123 tAVRC_RESPONSE avrc_rsp;
2124 UINT32 i;
2125 tAVRC_APP_SETTING app_sett[AVRC_MAX_APP_ATTR_SIZE];
2126
2127 CHECK_RC_CONNECTED
2128 memset(&(avrc_rsp.get_cur_app_val) ,0 , sizeof(tAVRC_GET_CUR_APP_VALUE_RSP));
2129 avrc_rsp.get_cur_app_val.p_vals = app_sett ;
2130 //Check for Error Condition
Amit Goel85a35032014-07-31 20:14:27 -07002131 if ((p_vals == NULL) || (p_vals->num_attr== 0) || (p_vals->num_attr > BTRC_MAX_ELEM_ATTR_SIZE))
Ayan Ghoshd74324f2014-07-25 17:51:32 +05302132 {
2133 avrc_rsp.get_cur_app_val.status = AVRC_STS_BAD_PARAM;
2134 }
Sai Aitharajud12d60e2015-02-06 09:20:32 +05302135 else if (p_vals->num_attr <= BTRC_MAX_APP_SETTINGS)
Ayan Ghoshd74324f2014-07-25 17:51:32 +05302136 {
2137 memset(app_sett, 0, sizeof(tAVRC_APP_SETTING)*p_vals->num_attr );
2138 //update num_val
2139 avrc_rsp.get_cur_app_val.num_val = p_vals->num_attr ;
2140 avrc_rsp.get_cur_app_val.p_vals = app_sett ;
2141 for (i = 0; i < p_vals->num_attr; ++i)
2142 {
2143 app_sett[i].attr_id = p_vals->attr_ids[i] ;
2144 app_sett[i].attr_val = p_vals->attr_values[i];
2145 BTIF_TRACE_DEBUG("%s attr_id:0x%x, charset_id:0x%x, num_element:%d",
2146 __FUNCTION__, (unsigned int)app_sett[i].attr_id,
2147 app_sett[i].attr_val ,p_vals->num_attr );
2148 }
2149 //Update PDU , status aind
2150 avrc_rsp.get_cur_app_val.status = AVRC_STS_NO_ERROR;
2151 }
2152 avrc_rsp.get_cur_app_val.pdu = AVRC_PDU_GET_CUR_PLAYER_APP_VALUE;
2153 avrc_rsp.get_cur_app_val.opcode = opcode_from_pdu(AVRC_PDU_GET_CUR_PLAYER_APP_VALUE);
2154 SEND_METAMSG_RSP(IDX_GET_CURR_APP_VAL_RSP, &avrc_rsp);
2155 return BT_STATUS_SUCCESS;
2156}
2157
2158/********************************************************************
2159**
2160** Function set_player_app_value_rsp
2161**
2162** Description This method is called in response to
2163** application value
2164**
2165** Return bt_staus_t
2166**
2167*******************************************************************/
2168static bt_status_t set_player_app_value_rsp (btrc_status_t rsp_status )
2169{
2170 tAVRC_RESPONSE avrc_rsp;
2171 tAVRC_RSP set_app_val;
2172
2173 CHECK_RC_CONNECTED
2174 avrc_rsp.set_app_val.opcode = opcode_from_pdu(AVRC_PDU_SET_PLAYER_APP_VALUE);
2175 avrc_rsp.set_app_val.pdu = AVRC_PDU_SET_PLAYER_APP_VALUE ;
2176 avrc_rsp.set_app_val.status = rsp_status ;
2177 SEND_METAMSG_RSP(IDX_SET_APP_VAL_RSP, &avrc_rsp);
2178 return BT_STATUS_SUCCESS;
2179}
2180
2181/********************************************************************
2182**
2183** Function get_player_app_attr_text_rsp
2184**
2185** Description This method is called in response to get player
2186** applicaton attribute text response
2187**
2188**
2189*******************************************************************/
2190static bt_status_t get_player_app_attr_text_rsp(int num_attr, btrc_player_setting_text_t *p_attrs)
2191{
2192 tAVRC_RESPONSE avrc_rsp;
2193 tAVRC_APP_SETTING_TEXT attr_txt[AVRC_MAX_APP_ATTR_SIZE];
2194 int i;
2195
2196 CHECK_RC_CONNECTED
2197 if (num_attr == 0)
2198 {
2199 avrc_rsp.get_app_attr_txt.status = AVRC_STS_BAD_PARAM;
2200 }
2201 else
2202 {
2203 for (i =0; i< num_attr; ++i)
2204 {
2205 attr_txt[i].charset_id = AVRC_CHARSET_ID_UTF8;
2206 attr_txt[i].attr_id = p_attrs[i].id ;
2207 attr_txt[i].str_len = (UINT8)strnlen((char *)p_attrs[i].text, BTRC_MAX_ATTR_STR_LEN);
2208 attr_txt[i].p_str = p_attrs[i].text ;
2209 BTIF_TRACE_DEBUG("%s attr_id:0x%x, charset_id:0x%x, str_len:%d, str:%s",
2210 __FUNCTION__, (unsigned int)attr_txt[i].attr_id,
2211 attr_txt[i].charset_id , attr_txt[i].str_len, attr_txt[i].p_str);
2212 }
2213 avrc_rsp.get_app_attr_txt.status = AVRC_STS_NO_ERROR;
2214 }
2215 avrc_rsp.get_app_attr_txt.p_attrs = attr_txt ;
2216 avrc_rsp.get_app_attr_txt.num_attr = (UINT8)num_attr;
2217 avrc_rsp.get_app_attr_txt.pdu = AVRC_PDU_GET_PLAYER_APP_ATTR_TEXT;
2218 avrc_rsp.get_app_attr_txt.opcode = opcode_from_pdu(AVRC_PDU_GET_PLAYER_APP_ATTR_TEXT);
2219 /* Send the response */
2220 SEND_METAMSG_RSP(IDX_GET_APP_ATTR_TXT_RSP, &avrc_rsp);
2221 return BT_STATUS_SUCCESS;
2222}
2223
2224/********************************************************************
2225**
2226** Function get_player_app_value_text_rsp
2227**
2228** Description This method is called in response to Player application
2229** value text
2230**
2231** Return bt_status_t
2232**
2233*******************************************************************/
2234static bt_status_t get_player_app_value_text_rsp(int num_attr, btrc_player_setting_text_t *p_attrs)
2235{
2236 tAVRC_RESPONSE avrc_rsp;
2237 tAVRC_APP_SETTING_TEXT attr_txt[AVRC_MAX_APP_ATTR_SIZE];
2238 int i;
2239
2240 CHECK_RC_CONNECTED
2241 if (num_attr == 0)
2242 {
2243 avrc_rsp.get_app_val_txt.status = AVRC_STS_BAD_PARAM;
2244 }
2245 else
2246 {
2247 for (i =0; i< num_attr; ++i)
2248 {
2249 attr_txt[i].charset_id = AVRC_CHARSET_ID_UTF8;
2250 attr_txt[i].attr_id = p_attrs[i].id ;
2251 attr_txt[i].str_len = (UINT8)strnlen((char *)p_attrs[i].text ,BTRC_MAX_ATTR_STR_LEN );
2252 attr_txt[i].p_str = p_attrs[i].text ;
2253 BTIF_TRACE_DEBUG("%s attr_id:0x%x, charset_id:0x%x, str_len:%d, str:%s",
2254 __FUNCTION__, (unsigned int)attr_txt[i].attr_id,
2255 attr_txt[i].charset_id , attr_txt[i].str_len,attr_txt[i].p_str);
2256 }
2257 avrc_rsp.get_app_val_txt.status = AVRC_STS_NO_ERROR;
2258 }
2259 avrc_rsp.get_app_val_txt.p_attrs = attr_txt;
2260 avrc_rsp.get_app_val_txt.num_attr = (UINT8)num_attr;
2261 avrc_rsp.get_app_val_txt.pdu = AVRC_PDU_GET_PLAYER_APP_VALUE_TEXT;
2262 avrc_rsp.get_app_val_txt.opcode = opcode_from_pdu(AVRC_PDU_GET_PLAYER_APP_VALUE_TEXT);
2263 /* Send the response */
2264 SEND_METAMSG_RSP(IDX_GET_APP_VAL_TXT_RSP, &avrc_rsp);
2265 return BT_STATUS_SUCCESS;
2266}
2267
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08002268/***************************************************************************
2269**
2270** Function get_element_attr_rsp
2271**
2272** Description Returns the current songs' element attributes
Ayan Ghoshd74324f2014-07-25 17:51:32 +05302273** in text.
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08002274**
2275** Returns bt_status_t
2276**
2277***************************************************************************/
2278static bt_status_t get_element_attr_rsp(uint8_t num_attr, btrc_element_attr_val_t *p_attrs)
2279{
2280 tAVRC_RESPONSE avrc_rsp;
2281 UINT32 i;
2282 uint8_t j;
2283 tAVRC_ATTR_ENTRY element_attrs[BTRC_MAX_ELEM_ATTR_SIZE];
2284 CHECK_RC_CONNECTED
2285 memset(element_attrs, 0, sizeof(tAVRC_ATTR_ENTRY) * num_attr);
2286
2287 if (num_attr == 0)
2288 {
2289 avrc_rsp.get_play_status.status = AVRC_STS_BAD_PARAM;
2290 }
2291 else
2292 {
Ayan Ghoshd74324f2014-07-25 17:51:32 +05302293 for (i=0; i<num_attr; i++)
2294 {
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08002295 element_attrs[i].attr_id = p_attrs[i].attr_id;
2296 element_attrs[i].name.charset_id = AVRC_CHARSET_ID_UTF8;
2297 element_attrs[i].name.str_len = (UINT16)strlen((char *)p_attrs[i].text);
2298 element_attrs[i].name.p_str = p_attrs[i].text;
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002299 BTIF_TRACE_DEBUG("%s attr_id:0x%x, charset_id:0x%x, str_len:%d, str:%s",
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08002300 __FUNCTION__, (unsigned int)element_attrs[i].attr_id,
2301 element_attrs[i].name.charset_id, element_attrs[i].name.str_len,
2302 element_attrs[i].name.p_str);
2303 }
2304 avrc_rsp.get_play_status.status = AVRC_STS_NO_ERROR;
2305 }
2306 avrc_rsp.get_elem_attrs.num_attr = num_attr;
2307 avrc_rsp.get_elem_attrs.p_attrs = element_attrs;
2308 avrc_rsp.get_elem_attrs.pdu = AVRC_PDU_GET_ELEMENT_ATTR;
2309 avrc_rsp.get_elem_attrs.opcode = opcode_from_pdu(AVRC_PDU_GET_ELEMENT_ATTR);
2310 /* Send the response */
2311 SEND_METAMSG_RSP(IDX_GET_ELEMENT_ATTR_RSP, &avrc_rsp);
2312 return BT_STATUS_SUCCESS;
2313}
2314
2315/***************************************************************************
2316**
2317** Function register_notification_rsp
2318**
2319** Description Response to the register notification request.
2320** in text.
2321**
2322** Returns bt_status_t
2323**
2324***************************************************************************/
2325static bt_status_t register_notification_rsp(btrc_event_id_t event_id,
2326 btrc_notification_type_t type, btrc_register_notification_t *p_param)
2327{
2328 tAVRC_RESPONSE avrc_rsp;
2329 CHECK_RC_CONNECTED
rakesh reddy03b63652014-08-14 11:58:45 +05302330 BTIF_TRACE_IMP("## %s ## event_id:%s", __FUNCTION__, dump_rc_notification_event_id(event_id));
Nitin Srivastava68c53de2014-02-13 19:31:40 +05302331 if (btif_rc_cb.rc_notif[event_id-1].bNotify == FALSE)
2332 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002333 BTIF_TRACE_ERROR("Avrcp Event id not registered: event_id = %x", event_id);
Nitin Srivastava68c53de2014-02-13 19:31:40 +05302334 return BT_STATUS_NOT_READY;
2335 }
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08002336 memset(&(avrc_rsp.reg_notif), 0, sizeof(tAVRC_REG_NOTIF_RSP));
2337 avrc_rsp.reg_notif.event_id = event_id;
2338
2339 switch(event_id)
2340 {
2341 case BTRC_EVT_PLAY_STATUS_CHANGED:
2342 avrc_rsp.reg_notif.param.play_status = p_param->play_status;
Rohit Singha9fb00a2013-07-27 14:46:29 +05302343 /* Clear remote suspend flag, as remote device issues
2344 * suspend within 3s after pause, and DUT within 3s
2345 * initiates Play
2346 */
2347 if (avrc_rsp.reg_notif.param.play_status == PLAY_STATUS_PLAYING)
2348 btif_av_clear_remote_suspend_flag();
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08002349 break;
2350 case BTRC_EVT_TRACK_CHANGE:
2351 memcpy(&(avrc_rsp.reg_notif.param.track), &(p_param->track), sizeof(btrc_uid_t));
2352 break;
Ravi Nagarajanb88fc6c2013-04-02 07:11:14 -07002353 case BTRC_EVT_PLAY_POS_CHANGED:
2354 avrc_rsp.reg_notif.param.play_pos = p_param->song_pos;
2355 break;
Ayan Ghoshd74324f2014-07-25 17:51:32 +05302356 case BTRC_EVT_APP_SETTINGS_CHANGED:
2357 avrc_rsp.reg_notif.param.player_setting.num_attr = p_param->player_setting.num_attr;
2358 memcpy(&avrc_rsp.reg_notif.param.player_setting.attr_id,
2359 p_param->player_setting.attr_ids, 2);
2360 memcpy(&avrc_rsp.reg_notif.param.player_setting.attr_value,
2361 p_param->player_setting.attr_values, 2);
2362 break;
2363 case BTRC_EVT_ADDRESSED_PLAYER_CHANGED:
2364 avrc_rsp.reg_notif.param.addr_player.player_id = p_param->player_id;
2365 avrc_rsp.reg_notif.param.addr_player.uid_counter = 0;
2366 break;
2367 case BTRC_EVT_AVAILABLE_PLAYERS_CHANGED:
2368 avrc_rsp.reg_notif.param.evt = 0x0a;
2369 break;
2370 case BTRC_EVT_NOW_PLAYING_CONTENT_CHANGED:
2371 avrc_rsp.reg_notif.param.evt = 0x09;
2372 break;
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08002373 default:
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002374 BTIF_TRACE_WARNING("%s : Unhandled event ID : 0x%x", __FUNCTION__, event_id);
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08002375 return BT_STATUS_UNHANDLED;
2376 }
2377
2378 avrc_rsp.reg_notif.pdu = AVRC_PDU_REGISTER_NOTIFICATION;
2379 avrc_rsp.reg_notif.opcode = opcode_from_pdu(AVRC_PDU_REGISTER_NOTIFICATION);
Ayan Ghoshd74324f2014-07-25 17:51:32 +05302380 if (type == BTRC_NOTIFICATION_TYPE_REJECT)
2381 {
2382 /* Spec AVRCP 1.5 ,section 6.9.2.2, on completion
2383 * of the addressed player changed notificatons the TG shall
2384 * complete all player specific notification with AV/C C-type
2385 * Rejected with error code Addressed Player changed.
2386 * This will happen in case when music player has changed
2387 * Application should take care of sending reject response.
2388 */
2389 avrc_rsp.get_play_status.status = AVRC_STS_ADDR_PLAYER_CHG;
2390 }
2391 else
2392 {
2393 avrc_rsp.get_play_status.status = AVRC_STS_NO_ERROR;
2394 }
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08002395
2396 /* Send the response. */
2397 send_metamsg_rsp(btif_rc_cb.rc_handle, btif_rc_cb.rc_notif[event_id-1].label,
2398 ((type == BTRC_NOTIFICATION_TYPE_INTERIM)?AVRC_CMD_NOTIF:AVRC_RSP_CHANGED), &avrc_rsp);
2399 return BT_STATUS_SUCCESS;
2400}
2401
Ayan Ghoshd74324f2014-07-25 17:51:32 +05302402
2403/***************************************************************************
2404**
2405** Function get_folderitem_rsp
2406**
2407** Description Response to Get Folder Items , PDU 0x71
2408**
2409** Returns bt_status_t
2410**
2411***************************************************************************/
2412static bt_status_t get_folderitem_rsp(btrc_folder_list_entries_t *rsp)
2413{
2414 tAVRC_RESPONSE avrc_rsp;
2415 CHECK_RC_CONNECTED
2416 tAVRC_ITEM item[MAX_FOLDER_RSP_SUPPORT]; //Number of players that could be supported
2417 UINT8 index, i, xx, media_attr_cnt;
2418 UINT8 *p_conversion;
2419
2420 BTIF_TRACE_EVENT("%s() AVRC_PDU_GET_FOLDER_ITEMS", __FUNCTION__);
2421 index = IDX_GET_FOLDER_ITEMS_RSP ;
2422 avrc_rsp.get_items.pdu = AVRC_PDU_GET_FOLDER_ITEMS;
2423 avrc_rsp.get_items.opcode = AVRC_OP_BROWSE;
2424 avrc_rsp.get_items.uid_counter = rsp->uid_counter;
2425 avrc_rsp.get_items.status = rsp->status ;//4 means SUCCESS
2426 avrc_rsp.get_items.item_count = 0;
2427 BTIF_TRACE_EVENT("status =%d, item_count =%d",rsp->status, rsp->item_count);
2428
2429 for (i=0; (i < rsp->item_count && i < MAX_FOLDER_RSP_SUPPORT) ; ++i)
2430 {
2431 item[i].item_type = rsp->p_item_list[i].item_type;
2432 BTIF_TRACE_EVENT("item_type = %d", rsp->p_item_list[i].item_type);
2433 switch (item[i].item_type)
2434 {
2435 case AVRC_ITEM_PLAYER:
2436 memcpy(item[i].u.player.features, rsp->p_item_list[i].u.player.features,
2437 AVRC_FEATURE_MASK_SIZE);
2438 item[i].u.player.major_type = rsp->p_item_list[i].u.player.major_type;
2439 item[i].u.player.sub_type = rsp->p_item_list[i].u.player.sub_type;
2440 item[i].u.player.play_status = rsp->p_item_list[i].u.player.play_status;
2441 item[i].u.player.player_id = rsp->p_item_list[i].u.player.player_id;
2442 item[i].u.player.name.charset_id = rsp->p_item_list[i].u.player.name.charset_id;
2443 item[i].u.player.name.str_len = rsp->p_item_list[i].u.player.name.str_len;
2444 item[i].u.player.name.p_str = rsp->p_item_list[i].u.player.name.p_str;
2445 ++avrc_rsp.get_items.item_count;
2446 break;
2447
2448 case AVRC_ITEM_FOLDER:
2449 item[i].u.folder.type = rsp->p_item_list[i].u.folder.type;
2450 item[i].u.folder.playable = rsp->p_item_list[i].u.folder.playable;
2451 {
2452 p_conversion = (UINT8*)&(rsp->p_item_list[i].u.folder.uid);
2453 for (xx = 0; xx < AVRC_UID_SIZE; xx++)
2454 {
2455 ((UINT8 *) item[i].u.folder.uid)[AVRC_UID_SIZE - (xx + 1)] = \
2456 *p_conversion++;
2457 }
2458 }
2459
2460 item[i].u.folder.name.charset_id = rsp->p_item_list[i].u.folder.name.charset_id;
2461 item[i].u.folder.name.str_len = rsp->p_item_list[i].u.folder.name.str_len;
2462 item[i].u.folder.name.p_str = rsp->p_item_list[i].u.folder.name.p_str;
2463 ++avrc_rsp.get_items.item_count;
2464 break;
2465
2466 case AVRC_ITEM_MEDIA:
2467 item[i].u.media.type = rsp->p_item_list[i].u.media.type;
2468 {
2469 p_conversion = (UINT8*)&(rsp->p_item_list[i].u.media.uid);
2470 //BE_STREAM_TO_ARRAY(p_conversion, item[i].u.folder.uid, AVRC_UID_SIZE);
2471 for (xx = 0; xx < AVRC_UID_SIZE; xx++)
2472 {
2473 ((UINT8 *) item[i].u.folder.uid)[AVRC_UID_SIZE - (xx + 1)] = \
2474 *p_conversion++;
2475 }
2476 }
2477 item[i].u.media.name.charset_id = rsp->p_item_list[i].u.media.name.charset_id;
2478 item[i].u.media.name.str_len = rsp->p_item_list[i].u.media.name.str_len;
2479 item[i].u.media.name.p_str = rsp->p_item_list[i].u.media.name.p_str;
2480 media_attr_cnt = rsp->p_item_list[i].u.media.attr_count;
2481 item[i].u.media.attr_count = rsp->p_item_list[i].u.media.attr_count;
2482 BTIF_TRACE_ERROR("attr count = %d", media_attr_cnt);
2483 if (media_attr_cnt > 0)
2484 {
Ayan Ghosh4f287fe2014-11-09 18:38:47 +05302485 if ((item[i].u.media.p_attr_list = \
Ayan Ghoshd74324f2014-07-25 17:51:32 +05302486 (tAVRC_ATTR_ENTRY *)GKI_getbuf((UINT16)(media_attr_cnt * \
Ayan Ghosh4f287fe2014-11-09 18:38:47 +05302487 sizeof(tAVRC_ATTR_ENTRY)))) != NULL)
Ayan Ghoshd74324f2014-07-25 17:51:32 +05302488 {
2489 for (xx = 0; xx < media_attr_cnt; xx++)
2490 {
2491 item[i].u.media.p_attr_list[xx].attr_id = \
2492 rsp->p_item_list[i].u.media.p_attr_list[xx].attr_id;
2493 item[i].u.media.p_attr_list[xx].name.charset_id = \
2494 rsp->p_item_list[i].u.media.p_attr_list[xx].name.charset_id;
2495 item[i].u.media.p_attr_list[xx].name.str_len = \
2496 rsp->p_item_list[i].u.media.p_attr_list[xx].name.str_len;
2497 item[i].u.media.p_attr_list[xx].name.p_str = \
2498 rsp->p_item_list[i].u.media.p_attr_list[xx].name.p_str;
2499 BTIF_TRACE_ERROR("attr_id = %d", item[i].u.media.p_attr_list[xx].\
2500 attr_id);
2501 BTIF_TRACE_ERROR("str_len = %d", item[i].u.media.p_attr_list[xx].\
2502 name.str_len);
2503 }
2504 }
2505 else
2506 {
2507 BTIF_TRACE_ERROR("Not enough buffer allocated to accomodate attributes");
2508 item[i].u.media.attr_count = 0;
2509 }
2510 }
2511 ++avrc_rsp.get_items.item_count;
2512 break;
2513
2514 default:
2515 return BT_STATUS_UNHANDLED;
2516 break;
2517 }
2518 }
2519 if (avrc_rsp.get_items.item_count == 0) {
2520 /*As per spec Send proper Error if no Music App is registered.*/
2521 avrc_rsp.get_items.status = AVRC_STS_BAD_RANGE;
2522 }
2523 avrc_rsp.get_items.p_item_list = item;
2524 app_sendbrowsemsg(IDX_GET_FOLDER_ITEMS_RSP ,&avrc_rsp);
2525 BTIF_TRACE_ERROR("free attr list");
2526 for (i=0; (i < rsp->item_count && i < MAX_FOLDER_RSP_SUPPORT) ; ++i)
2527 {
2528 if (item[i].item_type == AVRC_ITEM_MEDIA)
2529 {
2530 if (rsp->p_item_list[i].u.media.attr_count > 0)
2531 {
2532 GKI_freebuf(item[i].u.media.p_attr_list);
2533 }
2534 }
2535 }
2536 return BT_STATUS_SUCCESS;
2537}
2538
2539/**********************************************************************
2540**
2541** Function set_addrplayer_rsp
2542**
2543** Description Response to Set Addressed Player , PDU 0x60
2544**
2545** Return status
2546**
2547*********************************************************************/
2548
2549static bt_status_t set_addrplayer_rsp(btrc_status_t status_code)
2550{
2551 tAVRC_RESPONSE avrc_rsp;
2552 CHECK_RC_CONNECTED
2553 avrc_rsp.addr_player.status = status_code;
2554 avrc_rsp.addr_player.opcode = opcode_from_pdu(AVRC_PDU_SET_ADDRESSED_PLAYER);
2555 avrc_rsp.addr_player.pdu = AVRC_PDU_SET_ADDRESSED_PLAYER;
2556 /* Send the response */
2557 SEND_METAMSG_RSP(IDX_SET_ADDRESS_PLAYER_RSP, &avrc_rsp);
2558 return BT_STATUS_SUCCESS;
2559}
2560
2561/**********************************************************************
2562**
2563** Function set_browseplayer_rsp
2564**
2565** Description Response to Set Browsed Player , PDU 0x70
2566**
2567** Return status
2568**
2569*********************************************************************/
2570
2571static bt_status_t set_browseplayer_rsp(btrc_set_browsed_player_rsp_t *p_param)
2572{
2573 tAVRC_RESPONSE avrc_rsp;
2574
2575 CHECK_RC_CONNECTED
2576 avrc_rsp.br_player.pdu = AVRC_PDU_SET_BROWSED_PLAYER;
2577 avrc_rsp.br_player.folder_depth = p_param->folder_depth;
2578 avrc_rsp.br_player.charset_id = p_param->charset_id;
2579 avrc_rsp.br_player.num_items = p_param->num_items;
2580 avrc_rsp.br_player.opcode = opcode_from_pdu(AVRC_PDU_SET_BROWSED_PLAYER);
2581 avrc_rsp.br_player.status = p_param->status;
2582 avrc_rsp.br_player.uid_counter = p_param->uid_counter;
2583 avrc_rsp.br_player.p_folders = (tAVRC_NAME*)p_param->p_folders;
2584 /* Send the response */
2585 SEND_BROWSEMSG_RSP(IDX_SET_BROWSE_PLAYER_RSP, &avrc_rsp);
2586 return BT_STATUS_SUCCESS;
2587}
2588
2589/**********************************************************************
2590**
2591** Function changepath_rsp
2592**
2593** Description Response to Change Path , PDU 0x60
2594**
2595** Return status
2596**
2597*********************************************************************/
2598
2599static bt_status_t changepath_rsp(uint8_t status_code, uint32_t item_count)
2600{
2601 tAVRC_RESPONSE avrc_rsp;
2602
2603 CHECK_RC_CONNECTED
2604 avrc_rsp.chg_path.num_items = item_count;
2605 avrc_rsp.chg_path.opcode = opcode_from_pdu(AVRC_PDU_CHANGE_PATH);
2606 avrc_rsp.chg_path.pdu = AVRC_PDU_CHANGE_PATH;
2607 avrc_rsp.chg_path.status = status_code;
2608 /* Send the response */
2609 SEND_BROWSEMSG_RSP(IDX_CHANGE_PATH_RSP, &avrc_rsp);
2610 return BT_STATUS_SUCCESS;
2611}
2612
2613/**********************************************************************
2614**
2615** Function playitem_rsp
2616**
2617** Description Response to Play Item , PDU 0x60
2618**
2619** Return status
2620**
2621*********************************************************************/
2622
2623static bt_status_t playitem_rsp(uint8_t status_code)
2624{
2625 tAVRC_RESPONSE avrc_rsp;
2626
2627 CHECK_RC_CONNECTED
2628 avrc_rsp.play_item.status = status_code;
2629 avrc_rsp.play_item.opcode = opcode_from_pdu(AVRC_PDU_PLAY_ITEM);
2630 avrc_rsp.play_item.pdu = AVRC_PDU_PLAY_ITEM;
2631 /* Send the response */
2632 SEND_METAMSG_RSP(IDX_PLAY_ITEM_RSP, &avrc_rsp);
2633 return BT_STATUS_SUCCESS;
2634}
2635
2636/**********************************************************************
2637**
2638** Function get_itemattr_rsp
2639**
2640** Description Response to Get Item , PDU 0x60
2641**
2642** Return status
2643**
2644*********************************************************************/
2645
2646static bt_status_t get_itemattr_rsp(uint8_t num_attr, btrc_element_attr_val_t *p_attrs)
2647{
2648 tAVRC_RESPONSE avrc_rsp;
2649 UINT32 i;
2650 uint8_t j;
2651 tAVRC_ATTR_ENTRY element_attrs[BTRC_MAX_ELEM_ATTR_SIZE];
2652
2653 CHECK_RC_CONNECTED
2654 memset(element_attrs, 0, sizeof(tAVRC_ATTR_ENTRY) * num_attr);
2655
2656 if (num_attr == 0)
2657 {
2658 avrc_rsp.get_attrs.status = AVRC_STS_INTERNAL_ERR;
2659 }
2660 else
2661 {
2662 for (i=0; i<num_attr; i++)
2663 {
2664 element_attrs[i].attr_id = p_attrs[i].attr_id;
2665 element_attrs[i].name.charset_id = AVRC_CHARSET_ID_UTF8;
2666 element_attrs[i].name.str_len = (UINT16)strlen((char *)p_attrs[i].text);
2667 element_attrs[i].name.p_str = p_attrs[i].text;
2668 BTIF_TRACE_DEBUG("%s attr_id:0x%x, charset_id:0x%x, str_len:%d, str:%s",
2669 __FUNCTION__, (unsigned int)element_attrs[i].attr_id,
2670 element_attrs[i].name.charset_id, element_attrs[i].name.str_len,
2671 element_attrs[i].name.p_str);
2672 }
2673 avrc_rsp.get_attrs.status = AVRC_STS_NO_ERROR;
2674 }
2675 avrc_rsp.get_attrs.attr_count = num_attr;
2676 avrc_rsp.get_attrs.p_attr_list = element_attrs;
2677 avrc_rsp.get_attrs.pdu = AVRC_PDU_GET_ITEM_ATTRIBUTES;
2678 avrc_rsp.get_attrs.opcode = opcode_from_pdu(AVRC_PDU_GET_ITEM_ATTRIBUTES);
2679 /* Send the response */
2680 SEND_BROWSEMSG_RSP(IDX_GET_ITEM_ATTR_RSP, &avrc_rsp);
2681 return BT_STATUS_SUCCESS;
2682}
2683
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08002684/***************************************************************************
2685**
Satya Calloji247c68f2013-08-01 02:14:43 -07002686** Function set_volume
2687**
2688** Description Send current volume setting to remote side.
2689** Support limited to SetAbsoluteVolume
2690** This can be enhanced to support Relative Volume (AVRCP 1.0).
2691** With RelateVolume, we will send VOLUME_UP/VOLUME_DOWN
2692** as opposed to absolute volume level
2693** volume: Should be in the range 0-127. bit7 is reseved and cannot be set
2694**
2695** Returns bt_status_t
2696**
2697***************************************************************************/
2698static bt_status_t set_volume(uint8_t volume)
2699{
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002700 BTIF_TRACE_DEBUG("%s", __FUNCTION__);
Satya Calloji247c68f2013-08-01 02:14:43 -07002701 CHECK_RC_CONNECTED
2702 tAVRC_STS status = BT_STATUS_UNSUPPORTED;
2703 rc_transaction_t *p_transaction=NULL;
2704
2705 if(btif_rc_cb.rc_volume==volume)
2706 {
2707 status=BT_STATUS_DONE;
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002708 BTIF_TRACE_ERROR("%s: volume value already set earlier: 0x%02x",__FUNCTION__, volume);
Satya Calloji247c68f2013-08-01 02:14:43 -07002709 return status;
2710 }
2711
2712 if ((btif_rc_cb.rc_features & BTA_AV_FEAT_RCTG) &&
2713 (btif_rc_cb.rc_features & BTA_AV_FEAT_ADV_CTRL))
2714 {
2715 tAVRC_COMMAND avrc_cmd = {0};
2716 BT_HDR *p_msg = NULL;
2717
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002718 BTIF_TRACE_DEBUG("%s: Peer supports absolute volume. newVolume=%d", __FUNCTION__, volume);
Satya Calloji247c68f2013-08-01 02:14:43 -07002719 avrc_cmd.volume.opcode = AVRC_OP_VENDOR;
2720 avrc_cmd.volume.pdu = AVRC_PDU_SET_ABSOLUTE_VOLUME;
2721 avrc_cmd.volume.status = AVRC_STS_NO_ERROR;
2722 avrc_cmd.volume.volume = volume;
2723
2724 if (AVRC_BldCommand(&avrc_cmd, &p_msg) == AVRC_STS_NO_ERROR)
2725 {
2726 bt_status_t tran_status=get_transaction(&p_transaction);
2727 if(BT_STATUS_SUCCESS == tran_status && NULL!=p_transaction)
2728 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002729 BTIF_TRACE_DEBUG("%s msgreq being sent out with label %d",
Satya Calloji247c68f2013-08-01 02:14:43 -07002730 __FUNCTION__,p_transaction->lbl);
2731 BTA_AvMetaCmd(btif_rc_cb.rc_handle,p_transaction->lbl, AVRC_CMD_CTRL, p_msg);
2732 status = BT_STATUS_SUCCESS;
2733 }
2734 else
2735 {
2736 if(NULL!=p_msg)
2737 GKI_freebuf(p_msg);
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002738 BTIF_TRACE_ERROR("%s: failed to obtain transaction details. status: 0x%02x",
Satya Calloji247c68f2013-08-01 02:14:43 -07002739 __FUNCTION__, tran_status);
2740 status = BT_STATUS_FAIL;
2741 }
2742 }
2743 else
2744 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002745 BTIF_TRACE_ERROR("%s: failed to build absolute volume command. status: 0x%02x",
Satya Calloji247c68f2013-08-01 02:14:43 -07002746 __FUNCTION__, status);
2747 status = BT_STATUS_FAIL;
2748 }
2749 }
2750 else
2751 status=BT_STATUS_NOT_READY;
2752 return status;
2753}
2754
2755
2756/***************************************************************************
2757**
2758** Function register_volumechange
2759**
2760** Description Register for volume change notification from remote side.
2761**
2762** Returns void
2763**
2764***************************************************************************/
2765
2766static void register_volumechange (UINT8 lbl)
2767{
2768 tAVRC_COMMAND avrc_cmd = {0};
2769 BT_HDR *p_msg = NULL;
2770 tAVRC_STS BldResp=AVRC_STS_BAD_CMD;
2771 UINT16 rv = 0;
2772 bt_status_t tran_status;
2773 rc_transaction_t *p_transaction=NULL;
2774
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002775 BTIF_TRACE_DEBUG("%s called with label:%d",__FUNCTION__,lbl);
Satya Calloji247c68f2013-08-01 02:14:43 -07002776
2777 avrc_cmd.cmd.opcode=0x00;
2778 avrc_cmd.pdu = AVRC_PDU_REGISTER_NOTIFICATION;
2779 avrc_cmd.reg_notif.event_id = AVRC_EVT_VOLUME_CHANGE;
2780 avrc_cmd.reg_notif.status = AVRC_STS_NO_ERROR;
2781
2782 BldResp=AVRC_BldCommand(&avrc_cmd, &p_msg);
2783 if(AVRC_STS_NO_ERROR==BldResp && p_msg)
2784 {
2785 p_transaction=get_transaction_by_lbl(lbl);
2786 if(NULL!=p_transaction)
2787 {
2788 BTA_AvMetaCmd(btif_rc_cb.rc_handle,p_transaction->lbl, AVRC_CMD_NOTIF, p_msg);
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002789 BTIF_TRACE_DEBUG("%s:BTA_AvMetaCmd called",__FUNCTION__);
Satya Calloji247c68f2013-08-01 02:14:43 -07002790 }
2791 else
2792 {
2793 if(NULL!=p_msg)
2794 GKI_freebuf(p_msg);
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002795 BTIF_TRACE_ERROR("%s transaction not obtained with label: %d",__FUNCTION__,lbl);
Satya Calloji247c68f2013-08-01 02:14:43 -07002796 }
2797 }
2798 else
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002799 BTIF_TRACE_ERROR("%s failed to build command:%d",__FUNCTION__,BldResp);
Satya Calloji247c68f2013-08-01 02:14:43 -07002800}
2801
2802
2803/***************************************************************************
2804**
2805** Function handle_rc_metamsg_rsp
2806**
2807** Description Handle RC metamessage response
2808**
2809** Returns void
2810**
2811***************************************************************************/
2812static void handle_rc_metamsg_rsp(tBTA_AV_META_MSG *pmeta_msg)
2813{
2814 tAVRC_RESPONSE avrc_response = {0};
2815 UINT8 scratch_buf[512] = {0};
2816 tAVRC_STS status = BT_STATUS_UNSUPPORTED;
2817
2818 if(AVRC_OP_VENDOR==pmeta_msg->p_msg->hdr.opcode &&(AVRC_RSP_CHANGED==pmeta_msg->code
2819 || AVRC_RSP_INTERIM==pmeta_msg->code || AVRC_RSP_ACCEPT==pmeta_msg->code
2820 || AVRC_RSP_REJ==pmeta_msg->code || AVRC_RSP_NOT_IMPL==pmeta_msg->code))
2821 {
2822 status=AVRC_ParsResponse(pmeta_msg->p_msg, &avrc_response, scratch_buf, sizeof(scratch_buf));
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002823 BTIF_TRACE_DEBUG("%s: code %d,event ID %d,PDU %x,parsing status %d, label:%d",
Satya Calloji247c68f2013-08-01 02:14:43 -07002824 __FUNCTION__,pmeta_msg->code,avrc_response.reg_notif.event_id,avrc_response.reg_notif.pdu,
2825 status, pmeta_msg->label);
2826
2827 if (status != AVRC_STS_NO_ERROR)
2828 {
2829 if(AVRC_PDU_REGISTER_NOTIFICATION==avrc_response.rsp.pdu
2830 && AVRC_EVT_VOLUME_CHANGE==avrc_response.reg_notif.event_id
2831 && btif_rc_cb.rc_vol_label==pmeta_msg->label)
2832 {
2833 btif_rc_cb.rc_vol_label=MAX_LABEL;
2834 release_transaction(btif_rc_cb.rc_vol_label);
2835 }
2836 else if(AVRC_PDU_SET_ABSOLUTE_VOLUME==avrc_response.rsp.pdu)
2837 {
2838 release_transaction(pmeta_msg->label);
2839 }
2840 return;
2841 }
2842 else if(AVRC_PDU_REGISTER_NOTIFICATION==avrc_response.rsp.pdu
2843 && AVRC_EVT_VOLUME_CHANGE==avrc_response.reg_notif.event_id
2844 && btif_rc_cb.rc_vol_label!=pmeta_msg->label)
2845 {
2846 // Just discard the message, if the device sends back with an incorrect label
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002847 BTIF_TRACE_DEBUG("%s:Discarding register notfn in rsp.code: %d and label %d",
Satya Calloji247c68f2013-08-01 02:14:43 -07002848 __FUNCTION__, pmeta_msg->code, pmeta_msg->label);
2849 return;
2850 }
2851 }
2852 else
2853 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002854 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 -07002855 __FUNCTION__, pmeta_msg->code, pmeta_msg->len);
2856 return;
2857 }
2858
2859 if(AVRC_PDU_REGISTER_NOTIFICATION==avrc_response.rsp.pdu
2860 && AVRC_EVT_VOLUME_CHANGE==avrc_response.reg_notif.event_id
2861 && AVRC_RSP_CHANGED==pmeta_msg->code)
2862 {
2863 /* re-register for volume change notification */
2864 // Do not re-register for rejected case, as it might get into endless loop
2865 register_volumechange(btif_rc_cb.rc_vol_label);
2866 }
2867 else if(AVRC_PDU_SET_ABSOLUTE_VOLUME==avrc_response.rsp.pdu)
2868 {
2869 /* free up the label here */
2870 release_transaction(pmeta_msg->label);
2871 }
2872
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002873 BTIF_TRACE_EVENT("%s: Passing received metamsg response to app. pdu: %s",
Satya Calloji247c68f2013-08-01 02:14:43 -07002874 __FUNCTION__, dump_rc_pdu(avrc_response.pdu));
2875 btif_rc_upstreams_rsp_evt((uint16_t)avrc_response.rsp.pdu, &avrc_response, pmeta_msg->code,
2876 pmeta_msg->label);
2877}
2878
2879
2880/***************************************************************************
2881**
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08002882** Function cleanup
2883**
2884** Description Closes the AVRC interface
2885**
2886** Returns void
2887**
2888***************************************************************************/
2889static void cleanup()
2890{
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002891 BTIF_TRACE_EVENT("## %s ##", __FUNCTION__);
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08002892 close_uinput();
2893 if (bt_rc_callbacks)
2894 {
2895 bt_rc_callbacks = NULL;
2896 }
2897 memset(&btif_rc_cb, 0, sizeof(btif_rc_cb_t));
Satya Calloji247c68f2013-08-01 02:14:43 -07002898 lbl_destroy();
Ayan Ghoshf4f74a82014-09-08 16:00:22 +05302899 BTIF_TRACE_EVENT("## %s ## completed", __FUNCTION__);
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08002900}
2901
Ayan Ghoshf4f74a82014-09-08 16:00:22 +05302902/***************************************************************************
2903**
2904** Function cleanup_ctrl
2905**
2906** Description Closes the AVRC Controller interface
2907**
2908** Returns void
2909**
2910***************************************************************************/
2911static void cleanup_ctrl()
2912{
2913 BTIF_TRACE_EVENT("## %s ##", __FUNCTION__);
2914
2915 if (bt_rc_ctrl_callbacks)
2916 {
2917 bt_rc_ctrl_callbacks = NULL;
2918 }
2919 memset(&btif_rc_cb, 0, sizeof(btif_rc_cb_t));
2920 lbl_destroy();
2921 BTIF_TRACE_EVENT("## %s ## completed", __FUNCTION__);
2922}
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08002923
Mike Lockwood4ad470e2014-06-02 16:21:49 -07002924static bt_status_t send_passthrough_cmd(bt_bdaddr_t *bd_addr, uint8_t key_code, uint8_t key_state)
2925{
2926 tAVRC_STS status = BT_STATUS_UNSUPPORTED;
2927#if (AVRC_CTLR_INCLUDED == TRUE)
2928 CHECK_RC_CONNECTED
2929 rc_transaction_t *p_transaction=NULL;
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002930 BTIF_TRACE_DEBUG("%s: key-code: %d, key-state: %d", __FUNCTION__,
Mike Lockwood4ad470e2014-06-02 16:21:49 -07002931 key_code, key_state);
2932 if (btif_rc_cb.rc_features & BTA_AV_FEAT_RCTG)
2933 {
2934 tAVRC_MSG_PASS avrc_cmd;
2935 bt_status_t tran_status = get_transaction(&p_transaction);
2936 if(BT_STATUS_SUCCESS == tran_status && NULL != p_transaction)
2937 {
2938 BTA_AvRemoteCmd(btif_rc_cb.rc_handle, p_transaction->lbl,
2939 (tBTA_AV_RC)key_code, (tBTA_AV_STATE)key_state);
2940 status = BT_STATUS_SUCCESS;
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002941 BTIF_TRACE_DEBUG("%s: succesfully sent passthrough command to BTA", __FUNCTION__);
Mike Lockwood4ad470e2014-06-02 16:21:49 -07002942 }
2943 else
2944 {
2945 status = BT_STATUS_FAIL;
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002946 BTIF_TRACE_DEBUG("%s: error in fetching transaction", __FUNCTION__);
Mike Lockwood4ad470e2014-06-02 16:21:49 -07002947 }
2948 }
2949 else
2950 {
2951 status = BT_STATUS_FAIL;
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002952 BTIF_TRACE_DEBUG("%s: feature not supported", __FUNCTION__);
Mike Lockwood4ad470e2014-06-02 16:21:49 -07002953 }
2954#else
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002955 BTIF_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__);
Mike Lockwood4ad470e2014-06-02 16:21:49 -07002956#endif
2957 return status;
2958}
2959
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08002960static const btrc_interface_t bt_rc_interface = {
2961 sizeof(bt_rc_interface),
2962 init,
2963 get_play_status_rsp,
Ayan Ghoshd74324f2014-07-25 17:51:32 +05302964 list_player_app_attr_rsp, /* list_player_app_attr_rsp */
2965 list_player_app_value_rsp, /* list_player_app_value_rsp */
2966 get_player_app_value_rsp, /* get_player_app_value_rsp PDU 0x13*/
2967 get_player_app_attr_text_rsp, /* get_player_app_attr_text_rsp */
2968 get_player_app_value_text_rsp,/* get_player_app_value_text_rsp */
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08002969 get_element_attr_rsp,
Ayan Ghoshd74324f2014-07-25 17:51:32 +05302970 set_player_app_value_rsp, /* set_player_app_value_rsp */
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08002971 register_notification_rsp,
Satya Calloji247c68f2013-08-01 02:14:43 -07002972 set_volume,
Ayan Ghoshd74324f2014-07-25 17:51:32 +05302973 get_folderitem_rsp,
2974 set_addrplayer_rsp,
2975 set_browseplayer_rsp,
2976 changepath_rsp,
2977 playitem_rsp,
2978 get_itemattr_rsp,
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08002979 cleanup,
2980};
2981
Mike Lockwood4ad470e2014-06-02 16:21:49 -07002982static const btrc_ctrl_interface_t bt_rc_ctrl_interface = {
2983 sizeof(bt_rc_ctrl_interface),
2984 init_ctrl,
2985 send_passthrough_cmd,
Ayan Ghoshf4f74a82014-09-08 16:00:22 +05302986 cleanup_ctrl,
Mike Lockwood4ad470e2014-06-02 16:21:49 -07002987};
2988
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08002989/*******************************************************************************
2990**
2991** Function btif_rc_get_interface
2992**
Mike Lockwood4ad470e2014-06-02 16:21:49 -07002993** Description Get the AVRCP Target callback interface
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08002994**
2995** Returns btav_interface_t
2996**
2997*******************************************************************************/
2998const btrc_interface_t *btif_rc_get_interface(void)
2999{
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07003000 BTIF_TRACE_EVENT("%s", __FUNCTION__);
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08003001 return &bt_rc_interface;
Satya Calloji247c68f2013-08-01 02:14:43 -07003002}
3003
3004/*******************************************************************************
Mike Lockwood4ad470e2014-06-02 16:21:49 -07003005**
3006** Function btif_rc_ctrl_get_interface
3007**
3008** Description Get the AVRCP Controller callback interface
3009**
3010** Returns btav_interface_t
3011**
3012*******************************************************************************/
3013const btrc_ctrl_interface_t *btif_rc_ctrl_get_interface(void)
3014{
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07003015 BTIF_TRACE_EVENT("%s", __FUNCTION__);
Mike Lockwood4ad470e2014-06-02 16:21:49 -07003016 return &bt_rc_ctrl_interface;
3017}
3018
3019/*******************************************************************************
Satya Calloji247c68f2013-08-01 02:14:43 -07003020** Function initialize_transaction
3021**
3022** Description Initializes fields of the transaction structure
3023**
3024** Returns void
3025*******************************************************************************/
3026static void initialize_transaction(int lbl)
3027{
3028 pthread_mutex_lock(&device.lbllock);
3029 if(lbl < MAX_TRANSACTIONS_PER_SESSION)
3030 {
3031 device.transaction[lbl].lbl = lbl;
3032 device.transaction[lbl].in_use=FALSE;
3033 device.transaction[lbl].handle=0;
3034 }
3035 pthread_mutex_unlock(&device.lbllock);
3036}
3037
3038/*******************************************************************************
3039** Function lbl_init
3040**
3041** Description Initializes label structures and mutexes.
3042**
3043** Returns void
3044*******************************************************************************/
3045void lbl_init()
3046{
3047 memset(&device,0,sizeof(rc_device_t));
3048 pthread_mutexattr_t attr;
3049 pthread_mutexattr_init(&attr);
3050 pthread_mutex_init(&(device.lbllock), &attr);
3051 pthread_mutexattr_destroy(&attr);
3052 init_all_transactions();
3053}
3054
3055/*******************************************************************************
3056**
3057** Function init_all_transactions
3058**
3059** Description Initializes all transactions
3060**
3061** Returns void
3062*******************************************************************************/
3063void init_all_transactions()
3064{
3065 UINT8 txn_indx=0;
3066 for(txn_indx=0; txn_indx < MAX_TRANSACTIONS_PER_SESSION; txn_indx++)
3067 {
3068 initialize_transaction(txn_indx);
3069 }
3070}
3071
3072/*******************************************************************************
3073**
3074** Function get_transaction_by_lbl
3075**
3076** Description Will return a transaction based on the label. If not inuse
3077** will return an error.
3078**
3079** Returns bt_status_t
3080*******************************************************************************/
3081rc_transaction_t *get_transaction_by_lbl(UINT8 lbl)
3082{
3083 rc_transaction_t *transaction = NULL;
3084 pthread_mutex_lock(&device.lbllock);
3085
3086 /* Determine if this is a valid label */
3087 if (lbl < MAX_TRANSACTIONS_PER_SESSION)
3088 {
3089 if (FALSE==device.transaction[lbl].in_use)
3090 {
3091 transaction = NULL;
3092 }
3093 else
3094 {
3095 transaction = &(device.transaction[lbl]);
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07003096 BTIF_TRACE_DEBUG("%s: Got transaction.label: %d",__FUNCTION__,lbl);
Satya Calloji247c68f2013-08-01 02:14:43 -07003097 }
3098 }
3099
3100 pthread_mutex_unlock(&device.lbllock);
3101 return transaction;
3102}
3103
3104/*******************************************************************************
3105**
3106** Function get_transaction
3107**
3108** Description Obtains the transaction details.
3109**
3110** Returns bt_status_t
3111*******************************************************************************/
3112
3113bt_status_t get_transaction(rc_transaction_t **ptransaction)
3114{
3115 bt_status_t result = BT_STATUS_NOMEM;
3116 UINT8 i=0;
3117 pthread_mutex_lock(&device.lbllock);
3118
3119 // Check for unused transactions
3120 for (i=0; i<MAX_TRANSACTIONS_PER_SESSION; i++)
3121 {
3122 if (FALSE==device.transaction[i].in_use)
3123 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07003124 BTIF_TRACE_DEBUG("%s:Got transaction.label: %d",__FUNCTION__,device.transaction[i].lbl);
Satya Calloji247c68f2013-08-01 02:14:43 -07003125 device.transaction[i].in_use = TRUE;
3126 *ptransaction = &(device.transaction[i]);
3127 result = BT_STATUS_SUCCESS;
3128 break;
3129 }
3130 }
3131
3132 pthread_mutex_unlock(&device.lbllock);
3133 return result;
3134}
3135
3136
3137/*******************************************************************************
3138**
3139** Function release_transaction
3140**
3141** Description Will release a transaction for reuse
3142**
3143** Returns bt_status_t
3144*******************************************************************************/
3145void release_transaction(UINT8 lbl)
3146{
3147 rc_transaction_t *transaction = get_transaction_by_lbl(lbl);
3148
3149 /* If the transaction is in use... */
3150 if (transaction != NULL)
3151 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07003152 BTIF_TRACE_DEBUG("%s: lbl: %d", __FUNCTION__, lbl);
Satya Calloji247c68f2013-08-01 02:14:43 -07003153 initialize_transaction(lbl);
3154 }
3155}
3156
3157/*******************************************************************************
3158**
3159** Function lbl_destroy
3160**
3161** Description Cleanup of the mutex
3162**
3163** Returns void
3164*******************************************************************************/
3165void lbl_destroy()
3166{
3167 pthread_mutex_destroy(&(device.lbllock));
3168}
Matthew Xiea7ae4a12013-10-24 01:09:52 -07003169
3170/*******************************************************************************
3171** Function dev_blacklisted_for_absolute_volume
3172**
3173** Description Blacklist Devices that donot handle absolute volume well
Matthew Xie7850a932013-11-05 17:19:39 -08003174** We are blacklisting all the devices that are not in whitelist
Matthew Xiea7ae4a12013-10-24 01:09:52 -07003175**
3176** Returns True if the device is in the list
3177*******************************************************************************/
3178static BOOLEAN dev_blacklisted_for_absolute_volume(BD_ADDR peer_dev)
3179{
3180 int i;
Thomas.TT_Linc9fbcde2014-04-07 16:13:06 +08003181 char *dev_name_str = NULL;
Matthew Xie7850a932013-11-05 17:19:39 -08003182 int whitelist_size = sizeof(rc_white_addr_prefix)/sizeof(rc_white_addr_prefix[0]);
Thomas.TT_Linc9fbcde2014-04-07 16:13:06 +08003183
Matthew Xie7850a932013-11-05 17:19:39 -08003184 for (i = 0; i < whitelist_size; i++) {
3185 if (rc_white_addr_prefix[i][0] == peer_dev[0] &&
3186 rc_white_addr_prefix[i][1] == peer_dev[1] &&
3187 rc_white_addr_prefix[i][2] == peer_dev[2]) {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07003188 BTIF_TRACE_DEBUG("whitelist absolute volume for %02x:%02x:%02x",
Thomas.TT_Linc9fbcde2014-04-07 16:13:06 +08003189 peer_dev[0], peer_dev[1], peer_dev[2]);
Matthew Xie7850a932013-11-05 17:19:39 -08003190 return FALSE;
Matthew Xiea7ae4a12013-10-24 01:09:52 -07003191 }
3192 }
Thomas.TT_Linc9fbcde2014-04-07 16:13:06 +08003193
3194 dev_name_str = BTM_SecReadDevName(peer_dev);
3195 whitelist_size = sizeof(rc_white_name)/sizeof(char*);
3196 if (dev_name_str != NULL) {
3197 for (i = 0; i < whitelist_size; i++) {
3198 if (strcmp(dev_name_str, rc_white_name[i]) == 0) {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07003199 BTIF_TRACE_DEBUG("whitelist absolute volume for %s", dev_name_str);
Thomas.TT_Linc9fbcde2014-04-07 16:13:06 +08003200 return FALSE;
3201 }
3202 }
3203 }
3204
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07003205 BTIF_TRACE_WARNING("blacklist absolute volume for %02x:%02x:%02x, name = %s",
Thomas.TT_Linc9fbcde2014-04-07 16:13:06 +08003206 peer_dev[0], peer_dev[1], peer_dev[2], dev_name_str);
Matthew Xie7850a932013-11-05 17:19:39 -08003207 return TRUE;
Matthew Xiea7ae4a12013-10-24 01:09:52 -07003208}